diff --git a/app/package.json b/app/package.json index 8b128cb413d..5e327c9c229 100644 --- a/app/package.json +++ b/app/package.json @@ -46,6 +46,7 @@ "memoize-one": "^4.0.3", "mri": "^1.1.0", "p-limit": "^2.2.0", + "p-memoize": "^7.1.1", "primer-support": "^4.0.0", "prop-types": "^15.7.2", "quick-lru": "^3.0.0", diff --git a/app/src/lib/git/core.ts b/app/src/lib/git/core.ts index 81f3b1f2dca..c366fe5e530 100644 --- a/app/src/lib/git/core.ts +++ b/app/src/lib/git/core.ts @@ -157,6 +157,16 @@ export class GitError extends Error { } } +export const isGitError = ( + e: unknown, + parsedError?: DugiteError +): e is GitError => { + return ( + e instanceof GitError && + (parsedError === undefined || e.result.gitError === parsedError) + ) +} + /** * Shell out to git with the given arguments, at the given path. * diff --git a/app/src/lib/git/merge-tree.ts b/app/src/lib/git/merge-tree.ts index eb6b5a58770..a6e469901c1 100644 --- a/app/src/lib/git/merge-tree.ts +++ b/app/src/lib/git/merge-tree.ts @@ -1,117 +1,41 @@ -import byline from 'byline' import { Branch } from '../../models/branch' import { ComputedAction } from '../../models/computed-action' import { MergeTreeResult } from '../../models/merge' import { Repository } from '../../models/repository' -import { isErrnoException } from '../errno-exception' -import { getMergeBase } from './merge' -import { spawnGit } from './spawn' - -// the merge-tree output is a collection of entries like this -// -// changed in both -// base 100644 f69fbc5c40409a1db7a3f8353bfffe46a21d6054 atom/browser/resources/mac/Info.plist -// our 100644 9094f0f7335edf833d51f688851e6a105de60433 atom/browser/resources/mac/Info.plist -// their 100644 2dd8bc646cff3869557549a39477e30022e6cfdd atom/browser/resources/mac/Info.plist -// @@ -17,9 +17,15 @@ -// CFBundleIconFile -// electron.icns -// CFBundleVersion -// +<<<<<<< .our -// 4.0.0 -// CFBundleShortVersionString -// 4.0.0 -// +======= -// + 1.4.16 -// + CFBundleShortVersionString -// + 1.4.16 -// +>>>>>>> .their -// LSApplicationCategoryType -//public.app-category.developer-tools -// LSMinimumSystemVersion - -// The first line for each entry is what I'm referring to as the the header -// This regex filters on the known entries that can appear -const contextHeaderRe = - /^(merged|added in remote|removed in remote|changed in both|removed in local|added in both)$/ - -const conflictMarkerRe = /^\+[<>=]{7}$/ +import { git, isGitError } from './core' +import { GitError } from 'dugite' export async function determineMergeability( repository: Repository, ours: Branch, theirs: Branch -): Promise { - const mergeBase = await getMergeBase(repository, ours.tip.sha, theirs.tip.sha) - - if (mergeBase === null) { - return { kind: ComputedAction.Invalid } - } - - if (mergeBase === ours.tip.sha || mergeBase === theirs.tip.sha) { - return { kind: ComputedAction.Clean } - } - - const process = await spawnGit( - ['merge-tree', mergeBase, ours.tip.sha, theirs.tip.sha], +) { + return git( + [ + 'merge-tree', + '--write-tree', + '--name-only', + '--no-messages', + '-z', + ours.tip.sha, + theirs.tip.sha, + ], repository.path, - 'mergeTree' + 'determineMergeability', + { successExitCodes: new Set([0, 1]) } ) - - return await new Promise((resolve, reject) => { - const mergeTreeResultPromise: Promise = - process.stdout !== null - ? parseMergeTreeResult(process.stdout) - : Promise.reject(new Error('Failed reading merge-tree output')) - - // If this is an exception thrown by Node.js while attempting to - // spawn let's keep the salient details but include the name of - // the operation. - process.on('error', e => - reject( - isErrnoException(e) ? new Error(`merge-tree failed: ${e.code}`) : e - ) - ) - - process.on('exit', code => { - if (code !== 0) { - reject(new Error(`merge-tree exited with code '${code}'`)) - } else { - mergeTreeResultPromise.then(resolve, reject) - } + .then(({ stdout }) => { + // The output will be "\0[\0]*" so we can get the + // number of conflicted files by counting the number of null bytes and + // subtracting one for the tree id. + const conflictedFiles = (stdout.match(/\0/g)?.length ?? 0) - 1 + return conflictedFiles > 0 + ? { kind: ComputedAction.Conflicts, conflictedFiles } + : { kind: ComputedAction.Clean } }) - }) -} - -export function parseMergeTreeResult(stream: NodeJS.ReadableStream) { - return new Promise(resolve => { - let seenConflictMarker = false - let conflictedFiles = 0 - - stream - .pipe(byline()) - .on('data', (line: string) => { - // New header means new file, reset conflict flag and record if we've - // seen a conflict in this file or not - if (contextHeaderRe.test(line)) { - if (seenConflictMarker) { - conflictedFiles++ - seenConflictMarker = false - } - } else if (conflictMarkerRe.test(line)) { - seenConflictMarker = true - } - }) - .on('end', () => { - if (seenConflictMarker) { - conflictedFiles++ - } - - resolve( - conflictedFiles > 0 - ? { kind: ComputedAction.Conflicts, conflictedFiles } - : { kind: ComputedAction.Clean } - ) - }) - }) + .catch(e => + isGitError(e, GitError.CannotMergeUnrelatedHistories) + ? Promise.resolve({ kind: ComputedAction.Invalid }) + : Promise.reject(e) + ) } diff --git a/app/src/ui/multi-commit-operation/choose-branch/base-choose-branch-dialog.tsx b/app/src/ui/multi-commit-operation/choose-branch/base-choose-branch-dialog.tsx index 72e3e235a3b..aefa83d5ff6 100644 --- a/app/src/ui/multi-commit-operation/choose-branch/base-choose-branch-dialog.tsx +++ b/app/src/ui/multi-commit-operation/choose-branch/base-choose-branch-dialog.tsx @@ -39,6 +39,12 @@ export function canStartOperation( return false } + // We can always start if there are conflicts, we'll just + // have to deal with the conflicts post the operation + if (statusKind === ComputedAction.Conflicts) { + return true + } + // Are there even commits to operate on? if (commitCount === undefined || commitCount === 0) { return false diff --git a/app/src/ui/multi-commit-operation/choose-branch/merge-choose-branch-dialog.tsx b/app/src/ui/multi-commit-operation/choose-branch/merge-choose-branch-dialog.tsx index 891f7fa6a6b..2de231e524c 100644 --- a/app/src/ui/multi-commit-operation/choose-branch/merge-choose-branch-dialog.tsx +++ b/app/src/ui/multi-commit-operation/choose-branch/merge-choose-branch-dialog.tsx @@ -1,8 +1,7 @@ import React from 'react' import { getAheadBehind, revSymmetricDifference } from '../../../lib/git' import { determineMergeability } from '../../../lib/git/merge-tree' -import { promiseWithMinimumTimeout } from '../../../lib/promise' -import { Branch } from '../../../models/branch' +import { Branch, IAheadBehind } from '../../../models/branch' import { ComputedAction } from '../../../models/computed-action' import { MergeTreeResult } from '../../../models/merge' import { MultiCommitOperationKind } from '../../../models/multi-commit-operation' @@ -14,6 +13,19 @@ import { canStartOperation, } from './base-choose-branch-dialog' import { truncateWithEllipsis } from '../../../lib/truncate-with-ellipsis' +import QuickLRU from 'quick-lru' +import pMemoize from 'p-memoize' + +const mergeTreeCache = pMemoize(determineMergeability, { + cache: new QuickLRU({ maxSize: 250 }), + cacheKey: ([_, ours, theirs]: Parameters) => + `${ours.tip.sha} <- ${theirs.tip.sha}`, +}) + +const aheadBehindCache = pMemoize(getAheadBehind, { + cache: new QuickLRU({ maxSize: 250 }), + cacheKey: ([_, range]: Parameters) => range, +}) interface IMergeChooseBranchDialogState { readonly commitCount: number @@ -69,14 +81,18 @@ export class MergeChooseBranchDialog extends React.Component< } private onSelectionChanged = (selectedBranch: Branch | null) => { - this.setState({ selectedBranch }) - if (selectedBranch === null) { - this.setState({ commitCount: 0, mergeStatus: null }) - return + this.setState({ selectedBranch, commitCount: 0, mergeStatus: null }) + } else { + this.setState( + { + selectedBranch, + commitCount: 0, + mergeStatus: { kind: ComputedAction.Loading }, + }, + () => this.updateStatus(selectedBranch) + ) } - - this.updateStatus(selectedBranch) } private getDialogTitle = () => { @@ -97,22 +113,23 @@ export class MergeChooseBranchDialog extends React.Component< private updateStatus = async (branch: Branch) => { const { currentBranch, repository } = this.props - this.setState({ - commitCount: 0, - mergeStatus: { kind: ComputedAction.Loading }, - }) - const mergeStatus = await promiseWithMinimumTimeout( - () => determineMergeability(repository, currentBranch, branch), - 500 + const mergeStatus = await mergeTreeCache( + repository, + currentBranch, + branch ).catch(e => { log.error('Failed determining mergeability', e) return { kind: ComputedAction.Clean } }) - // The user has selected a different branch since we started, so don't - // update the preview with stale data. - if (this.state.selectedBranch !== branch) { + // The user has selected a different branch since we started or the branch + // has changed, so don't update the preview with stale data. + // + // We don't have to check if the state changed from underneath us if we + // loaded the status from cache, because that means we never kicked off an + // async operation. + if (this.state.selectedBranch?.tip.sha !== branch.tip.sha) { return } @@ -125,10 +142,10 @@ export class MergeChooseBranchDialog extends React.Component< // Commit count is used in the UI output as well as determining whether the // submit button is enabled const range = revSymmetricDifference('', branch.name) - const aheadBehind = await getAheadBehind(this.props.repository, range) + const aheadBehind = await aheadBehindCache(repository, range) const commitCount = aheadBehind ? aheadBehind.behind : 0 - if (this.state.selectedBranch !== branch) { + if (this.state.selectedBranch.tip.sha !== branch.tip.sha) { return } diff --git a/app/test/fixtures/merge-parser/desktop/failed-merge-master-into-stale-branch-really.txt b/app/test/fixtures/merge-parser/desktop/failed-merge-master-into-stale-branch-really.txt deleted file mode 100644 index 24827c3c4f4..00000000000 --- a/app/test/fixtures/merge-parser/desktop/failed-merge-master-into-stale-branch-really.txt +++ /dev/null @@ -1,27968 +0,0 @@ -added in remote - their 100644 796fcffcd129e9594b5d578f18893807a5dfd4e8 .babelrc -@@ -0,0 +1,3 @@ -+{ -+ "plugins": ["syntax-dynamic-import"] -+} -merged - result 100644 1ec8067f831c1ed1de768f65d3f2df91c43b29ae .eslintrc.yml - our 100644 f724d1b1129c863e41f4e78d2b1a200c0aea07e7 .eslintrc.yml -@@ -66,6 +66,9 @@ - eqeqeq: - - error - - smart -+ strict: -+ - error -+ - global - - ########### - # SPECIAL # -@@ -79,7 +82,15 @@ - - selector: ExportDefaultDeclaration - message: Use of default exports is forbidden - -+overrides: -+ - files: '*.d.ts' -+ rules: -+ strict: -+ - error -+ - never -+ - parserOptions: - sourceType: module - ecmaFeatures: - jsx: true -+ -merged - result 100644 59072918c96565e2427754f755ca662d7b067423 .github/CONTRIBUTING.md - our 100644 9d5b8dd9584adfcadfca0e70c747b3519a315309 .github/CONTRIBUTING.md -@@ -72,15 +72,15 @@ - - Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). - --Simply create an issue on the [GitHub Desktop issue tracker](https://github.com/desktop/desktop/issues) --and fill out the provided [issue template](ISSUE_TEMPLATE.md). -+Simply create an issue on the [GitHub Desktop issue tracker](https://github.com/desktop/desktop/issues/new?template=bug_report.md) -+and fill out the provided issue template. - - The information we are interested in includes: - - - details about your environment - which build, which operating system - - details about reproducing the issue - what steps to take, what happens, how - often it happens -- - other relevant information - log files, screenshots, etc. -+ - other relevant information - log files, screenshots, etc - - ### Suggesting Enhancements - -@@ -107,20 +107,21 @@ - - Enhancement suggestions are tracked as [GitHub issues](https://guides.github.com/features/issues/). - --Simply create an issue on the [GitHub Desktop issue tracker](https://github.com/desktop/desktop/issues) --and provide the following information: -+Simply create an issue on the [GitHub Desktop issue tracker](https://github.com/desktop/desktop/issues/new?template=feature_request.md) -+and fill out the provided issue template. - --* **Use a clear and descriptive title** for the issue to identify the -- suggestion. --* **Provide a step-by-step description of the suggested enhancement** in as -- much detail as possible. This additional context helps the maintainers to -- understand the enhancement from your perspective --* **Explain why this enhancement would be useful** to GitHub Desktop users. -+Some additional advice: -+ -+* **Use a clear and descriptive title** for the feature request -+* **Provide a step-by-step description of the suggested enhancement** -+ This additional context helps the maintainers understand the enhancement from -+ your perspective -+* **Explain why this enhancement would be useful** to GitHub Desktop users - * **Include screenshots and animated GIFs** if relevant to help you demonstrate - the steps or point out the part of GitHub Desktop which the suggestion is - related to. You can use [this tool](http://www.cockos.com/licecap/) to record -- GIFs on macOS and Windows. --* **List some other applications where this enhancement exists, if applicable.** -+ GIFs on macOS and Windows -+* **List some other applications where this enhancement exists, if applicable** - - ### Help Wanted - -@@ -148,27 +149,30 @@ - - | Label name | :mag_right: | Description | - | --- | --- | --- | --| `enhancement` | [search](https://github.com/desktop/desktop/labels/enhancement) | Feature requests. | --| `bug` | [search](https://github.com/desktop/desktop/labels/bug) | Confirmed bugs or reports that are very likely to be bugs. | --| `more-information-needed` | [search](https://github.com/desktop/desktop/labels/more-information-needed) | More information needs to be collected about these problems or feature requests (e.g. steps to reproduce). | --| `reviewer-needs-to-reproduce` | [search](https://github.com/desktop/desktop/labels/reviewer-needs-to-reproduce) | Likely bugs, but haven't been reliably reproduced by a reviewer. | --| `stale` | [search](https://github.com/desktop/desktop/labels/stale) | Issues that are inactive and marked to be closed. | --| `macOS` | [search](https://github.com/desktop/desktop/labels/macOS) | Issues specific to macOS users. | --| `Windows` | [search](https://github.com/desktop/desktop/labels/Windows) | Issues specific to Windows users. | --| `codemirror` | [search](https://github.com/desktop/desktop/labels/codemirror) | Issues related to our use of [CodeMirror](https://codemirror.net/) that may require upstream fixes. | --| `electron` | [search](https://github.com/desktop/desktop/labels/electron) | Issues related to our use of [Electron](https://electron.atom.io) that may require upstream fixes. | -+| `enhancement` | [search](https://github.com/desktop/desktop/labels/enhancement) | Feature requests | -+| `bug` | [search](https://github.com/desktop/desktop/labels/bug) | Confirmed bugs or reports that are very likely to be bugs | -+| `more-information-needed` | [search](https://github.com/desktop/desktop/labels/more-information-needed) | More information needs to be collected about these problems or feature requests (e.g. steps to reproduce) | -+| `reviewer-needs-to-reproduce` | [search](https://github.com/desktop/desktop/labels/reviewer-needs-to-reproduce) | Potential bugs that still need to be reliably reproduced by a reviewer | -+| `stale` | [search](https://github.com/desktop/desktop/labels/stale) | Issues that are inactive and marked to be closed | -+| `macOS` | [search](https://github.com/desktop/desktop/labels/macOS) | Issues specific to macOS users | -+| `Windows` | [search](https://github.com/desktop/desktop/labels/Windows) | Issues specific to Windows users | -+| `codemirror` | [search](https://github.com/desktop/desktop/labels/codemirror) | Issues related to our use of [CodeMirror](https://codemirror.net/) that may require upstream fixes | -+| `electron` | [search](https://github.com/desktop/desktop/labels/electron) | Issues related to our use of [Electron](https://electron.atom.io) that may require upstream fixes | -+| `themes` | [search](https://github.com/desktop/desktop/labels/themes) | Issues related the light or dark themes that ship in Desktop | -+| `user-research` | [search](https://github.com/desktop/desktop/labels/user-research) | Issues that might benefit from user interviews, validations, and/or usability testing | -+| `integrations` | [search](https://github.com/desktop/desktop/labels/integrations) | Issues related to editor and shell integrations that ship in Desktop | - - #### Topics - - | Label name | :mag_right: | Description | - | --- | --- | --- | --| `help wanted` | [search](https://github.com/desktop/desktop/labels/help%20wanted) | Issues marked as ideal for external contributors. | --| `tech-debt` | [search](https://github.com/desktop/desktop/labels/tech-debt) | Issues related to code or architecture decisions. | --| `needs-design-input` | [search](https://github.com/desktop/desktop/labels/needs-design-input) | Issues that require design input from the core team before the work can be started. | -+| `help wanted` | [search](https://github.com/desktop/desktop/labels/help%20wanted) | Issues marked as ideal for external contributors | -+| `tech-debt` | [search](https://github.com/desktop/desktop/labels/tech-debt) | Issues related to code or architecture decisions | -+| `needs-design-input` | [search](https://github.com/desktop/desktop/labels/needs-design-input) | Issues that require design input from the core team before the work can be started | - - #### Workflow - - | Label name | :mag_right: | Description | - | --- | --- | --- | --| `infrastructure` | [search](https://github.com/desktop/desktop/labels/infrastructure) | Pull requests not related to the core application - documentation, dependencies, tooling, etc. | --| `ready-for-review` | [search](https://github.com/desktop/desktop/labels/ready-for-review) | Pull Requests that are ready to be reviewed by the maintainers. | -+| `infrastructure` | [search](https://github.com/desktop/desktop/labels/infrastructure) | Pull requests not related to the core application - documentation, dependencies, tooling, etc | -+| `ready-for-review` | [search](https://github.com/desktop/desktop/labels/ready-for-review) | Pull Requests that are ready to be reviewed by the maintainers | -added in remote - their 100644 56219510678c2797ba48167a1e1d912ccf843eac .github/ISSUE_TEMPLATE/bug_report.md -@@ -0,0 +1,71 @@ -+--- -+name: 🐛 Bug report -+about: Report a problem encountered while using GitHub Desktop -+ -+--- -+ -+ -+ -+## Description -+ -+ -+ -+## Version -+ -+* GitHub Desktop: -+ -+* Operating system: -+ -+ -+## Steps to Reproduce -+ -+ -+### Expected Behavior -+ -+ -+### Actual Behavior -+ -+ -+ -+## Additional Information -+ -+ -+### Logs -+ -added in remote - their 100644 7c297531a2dd774e2b066ddc50384a12f5e8e034 .github/ISSUE_TEMPLATE/feature_request.md -@@ -0,0 +1,17 @@ -+--- -+name: 🎉 Feature request -+about: Suggest an idea to improve GitHub Desktop -+--- -+ -+**Is your feature request related to a problem? Please describe.** -+A clear and concise description of what the problem is. Ex. I have an issue when [...] -+ -+**Describe the solution you'd like** -+A clear and concise description of what you want to happen. Add any considered drawbacks. -+ -+**Describe alternatives you've considered** -+A clear and concise description of any alternative solutions or features you've considered. -+ -+**Teachability, Documentation, Adoption, Migration Strategy** -+If you can, explain how users will be able to use this. This will help the core team understand how the feature would work, and assist with future work like documentation. -+Screenshots or mockups here are a great help! -\ No newline at end of file -removed in remote - base 100644 65c8c0a5f5c37299d369ce4811128ae829368d2d .github/ISSUE_TEMPLATE.md - our 100644 65c8c0a5f5c37299d369ce4811128ae829368d2d .github/ISSUE_TEMPLATE.md -@@ -1,65 +0,0 @@ -- -- --## Description -- -- -- --## Version -- --* GitHub Desktop: -- --* Operating system: -- -- --## Steps to Reproduce -- -- --### Expected Behavior -- -- --### Actual Behavior -- -- -- --## Additional Information -- -- --### Logs -- -merged - result 100644 63a2cc1a341c354faf7c4979d2fffb86d5e93501 .gitignore - our 100644 de84018cf2395164cee116bb3a01759e6cf3c41a .gitignore -@@ -9,3 +9,4 @@ - .idea/ - .vs/ - .eslintcache -+*.iml -merged - result 100644 dba04c1e1786b2c5f953ebf2c24c6fcc615c2d9a .node-version - our 100644 32c861f970d80180ef7668a04d5e3ce61bbd706e .node-version -@@ -1 +1 @@ --8.9.2 -+8.11.3 -merged - result 100644 ab983e8df0a9388373270ef9d669c8806ec4ccf9 .prettierrc.yml - our 100644 a99d2fbed4d8d42c708293ed1a1d310b3ff27c5a .prettierrc.yml -@@ -2,3 +2,8 @@ - trailingComma: es5 - semi: false - proseWrap: always -+ -+overrides: -+- files: "*.scss" -+ options: -+ printWidth: 200 -\ No newline at end of file -merged - result 100644 fde223649b6eef6edf60d8726f22ddd799873819 .travis.yml - our 100644 15b264ab77bd3f42b71b4f5f9072b455a964ca95 .travis.yml -@@ -38,7 +38,7 @@ - - language: node_js - node_js: -- - "8.9.0" -+ - "8.11.0" - - cache: - yarn: true -@@ -50,7 +50,7 @@ - - $HOME/.cache/electron-builder - - before_install: -- - curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.3.2 -+ - curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.5.1 - - export PATH=$HOME/.yarn/bin:$PATH - - install: -merged - result 100644 2de5029d6613dc9f507cd891b707d66e78b68851 README.md - our 100644 574e4d56ae5ca7982571359a903164b85027cf81 README.md -@@ -3,6 +3,7 @@ - [![Travis](https://img.shields.io/travis/desktop/desktop.svg?style=flat-square&label=Travis+CI)](https://travis-ci.org/desktop/desktop) - [![CircleCI](https://img.shields.io/circleci/project/github/desktop/desktop.svg?style=flat-square&label=CircleCI)](https://circleci.com/gh/desktop/desktop) - [![AppVeyor Build Status](https://img.shields.io/appveyor/ci/github-windows/desktop/master.svg?style=flat-square&label=AppVeyor&logo=appveyor)](https://ci.appveyor.com/project/github-windows/desktop/branch/master) -+[![VSTS Build Status](https://github.visualstudio.com/_apis/public/build/definitions/845028c2-21f3-4eb1-80b9-215d3e9b1d08/3/badge)](https://github.visualstudio.com/Desktop/_build/index?definitionId=3) - [![license](https://img.shields.io/github/license/desktop/desktop.svg?style=flat-square)](https://github.com/desktop/desktop/blob/master/LICENSE) - ![90+% TypeScript](https://img.shields.io/github/languages/top/desktop/desktop.svg?style=flat-square&colorB=green) - -@@ -51,8 +52,8 @@ - There is also a list of [known issues](https://github.com/desktop/desktop/blob/master/docs/known-issues.md) - that are being tracked against Desktop, and some of these issues have workarounds. - --If you can't find an issue that matches what you're seeing, open a [new issue](https://github.com/desktop/desktop/issues/new) --and fill out the template to provide us with enough information to investigate -+If you can't find an issue that matches what you're seeing, open a [new issue](https://github.com/desktop/desktop/issues/new/choose), -+choose the right template and provide us with enough information to investigate - further. - - ## How can I contribute to GitHub Desktop? -merged - result 100644 f7a365459e5cee710b2f3156119a6a2b2ff65a7d app/.npmrc - our 100644 3b80cccbdce21610474a65dcdc28c309d819e278 app/.npmrc -@@ -1,4 +1,4 @@ - runtime = electron - disturl = https://atom.io/download/electron --target = 1.8.3 -+target = 1.8.7 - arch = x64 -removed in remote - base 100644 996444dc72a75f727b5f5e62cac72e4fe4a21302 app/app-info.d.ts - our 100644 996444dc72a75f727b5f5e62cac72e4fe4a21302 app/app-info.d.ts -@@ -1,2 +0,0 @@ --export function getReplacements(): {} --export function getCLICommands(): string[] -removed in remote - base 100644 53ac0bb5d571c6f678ac4794df6004fed9c17cd7 app/app-info.js - our 100644 53ac0bb5d571c6f678ac4794df6004fed9c17cd7 app/app-info.js -@@ -1,50 +0,0 @@ --'use strict' -- --const fs = require('fs') --const path = require('path') -- --const gitInfo = require('./git-info') --const distInfo = require('../script/dist-info') -- --const projectRoot = path.join(__dirname, '..') -- --const devClientId = '3a723b10ac5575cc5bb9' --const devClientSecret = '22c34d87789a365981ed921352a7b9a8c3f69d54' -- --const channel = distInfo.getReleaseChannel() -- --function getCLICommands() { -- return ( -- // eslint-disable-next-line no-sync -- fs -- .readdirSync(path.resolve(projectRoot, 'app', 'src', 'cli', 'commands')) -- .filter(name => name.endsWith('.ts')) -- .map(name => name.replace(/\.ts$/, '')) -- ) --} -- --function s(text) { -- return JSON.stringify(text) --} -- --function getReplacements() { -- return { -- __OAUTH_CLIENT_ID__: s(process.env.DESKTOP_OAUTH_CLIENT_ID || devClientId), -- __OAUTH_SECRET__: s( -- process.env.DESKTOP_OAUTH_CLIENT_SECRET || devClientSecret -- ), -- __DARWIN__: process.platform === 'darwin', -- __WIN32__: process.platform === 'win32', -- __LINUX__: process.platform === 'linux', -- __DEV__: channel === 'development', -- __RELEASE_CHANNEL__: s(channel), -- __UPDATES_URL__: s(distInfo.getUpdatesURL()), -- __SHA__: s(gitInfo.getSHA()), -- __CLI_COMMANDS__: s(getCLICommands()), -- 'process.platform': s(process.platform), -- 'process.env.NODE_ENV': s(process.env.NODE_ENV || 'development'), -- 'process.env.TEST_ENV': s(process.env.TEST_ENV), -- } --} -- --module.exports = { getReplacements, getCLICommands } -added in remote - their 100644 bb6679dfc6714a548b27c030dd653216c7e19833 app/app-info.ts -@@ -0,0 +1,44 @@ -+import * as fs from 'fs' -+import * as Path from 'path' -+ -+import { getSHA } from './git-info' -+import { getUpdatesURL, getReleaseChannel } from '../script/dist-info' -+ -+const projectRoot = Path.dirname(__dirname) -+ -+const devClientId = '3a723b10ac5575cc5bb9' -+const devClientSecret = '22c34d87789a365981ed921352a7b9a8c3f69d54' -+ -+const channel = getReleaseChannel() -+ -+export function getCLICommands() { -+ return ( -+ // eslint-disable-next-line no-sync -+ fs -+ .readdirSync(Path.resolve(projectRoot, 'app', 'src', 'cli', 'commands')) -+ .filter(name => name.endsWith('.ts')) -+ .map(name => name.replace(/\.ts$/, '')) -+ ) -+} -+ -+const s = JSON.stringify -+ -+export function getReplacements() { -+ return { -+ __OAUTH_CLIENT_ID__: s(process.env.DESKTOP_OAUTH_CLIENT_ID || devClientId), -+ __OAUTH_SECRET__: s( -+ process.env.DESKTOP_OAUTH_CLIENT_SECRET || devClientSecret -+ ), -+ __DARWIN__: process.platform === 'darwin', -+ __WIN32__: process.platform === 'win32', -+ __LINUX__: process.platform === 'linux', -+ __DEV__: channel === 'development', -+ __RELEASE_CHANNEL__: s(channel), -+ __UPDATES_URL__: s(getUpdatesURL()), -+ __SHA__: s(getSHA()), -+ __CLI_COMMANDS__: s(getCLICommands()), -+ 'process.platform': s(process.platform), -+ 'process.env.NODE_ENV': s(process.env.NODE_ENV || 'development'), -+ 'process.env.TEST_ENV': s(process.env.TEST_ENV), -+ } -+} -removed in remote - base 100644 db784cfd0f0a6592eb885f2049f8afc835d6e910 app/git-info.d.ts - our 100644 db784cfd0f0a6592eb885f2049f8afc835d6e910 app/git-info.d.ts -@@ -1 +0,0 @@ --export function getSHA(): string -removed in remote - base 100644 4e9e8240c199c8ad4b02c7453d746c07e9e77502 app/git-info.js - our 100644 4e9e8240c199c8ad4b02c7453d746c07e9e77502 app/git-info.js -@@ -1,93 +0,0 @@ --'use strict' -- --const fs = require('fs') --const path = require('path') -- --/** -- * Attempt to find a ref in the .git/packed-refs file, which is often -- * created by Git as part of cleaning up loose refs in the repository. -- * -- * Will return null if the packed-refs file is missing. -- * Will throw an error if the entry is not found in the packed-refs file -- * -- * @param {string} gitDir The path to the Git repository's .git directory -- * @param {string} ref A qualified git ref such as 'refs/heads/master' -- */ --function readPackedRefsFile(gitDir, ref) { -- const packedRefsPath = path.join(gitDir, 'packed-refs') -- -- try { -- // eslint-disable-next-line no-sync -- fs.statSync(packedRefsPath) -- } catch (err) { -- // fail quietly if packed-refs not found -- return null -- } -- -- // eslint-disable-next-line no-sync -- const packedRefsContents = fs.readFileSync(packedRefsPath) -- -- // we need to build up the regex on the fly using the ref -- const refRe = new RegExp('([a-f0-9]{40}) ' + ref) -- const packedRefMatch = refRe.exec(packedRefsContents) -- -- if (!packedRefMatch) { -- throw new Error(`Could not find ref entry in .git/packed-refs file: ${ref}`) -- } -- return packedRefMatch[1] --} -- --/** -- * Attempt to dereference the given ref without requiring a Git environment -- * to be present. Note that this method will not be able to dereference packed -- * refs but should suffice for simple refs like 'HEAD'. -- * -- * Will throw an error for unborn HEAD. -- * -- * @param {string} gitDir The path to the Git repository's .git directory -- * @param {string} ref A qualified git ref such as 'HEAD' or 'refs/heads/master' -- */ --function revParse(gitDir, ref) { -- const refPath = path.join(gitDir, ref) -- -- try { -- // eslint-disable-next-line no-sync -- fs.statSync(refPath) -- } catch (err) { -- const packedRefMatch = readPackedRefsFile(gitDir, ref) -- if (packedRefMatch) { -- return packedRefMatch -- } -- -- throw new Error( -- `Could not de-reference HEAD to SHA, ref does not exist on disk: ${refPath}` -- ) -- } -- // eslint-disable-next-line no-sync -- const refContents = fs.readFileSync(refPath) -- const refRe = /^([a-f0-9]{40})|(?:ref: (refs\/.*))$/m -- const refMatch = refRe.exec(refContents) -- -- if (!refMatch) { -- throw new Error( -- `Could not de-reference HEAD to SHA, invalid ref in ${refPath}: ${refContents}` -- ) -- } -- -- return refMatch[1] || revParse(gitDir, refMatch[2]) --} -- --function getSHA() { -- // CircleCI does some funny stuff where HEAD points to an packed ref, but -- // luckily it gives us the SHA we want in the environment. -- const circleSHA = process.env.CIRCLE_SHA1 -- if (circleSHA) { -- return circleSHA -- } -- -- return revParse(path.resolve(__dirname, '../.git'), 'HEAD') --} -- --module.exports = { -- getSHA, --} -added in remote - their 100644 1bf399b381dab7c260c1dc4126025c7ab1a437af app/git-info.ts -@@ -0,0 +1,88 @@ -+import * as Fs from 'fs' -+import * as Path from 'path' -+ -+/** -+ * Attempt to find a ref in the .git/packed-refs file, which is often -+ * created by Git as part of cleaning up loose refs in the repository. -+ * -+ * Will return null if the packed-refs file is missing. -+ * Will throw an error if the entry is not found in the packed-refs file -+ * -+ * @param gitDir The path to the Git repository's .git directory -+ * @param ref A qualified git ref such as 'refs/heads/master' -+ */ -+function readPackedRefsFile(gitDir: string, ref: string) { -+ const packedRefsPath = Path.join(gitDir, 'packed-refs') -+ -+ try { -+ // eslint-disable-next-line no-sync -+ Fs.statSync(packedRefsPath) -+ } catch (err) { -+ // fail quietly if packed-refs not found -+ return null -+ } -+ -+ // eslint-disable-next-line no-sync -+ const packedRefsContents = Fs.readFileSync(packedRefsPath, 'utf8') -+ -+ // we need to build up the regex on the fly using the ref -+ const refRe = new RegExp('([a-f0-9]{40}) ' + ref) -+ const packedRefMatch = refRe.exec(packedRefsContents) -+ -+ if (!packedRefMatch) { -+ throw new Error(`Could not find ref entry in .git/packed-refs file: ${ref}`) -+ } -+ return packedRefMatch[1] -+} -+ -+/** -+ * Attempt to dereference the given ref without requiring a Git environment -+ * to be present. Note that this method will not be able to dereference packed -+ * refs but should suffice for simple refs like 'HEAD'. -+ * -+ * Will throw an error for unborn HEAD. -+ * -+ * @param gitDir The path to the Git repository's .git directory -+ * @param ref A qualified git ref such as 'HEAD' or 'refs/heads/master' -+ * @returns The ref SHA -+ */ -+function revParse(gitDir: string, ref: string): string { -+ const refPath = Path.join(gitDir, ref) -+ -+ try { -+ // eslint-disable-next-line no-sync -+ Fs.statSync(refPath) -+ } catch (err) { -+ const packedRefMatch = readPackedRefsFile(gitDir, ref) -+ if (packedRefMatch) { -+ return packedRefMatch -+ } -+ -+ throw new Error( -+ `Could not de-reference HEAD to SHA, ref does not exist on disk: ${refPath}` -+ ) -+ } -+ // eslint-disable-next-line no-sync -+ const refContents = Fs.readFileSync(refPath, 'utf8') -+ const refRe = /^([a-f0-9]{40})|(?:ref: (refs\/.*))$/m -+ const refMatch = refRe.exec(refContents) -+ -+ if (!refMatch) { -+ throw new Error( -+ `Could not de-reference HEAD to SHA, invalid ref in ${refPath}: ${refContents}` -+ ) -+ } -+ -+ return refMatch[1] || revParse(gitDir, refMatch[2]) -+} -+ -+export function getSHA() { -+ // CircleCI does some funny stuff where HEAD points to an packed ref, but -+ // luckily it gives us the SHA we want in the environment. -+ const circleSHA = process.env.CIRCLE_SHA1 -+ if (circleSHA != null) { -+ return circleSHA -+ } -+ -+ return revParse(Path.resolve(__dirname, '../.git'), 'HEAD') -+} -removed in remote - base 100644 5f169d7f8e0a82168c2c13ea3ba71b5b101f0c73 app/package-info.d.ts - our 100644 5f169d7f8e0a82168c2c13ea3ba71b5b101f0c73 app/package-info.d.ts -@@ -1,4 +0,0 @@ --export function getProductName(): string --export function getCompanyName(): string --export function getVersion(): string --export function getBundleID(): string -removed in remote - base 100644 b63ebe090392d9f6829519ac340cbba3901300cb app/package-info.js - our 100644 b63ebe090392d9f6829519ac340cbba3901300cb app/package-info.js -@@ -1,33 +0,0 @@ --'use strict' -- --const path = require('path') -- --const projectRoot = __dirname --// eslint-disable-next-line import/no-dynamic-require --const appPackage = require(path.join(projectRoot, 'package.json')) -- --function getProductName() { -- const productName = appPackage.productName -- return process.env.NODE_ENV === 'development' -- ? `${productName}-dev` -- : productName --} -- --function getCompanyName() { -- return appPackage.companyName --} -- --function getVersion() { -- return appPackage.version --} -- --function getBundleID() { -- return appPackage.bundleID --} -- --module.exports = { -- getProductName, -- getCompanyName, -- getVersion, -- getBundleID, --} -added in remote - their 100644 ec6e40fb46f6554d62823e5f27a8743de594acff app/package-info.ts -@@ -0,0 +1,20 @@ -+const appPackage: Record = require('./package.json') -+ -+export function getProductName() { -+ const productName = appPackage.productName -+ return process.env.NODE_ENV === 'development' -+ ? `${productName}-dev` -+ : productName -+} -+ -+export function getCompanyName() { -+ return appPackage.companyName -+} -+ -+export function getVersion() { -+ return appPackage.version -+} -+ -+export function getBundleID() { -+ return appPackage.bundleID -+} -merged - result 100644 8a1178e723ae9609c53f3bcc8b0d06771b3de809 app/package.json - our 100644 0ec1aae7a11244ccf59f08de5e97e1824f63fc85 app/package.json -@@ -3,7 +3,7 @@ - "productName": "GitHub Desktop", - "bundleID": "com.github.GitHubClient", - "companyName": "GitHub, Inc.", -- "version": "1.1.2-beta1", -+ "version": "1.2.7-test1", - "main": "./main.js", - "repository": { - "type": "git", -@@ -25,23 +25,23 @@ - "codemirror-mode-elixir": "1.1.1", - "deep-equal": "^1.0.1", - "dexie": "^2.0.0", -- "dugite": "1.61.0", -+ "dugite": "^1.67.0", - "electron-window-state": "^4.0.2", - "event-kit": "^2.0.0", - "file-uri-to-path": "0.0.2", - "file-url": "^2.0.2", -- "front-matter": "^2.1.2", -- "fs-extra": "^2.1.2", -+ "fs-extra": "^6.0.0", - "fuzzaldrin-plus": "^0.6.0", - "keytar": "^4.0.4", - "moment": "^2.17.1", - "mri": "^1.1.0", - "primer-support": "^4.0.0", -- "react": "^16.2.0", -+ "queue": "^4.4.2", -+ "react": "^16.3.2", - "react-addons-shallow-compare": "^15.6.2", -- "react-dom": "^16.2.0", -+ "react-dom": "^16.3.2", - "react-transition-group": "^1.2.0", -- "react-virtualized": "^9.18.5", -+ "react-virtualized": "^9.20.0", - "registry-js": "^1.0.7", - "runas": "^3.1.1", - "source-map-support": "^0.4.15", -@@ -59,7 +59,6 @@ - "devtron": "^1.4.0", - "electron-debug": "^1.1.0", - "electron-devtools-installer": "^2.2.3", -- "style-loader": "^0.13.2", - "temp": "^0.8.3", - "webpack-hot-middleware": "^2.10.0" - } -merged - result 100644 e427588f02a3f1fd3d89705d05dedc0fe2ccfbfb app/src/ask-pass/ask-pass.ts - our 100644 537e5a421b8fac3f1bc529212cd0bd1ad86330b6 app/src/ask-pass/ask-pass.ts -@@ -5,16 +5,16 @@ - export async function responseForPrompt( - prompt: string - ): Promise { -- const username: string | null = process.env.DESKTOP_USERNAME -- if (!username || !username.length) { -+ const username = process.env.DESKTOP_USERNAME -+ if (username == null || username.length === 0) { - return null - } - - if (prompt.startsWith('Username')) { - return username - } else if (prompt.startsWith('Password')) { -- const endpoint: string | null = process.env.DESKTOP_ENDPOINT -- if (!endpoint || !endpoint.length) { -+ const endpoint = process.env.DESKTOP_ENDPOINT -+ if (endpoint == null || endpoint.length === 0) { - return null - } - -removed in remote - base 100644 66965ffb5ca93dbeaa3562652443adc8c8dd4715 app/src/cli/dev-commands-global.js - our 100644 66965ffb5ca93dbeaa3562652443adc8c8dd4715 app/src/cli/dev-commands-global.js -@@ -1,3 +0,0 @@ --const appInfo = require('../../../app/app-info') -- --global.__CLI_COMMANDS__ = appInfo.getCLICommands() -added in remote - their 100644 2199e5e0c456edb57048a02298f9925eb4953327 app/src/cli/dev-commands-global.ts -@@ -0,0 +1,4 @@ -+import { getCLICommands } from '../../../app/app-info' -+ -+const g: any = global -+g.__CLI_COMMANDS__ = getCLICommands() -merged - result 100644 d6887c4c182d239a574563f5a552b6c44bab229d app/src/highlighter/globals.d.ts - our 100644 a639311f88f661769bc71af8d6a36e20b314709d app/src/highlighter/globals.d.ts -@@ -251,3 +251,128 @@ - declare module 'codemirror/addon/runmode/runmode.node.js' { - export = CodeMirror - } -+ -+declare module 'codemirror-mode-elixir' -+ -+// find app/node_modules/codemirror/mode -iname *.js | cut -d '/' -f 3- | cut -d '.' -f 1 | sed -e "s/^/declare module '/" | sed -e "s/$/'/" -+declare module 'codemirror/mode/scheme/scheme' -+declare module 'codemirror/mode/modelica/modelica' -+declare module 'codemirror/mode/idl/idl' -+declare module 'codemirror/mode/pascal/pascal' -+declare module 'codemirror/mode/nsis/nsis' -+declare module 'codemirror/mode/haml/haml' -+declare module 'codemirror/mode/toml/toml' -+declare module 'codemirror/mode/pig/pig' -+declare module 'codemirror/mode/gas/gas' -+declare module 'codemirror/mode/go/go' -+declare module 'codemirror/mode/apl/apl' -+declare module 'codemirror/mode/textile/textile' -+declare module 'codemirror/mode/turtle/turtle' -+declare module 'codemirror/mode/sparql/sparql' -+declare module 'codemirror/mode/troff/troff' -+declare module 'codemirror/mode/cmake/cmake' -+declare module 'codemirror/mode/htmlembedded/htmlembedded' -+declare module 'codemirror/mode/xquery/xquery' -+declare module 'codemirror/mode/python/python' -+declare module 'codemirror/mode/css/css' -+declare module 'codemirror/mode/clojure/clojure' -+declare module 'codemirror/mode/spreadsheet/spreadsheet' -+declare module 'codemirror/mode/asn.1/asn.1' -+declare module 'codemirror/mode/z80/z80' -+declare module 'codemirror/mode/jinja2/jinja2' -+declare module 'codemirror/mode/gherkin/gherkin' -+declare module 'codemirror/mode/asterisk/asterisk' -+declare module 'codemirror/mode/dockerfile/dockerfile' -+declare module 'codemirror/mode/dart/dart' -+declare module 'codemirror/mode/shell/shell' -+declare module 'codemirror/mode/yacas/yacas' -+declare module 'codemirror/mode/markdown/markdown' -+declare module 'codemirror/mode/haxe/haxe' -+declare module 'codemirror/mode/soy/soy' -+declare module 'codemirror/mode/perl/perl' -+declare module 'codemirror/mode/smalltalk/smalltalk' -+declare module 'codemirror/mode/dylan/dylan' -+declare module 'codemirror/mode/stylus/stylus' -+declare module 'codemirror/mode/vue/vue' -+declare module 'codemirror/mode/rust/rust' -+declare module 'codemirror/mode/rst/rst' -+declare module 'codemirror/mode/tiddlywiki/tiddlywiki' -+declare module 'codemirror/mode/pug/pug' -+declare module 'codemirror/mode/erlang/erlang' -+declare module 'codemirror/mode/r/r' -+declare module 'codemirror/mode/mathematica/mathematica' -+declare module 'codemirror/mode/yaml-frontmatter/yaml-frontmatter' -+declare module 'codemirror/mode/diff/diff' -+declare module 'codemirror/mode/elm/elm' -+declare module 'codemirror/mode/crystal/crystal' -+declare module 'codemirror/mode/cypher/cypher' -+declare module 'codemirror/mode/htmlmixed/htmlmixed' -+declare module 'codemirror/mode/ebnf/ebnf' -+declare module 'codemirror/mode/webidl/webidl' -+declare module 'codemirror/mode/smarty/smarty' -+declare module 'codemirror/mode/stex/stex' -+declare module 'codemirror/mode/haskell/haskell' -+declare module 'codemirror/mode/factor/factor' -+declare module 'codemirror/mode/php/php' -+declare module 'codemirror/mode/pegjs/pegjs' -+declare module 'codemirror/mode/lua/lua' -+declare module 'codemirror/mode/velocity/velocity' -+declare module 'codemirror/mode/xml/xml' -+declare module 'codemirror/mode/solr/solr' -+declare module 'codemirror/mode/mbox/mbox' -+declare module 'codemirror/mode/mllike/mllike' -+declare module 'codemirror/mode/vb/vb' -+declare module 'codemirror/mode/powershell/powershell' -+declare module 'codemirror/mode/tornado/tornado' -+declare module 'codemirror/mode/vhdl/vhdl' -+declare module 'codemirror/mode/tiki/tiki' -+declare module 'codemirror/mode/clike/clike' -+declare module 'codemirror/mode/tcl/tcl' -+declare module 'codemirror/mode/brainfuck/brainfuck' -+declare module 'codemirror/mode/ttcn/ttcn' -+declare module 'codemirror/mode/dtd/dtd' -+declare module 'codemirror/mode/octave/octave' -+declare module 'codemirror/mode/properties/properties' -+declare module 'codemirror/mode/verilog/verilog' -+declare module 'codemirror/mode/handlebars/handlebars' -+declare module 'codemirror/mode/nginx/nginx' -+declare module 'codemirror/mode/http/http' -+declare module 'codemirror/mode/asciiarmor/asciiarmor' -+declare module 'codemirror/mode/swift/swift' -+declare module 'codemirror/mode/meta' -+declare module 'codemirror/mode/sas/sas' -+declare module 'codemirror/mode/sieve/sieve' -+declare module 'codemirror/mode/livescript/livescript' -+declare module 'codemirror/mode/commonlisp/commonlisp' -+declare module 'codemirror/mode/fcl/fcl' -+declare module 'codemirror/mode/yaml/yaml' -+declare module 'codemirror/mode/fortran/fortran' -+declare module 'codemirror/mode/julia/julia' -+declare module 'codemirror/mode/oz/oz' -+declare module 'codemirror/mode/groovy/groovy' -+declare module 'codemirror/mode/coffeescript/coffeescript' -+declare module 'codemirror/mode/slim/slim' -+declare module 'codemirror/mode/javascript/javascript' -+declare module 'codemirror/mode/mscgen/mscgen' -+declare module 'codemirror/mode/twig/twig' -+declare module 'codemirror/mode/eiffel/eiffel' -+declare module 'codemirror/mode/cobol/cobol' -+declare module 'codemirror/mode/sass/sass' -+declare module 'codemirror/mode/rpm/rpm' -+declare module 'codemirror/mode/mumps/mumps' -+declare module 'codemirror/mode/vbscript/vbscript' -+declare module 'codemirror/mode/ttcn-cfg/ttcn-cfg' -+declare module 'codemirror/mode/forth/forth' -+declare module 'codemirror/mode/puppet/puppet' -+declare module 'codemirror/mode/django/django' -+declare module 'codemirror/mode/d/d' -+declare module 'codemirror/mode/q/q' -+declare module 'codemirror/mode/jsx/jsx' -+declare module 'codemirror/mode/protobuf/protobuf' -+declare module 'codemirror/mode/gfm/gfm' -+declare module 'codemirror/mode/ecl/ecl' -+declare module 'codemirror/mode/ruby/ruby' -+declare module 'codemirror/mode/mirc/mirc' -+declare module 'codemirror/mode/haskell-literate/haskell-literate' -+declare module 'codemirror/mode/ntriples/ntriples' -+declare module 'codemirror/mode/sql/sql' -merged - result 100644 cb77ca464e7d706ddd17c526debdac45e670cf4f app/src/highlighter/index.ts - our 100644 998448323560f91d6522bad31da1dc4317501f5d app/src/highlighter/index.ts -@@ -11,106 +11,250 @@ - - import { ITokens, IHighlightRequest } from '../lib/highlighter/types' - -+/** -+ * A mode definition object is used to map a certain file -+ * extension to a mode loader (see the documentation for -+ * the install property). -+ */ -+interface IModeDefinition { -+ /** -+ * A function that, when called, will attempt to asynchronously -+ * load the required modules for a particular mode. This function -+ * is idempotent and can be called multiple times with no adverse -+ * effect. -+ */ -+ readonly install: () => Promise -+ -+ /** -+ * A map between file extensions (including the leading dot, i.e. -+ * ".jpeg") and the selected mime type to use when highlighting -+ * that extension as specified in the CodeMirror mode itself. -+ */ -+ readonly extensions: { -+ readonly [key: string]: string -+ } -+} -+ -+/** -+ * Array describing all currently supported modes and the file extensions -+ * that they cover. -+ */ -+const modes: ReadonlyArray = [ -+ { -+ install: () => import('codemirror/mode/javascript/javascript'), -+ extensions: { -+ '.ts': 'text/typescript', -+ '.js': 'text/javascript', -+ '.json': 'application/json', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/coffeescript/coffeescript'), -+ extensions: { -+ '.coffee': 'text/x-coffeescript', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/jsx/jsx'), -+ extensions: { -+ '.tsx': 'text/typescript-jsx', -+ '.jsx': 'text/jsx', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/htmlmixed/htmlmixed'), -+ extensions: { -+ '.html': 'text/html', -+ '.htm': 'text/html', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/htmlembedded/htmlembedded'), -+ extensions: { -+ '.jsp': 'application/x-jsp', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/css/css'), -+ extensions: { -+ '.css': 'text/css', -+ '.scss': 'text/x-scss', -+ '.less': 'text/x-less', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/vue/vue'), -+ extensions: { -+ '.vue': 'text/x-vue', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/markdown/markdown'), -+ extensions: { -+ '.markdown': 'text/x-markdown', -+ '.md': 'text/x-markdown', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/yaml/yaml'), -+ extensions: { -+ '.yaml': 'text/yaml', -+ '.yml': 'text/yaml', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/xml/xml'), -+ extensions: { -+ '.xml': 'text/xml', -+ '.xaml': 'text/xml', -+ '.csproj': 'text/xml', -+ '.fsproj': 'text/xml', -+ '.vcxproj': 'text/xml', -+ '.vbproj': 'text/xml', -+ '.svg': 'text/xml', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/clike/clike'), -+ extensions: { -+ '.m': 'text/x-objectivec', -+ '.scala': 'text/x-scala', -+ '.sc': 'text/x-scala', -+ '.cs': 'text/x-csharp', -+ '.cake': 'text/x-csharp', -+ '.java': 'text/x-java', -+ '.c': 'text/x-c', -+ '.h': 'text/x-c', -+ '.cpp': 'text/x-c++src', -+ '.hpp': 'text/x-c++src', -+ '.kt': 'text/x-kotlin', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/mllike/mllike'), -+ extensions: { -+ '.ml': 'text/x-ocaml', -+ '.fs': 'text/x-fsharp', -+ '.fsx': 'text/x-fsharp', -+ '.fsi': 'text/x-fsharp', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/swift/swift'), -+ extensions: { -+ '.swift': 'text/x-swift', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/shell/shell'), -+ extensions: { -+ '.sh': 'text/x-sh', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/sql/sql'), -+ extensions: { -+ '.sql': 'text/x-sql', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/cypher/cypher'), -+ extensions: { -+ '.cql': 'application/x-cypher-query', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/go/go'), -+ extensions: { -+ '.go': 'text/x-go', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/perl/perl'), -+ extensions: { -+ '.pl': 'text/x-perl', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/php/php'), -+ extensions: { -+ '.php': 'application/x-httpd-php', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/python/python'), -+ extensions: { -+ '.py': 'text/x-python', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/ruby/ruby'), -+ extensions: { -+ '.rb': 'text/x-ruby', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/clojure/clojure'), -+ extensions: { -+ '.clj': 'text/x-clojure', -+ '.cljc': 'text/x-clojure', -+ '.cljs': 'text/x-clojure', -+ '.edn': 'text/x-clojure', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/rust/rust'), -+ extensions: { -+ '.rs': 'text/x-rustsrc', -+ }, -+ }, -+ { -+ install: () => import('codemirror-mode-elixir'), -+ extensions: { -+ '.ex': 'text/x-elixir', -+ '.exs': 'text/x-elixir', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/haxe/haxe'), -+ extensions: { -+ '.hx': 'text/x-haxe', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/r/r'), -+ extensions: { -+ '.r': 'text/x-rsrc', -+ }, -+ }, -+ { -+ install: () => import('codemirror/mode/powershell/powershell'), -+ extensions: { -+ '.ps1': 'application/x-powershell', -+ }, -+ }, -+] -+ -+/** -+ * A map between file extensions and mime types, see -+ * the 'extensions' property on the IModeDefinition interface -+ * for more information -+ */ - const extensionMIMEMap = new Map() - --import 'codemirror/mode/javascript/javascript' --extensionMIMEMap.set('.ts', 'text/typescript') --extensionMIMEMap.set('.js', 'text/javascript') --extensionMIMEMap.set('.json', 'application/json') -- --import 'codemirror/mode/coffeescript/coffeescript' --extensionMIMEMap.set('.coffee', 'text/x-coffeescript') -- --import 'codemirror/mode/jsx/jsx' --extensionMIMEMap.set('.tsx', 'text/typescript-jsx') --extensionMIMEMap.set('.jsx', 'text/jsx') -- --import 'codemirror/mode/htmlmixed/htmlmixed' --extensionMIMEMap.set('.html', 'text/html') --extensionMIMEMap.set('.htm', 'text/html') -- --import 'codemirror/mode/css/css' --extensionMIMEMap.set('.css', 'text/css') --extensionMIMEMap.set('.scss', 'text/x-scss') --extensionMIMEMap.set('.less', 'text/x-less') -- --import 'codemirror/mode/vue/vue' --extensionMIMEMap.set('.vue', 'text/x-vue') -- --import 'codemirror/mode/markdown/markdown' --extensionMIMEMap.set('.markdown', 'text/x-markdown') --extensionMIMEMap.set('.md', 'text/x-markdown') -- --import 'codemirror/mode/yaml/yaml' --extensionMIMEMap.set('.yaml', 'text/yaml') --extensionMIMEMap.set('.yml', 'text/yaml') -- --import 'codemirror/mode/xml/xml' --extensionMIMEMap.set('.xml', 'text/xml') --extensionMIMEMap.set('.xaml', 'text/xml') --extensionMIMEMap.set('.csproj', 'text/xml') --extensionMIMEMap.set('.fsproj', 'text/xml') --extensionMIMEMap.set('.vcxproj', 'text/xml') --extensionMIMEMap.set('.vbproj', 'text/xml') --extensionMIMEMap.set('.svg', 'text/xml') -- --import 'codemirror/mode/clike/clike' --extensionMIMEMap.set('.m', 'text/x-objectivec') --extensionMIMEMap.set('.scala', 'text/x-scala') --extensionMIMEMap.set('.sc', 'text/x-scala') --extensionMIMEMap.set('.cs', 'text/x-csharp') --extensionMIMEMap.set('.java', 'text/x-java') --extensionMIMEMap.set('.c', 'text/x-c') --extensionMIMEMap.set('.h', 'text/x-c') --extensionMIMEMap.set('.cpp', 'text/x-c++src') --extensionMIMEMap.set('.hpp', 'text/x-c++src') --extensionMIMEMap.set('.kt', 'text/x-kotlin') -- --import 'codemirror/mode/mllike/mllike' --extensionMIMEMap.set('.ml', 'text/x-ocaml') --extensionMIMEMap.set('.fs', 'text/x-fsharp') --extensionMIMEMap.set('.fsx', 'text/x-fsharp') --extensionMIMEMap.set('.fsi', 'text/x-fsharp') -- --import 'codemirror/mode/swift/swift' --extensionMIMEMap.set('.swift', 'text/x-swift') -- --import 'codemirror/mode/shell/shell' --extensionMIMEMap.set('.sh', 'text/x-sh') -- --import 'codemirror/mode/sql/sql' --extensionMIMEMap.set('.sql', 'text/x-sql') -- --import 'codemirror/mode/cypher/cypher' --extensionMIMEMap.set('.cql', 'application/x-cypher-query') -- --import 'codemirror/mode/go/go' --extensionMIMEMap.set('.go', 'text/x-go') -- --import 'codemirror/mode/perl/perl' --extensionMIMEMap.set('.pl', 'text/x-perl') -- --import 'codemirror/mode/php/php' --extensionMIMEMap.set('.php', 'application/x-httpd-php') -- --import 'codemirror/mode/python/python' --extensionMIMEMap.set('.py', 'text/x-python') -- --import 'codemirror/mode/ruby/ruby' --extensionMIMEMap.set('.rb', 'text/x-ruby') -- --import 'codemirror/mode/clojure/clojure' --extensionMIMEMap.set('.clj', 'text/x-clojure') --extensionMIMEMap.set('.cljc', 'text/x-clojure') --extensionMIMEMap.set('.cljs', 'text/x-clojure') --extensionMIMEMap.set('.edn', 'text/x-clojure') -- --import 'codemirror/mode/rust/rust' --extensionMIMEMap.set('.rs', 'text/x-rustsrc') -- --import 'codemirror-mode-elixir' --extensionMIMEMap.set('.ex', 'text/x-elixir') --extensionMIMEMap.set('.exs', 'text/x-elixir') -+/** -+ * A map between mime types and mode definitions. See the -+ * documentation for the IModeDefinition interface -+ * for more information -+ */ -+const mimeModeMap = new Map() -+ -+for (const mode of modes) { -+ for (const [extension, mimeType] of Object.entries(mode.extensions)) { -+ extensionMIMEMap.set(extension, mimeType) -+ mimeModeMap.set(mimeType, mode) -+ } -+} - - function guessMimeType(contents: string) { - if (contents.startsWith(' | null { -+async function detectMode( -+ request: IHighlightRequest -+): Promise | null> { - const mimeType = -- extensionMIMEMap.get(request.extension) || guessMimeType(request.contents) -+ extensionMIMEMap.get(request.extension.toLowerCase()) || -+ guessMimeType(request.contents) - - if (!mimeType) { - return null - } - -+ const modeDefinition = mimeModeMap.get(mimeType) -+ -+ if (modeDefinition === undefined) { -+ return null -+ } -+ -+ await modeDefinition.install() -+ - return getMode({}, mimeType) || null - } - -@@ -213,14 +368,14 @@ - throw new Error(`Mode ${getModeName(mode)} failed to advance stream.`) - } - --onmessage = (ev: MessageEvent) => { -+onmessage = async (ev: MessageEvent) => { - const request = ev.data as IHighlightRequest - - const tabSize = request.tabSize || 4 - const contents = request.contents - const addModeClass = request.addModeClass === true - -- const mode = detectMode(request) -+ const mode = await detectMode(request) - - if (!mode) { - postMessage({}) -merged - result 100644 28bceee1eb85ee67e5615f600cd692fd1286c44b app/src/highlighter/tsconfig.json - our 100644 ac72a2f6877ed0b4f8a01b2e6cdf721c2ad59ccf app/src/highlighter/tsconfig.json -@@ -1,6 +1,6 @@ - { - "compilerOptions": { -- "module": "commonjs", -+ "module": "esnext", - "moduleResolution": "node", - "target": "es2017", - "noImplicitReturns": true, -merged - result 100644 e315e51baf72a2f8735ae86ea485b0e6d5bebeed app/src/lib/app-shell.ts - our 100644 1fd1d56b84996afc63dce165e2dda4f5b8e20d94 app/src/lib/app-shell.ts -@@ -1,4 +1,7 @@ - import { shell as electronShell, ipcRenderer } from 'electron' -+import * as Path from 'path' -+ -+import { Repository } from '../models/repository' - - export interface IAppShell { - readonly moveItemToTrash: (path: string) => boolean -@@ -28,3 +31,14 @@ - }, - openItem: electronShell.openItem, - } -+ -+/** -+ * Reveals a file from a repository in the native file manager. -+ * -+ * @param repository The currently active repository instance -+ * @param path The path of the file relative to the root of the repository -+ */ -+export function revealInFileManager(repository: Repository, path: string) { -+ const fullyQualifiedFilePath = Path.join(repository.path, path) -+ return shell.showItemInFolder(fullyQualifiedFilePath) -+} -merged - result 100644 711a4f16bab17ee49c4dd510d5a575cf149f5a5c app/src/lib/app-state.ts - our 100644 c329944f04e7a0db1cdd5851028416024f3c5c16 app/src/lib/app-state.ts -@@ -1,9 +1,9 @@ - import { Account } from '../models/account' - import { CommitIdentity } from '../models/commit-identity' - import { IDiff } from '../models/diff' --import { Repository } from '../models/repository' --import { IAheadBehind } from './git' --import { Branch } from '../models/branch' -+import { Repository, ILocalRepositoryState } from '../models/repository' -+ -+import { Branch, IAheadBehind } from '../models/branch' - import { Tip } from '../models/tip' - import { Commit } from '../models/commit' - import { -@@ -26,9 +26,10 @@ - import { BranchesTab } from '../models/branches-tab' - import { PullRequest } from '../models/pull-request' - import { IAuthor } from '../models/author' -+import { ComparisonCache } from './comparison-cache' -+import { ApplicationTheme } from '../ui/lib/application-theme' - - export { ICommitMessage } --export { IAheadBehind } - - export enum SelectionType { - Repository, -@@ -67,8 +68,16 @@ - /** All of the shared app state. */ - export interface IAppState { - readonly accounts: ReadonlyArray -+ /** -+ * The current list of repositories tracked in the application -+ */ - readonly repositories: ReadonlyArray - -+ /** -+ * A cache of the latest repository state values, keyed by the repository id -+ */ -+ readonly localRepositoryStateLookup: Map -+ - readonly selectedState: PossibleSelections | null - - /** -@@ -178,6 +187,11 @@ - - /** The currently selected tab for the Branches foldout. */ - readonly selectedBranchesTab: BranchesTab -+ -+ /** Show the diverging notification banner */ -+ readonly isDivergingBranchBannerVisible: boolean -+ /** The currently selected appearance (aka theme) */ -+ readonly selectedTheme: ApplicationTheme - } - - export enum PopupType { -@@ -208,6 +222,7 @@ - LFSAttributeMismatch, - UpstreamAlreadyExists, - DeletePullRequest, -+ MergeConflicts, - } - - export type Popup = -@@ -222,9 +237,14 @@ - type: PopupType.ConfirmDiscardChanges - repository: Repository - files: ReadonlyArray -+ showDiscardChangesSetting?: boolean - } - | { type: PopupType.Preferences; initialSelectedTab?: PreferencesTab } -- | { type: PopupType.MergeBranch; repository: Repository } -+ | { -+ type: PopupType.MergeBranch -+ repository: Repository -+ branch?: Branch -+ } - | { type: PopupType.RepositorySettings; repository: Repository } - | { type: PopupType.AddRepository; path?: string } - | { type: PopupType.CreateRepository; path?: string } -@@ -281,6 +301,7 @@ - branch: Branch - pullRequest: PullRequest - } -+ | { type: PopupType.MergeConflicts; repository: Repository } - - export enum FoldoutType { - Repository, -@@ -315,7 +336,7 @@ - | { type: FoldoutType.AddMenu } - | AppMenuFoldout - --export enum RepositorySection { -+export enum RepositorySectionTab { - Changes, - History, - } -@@ -323,7 +344,8 @@ - export interface IRepositoryState { - readonly historyState: IHistoryState - readonly changesState: IChangesState -- readonly selectedSection: RepositorySection -+ readonly compareState: ICompareState -+ readonly selectedSection: RepositorySectionTab - - /** - * The name and email that will be used for the author info -@@ -559,10 +581,10 @@ - readonly workingDirectory: WorkingDirectoryStatus - - /** -- * The ID of the selected file. The file itself can be looked up in -+ * The ID of the selected files. The files themselves can be looked up in - * `workingDirectory`. - */ -- readonly selectedFileID: string | null -+ readonly selectedFileIDs: string[] - - readonly diff: IDiff | null - -@@ -590,3 +612,105 @@ - */ - readonly coAuthors: ReadonlyArray - } -+ -+export enum ComparisonView { -+ None = 'none', -+ Ahead = 'ahead', -+ Behind = 'behind', -+} -+ -+/** -+ * The default comparison state is to display the history for the current -+ * branch. -+ */ -+export interface IDisplayHistory { -+ readonly kind: ComparisonView.None -+} -+ -+/** -+ * When the user has chosen another branch to compare, using their current -+ * branch as the base branch. -+ */ -+export interface ICompareBranch { -+ /** The chosen comparison mode determines which commits to show */ -+ readonly kind: ComparisonView.Ahead | ComparisonView.Behind -+ -+ /** The branch to compare against the base branch */ -+ readonly comparisonBranch: Branch -+ -+ /** The number of commits the selected branch is ahead/behind the current branch */ -+ readonly aheadBehind: IAheadBehind -+} -+ -+export interface ICompareState { -+ /** The current state of the compare form, based on user input */ -+ readonly formState: IDisplayHistory | ICompareBranch -+ -+ /** Whether the branch list should be expanded or hidden */ -+ readonly showBranchList: boolean -+ -+ /** The text entered into the compare branch filter text box */ -+ readonly filterText: string -+ -+ /** The SHAs of commits to render in the compare list */ -+ readonly commitSHAs: ReadonlyArray -+ -+ /** A list of all branches (remote and local) currently in the repository. */ -+ readonly allBranches: ReadonlyArray -+ -+ /** -+ * A list of zero to a few (at time of writing 5 but check loadRecentBranches -+ * in git-store for definitive answer) branches that have been checked out -+ * recently. This list is compiled by reading the reflog and tracking branch -+ * switches over the last couple of thousand reflog entries. -+ */ -+ readonly recentBranches: ReadonlyArray -+ -+ /** -+ * The default branch for a given repository. Most commonly this -+ * will be the 'master' branch but GitHub users are able to change -+ * their default branch in the web UI. -+ */ -+ readonly defaultBranch: Branch | null -+ -+ /** -+ * A local cache of ahead/behind computations to compare other refs to the current branch -+ */ -+ readonly aheadBehindCache: ComparisonCache -+ -+ /** -+ * The best candidate branch to compare the current branch to. -+ * Also includes the ahead/behind info for the inferred branch -+ * relative to the current branch. -+ */ -+ readonly inferredComparisonBranch: { -+ branch: Branch | null -+ aheadBehind: IAheadBehind | null -+ } -+} -+ -+export interface ICompareFormUpdate { -+ /** The updated filter text to set */ -+ readonly filterText: string -+ -+ /** Thew new state of the branches list */ -+ readonly showBranchList: boolean -+} -+ -+export enum CompareActionKind { -+ History = 'History', -+ Branch = 'Branch', -+} -+ -+/** -+ * An action to send to the application store to update the compare state -+ */ -+export type CompareAction = -+ | { -+ readonly kind: CompareActionKind.History -+ } -+ | { -+ readonly kind: CompareActionKind.Branch -+ readonly branch: Branch -+ readonly mode: ComparisonView.Ahead | ComparisonView.Behind -+ } -added in remote - their 100644 9745def3e5a5e6046e8f8ea32a90a530172dd312 app/src/lib/comparison-cache.ts -@@ -0,0 +1,29 @@ -+import { IAheadBehind } from '../models/branch' -+import { revSymmetricDifference } from '../lib/git' -+ -+export class ComparisonCache { -+ private backingStore = new Map() -+ -+ public set(from: string, to: string, value: IAheadBehind) { -+ const key = revSymmetricDifference(from, to) -+ this.backingStore.set(key, value) -+ } -+ -+ public get(from: string, to: string) { -+ const key = revSymmetricDifference(from, to) -+ return this.backingStore.get(key) || null -+ } -+ -+ public has(from: string, to: string) { -+ const key = revSymmetricDifference(from, to) -+ return this.backingStore.has(key) -+ } -+ -+ public get size() { -+ return this.backingStore.size -+ } -+ -+ public clear() { -+ this.backingStore.clear() -+ } -+} -merged - result 100644 6989ac27cc613156ffcb3cf61e2e33863a75d3cd app/src/lib/dispatcher/dispatcher.ts - our 100644 bd55d7427357a36ac24db03b82d32fa9cebe5ac7 app/src/lib/dispatcher/dispatcher.ts -@@ -11,12 +11,14 @@ - } from '../../models/status' - import { DiffSelection } from '../../models/diff' - import { -- RepositorySection, -+ RepositorySectionTab, - Popup, - PopupType, - Foldout, - FoldoutType, - ImageDiffType, -+ CompareAction, -+ ICompareFormUpdate, - } from '../app-state' - import { AppStore } from '../stores/app-store' - import { CloningRepository } from '../../models/cloning-repository' -@@ -54,6 +56,8 @@ - import { PullRequest } from '../../models/pull-request' - import { IAuthor } from '../../models/author' - import { ITrailer } from '../git/interpret-trailers' -+import { isGitRepository } from '../git' -+import { ApplicationTheme } from '../../ui/lib/application-theme' - - /** - * An error handler function. -@@ -109,11 +113,6 @@ - return this.appStore._updateRepositoryMissing(repository, missing) - } - -- /** Load the history for the repository. */ -- public loadHistory(repository: Repository): Promise { -- return this.appStore._loadHistory(repository) -- } -- - /** Load the next batch of history for the repository. */ - public loadNextHistoryBatch(repository: Repository): Promise { - return this.appStore._loadNextHistoryBatch(repository) -@@ -177,7 +176,7 @@ - /** Change the selected section in the repository. */ - public changeRepositorySection( - repository: Repository, -- section: RepositorySection -+ section: RepositorySectionTab - ): Promise { - return this.appStore._changeRepositorySection(repository, section) - } -@@ -185,9 +184,9 @@ - /** Change the currently selected file in Changes. */ - public changeChangesSelection( - repository: Repository, -- selectedFile: WorkingDirectoryFileChange -+ selectedFiles: WorkingDirectoryFileChange[] - ): Promise { -- return this.appStore._changeChangesSelection(repository, selectedFile) -+ return this.appStore._changeChangesSelection(repository, selectedFiles) - } - - /** -@@ -460,6 +459,13 @@ - } - - /** -+ * Set the divering branch notification banner's visibility -+ */ -+ public setDivergingBranchBannerVisibility(isVisible: boolean) { -+ return this.appStore._setDivergingBranchBannerVisibility(isVisible) -+ } -+ -+ /** - * Reset the width of the repository sidebar to its default - * value. This affects the changes and history sidebar - * as well as the first toolbar section which contains -@@ -585,7 +591,10 @@ - } - - /** Add the pattern to the repository's gitignore. */ -- public ignore(repository: Repository, pattern: string): Promise { -+ public ignore( -+ repository: Repository, -+ pattern: string | string[] -+ ): Promise { - return this.appStore._ignore(repository, pattern) - } - -@@ -602,9 +611,11 @@ - } - } - -- /** Opens a Git repository in the user provided program */ -- public async openInExternalEditor(path: string): Promise { -- return this.appStore._openInExternalEditor(path) -+ /** -+ * Opens a path in the external editor selected by the user. -+ */ -+ public async openInExternalEditor(fullPath: string): Promise { -+ return this.appStore._openInExternalEditor(fullPath) - } - - /** -@@ -843,13 +854,22 @@ - // this ensures we use the repository root, if it is actually a repository - // otherwise we consider it an untracked repository - const path = (await validatedRepositoryPath(action.path)) || action.path -- - const state = this.appStore.getState() -- const existingRepository = matchExistingRepository( -+ let existingRepository = matchExistingRepository( - state.repositories, - path - ) - -+ // in case this is valid git repository, there is no need to ask -+ // user for confirmation and it can be added automatically -+ if (existingRepository == null) { -+ const isRepository = await isGitRepository(path) -+ if (isRepository) { -+ const addedRepositories = await this.addRepositories([path]) -+ existingRepository = addedRepositories[0] -+ } -+ } -+ - if (existingRepository) { - await this.selectRepository(existingRepository) - } else { -@@ -879,10 +899,6 @@ - - /** - * Sets the user's preference so that confirmation to discard changes is not asked -- * -- * @param {boolean} value -- * @returns {Promise} -- * @memberof Dispatcher - */ - public setConfirmDiscardChangesSetting(value: boolean): Promise { - return this.appStore._setConfirmDiscardChangesSetting(value) -@@ -902,32 +918,38 @@ - return this.appStore._setShell(shell) - } - -- /** -- * Reveals a file from a repository in the native file manager. -- * @param repository The currently active repository instance -- * @param path The path of the file relative to the root of the repository -- */ -- public revealInFileManager(repository: Repository, path: string) { -- const normalized = Path.join(repository.path, path) -- return shell.showItemInFolder(normalized) -- } -- - private async handleCloneInDesktopOptions( - repository: Repository, - action: IOpenRepositoryFromURLAction - ): Promise { - const { filepath, pr, branch } = action - -- if (pr && branch) { -+ if (pr != null && branch != null) { - // we need to refetch for a forked PR and check that out - await this.fetchRefspec(repository, `pull/${pr}/head:${branch}`) - } - -- if (branch) { -+ if (pr == null && branch != null) { -+ const state = this.appStore.getRepositoryState(repository) -+ const branches = state.branchesState.allBranches -+ -+ // I don't want to invoke Git functionality from the dispatcher, which -+ // would help by using getDefaultRemote here to get the definitive ref, -+ // so this falls back to finding any remote branch matching the name -+ // received from the "Clone in Desktop" action -+ const localBranch = -+ branches.find(b => b.upstreamWithoutRemote === branch) || null -+ -+ if (localBranch == null) { -+ await this.fetch(repository, FetchType.BackgroundTask) -+ } -+ } -+ -+ if (branch != null) { - await this.checkoutBranch(repository, branch) - } - -- if (filepath) { -+ if (filepath != null) { - const fullPath = Path.join(repository.path, filepath) - // because Windows uses different path separators here - const normalized = Path.normalize(fullPath) -@@ -1148,4 +1170,93 @@ - ) { - return this.appStore._setCoAuthors(repository, coAuthors) - } -+ -+ /** -+ * Initialze the compare state for the current repository. -+ */ -+ public initializeCompare( -+ repository: Repository, -+ initialAction?: CompareAction -+ ) { -+ return this.appStore._initializeCompare(repository, initialAction) -+ } -+ -+ /** -+ * Update the compare state for the current repository -+ */ -+ public executeCompare(repository: Repository, action: CompareAction) { -+ return this.appStore._executeCompare(repository, action) -+ } -+ -+ /** Update the compare form state for the current repository */ -+ public updateCompareForm( -+ repository: Repository, -+ newState: Pick -+ ) { -+ return this.appStore._updateCompareForm(repository, newState) -+ } -+ -+ /** -+ * Increments the `mergeIntoCurrentBranchMenuCount` metric -+ */ -+ public recordMenuInitiatedMerge() { -+ return this.appStore._recordMenuInitiatedMerge() -+ } -+ -+ /** -+ * Increments the `updateFromDefaultBranchMenuCount` metric -+ */ -+ public recordMenuInitiatedUpdate() { -+ return this.appStore._recordMenuInitiatedUpdate() -+ } -+ -+ /** -+ * Increments the `mergesInitiatedFromComparison` metric -+ */ -+ public recordCompareInitiatedMerge() { -+ return this.appStore._recordCompareInitiatedMerge() -+ } -+ -+ /** -+ * Set the application-wide theme -+ */ -+ public setSelectedTheme(theme: ApplicationTheme) { -+ return this.appStore._setSelectedTheme(theme) -+ } -+ -+ /** -+ * Increments either the `repoWithIndicatorClicked` or -+ * the `repoWithoutIndicatorClicked` metric -+ */ -+ public recordRepoClicked(repoHasIndicator: boolean) { -+ return this.appStore._recordRepoClicked(repoHasIndicator) -+ } -+ -+ /** The number of times the user dismisses the diverged branch notification -+ * Increments the `divergingBranchBannerDismissal` metric -+ */ -+ public recordDivergingBranchBannerDismissal() { -+ return this.appStore._recordDivergingBranchBannerDismissal() -+ } -+ -+ /** -+ * Increments the `divergingBranchBannerInitiatedCompare` metric -+ */ -+ public recordDivergingBranchBannerInitiatedCompare() { -+ return this.appStore._recordDivergingBranchBannerInitiatedCompare() -+ } -+ -+ /** -+ * Increments the `divergingBranchBannerInfluencedMerge` metric -+ */ -+ public recordDivergingBranchBannerInfluencedMerge() { -+ return this.appStore._recordDivergingBranchBannerInfluencedMerge() -+ } -+ -+ /** -+ * Increments the `divergingBranchBannerInitatedMerge` metric -+ */ -+ public recordDivergingBranchBannerInitatedMerge() { -+ return this.appStore._recordDivergingBranchBannerInitatedMerge() -+ } - } -merged - result 100644 ad71f6491a65fc7927e53f0b9d61a0e8c53ed070 app/src/lib/dispatcher/error-handlers.ts - our 100644 e4bcde44c63c77e4be9175742b2312202cb79018 app/src/lib/dispatcher/error-handlers.ts -@@ -246,6 +246,50 @@ - } - - /** -+ * Handler for detecting when a merge conflict is reported to direct the user -+ * to a different dialog than the generic Git error dialog. -+ */ -+export async function mergeConflictHandler( -+ error: Error, -+ dispatcher: Dispatcher -+): Promise { -+ const e = asErrorWithMetadata(error) -+ if (!e) { -+ return error -+ } -+ -+ const gitError = asGitError(e.underlyingError) -+ if (!gitError) { -+ return error -+ } -+ -+ const dugiteError = gitError.result.gitError -+ if (!dugiteError) { -+ return error -+ } -+ -+ if (dugiteError !== DugiteError.MergeConflicts) { -+ return error -+ } -+ -+ const repository = e.metadata.repository -+ if (!repository) { -+ return error -+ } -+ -+ if (!(repository instanceof Repository)) { -+ return error -+ } -+ -+ dispatcher.showPopup({ -+ type: PopupType.MergeConflicts, -+ repository, -+ }) -+ -+ return null -+} -+ -+/** - * Handler for when we attempt to install the global LFS filters and LFS throws - * an error. - */ -merged - result 100644 396f15cea083d101fb676c2b851376917b67b1a8 app/src/lib/editors/darwin.ts - our 100644 830d42cfa11aea16cec5fa79dbc8b87e4ffb56aa app/src/lib/editors/darwin.ts -@@ -1,10 +1,11 @@ - import * as Path from 'path' --import { pathExists } from '../file-system' -+import { pathExists } from 'fs-extra' - import { IFoundEditor } from './found-editor' - import { assertNever } from '../fatal-error' - - export enum ExternalEditor { - Atom = 'Atom', -+ MacVim = 'MacVim', - VisualStudioCode = 'Visual Studio Code', - VisualStudioCodeInsiders = 'Visual Studio Code (Insiders)', - SublimeText = 'Sublime Text', -@@ -12,12 +13,17 @@ - PhpStorm = 'PhpStorm', - RubyMine = 'RubyMine', - TextMate = 'TextMate', -+ Brackets = 'Brackets', -+ WebStorm = 'WebStorm', - } - - export function parse(label: string): ExternalEditor | null { - if (label === ExternalEditor.Atom) { - return ExternalEditor.Atom - } -+ if (label === ExternalEditor.MacVim) { -+ return ExternalEditor.MacVim -+ } - if (label === ExternalEditor.VisualStudioCode) { - return ExternalEditor.VisualStudioCode - } -@@ -39,6 +45,12 @@ - if (label === ExternalEditor.TextMate) { - return ExternalEditor.TextMate - } -+ if (label === ExternalEditor.Brackets) { -+ return ExternalEditor.Brackets -+ } -+ if (label === ExternalEditor.WebStorm) { -+ return ExternalEditor.WebStorm -+ } - return null - } - -@@ -51,6 +63,8 @@ - switch (editor) { - case ExternalEditor.Atom: - return ['com.github.atom'] -+ case ExternalEditor.MacVim: -+ return ['org.vim.MacVim'] - case ExternalEditor.VisualStudioCode: - return ['com.microsoft.VSCode'] - case ExternalEditor.VisualStudioCodeInsiders: -@@ -65,6 +79,10 @@ - return ['com.jetbrains.RubyMine'] - case ExternalEditor.TextMate: - return ['com.macromates.TextMate'] -+ case ExternalEditor.Brackets: -+ return ['io.brackets.appshell'] -+ case ExternalEditor.WebStorm: -+ return ['com.jetbrains.WebStorm'] - default: - return assertNever(editor, `Unknown external editor: ${editor}`) - } -@@ -87,6 +105,8 @@ - 'bin', - 'code' - ) -+ case ExternalEditor.MacVim: -+ return Path.join(installPath, 'Contents', 'MacOS', 'MacVim') - case ExternalEditor.SublimeText: - return Path.join(installPath, 'Contents', 'SharedSupport', 'bin', 'subl') - case ExternalEditor.BBEdit: -@@ -97,6 +117,10 @@ - return Path.join(installPath, 'Contents', 'MacOS', 'rubymine') - case ExternalEditor.TextMate: - return Path.join(installPath, 'Contents', 'Resources', 'mate') -+ case ExternalEditor.Brackets: -+ return Path.join(installPath, 'Contents', 'MacOS', 'Brackets') -+ case ExternalEditor.WebStorm: -+ return Path.join(installPath, 'Contents', 'MacOS', 'WebStorm') - default: - return assertNever(editor, `Unknown external editor: ${editor}`) - } -@@ -133,6 +157,7 @@ - - const [ - atomPath, -+ macVimPath, - codePath, - codeInsidersPath, - sublimePath, -@@ -140,8 +165,11 @@ - phpStormPath, - rubyMinePath, - textMatePath, -+ bracketsPath, -+ webStormPath, - ] = await Promise.all([ - findApplication(ExternalEditor.Atom), -+ findApplication(ExternalEditor.MacVim), - findApplication(ExternalEditor.VisualStudioCode), - findApplication(ExternalEditor.VisualStudioCodeInsiders), - findApplication(ExternalEditor.SublimeText), -@@ -149,12 +177,18 @@ - findApplication(ExternalEditor.PhpStorm), - findApplication(ExternalEditor.RubyMine), - findApplication(ExternalEditor.TextMate), -+ findApplication(ExternalEditor.Brackets), -+ findApplication(ExternalEditor.WebStorm), - ]) - - if (atomPath) { - results.push({ editor: ExternalEditor.Atom, path: atomPath }) - } - -+ if (macVimPath) { -+ results.push({ editor: ExternalEditor.MacVim, path: macVimPath }) -+ } -+ - if (codePath) { - results.push({ editor: ExternalEditor.VisualStudioCode, path: codePath }) - } -@@ -186,5 +220,13 @@ - results.push({ editor: ExternalEditor.TextMate, path: textMatePath }) - } - -+ if (bracketsPath) { -+ results.push({ editor: ExternalEditor.Brackets, path: bracketsPath }) -+ } -+ -+ if (webStormPath) { -+ results.push({ editor: ExternalEditor.WebStorm, path: webStormPath }) -+ } -+ - return results - } -merged - result 100644 14fcc4b0ea50c3d49e60a2f61796f87d9edaaec4 app/src/lib/editors/launch.ts - our 100644 71e53504e0c9701cec78d2c5fd6dbefed636537e app/src/lib/editors/launch.ts -@@ -1,15 +1,15 @@ - import { spawn } from 'child_process' --import { pathExists } from '../file-system' -+import { pathExists } from 'fs-extra' - import { ExternalEditorError, FoundEditor } from './shared' - - /** -- * Open a given folder in the desired external editor. -+ * Open a given file or folder in the desired external editor. - * -- * @param path The folder to pass as an argument when launching the editor. -+ * @param fullPath A folder or file path to pass as an argument when launching the editor. - * @param editor The external editor to launch. - */ - export async function launchExternalEditor( -- path: string, -+ fullPath: string, - editor: FoundEditor - ): Promise { - const editorPath = editor.path -@@ -24,5 +24,5 @@ - ) - } - -- spawn(editorPath, [path]) -+ spawn(editorPath, [fullPath]) - } -merged - result 100644 61446be3534a72d03d35e5f535726b1d369508ed app/src/lib/editors/linux.ts - our 100644 a338bd034876cad8e313ca505f0764220e4b3600 app/src/lib/editors/linux.ts -@@ -1,5 +1,6 @@ -+import { pathExists } from 'fs-extra' -+ - import { IFoundEditor } from './found-editor' --import { pathExists } from '../file-system' - import { assertNever } from '../fatal-error' - - export enum ExternalEditor { -merged - result 100644 fbc6a4cc3563a6085b030129507ee04749354b37 app/src/lib/editors/win32.ts - our 100644 06c6ea78811e4a48e1f82201e7b7826ea48dd564 app/src/lib/editors/win32.ts -@@ -7,7 +7,7 @@ - RegistryValueType, - } from 'registry-js' - --import { pathExists } from '../file-system' -+import { pathExists } from 'fs-extra' - import { IFoundEditor } from './found-editor' - - import { assertNever } from '../fatal-error' -merged - result 100644 be95c011127ed3931f5b6fe25a4afe37f46c593e app/src/lib/fatal-error.ts - our 100644 a54e675b9e3ce44b64e2a17668c095e9d903770e app/src/lib/fatal-error.ts -@@ -9,11 +9,11 @@ - * If the type system is bypassed or this method will throw an exception - * using the second parameter as the message. - * -- * @param {x} Placeholder parameter in order to leverage the type -+ * @param x Placeholder parameter in order to leverage the type - * system. Pass the variable which has been type narrowed - * in an exhaustive check. - * -- * @param {message} The message to be used in the runtime exception. -+ * @param message The message to be used in the runtime exception. - * - */ - export function assertNever(x: never, message: string): never { -merged - result 100644 a709cc9f974b35dc9a357b3b8ca94677b01d1092 app/src/lib/feature-flag.ts - our 100644 64f061a69053457ba9ad6ca62c78bc534f3b6d57 app/src/lib/feature-flag.ts -@@ -14,7 +14,7 @@ - return true - } - -- if (process.env.GITHUB_DESKTOP_PREVIEW_FEATURES) { -+ if (process.env.GITHUB_DESKTOP_PREVIEW_FEATURES === '1') { - return true - } - -@@ -22,16 +22,22 @@ - } - - /** Should the app enable beta features? */ -+//@ts-ignore: this will be used again in the future - function enableBetaFeatures(): boolean { - return enableDevelopmentFeatures() || __RELEASE_CHANNEL__ === 'beta' - } - --/** Should the new Compare view be enabled? */ --export function enableCompareBranch(): boolean { -+/** Should merge tool integration be enabled? */ -+export function enableMergeTool(): boolean { -+ return enableDevelopmentFeatures() -+} -+ -+/** Should the Notification of Diverging From Default Branch (NDDB) feature be enabled? */ -+export function enableNotificationOfBranchUpdates(): boolean { - return enableBetaFeatures() - } - --/** Should merge tool integration be enabled? */ --export function enableMergeTool(): boolean { -+/** Should the repository list display info indicators? */ -+export function enableRepoInfoIndicators(): boolean { - return enableDevelopmentFeatures() - } -merged - result 100644 a696107c681c84a8da5190495b8d23ee51f935e9 app/src/lib/file-system.ts - our 100644 185776306e2fc257862b11ad55f92cadb113eb66 app/src/lib/file-system.ts -@@ -1,4 +1,4 @@ --import * as Fs from 'fs-extra' -+import * as FSE from 'fs-extra' - import * as Os from 'os' - import * as Path from 'path' - import { Disposable } from 'event-kit' -@@ -6,63 +6,14 @@ - - const byline = require('byline') - --/** Create directory using basic Fs.mkdir but ignores -- * the error thrown when directory already exists. -- * All other errors must be handled by caller. -- * -- * @param directoryPath the path of the directory the caller wants to create. -- */ --export function mkdirIfNeeded(directoryPath: string): Promise { -- return new Promise((resolve, reject) => { -- Fs.mkdir(directoryPath, err => { -- if (err && err.code !== 'EEXIST') { -- reject(err) -- return -- } -- resolve() -- }) -- }) --} -- --/* -- * Write a file using the standard fs.writeFile API, but wrapped in a promise. -- * -- * @param path the path to the file on disk -- * @param data the contents of the file to write -- * @param options the default Fs.writeFile options -- */ --export function writeFile( -- path: string, -- data: any, -- options: { encoding?: string; mode?: number; flag?: string } = {} --): Promise { -- return new Promise((resolve, reject) => { -- Fs.writeFile(path, data, options, err => { -- if (err) { -- reject(err) -- } else { -- resolve() -- } -- }) -- }) --} -- - /** - * Get a path to a temp file using the given name. Note that the file itself - * will not be created. - */ --export function getTempFilePath(name: string): Promise { -- return new Promise((resolve, reject) => { -- const tempDir = Path.join(Os.tmpdir(), `${name}-`) -- Fs.mkdtemp(tempDir, (err, directory) => { -- if (err) { -- reject(err) -- } else { -- const fullPath = Path.join(directory, name) -- resolve(fullPath) -- } -- }) -- }) -+export async function getTempFilePath(name: string): Promise { -+ const tempDir = Path.join(Os.tmpdir(), `${name}-`) -+ const directory = await FSE.mkdtemp(tempDir) -+ return Path.join(directory, name) - } - - /** -@@ -101,23 +52,6 @@ - }) - } - --/* -- * Helper function to promisify and simplify fs.stat. -- * -- * @param path Path to check for existence. -- */ --export function pathExists(path: string): Promise { -- return new Promise((resolve, reject) => { -- Fs.stat(path, (error, stats) => { -- if (error) { -- resolve(false) -- } else { -- resolve(true) -- } -- }) -- }) --} -- - /** - * Asynchronous readFile - Asynchronously reads the entire contents of a file. - * -@@ -141,7 +75,7 @@ - ): Promise { - return new Promise((resolve, reject) => { - options = options || { flag: 'r' } -- Fs.readFile(filename, options, (err, data) => { -+ FSE.readFile(filename, options, (err, data) => { - if (err) { - reject(err) - } else { -@@ -169,7 +103,7 @@ - const chunks = new Array() - let total = 0 - -- Fs.createReadStream(path, { start, end }) -+ FSE.createReadStream(path, { start, end }) - .on('data', (chunk: Buffer) => { - chunks.push(chunk) - total += chunk.length -merged - result 100644 7ade1dfc6be6bbfd8149dfb41a77caded99e26c0 app/src/lib/fuzzy-find.ts - our 100644 0eaf1391d7ca722e5bc57bd57cccecc35f68e126 app/src/lib/fuzzy-find.ts -@@ -12,36 +12,48 @@ - return fuzzAldrin.score(str, query, undefined, options) / maxScore - } - -+export interface IMatches { -+ readonly title: ReadonlyArray -+ readonly subtitle: ReadonlyArray -+} -+ - export interface IMatch { - /** `0 <= score <= 1` */ - score: number - item: T -- matches: ReadonlyArray -+ matches: IMatches - } - --export type KeyFunction = (item: T) => string -+export type KeyFunction = (item: T) => ReadonlyArray - - export function match( - query: string, - items: ReadonlyArray, -- getKey: _K | KeyFunction -+ getKey: KeyFunction - ): ReadonlyArray> { - // matching `query` against itself is a perfect match. - const maxScore = score(query, query, 1) - const result = items - .map((item): IMatch => { -- const key: string = -- typeof getKey === 'function' -- ? (getKey as KeyFunction)(item) -- : String(item[getKey]) -+ const matches: Array> = [] -+ const itemTextArray = getKey(item) -+ itemTextArray.forEach(text => { -+ matches.push(fuzzAldrin.match(text, query, undefined, options)) -+ }) - - return { -- score: score(key, query, maxScore), -+ score: score(itemTextArray.join(''), query, maxScore), - item, -- matches: fuzzAldrin.match(key, query, undefined, options), -+ matches: { -+ title: matches[0], -+ subtitle: matches.length > 1 ? matches[1] : [], -+ }, - } - }) -- .filter(({ matches }) => matches.length > 0) -+ .filter( -+ ({ matches }) => matches.title.length > 0 || matches.subtitle.length > 0 -+ ) - .sort(({ score: left }, { score: right }) => compareDescending(left, right)) -+ - return result - } -merged - result 100644 35f7c40e561385a93aea0741a57c129bf257a68d app/src/lib/git/core.ts - our 100644 37970522f470e82f498549b87c8d69c886bf8675 app/src/lib/git/core.ts -@@ -81,17 +81,17 @@ - /** - * Shell out to git with the given arguments, at the given path. - * -- * @param {args} The arguments to pass to `git`. -+ * @param args The arguments to pass to `git`. - * -- * @param {path} The working directory path for the execution of the -- * command. -+ * @param path The working directory path for the execution of the -+ * command. - * -- * @param {name} The name for the command based on its caller's -- * context. This will be used for performance -- * measurements and debugging. -+ * @param name The name for the command based on its caller's -+ * context. This will be used for performance -+ * measurements and debugging. - * -- * @param {options} Configuration options for the execution of git, -- * see IGitExecutionOptions for more information. -+ * @param options Configuration options for the execution of git, -+ * see IGitExecutionOptions for more information. - * - * Returns the result. If the command exits with a code not in - * `successExitCodes` or an error not in `expectedErrors`, a `GitError` will be -@@ -247,6 +247,14 @@ - return 'The push was rejected by the remote server because a required status check has not been satisfied.' - case DugiteError.BranchRenameFailed: - return 'The branch could not be renamed.' -+ case DugiteError.PathDoesNotExist: -+ return 'The path does not exist on disk.' -+ case DugiteError.InvalidObjectName: -+ return 'The object was not found in the Git repository.' -+ case DugiteError.OutsideRepository: -+ return 'This path is not a valid path inside the repository.' -+ case DugiteError.LockFileAlreadyExists: -+ return 'A lock file already exists in the repository, which blocks this operation from completing.' - default: - return assertNever(error, `Unknown error: ${error}`) - } -merged - result 100644 9f960230f3855e6a05f0ae2024a119e6bf720a88 app/src/lib/git/description.ts - our 100644 0468f171d5553c74bc9196bbd89c240ac253b3d1 app/src/lib/git/description.ts -@@ -1,5 +1,5 @@ - import * as Path from 'path' --import * as Fs from 'fs' -+import * as FSE from 'fs-extra' - - const GitDescriptionPath = '.git/description' - -@@ -12,22 +12,15 @@ - ): Promise { - const path = Path.join(repositoryPath, GitDescriptionPath) - -- return new Promise((resolve, reject) => { -- Fs.readFile(path, 'utf8', (err, data) => { -- if (err) { -- /** No .git/description file existed, just return an empty one. */ -- resolve('') -- return -- } -- -- if (data === DefaultGitDescription) { -- resolve('') -- return -- } -- -- resolve(data) -- }) -- }) -+ try { -+ const data = await FSE.readFile(path, 'utf8') -+ if (data === DefaultGitDescription) { -+ return '' -+ } -+ return data -+ } catch (err) { -+ return '' -+ } - } - - /** Write a .git/description file to the repository. */ -@@ -36,14 +29,5 @@ - description: string - ): Promise { - const fullPath = Path.join(repositoryPath, GitDescriptionPath) -- -- return new Promise((resolve, reject) => { -- Fs.writeFile(fullPath, description, err => { -- if (err) { -- reject(err) -- } else { -- resolve() -- } -- }) -- }) -+ await FSE.writeFile(fullPath, description) - } -merged - result 100644 c7b70925514f334e2076ddb67f208c2f3f12672f app/src/lib/git/diff.ts - our 100644 be540d047988bd54344edfed49aa5e5ad2a4ae52 app/src/lib/git/diff.ts -@@ -44,7 +44,7 @@ - * The longest line length we should try to display. If a diff has a line longer - * than this, we probably shouldn't attempt it - */ --const MaxLineLength = 500000 -+const MaxCharactersPerLine = 5000 - - /** - * Utility function to check whether parsing this buffer is going to cause -@@ -65,7 +65,7 @@ - function isDiffTooLarge(diff: IRawDiff) { - for (const hunk of diff.hunks) { - for (const line of hunk.lines) { -- if (line.text.length > MaxLineLength) { -+ if (line.text.length > MaxCharactersPerLine) { - return true - } - } -@@ -84,6 +84,7 @@ - '.gif', - '.ico', - '.webp', -+ '.bmp', - ]) - - /** -@@ -267,9 +268,9 @@ - commitish: string, - lineEndingsChange?: LineEndingsChange - ): Promise { -- if (diff.isBinary) { -- const extension = Path.extname(file.path) -+ const extension = Path.extname(file.path).toLowerCase() - -+ if (diff.isBinary) { - // some extension we don't know how to parse, never mind - if (!imageFileExtensions.has(extension)) { - return { -@@ -307,6 +308,9 @@ - if (extension === '.webp') { - return 'image/webp' - } -+ if (extension === '.bmp') { -+ return 'image/bmp' -+ } - - // fallback value as per the spec - return 'text/plain' -@@ -405,7 +409,11 @@ - ): Promise { - const extension = Path.extname(path) - const contents = await getBlobContents(repository, commitish, path) -- return new Image(contents.toString('base64'), getMediaType(extension)) -+ return new Image( -+ contents.toString('base64'), -+ getMediaType(extension), -+ contents.length -+ ) - } - /** - * Retrieve the binary contents of a blob from the working directory -@@ -425,6 +433,7 @@ - ) - return new Image( - contents.toString('base64'), -- getMediaType(Path.extname(file.path)) -+ getMediaType(Path.extname(file.path)), -+ contents.length - ) - } -merged - result 100644 fe76c1c138388cc995fcb26283c9619d2c47cdf2 app/src/lib/git/index.ts - our 100644 e5cb2e11f5be7e44292fa768f1971cca56b88440 app/src/lib/git/index.ts -@@ -5,6 +5,7 @@ - export * from './commit' - export * from './config' - export * from './core' -+export * from './description' - export * from './diff' - export * from './fetch' - export * from './for-each-ref' -merged - result 100644 b5ff0aa56eda967e9740dce0effc2d759c248634 app/src/lib/git/refs.ts - our 100644 4227634cb2503fed378f64d1e28ff7f41216f944 app/src/lib/git/refs.ts -@@ -1,3 +1,6 @@ -+import { git } from './core' -+import { Repository } from '../../models/repository' -+ - /** - * Format a local branch in the ref syntax, ensuring situations when the branch - * is ambiguous are handled. -@@ -19,3 +22,37 @@ - return `refs/heads/${name}` - } - } -+ -+/** -+ * Read a symbolic ref from the repository. -+ * -+ * Symbolic refs are used to point to other refs, similar to how symlinks work -+ * for files. Because refs can be removed easily from a Git repository, -+ * symbolic refs should only be used when absolutely necessary. -+ * -+ * @param repository The repository to lookup -+ * @param ref The symbolic ref to resolve -+ * -+ * @returns the canonical ref, if found, or `null` if `ref` cannot be found or -+ * is not a symbolic ref -+ */ -+export async function getSymbolicRef( -+ repository: Repository, -+ ref: string -+): Promise { -+ const result = await git( -+ ['symbolic-ref', '-q', ref], -+ repository.path, -+ 'getSymbolicRef', -+ { -+ successExitCodes: new Set([0, 128]), -+ } -+ ) -+ -+ if (result.exitCode === 128) { -+ // ref was not a symbolic ref or ref does not exist -+ return null -+ } -+ -+ return result.stdout.trim() -+} -merged - result 100644 3f1e4abe01f964c4aa4b46ec41185ef132ec2c8a app/src/lib/git/rev-list.ts - our 100644 ce2b9ab3f38d37bcf3a74d6bb159ef3ab0257083 app/src/lib/git/rev-list.ts -@@ -1,12 +1,36 @@ - import { GitError } from 'dugite' - import { git } from './core' - import { Repository } from '../../models/repository' --import { Branch, BranchType } from '../../models/branch' -+import { Branch, BranchType, IAheadBehind } from '../../models/branch' - --/** The number of commits a revision range is ahead/behind. */ --export interface IAheadBehind { -- readonly ahead: number -- readonly behind: number -+/** -+ * Convert two refs into the Git range syntax representing the set of commits -+ * that are reachable from `to` but excluding those that are reachable from -+ * `from`. -+ * -+ * Each parameter can be the commit SHA or a ref name, or specify an empty -+ * string to represent HEAD. -+ * -+ * @param from The start of the range -+ * @param to The end of the range -+ */ -+export function revRange(from: string, to: string) { -+ return `${from}..${to}` -+} -+ -+/** -+ * Convert two refs into the Git symmetric difference syntax, which represents -+ * the set of commits that are reachable from either `from` or `to` but not -+ * from both. -+ * -+ * Each parameter can be the commit SHA or a ref name, or you can use an empty -+ * string to represent HEAD. -+ * -+ * @param from The start of the range -+ * @param to The end of the range -+ */ -+export function revSymmetricDifference(from: string, to: string) { -+ return `${from}...${to}` - } - - /** Calculate the number of commits the range is ahead and behind. */ -@@ -64,6 +88,6 @@ - // NB: The three dot form means we'll go all the way back to the merge base - // of the branch and its upstream. Practically this is important for seeing - // "through" merges. -- const range = `${branch.name}...${upstream}` -+ const range = revSymmetricDifference(branch.name, upstream) - return getAheadBehind(repository, range) - } -merged - result 100644 bc5a94f3cc8efd6c3f497b96d1379064021f0ced app/src/lib/git/status.ts - our 100644 886824ef09bccde31746939b3ad97e2d993918d7 app/src/lib/git/status.ts -@@ -9,7 +9,7 @@ - import { parsePorcelainStatus, mapStatus } from '../status-parser' - import { DiffSelectionType, DiffSelection } from '../../models/diff' - import { Repository } from '../../models/repository' --import { IAheadBehind } from './rev-list' -+import { IAheadBehind } from '../../models/branch' - import { fatalError } from '../../lib/fatal-error' - - /** The encapsulation of the result from 'git status' */ -@@ -62,7 +62,9 @@ - 'getStatus' - ) - -- const files = new Array() -+ // Map of files keyed on their paths. -+ // Note, map maintains insertion order -+ const files = new Map() - - let currentBranch: string | undefined = undefined - let currentUpstreamBranch: string | undefined = undefined -@@ -90,10 +92,7 @@ - // same path, we should ensure that we only draw one entry in the - // changes list - see if an entry already exists for this path and - // remove it if found -- const existingEntry = files.findIndex(p => p.path === entry.path) -- if (existingEntry > -1) { -- files.splice(existingEntry, 1) -- } -+ files.delete(entry.path) - } - - // for now we just poke at the existing summary -@@ -102,7 +101,8 @@ - DiffSelectionType.All - ) - -- files.push( -+ files.set( -+ entry.path, - new WorkingDirectoryFileChange( - entry.path, - summary, -@@ -134,7 +134,7 @@ - } - } - -- const workingDirectory = WorkingDirectoryStatus.fromFiles(files) -+ const workingDirectory = WorkingDirectoryStatus.fromFiles([...files.values()]) - - return { - currentBranch, -merged - result 100644 497889aae05c2de60409b2354678563f32994314 app/src/lib/git/submodule.ts - our 100644 964fa04fb165bbe2e1bd2628840922ade9b86fd6 app/src/lib/git/submodule.ts -@@ -1,8 +1,9 @@ -+import * as Path from 'path' -+import { pathExists } from 'fs-extra' -+ - import { git } from './core' - import { Repository } from '../../models/repository' - import { SubmoduleEntry } from '../../models/submodule' --import { pathExists } from '../file-system' --import * as Path from 'path' - - export async function listSubmodules( - repository: Repository -merged - result 100644 efb13fb0c1c8db7af2da3feffa6157cdfcffc386 app/src/lib/is-git-on-path.ts - our 100644 25f5e58c8ceb7199146a603c42fbb7d88e6c431c app/src/lib/is-git-on-path.ts -@@ -5,14 +5,13 @@ - // Modern versions of macOS ship with a Git shim that guides you through - // the process of setting everything up. We trust this is available, so - // don't worry about looking for it here. -- // I decide linux user have git too :) -- if (__DARWIN__ || __LINUX__) { -+ if (__DARWIN__) { - return Promise.resolve(true) - } - - // adapted from http://stackoverflow.com/a/34953561/1363815 -- return new Promise((resolve, reject) => { -- if (__WIN32__) { -+ if (__WIN32__) { -+ return new Promise((resolve, reject) => { - const windowsRoot = process.env.SystemRoot || 'C:\\Windows' - const wherePath = Path.join(windowsRoot, 'System32', 'where.exe') - -@@ -29,9 +28,20 @@ - resolve(code === 0) - }) - return -- } -+ }) -+ } -+ -+ if (__LINUX__) { -+ return new Promise((resolve, reject) => { -+ const process = spawn('which', ['git']) -+ -+ // `which` will return 0 when the executable -+ // is found under PATH, or 1 if it cannot be found -+ process.on('close', function(code) { -+ resolve(code === 0) -+ }) -+ }) -+ } - -- // in case you're on a non-Windows/non-macOS platform -- resolve(false) -- }) -+ return Promise.resolve(false) - } -merged - result 100644 d50be352ff1adc2c799a3f53fd983a2cdcbaa735 app/src/lib/menu-update.ts - our 100644 a12e7bdd46fd140f6b2b7ad6b947c9f93f2450b8 app/src/lib/menu-update.ts -@@ -104,7 +104,7 @@ - 'update-branch', - 'merge-branch', - 'view-repository-on-github', -- 'compare-branch', -+ 'compare-on-github', - 'open-in-shell', - 'push', - 'pull', -@@ -200,6 +200,7 @@ - 'show-history', - 'show-branches-list', - 'open-external-editor', -+ 'compare-to-branch', - ] - - const menuStateBuilder = new MenuStateBuilder() -@@ -227,7 +228,7 @@ - ) - menuStateBuilder.setEnabled('merge-branch', onBranch) - menuStateBuilder.setEnabled( -- 'compare-branch', -+ 'compare-on-github', - isHostedOnGitHub && hasPublishedBranch - ) - -@@ -278,10 +279,10 @@ - menuStateBuilder.disable('delete-branch') - menuStateBuilder.disable('update-branch') - menuStateBuilder.disable('merge-branch') -- menuStateBuilder.disable('compare-branch') - - menuStateBuilder.disable('push') - menuStateBuilder.disable('pull') -+ menuStateBuilder.disable('compare-to-branch') - } - return menuStateBuilder - } -merged - result 100644 b9e38022ccb3b75ba35fc496a1e77a8857d825f6 app/src/lib/parse-app-url.ts - our 100644 e01d63715d1d361dacd2f6a1fa3c1ff44ff12eb4 app/src/lib/parse-app-url.ts -@@ -13,13 +13,13 @@ - readonly url: string - - /** the optional branch name which should be checked out. use the default branch otherwise. */ -- readonly branch?: string -+ readonly branch: string | null - - /** the pull request number, if pull request originates from a fork of the repository */ -- readonly pr?: string -+ readonly pr: string | null - - /** the file to open after cloning the repository */ -- readonly filepath?: string -+ readonly filepath: string | null - } - - export interface IOpenRepositoryFromPathAction { -@@ -40,6 +40,36 @@ - | IOpenRepositoryFromPathAction - | IUnknownAction - -+// eslint-disable-next-line typescript/interface-name-prefix -+interface ParsedUrlQueryWithUndefined { -+ // `undefined` is added here to ensure we handle the missing querystring key -+ // See https://github.com/Microsoft/TypeScript/issues/13778 for discussion about -+ // why this isn't supported natively in TypeScript -+ [key: string]: string | string[] | undefined -+} -+ -+/** -+ * Parse the URL to find a given key in the querystring text. -+ * -+ * @param url The source URL containing querystring key-value pairs -+ * @param key The key to look for in the querystring -+ */ -+function getQueryStringValue( -+ query: ParsedUrlQueryWithUndefined, -+ key: string -+): string | null { -+ const value = query[key] -+ if (value == null) { -+ return null -+ } -+ -+ if (Array.isArray(value)) { -+ return value[0] -+ } -+ -+ return value -+} -+ - export function parseAppURL(url: string): URLActionType { - const parsedURL = URL.parse(url, true) - const hostname = parsedURL.hostname -@@ -48,9 +78,16 @@ - return unknown - } - -+ const query = parsedURL.query -+ - const actionName = hostname.toLowerCase() - if (actionName === 'oauth') { -- return { name: 'oauth', code: parsedURL.query.code } -+ const code = getQueryStringValue(query, 'code') -+ if (code != null) { -+ return { name: 'oauth', code } -+ } else { -+ return unknown -+ } - } - - // we require something resembling a URL first -@@ -70,28 +107,23 @@ - // suffix the remote URL with `.git`, for backwards compatibility - const url = `${probablyAURL}.git` - -- const queryString = parsedURL.query -+ const pr = getQueryStringValue(query, 'pr') -+ const branch = getQueryStringValue(query, 'branch') -+ const filepath = getQueryStringValue(query, 'filepath') - -- const pr = queryString.pr -- const branch = queryString.branch -- const filepath = queryString.filepath -- -- if (pr) { -- // if anything other than a number is used for the PR value, exit -+ if (pr != null) { - if (!/^\d+$/.test(pr)) { - return unknown - } - - // we also expect the branch for a forked PR to be a given ref format -- if (!/^pr\/\d+$/.test(branch)) { -+ if (branch != null && !/^pr\/\d+$/.test(branch)) { - return unknown - } - } - -- if (branch) { -- if (testForInvalidChars(branch)) { -- return unknown -- } -+ if (branch != null && testForInvalidChars(branch)) { -+ return unknown - } - - return { -added in remote - their 100644 e53daf16a90439aa5a1aa9c6a1c5736f39274eda app/src/lib/process/win32.ts -@@ -0,0 +1,90 @@ -+import { spawn as spawnInternal } from 'child_process' -+import * as Path from 'path' -+ -+/** Get the path segments in the user's `Path`. */ -+export async function getPathSegments(): Promise> { -+ let powershellPath: string -+ const systemRoot = process.env.SystemRoot -+ if (systemRoot != null) { -+ const system32Path = Path.join(systemRoot, 'System32') -+ powershellPath = Path.join( -+ system32Path, -+ 'WindowsPowerShell', -+ 'v1.0', -+ 'powershell.exe' -+ ) -+ } else { -+ powershellPath = 'powershell.exe' -+ } -+ -+ const args = [ -+ '-noprofile', -+ '-ExecutionPolicy', -+ 'RemoteSigned', -+ '-command', -+ // Set encoding and execute the command, capture the output, and return it -+ // via .NET's console in order to have consistent UTF-8 encoding. -+ // See http://stackoverflow.com/questions/22349139/utf-8-output-from-powershell -+ // to address https://github.com/atom/atom/issues/5063 -+ ` -+ [Console]::OutputEncoding=[System.Text.Encoding]::UTF8 -+ $output=[environment]::GetEnvironmentVariable('Path', 'User') -+ [Console]::WriteLine($output) -+ `, -+ ] -+ -+ const stdout = await spawn(powershellPath, args) -+ const pathOutput = stdout.replace(/^\s+|\s+$/g, '') -+ return pathOutput.split(/;+/).filter(segment => segment.length) -+} -+ -+/** Set the user's `Path`. */ -+export async function setPathSegments( -+ paths: ReadonlyArray -+): Promise { -+ let setxPath: string -+ const systemRoot = process.env['SystemRoot'] -+ if (systemRoot) { -+ const system32Path = Path.join(systemRoot, 'System32') -+ setxPath = Path.join(system32Path, 'setx.exe') -+ } else { -+ setxPath = 'setx.exe' -+ } -+ -+ await spawn(setxPath, ['Path', paths.join(';')]) -+} -+ -+/** Spawn a command with arguments and capture its output. */ -+export function spawn( -+ command: string, -+ args: ReadonlyArray -+): Promise { -+ try { -+ const child = spawnInternal(command, args as string[]) -+ return new Promise((resolve, reject) => { -+ let stdout = '' -+ child.stdout.on('data', data => { -+ stdout += data -+ }) -+ -+ child.on('close', code => { -+ if (code === 0) { -+ resolve(stdout) -+ } else { -+ reject(new Error(`Command "${command} ${args}" failed: "${stdout}"`)) -+ } -+ }) -+ -+ child.on('error', (err: Error) => { -+ reject(err) -+ }) -+ -+ // This is necessary if using Powershell 2 on Windows 7 to get the events -+ // to raise. -+ // See http://stackoverflow.com/questions/9155289/calling-powershell-from-nodejs -+ child.stdin.end() -+ }) -+ } catch (error) { -+ return Promise.reject(error) -+ } -+} -merged - result 100644 f3e30a75fd83483f4729f3239ffd2bf3b780a7fd app/src/lib/progress/from-process.ts - our 100644 574666eff35b9d7681971fbb405c2bac00c106a0 app/src/lib/progress/from-process.ts -@@ -1,5 +1,6 @@ - import { ChildProcess } from 'child_process' - import * as Fs from 'fs' -+import * as Path from 'path' - import * as byline from 'byline' - - import { GitProgressParser, IGitProgress, IGitOutput } from './git' -@@ -23,8 +24,13 @@ - let lfsProgressPath = null - let env = {} - if (options.trackLFSProgress) { -- lfsProgressPath = await createLFSProgressFile() -- env = { GIT_LFS_PROGRESS: lfsProgressPath } -+ try { -+ lfsProgressPath = await createLFSProgressFile() -+ env = { GIT_LFS_PROGRESS: lfsProgressPath } -+ } catch (e) { -+ log.error('Error writing LFS progress file', e) -+ env = { GIT_LFS_PROGRESS: null } -+ } - } - - return merge(options, { -@@ -57,9 +63,17 @@ - - process.on('close', () => { - disposable.dispose() -- // NB: We don't really care about errors deleting the file, but Node -- // gets kinda bothered if we don't provide a callback. -- Fs.unlink(lfsProgressPath, () => {}) -+ // the order of these callbacks is important because -+ // - unlink can only be done on files -+ // - rmdir can only be done when the directory is empty -+ // - we don't want to surface errors to the user if something goes -+ // wrong (these files can stay in TEMP and be cleaned up eventually) -+ Fs.unlink(lfsProgressPath, err => { -+ if (err == null) { -+ const directory = Path.dirname(lfsProgressPath) -+ Fs.rmdir(directory, () => {}) -+ } -+ }) - }) - } - -merged - result 100644 466a25723137239fd49be2906d25e300ad5fa913 app/src/lib/progress/lfs.ts - our 100644 3b054c35fb65185af0628abc0d445ae6a1296b30 app/src/lib/progress/lfs.ts -@@ -1,19 +1,12 @@ --import * as Fs from 'fs' -+import * as FSE from 'fs-extra' - import { getTempFilePath } from '../file-system' - import { IGitProgress, IGitProgressInfo, IGitOutput } from './git' - - /** Create the Git LFS progress reporting file and return the path. */ - export async function createLFSProgressFile(): Promise { - const path = await getTempFilePath('GitHubDesktop-lfs-progress') -- return new Promise((resolve, reject) => { -- Fs.writeFile(path, '', err => { -- if (err) { -- reject(err) -- } else { -- resolve(path) -- } -- }) -- }) -+ await FSE.ensureFile(path) -+ return path - } - - // The regex for parsing LFS progress lines. See -merged - result 100644 df0a7f7ff234a7c89d0b2480c70661b30e5d90bd app/src/lib/remote-parsing.ts - our 100644 21114f701d33070680ccedbfcbd4b563dd3117cc app/src/lib/remote-parsing.ts -@@ -1,4 +1,8 @@ -+type Protocol = 'ssh' | 'https' -+ - interface IGitRemoteURL { -+ readonly protocol: Protocol -+ - /** The hostname of the remote. */ - readonly hostname: string - -@@ -15,21 +19,33 @@ - readonly name: string | null - } - -+// Examples: -+// https://github.com/octocat/Hello-World.git -+// https://github.com/octocat/Hello-World.git/ -+// git@github.com:octocat/Hello-World.git -+// git:github.com/octocat/Hello-World.git -+const remoteRegexes: ReadonlyArray<{ protocol: Protocol; regex: RegExp }> = [ -+ { -+ protocol: 'https', -+ regex: new RegExp('^https?://(?:.+@)?(.+)/(.+)/(.+?)(?:/|.git/?)?$'), -+ }, -+ { -+ protocol: 'ssh', -+ regex: new RegExp('^git@(.+):(.+)/(.+?)(?:/|.git)?$'), -+ }, -+ { -+ protocol: 'ssh', -+ regex: new RegExp('^git:(.+)/(.+)/(.+?)(?:/|.git)?$'), -+ }, -+ { -+ protocol: 'ssh', -+ regex: new RegExp('^ssh://git@(.+)/(.+)/(.+?)(?:/|.git)?$'), -+ }, -+] -+ - /** Parse the remote information from URL. */ - export function parseRemote(url: string): IGitRemoteURL | null { -- // Examples: -- // https://github.com/octocat/Hello-World.git -- // https://github.com/octocat/Hello-World.git/ -- // git@github.com:octocat/Hello-World.git -- // git:github.com/octocat/Hello-World.git -- const regexes = [ -- new RegExp('^https?://(?:.+@)?(.+)/(.+)/(.+?)(?:/|.git/?)?$'), -- new RegExp('^git@(.+):(.+)/(.+?)(?:/|.git)?$'), -- new RegExp('^git:(.+)/(.+)/(.+?)(?:/|.git)?$'), -- new RegExp('^ssh://git@(.+)/(.+)/(.+?)(?:/|.git)?$'), -- ] -- -- for (const regex of regexes) { -+ for (const { protocol, regex } of remoteRegexes) { - const result = url.match(regex) - if (!result) { - continue -@@ -39,7 +55,7 @@ - const owner = result[2] - const name = result[3] - if (hostname) { -- return { hostname, owner, name } -+ return { protocol, hostname, owner, name } - } - } - -merged - result 100644 63d2fe120af3eaaafc7fe69f833f40cd5e6b477e app/src/lib/shells/darwin.ts - our 100644 00a9aa293632a29b5bd02d296907bf9cdb3ffde5 app/src/lib/shells/darwin.ts -@@ -8,6 +8,7 @@ - Terminal = 'Terminal', - Hyper = 'Hyper', - iTerm2 = 'iTerm2', -+ PowerShellCore = 'PowerShell Core', - } - - export const Default = Shell.Terminal -@@ -25,6 +26,10 @@ - return Shell.iTerm2 - } - -+ if (label === Shell.PowerShellCore) { -+ return Shell.PowerShellCore -+ } -+ - return Default - } - -@@ -36,6 +41,8 @@ - return 'com.googlecode.iterm2' - case Shell.Hyper: - return 'co.zeit.hyper' -+ case Shell.PowerShellCore: -+ return 'com.microsoft.powershell' - default: - return assertNever(shell, `Unknown shell: ${shell}`) - } -@@ -54,10 +61,16 @@ - export async function getAvailableShells(): Promise< - ReadonlyArray> - > { -- const [terminalPath, hyperPath, iTermPath] = await Promise.all([ -+ const [ -+ terminalPath, -+ hyperPath, -+ iTermPath, -+ powerShellCorePath, -+ ] = await Promise.all([ - getShellPath(Shell.Terminal), - getShellPath(Shell.Hyper), - getShellPath(Shell.iTerm2), -+ getShellPath(Shell.PowerShellCore), - ]) - - const shells: Array> = [] -@@ -73,6 +86,10 @@ - shells.push({ shell: Shell.iTerm2, path: iTermPath }) - } - -+ if (powerShellCorePath) { -+ shells.push({ shell: Shell.PowerShellCore, path: powerShellCorePath }) -+ } -+ - return shells - } - -merged - result 100644 afc28e5ff68afd9388d5e17690d30eccc4ac1b75 app/src/lib/shells/linux.ts - our 100644 d1effa798ba21a6f706771f25cd9dfb957f0c7d0 app/src/lib/shells/linux.ts -@@ -1,5 +1,5 @@ - import { spawn, ChildProcess } from 'child_process' --import { pathExists } from '../file-system' -+import { pathExists } from 'fs-extra' - import { assertNever } from '../fatal-error' - import { IFoundShell } from './found-shell' - -merged - result 100644 0fef473ed40b7b043f025d9677ebb724939d0a8f app/src/lib/shells/shared.ts - our 100644 bc82735e7a7928d8280b488af550e97acbe8ab65 app/src/lib/shells/shared.ts -@@ -1,9 +1,9 @@ - import { ChildProcess } from 'child_process' -+import { pathExists } from 'fs-extra' - - import * as Darwin from './darwin' - import * as Win32 from './win32' - import * as Linux from './linux' --import { pathExists } from '../file-system' - import { IFoundShell } from './found-shell' - import { ShellError } from './error' - -merged - result 100644 9bfcb28a39ebb3d774a2995d510e3a4ece676b3a app/src/lib/shells/win32.ts - our 100644 94056bbd3c70887c371b620f95e77efeafb04518 app/src/lib/shells/win32.ts -@@ -1,14 +1,15 @@ - import { spawn, ChildProcess } from 'child_process' - import * as Path from 'path' - import { enumerateValues, HKEY, RegistryValueType } from 'registry-js' -+import { pathExists } from 'fs-extra' - --import { pathExists } from '../file-system' - import { assertNever } from '../fatal-error' - import { IFoundShell } from './found-shell' - - export enum Shell { - Cmd = 'Command Prompt', - PowerShell = 'PowerShell', -+ PowerShellCore = 'PowerShell Core', - Hyper = 'Hyper', - GitBash = 'Git Bash', - } -@@ -24,6 +25,10 @@ - return Shell.PowerShell - } - -+ if (label === Shell.PowerShellCore) { -+ return Shell.PowerShellCore -+ } -+ - if (label === Shell.Hyper) { - return Shell.Hyper - } -@@ -53,6 +58,14 @@ - }) - } - -+ const powerShellCorePath = await findPowerShellCore() -+ if (powerShellCorePath != null) { -+ shells.push({ -+ shell: Shell.PowerShellCore, -+ path: powerShellCorePath, -+ }) -+ } -+ - const hyperPath = await findHyper() - if (hyperPath != null) { - shells.push({ -@@ -111,6 +124,32 @@ - return null - } - -+async function findPowerShellCore(): Promise { -+ const powerShellCore = enumerateValues( -+ HKEY.HKEY_LOCAL_MACHINE, -+ 'Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\pwsh.exe' -+ ) -+ -+ if (powerShellCore.length === 0) { -+ return null -+ } -+ -+ const first = powerShellCore[0] -+ if (first.type === RegistryValueType.REG_SZ) { -+ const path = first.data -+ -+ if (await pathExists(path)) { -+ return path -+ } else { -+ log.debug( -+ `[PowerShellCore] registry entry found but does not exist at '${path}'` -+ ) -+ } -+ } -+ -+ return null -+} -+ - async function findHyper(): Promise { - const hyper = enumerateValues( - HKEY.HKEY_CURRENT_USER, -@@ -128,11 +167,19 @@ - // This regex is designed to get the path to the version-specific Hyper. - // commandPieces = ['"{installationPath}\app-x.x.x\Hyper.exe"', '"', '{installationPath}\app-x.x.x\Hyper.exe', ...] - const commandPieces = first.data.match(/(["'])(.*?)\1/) -+ const localAppData = process.env.LocalAppData -+ - const path = commandPieces - ? commandPieces[2] -- : process.env.LocalAppData.concat('\\hyper\\Hyper.exe') // fall back to the launcher in install root -+ : localAppData != null -+ ? localAppData.concat('\\hyper\\Hyper.exe') -+ : null // fall back to the launcher in install root - -- if (await pathExists(path)) { -+ if (path == null) { -+ log.debug( -+ `[Hyper] LOCALAPPDATA environment variable is unset, aborting fallback behavior` -+ ) -+ } else if (await pathExists(path)) { - return path - } else { - log.debug(`[Hyper] registry entry found but does not exist at '${path}'`) -@@ -181,6 +228,12 @@ - shell: true, - cwd: path, - }) -+ case Shell.PowerShellCore: -+ const psCoreCommand = `"Set-Location -LiteralPath '${path}'"` -+ return spawn('START', ['pwsh', '-NoExit', '-Command', psCoreCommand], { -+ shell: true, -+ cwd: path, -+ }) - case Shell.Hyper: - const hyperPath = `"${foundShell.path}"` - log.info(`launching ${shell} at path: ${hyperPath}`) -merged - result 100644 1a92eadda10120ed9ba6bec97c2fc0a752509fc2 app/src/lib/stats/stats-database.ts - our 100644 7911de79718900503165ac9ef13670da8c71cdc5 app/src/lib/stats/stats-database.ts -@@ -40,6 +40,47 @@ - - /** The number of commits created with one or more co-authors. */ - readonly coAuthoredCommits: number -+ -+ /** The number of times a branch is compared to an arbitrary branch */ -+ readonly branchComparisons: number -+ -+ /** The number of times a branch is compared to `master` */ -+ readonly defaultBranchComparisons: number -+ -+ /** The number of times a merge is initiated in the `compare` sidebar */ -+ readonly mergesInitiatedFromComparison: number -+ -+ /** The number of times the `Branch -> Update From Default Branch` menu item is used */ -+ readonly updateFromDefaultBranchMenuCount: number -+ -+ /** The number of times the `Branch -> Merge Into Current Branch` menu item is used */ -+ readonly mergeIntoCurrentBranchMenuCount: number -+ -+ /** The number of times the user checks out a branch using the PR menu */ -+ readonly prBranchCheckouts: number -+ -+ /** The numbers of times a repo with indicators is clicked on repo list view */ -+ readonly repoWithIndicatorClicked: number -+ /** The numbers of times a repo without indicators is clicked on repo list view */ -+ readonly repoWithoutIndicatorClicked: number -+ -+ /** The number of times the user dismisses the diverged branch notification */ -+ readonly divergingBranchBannerDismissal: number -+ -+ /** The number of times the user merges from the diverged branch notification merge CTA button */ -+ readonly divergingBranchBannerInitatedMerge: number -+ -+ /** The number of times the user compares from the diverged branch notification compare CTA button */ -+ readonly divergingBranchBannerInitiatedCompare: number -+ -+ /** -+ * The number of times the user merges from the compare view after getting to that state -+ * from the diverged branch notification compare CTA button -+ */ -+ readonly divergingBranchBannerInfluencedMerge: number -+ -+ /** The number of times the diverged branch notification is displayed */ -+ readonly divergingBranchBannerDisplayed: number - } - - export class StatsDatabase extends Dexie { -merged - result 100644 3866dcb7f85658b385e8d34e610a3f2321d9fbd8 app/src/lib/stats/stats-store.ts - our 100644 10e9a39560a0f09260217f2d9e598e9bbaf63613 app/src/lib/stats/stats-store.ts -@@ -7,6 +7,7 @@ - import { getGUID } from './get-guid' - import { Repository } from '../../models/repository' - import { merge } from '../../lib/merge' -+import { getPersistedThemeName } from '../../ui/lib/application-theme' - - const StatsEndpoint = 'https://central.github.com/api/usage/desktop' - -@@ -29,6 +30,19 @@ - partialCommits: 0, - openShellCount: 0, - coAuthoredCommits: 0, -+ branchComparisons: 0, -+ defaultBranchComparisons: 0, -+ mergesInitiatedFromComparison: 0, -+ updateFromDefaultBranchMenuCount: 0, -+ mergeIntoCurrentBranchMenuCount: 0, -+ prBranchCheckouts: 0, -+ repoWithIndicatorClicked: 0, -+ repoWithoutIndicatorClicked: 0, -+ divergingBranchBannerDismissal: 0, -+ divergingBranchBannerInitatedMerge: 0, -+ divergingBranchBannerInitiatedCompare: 0, -+ divergingBranchBannerInfluencedMerge: 0, -+ divergingBranchBannerDisplayed: 0, - } - - interface ICalculatedStats { -@@ -56,6 +70,12 @@ - /** Is the user logged in with an Enterprise account? */ - readonly enterpriseAccount: boolean - -+ /** -+ * The name of the currently selected theme/application -+ * appearance as set at time of stats submission. -+ */ -+ readonly theme: string -+ - readonly eventType: 'usage' - } - -@@ -171,6 +191,7 @@ - version: getVersion(), - osVersion: getOS(), - platform: process.platform, -+ theme: getPersistedThemeName(), - ...launchStats, - ...dailyMeasures, - ...userType, -@@ -294,6 +315,59 @@ - })) - } - -+ /** Record that a branch comparison has been made */ -+ public recordBranchComparison(): Promise { -+ return this.updateDailyMeasures(m => ({ -+ branchComparisons: m.branchComparisons + 1, -+ })) -+ } -+ -+ /** Record that a branch comparison has been made to the `master` branch */ -+ public recordDefaultBranchComparison(): Promise { -+ return this.updateDailyMeasures(m => ({ -+ defaultBranchComparisons: m.defaultBranchComparisons + 1, -+ })) -+ } -+ -+ /** Record that a merge has been initiated from the `compare` sidebar */ -+ public recordCompareInitiatedMerge(): Promise { -+ return this.updateDailyMeasures(m => ({ -+ mergesInitiatedFromComparison: m.mergesInitiatedFromComparison + 1, -+ })) -+ } -+ -+ /** Record that a merge has been initiated from the `Branch -> Update From Default Branch` menu item */ -+ public recordMenuInitiatedUpdate(): Promise { -+ return this.updateDailyMeasures(m => ({ -+ updateFromDefaultBranchMenuCount: m.updateFromDefaultBranchMenuCount + 1, -+ })) -+ } -+ -+ /** Record that a merge has been initiated from the `Branch -> Merge Into Current Branch` menu item */ -+ public recordMenuInitiatedMerge(): Promise { -+ return this.updateDailyMeasures(m => ({ -+ mergeIntoCurrentBranchMenuCount: m.mergeIntoCurrentBranchMenuCount + 1, -+ })) -+ } -+ -+ /** Record that the user checked out a PR branch */ -+ public recordPRBranchCheckout(): Promise { -+ return this.updateDailyMeasures(m => ({ -+ prBranchCheckouts: m.prBranchCheckouts + 1, -+ })) -+ } -+ -+ public recordRepoClicked(repoHasIndicator: boolean): Promise { -+ if (repoHasIndicator) { -+ return this.updateDailyMeasures(m => ({ -+ repoWithIndicatorClicked: m.repoWithIndicatorClicked + 1, -+ })) -+ } -+ return this.updateDailyMeasures(m => ({ -+ repoWithoutIndicatorClicked: m.repoWithoutIndicatorClicked + 1, -+ })) -+ } -+ - /** Set whether the user has opted out of stats reporting. */ - public async setOptOut(optOut: boolean): Promise { - const changed = this.optOut !== optOut -@@ -312,6 +386,47 @@ - return this.optOut - } - -+ /** Record that user dismissed diverging branch notification */ -+ public async recordDivergingBranchBannerDismissal(): Promise { -+ return this.updateDailyMeasures(m => ({ -+ divergingBranchBannerDismissal: m.divergingBranchBannerDismissal + 1, -+ })) -+ } -+ -+ /** Record that user initiated a merge from within the notification banner */ -+ public async recordDivergingBranchBannerInitatedMerge(): Promise { -+ return this.updateDailyMeasures(m => ({ -+ divergingBranchBannerInitatedMerge: -+ m.divergingBranchBannerInitatedMerge + 1, -+ })) -+ } -+ -+ /** Record that user initiated a compare from within the notification banner */ -+ public async recordDivergingBranchBannerInitiatedCompare(): Promise { -+ return this.updateDailyMeasures(m => ({ -+ divergingBranchBannerInitiatedCompare: -+ m.divergingBranchBannerInitiatedCompare + 1, -+ })) -+ } -+ -+ /** -+ * Record that user initiated a merge after getting to compare view -+ * from within notificatio banner -+ */ -+ public async recordDivergingBranchBannerInfluencedMerge(): Promise { -+ return this.updateDailyMeasures(m => ({ -+ divergingBranchBannerInfluencedMerge: -+ m.divergingBranchBannerInfluencedMerge + 1, -+ })) -+ } -+ -+ /** Record that the user was shown the notification banner */ -+ public async recordDivergingBranchBannerDisplayed(): Promise { -+ return this.updateDailyMeasures(m => ({ -+ divergingBranchBannerDisplayed: m.divergingBranchBannerDisplayed + 1, -+ })) -+ } -+ - /** Post some data to our stats endpoint. */ - private post(body: object): Promise { - const options: RequestInit = { -merged - result 100644 f11d691b980015ca4a257c25f28433f4a7514376 app/src/lib/stores/accounts-store.ts - our 100644 7b2bcf64296d13ab933c90d71368479c79c92e69 app/src/lib/stores/accounts-store.ts -@@ -213,7 +213,7 @@ - async function updatedAccount(account: Account): Promise { - if (!account.token) { - return fatalError( -- `Cannot update an account which doesn't have a token: ${account}` -+ `Cannot update an account which doesn't have a token: ${account.login}` - ) - } - -merged - result 100644 ee571b467f678151f67ef1ea677ecd440ff28df8 app/src/lib/stores/app-store.ts - our 100644 9f98922eb0685739d0e3a1ca94059e260529c827 app/src/lib/stores/app-store.ts -@@ -3,7 +3,7 @@ - IRepositoryState, - IHistoryState, - IAppState, -- RepositorySection, -+ RepositorySectionTab, - IChangesState, - Popup, - PopupType, -@@ -17,9 +17,16 @@ - ImageDiffType, - IRevertProgress, - IFetchProgress, -+ ICompareState, -+ ComparisonView, -+ CompareAction, -+ CompareActionKind, -+ IDisplayHistory, -+ ICompareBranch, -+ ICompareFormUpdate, - } from '../app-state' - import { Account } from '../../models/account' --import { Repository } from '../../models/repository' -+import { Repository, ILocalRepositoryState } from '../../models/repository' - import { GitHubRepository } from '../../models/github-repository' - import { - CommittedFileChange, -@@ -34,7 +41,11 @@ - } from '../../lib/repository-matching' - import { API, getAccountForEndpoint, IAPIUser } from '../../lib/api' - import { caseInsensitiveCompare } from '../compare' --import { Branch, BranchType } from '../../models/branch' -+import { -+ Branch, -+ eligibleForFastForward, -+ IAheadBehind, -+} from '../../models/branch' - import { TipState } from '../../models/tip' - import { CloningRepository } from '../../models/cloning-repository' - import { Commit } from '../../models/commit' -@@ -121,6 +132,15 @@ - import * as QueryString from 'querystring' - import { IRemote, ForkedRemotePrefix } from '../../models/remote' - import { IAuthor } from '../../models/author' -+import { ComparisonCache } from '../comparison-cache' -+import { AheadBehindUpdater } from './helpers/ahead-behind-updater' -+import { enableRepoInfoIndicators } from '../feature-flag' -+import { inferComparisonBranch } from './helpers/infer-comparison-branch' -+import { -+ ApplicationTheme, -+ getPersistedTheme, -+ setPersistedTheme, -+} from '../../ui/lib/application-theme' - - /** - * Enum used by fetch to determine if -@@ -131,6 +151,13 @@ - UserInitiatedTask, - } - -+/** -+ * As fast-forwarding local branches is proportional to the number of local -+ * branches, and is run after every fetch/push/pull, this is skipped when the -+ * number of eligible branches is greater than a given threshold. -+ */ -+const FastForwardBranchesThreshold = 20 -+ - const LastSelectedRepositoryIDKey = 'last-selected-repository-id' - - const defaultSidebarWidth: number = 250 -@@ -166,6 +193,9 @@ - /** The pull request updater for the currently selected repository */ - private currentPullRequestUpdater: PullRequestUpdater | null = null - -+ /** The ahead/behind updater or the currently selected repository */ -+ private currentAheadBehindUpdater: AheadBehindUpdater | null = null -+ - private repositoryState = new Map() - private showWelcomeFlow = false - private currentPopup: Popup | null = null -@@ -179,6 +209,11 @@ - string, - RepositorySettingsStore - >() -+ -+ private readonly localRepositoryStateLookup = new Map< -+ number, -+ ILocalRepositoryState -+ >() - public readonly gitHubUserStore: GitHubUserStore - private readonly cloningRepositoriesStore: CloningRepositoriesStore - private readonly emojiStore: EmojiStore -@@ -235,9 +270,11 @@ - | ((repository: Repository | null) => void) - | null = null - -- private selectedCloneRepositoryTab: CloneRepositoryTab = CloneRepositoryTab.DotCom -+ private selectedCloneRepositoryTab = CloneRepositoryTab.DotCom - - private selectedBranchesTab = BranchesTab.Branches -+ private selectedTheme = ApplicationTheme.Light -+ private isDivergingBranchBannerVisible = false - - public constructor( - gitHubUserStore: GitHubUserStore, -@@ -319,8 +356,7 @@ - this.accountsStore.onDidError(error => this.emitError(error)) - - this.repositoriesStore.onDidUpdate(async () => { -- const repositories = await this.repositoriesStore.getAll() -- this.repositories = repositories -+ this.repositories = await this.repositoriesStore.getAll() - this.updateRepositorySelectionAfterRepositoriesChanged() - this.emitUpdate() - }) -@@ -395,14 +431,14 @@ - workingDirectory: WorkingDirectoryStatus.fromFiles( - new Array() - ), -- selectedFileID: null, -+ selectedFileIDs: [], - diff: null, - contextualCommitMessage: null, - commitMessage: null, - coAuthors: [], - showCoAuthoredBy: false, - }, -- selectedSection: RepositorySection.Changes, -+ selectedSection: RepositorySectionTab.Changes, - branchesState: { - tip: { kind: TipState.Unknown }, - defaultBranch: null, -@@ -412,6 +448,17 @@ - currentPullRequest: null, - isLoadingPullRequests: false, - }, -+ compareState: { -+ formState: { kind: ComparisonView.None }, -+ showBranchList: false, -+ filterText: '', -+ commitSHAs: [], -+ aheadBehindCache: new ComparisonCache(), -+ allBranches: new Array(), -+ recentBranches: new Array(), -+ defaultBranch: null, -+ inferredComparisonBranch: { branch: null, aheadBehind: null }, -+ }, - commitAuthor: null, - gitHubUsers: new Map(), - commitLookup: new Map(), -@@ -462,6 +509,18 @@ - }) - } - -+ private updateCompareState( -+ repository: Repository, -+ fn: (state: ICompareState) => Pick -+ ) { -+ this.updateRepositoryState(repository, state => { -+ const compareState = state.compareState -+ const newValues = fn(compareState) -+ -+ return { compareState: merge(compareState, newValues) } -+ }) -+ } -+ - private updateChangesState( - repository: Repository, - fn: (changesState: IChangesState) => Pick -@@ -526,6 +585,7 @@ - ...this.repositories, - ...this.cloningRepositoriesStore.repositories, - ], -+ localRepositoryStateLookup: this.localRepositoryStateLookup, - windowState: this.windowState, - windowZoomFactor: this.windowZoomFactor, - appIsFocused: this.appIsFocused, -@@ -550,6 +610,8 @@ - repositoryFilterText: this.repositoryFilterText, - selectedCloneRepositoryTab: this.selectedCloneRepositoryTab, - selectedBranchesTab: this.selectedBranchesTab, -+ isDivergingBranchBannerVisible: this.isDivergingBranchBannerVisible, -+ selectedTheme: this.selectedTheme, - } - } - -@@ -629,8 +691,12 @@ - return store - } - -- /** This shouldn't be called directly. See `Dispatcher`. */ -- public async _loadHistory(repository: Repository): Promise { -+ /** -+ * TODO: -+ * This is some legacy code that no longer works with the new Compare tab. -+ * Need to investigate porting this to "refresh" the Compare tab state. -+ */ -+ private async _loadHistory(repository: Repository): Promise { - const gitStore = this.getGitStore(repository) - await gitStore.loadHistory() - -@@ -657,10 +723,247 @@ - this.emitUpdate() - } - -+ private startAheadBehindUpdater(repository: Repository) { -+ if (this.currentAheadBehindUpdater != null) { -+ fatalError( -+ `An ahead/behind updater is already active and cannot start updating on ${ -+ repository.name -+ }` -+ ) -+ -+ return -+ } -+ -+ const updater = new AheadBehindUpdater(repository, aheadBehindCache => { -+ this.updateCompareState(repository, state => ({ -+ aheadBehindCache, -+ })) -+ this.emitUpdate() -+ }) -+ -+ this.currentAheadBehindUpdater = updater -+ -+ this.currentAheadBehindUpdater.start() -+ } -+ -+ private stopAheadBehindUpdate() { -+ const updater = this.currentAheadBehindUpdater -+ -+ if (updater != null) { -+ updater.stop() -+ this.currentAheadBehindUpdater = null -+ } -+ } -+ -+ /** This shouldn't be called directly. See `Dispatcher`. */ -+ public async _initializeCompare( -+ repository: Repository, -+ initialAction?: CompareAction -+ ) { -+ log.debug('[AppStore] initializing compare state') -+ -+ const state = this.getRepositoryState(repository) -+ -+ const { branchesState, compareState } = state -+ const { tip, currentPullRequest } = branchesState -+ const currentBranch = tip.kind === TipState.Valid ? tip.branch : null -+ -+ const allBranches = -+ currentBranch != null -+ ? branchesState.allBranches.filter(b => b.name !== currentBranch.name) -+ : branchesState.allBranches -+ const recentBranches = currentBranch -+ ? branchesState.recentBranches.filter(b => b.name !== currentBranch.name) -+ : branchesState.recentBranches -+ -+ const cachedDefaultBranch = branchesState.defaultBranch -+ -+ // only include the default branch when comparing if the user is not on the default branch -+ // and it also exists in the repository -+ const defaultBranch = -+ currentBranch != null && -+ cachedDefaultBranch != null && -+ currentBranch.name !== cachedDefaultBranch.name -+ ? cachedDefaultBranch -+ : null -+ -+ let inferredBranch: Branch | null = null -+ let aheadBehindOfInferredBranch: IAheadBehind | null = null -+ if (tip.kind === TipState.Valid && compareState.aheadBehindCache !== null) { -+ inferredBranch = await inferComparisonBranch( -+ repository, -+ allBranches, -+ currentPullRequest, -+ tip.branch, -+ getRemotes, -+ compareState.aheadBehindCache -+ ) -+ -+ if (inferredBranch !== null) { -+ aheadBehindOfInferredBranch = compareState.aheadBehindCache.get( -+ tip.branch.tip.sha, -+ inferredBranch.tip.sha -+ ) -+ } -+ } -+ -+ this.updateCompareState(repository, state => ({ -+ allBranches, -+ recentBranches, -+ defaultBranch, -+ inferredComparisonBranch: { -+ branch: inferredBranch, -+ aheadBehind: aheadBehindOfInferredBranch, -+ }, -+ })) -+ -+ // we only want to show the banner when the the number -+ // commits behind has changed since the last it was visible -+ if ( -+ inferredBranch !== null && -+ aheadBehindOfInferredBranch !== null && -+ aheadBehindOfInferredBranch.behind > 0 -+ ) { -+ const prevInferredBranchState = -+ state.compareState.inferredComparisonBranch -+ if ( -+ prevInferredBranchState.aheadBehind === null || -+ prevInferredBranchState.aheadBehind.behind !== -+ aheadBehindOfInferredBranch.behind -+ ) { -+ this._setDivergingBranchBannerVisibility(true) -+ } -+ } else if ( -+ inferComparisonBranch !== null || -+ aheadBehindOfInferredBranch === null -+ ) { -+ this._setDivergingBranchBannerVisibility(false) -+ } -+ -+ const cachedState = compareState.formState -+ const action = -+ initialAction != null ? initialAction : getInitialAction(cachedState) -+ this._executeCompare(repository, action) -+ -+ if (currentBranch != null && this.currentAheadBehindUpdater != null) { -+ this.currentAheadBehindUpdater.schedule(currentBranch, allBranches) -+ } -+ } -+ -+ /** This shouldn't be called directly. See `Dispatcher`. */ -+ public async _executeCompare( -+ repository: Repository, -+ action: CompareAction -+ ): Promise { -+ const gitStore = this.getGitStore(repository) -+ const kind = action.kind -+ -+ if (action.kind === CompareActionKind.History) { -+ await gitStore.loadHistory() -+ -+ const repoState = this.getRepositoryState(repository).historyState -+ const commits = repoState.history -+ -+ this.updateCompareState(repository, state => ({ -+ formState: { -+ kind: ComparisonView.None, -+ }, -+ commitSHAs: commits, -+ })) -+ return this.emitUpdate() -+ } else if (action.kind === CompareActionKind.Branch) { -+ const comparisonBranch = action.branch -+ const compare = await gitStore.getCompareCommits( -+ comparisonBranch, -+ action.mode -+ ) -+ -+ this.statsStore.recordBranchComparison() -+ const { branchesState } = this.getRepositoryState(repository) -+ -+ if ( -+ branchesState.defaultBranch !== null && -+ comparisonBranch.name === branchesState.defaultBranch.name -+ ) { -+ this.statsStore.recordDefaultBranchComparison() -+ } -+ -+ if (compare !== null) { -+ const { ahead, behind } = compare -+ const aheadBehind = { ahead, behind } -+ -+ this.updateCompareState(repository, s => ({ -+ formState: { -+ comparisonBranch, -+ kind: action.mode, -+ aheadBehind, -+ }, -+ commitSHAs: compare.commits.map(commit => commit.sha), -+ filterText: comparisonBranch.name, -+ })) -+ -+ const tip = gitStore.tip -+ -+ let currentSha: string | null = null -+ -+ if (tip.kind === TipState.Valid) { -+ currentSha = tip.branch.tip.sha -+ } else if (tip.kind === TipState.Detached) { -+ currentSha = tip.currentSha -+ } -+ -+ if (this.currentAheadBehindUpdater != null && currentSha != null) { -+ const from = -+ action.mode === ComparisonView.Ahead -+ ? comparisonBranch.tip.sha -+ : currentSha -+ const to = -+ action.mode === ComparisonView.Ahead -+ ? currentSha -+ : comparisonBranch.tip.sha -+ -+ this.currentAheadBehindUpdater.insert(from, to, aheadBehind) -+ } -+ -+ return this.emitUpdate() -+ } -+ } else { -+ return assertNever(action, `Unknown action: ${kind}`) -+ } -+ } -+ -+ /** This shouldn't be called directly. See `Dispatcher`. */ -+ public _updateCompareForm( -+ repository: Repository, -+ newState: Pick -+ ) { -+ this.updateCompareState(repository, state => { -+ return merge(state, newState) -+ }) -+ -+ this.emitUpdate() -+ } -+ - /** This shouldn't be called directly. See `Dispatcher`. */ -- public _loadNextHistoryBatch(repository: Repository): Promise { -+ public async _loadNextHistoryBatch(repository: Repository): Promise { - const gitStore = this.getGitStore(repository) -- return gitStore.loadNextHistoryBatch() -+ -+ const state = this.getRepositoryState(repository) -+ const { formState } = state.compareState -+ if (formState.kind === ComparisonView.None) { -+ const commits = state.compareState.commitSHAs -+ const lastCommitSha = commits[commits.length - 1] -+ -+ const newCommits = await gitStore.loadCommitBatch(lastCommitSha) -+ if (newCommits == null) { -+ return -+ } -+ -+ this.updateCompareState(repository, state => ({ -+ commitSHAs: commits.concat(newCommits), -+ })) -+ this.emitUpdate() -+ } - } - - /** This shouldn't be called directly. See `Dispatcher`. */ -@@ -860,10 +1163,12 @@ - // ensures we clean up the existing background fetcher correctly (if set) - this.stopBackgroundFetching() - this.stopPullRequestUpdater() -+ this.stopAheadBehindUpdate() - - this.startBackgroundFetching(repository, !previouslySelectedRepository) - this.startPullRequestUpdater(repository) - -+ this.startAheadBehindUpdater(repository) - this.refreshMentionables(repository) - - this.addUpstreamRemoteIfNeeded(repository) -@@ -1081,9 +1386,12 @@ - ? imageDiffTypeDefault - : parseInt(imageDiffTypeValue) - -+ this.selectedTheme = getPersistedTheme() -+ - this.emitUpdateNow() - - this.accountsStore.refresh() -+ this.refreshAllRepositories() - } - - private async getSelectedExternalEditor(): Promise { -@@ -1231,24 +1539,39 @@ - }) - .sort((x, y) => caseInsensitiveCompare(x.path, y.path)) - -- const workingDirectory = WorkingDirectoryStatus.fromFiles(mergedFiles) -+ // Collect all the currently available file ids into a set to avoid O(N) -+ // lookups using .find on the mergedFiles array. -+ const mergedFileIds = new Set(mergedFiles.map(x => x.id)) - -- let selectedFileID = state.selectedFileID -- const matchedFile = mergedFiles.find(x => x.id === selectedFileID) -+ // The previously selected files might not be available in the working -+ // directory any more due to having been committed or discarded so we'll -+ // do a pass over and filter out any selected files that aren't available. -+ let selectedFileIDs = state.selectedFileIDs.filter(id => -+ mergedFileIds.has(id) -+ ) - -- // Select the first file if we don't have anything selected. -- if ((!selectedFileID || !matchedFile) && mergedFiles.length) { -- selectedFileID = mergedFiles[0].id || null -+ // Select the first file if we don't have anything selected and we -+ // have something to select. -+ if (selectedFileIDs.length === 0 && mergedFiles.length > 0) { -+ selectedFileIDs = [mergedFiles[0].id] - } - -- // The file selection could have changed if the previously selected file -- // is no longer selectable (it was reverted or committed) but if it hasn't -- // changed we can reuse the diff. -- const sameSelectedFileExists = state.selectedFileID -- ? workingDirectory.findFileWithID(state.selectedFileID) -- : null -- const diff = sameSelectedFileExists ? state.diff : null -- return { workingDirectory, selectedFileID, diff } -+ // The file selection could have changed if the previously selected files -+ // are no longer selectable (they were discarded or committed) but if they -+ // were not changed we can reuse the diff. Note, however that we only render -+ // a diff when a single file is selected. If the previous selection was -+ // a single file with the same id as the current selection we can keep the -+ // diff we had, if not we'll clear it. -+ const workingDirectory = WorkingDirectoryStatus.fromFiles(mergedFiles) -+ -+ const diff = -+ selectedFileIDs.length === 1 && -+ state.selectedFileIDs.length === 1 && -+ state.selectedFileIDs[0] === selectedFileIDs[0] -+ ? state.diff -+ : null -+ -+ return { workingDirectory, selectedFileIDs, diff } - }) - this.emitUpdate() - -@@ -1258,14 +1581,14 @@ - /** This shouldn't be called directly. See `Dispatcher`. */ - public async _changeRepositorySection( - repository: Repository, -- selectedSection: RepositorySection -+ selectedSection: RepositorySectionTab - ): Promise { - this.updateRepositoryState(repository, state => ({ selectedSection })) - this.emitUpdate() - -- if (selectedSection === RepositorySection.History) { -+ if (selectedSection === RepositorySectionTab.History) { - return this.refreshHistorySection(repository) -- } else if (selectedSection === RepositorySection.Changes) { -+ } else if (selectedSection === RepositorySectionTab.Changes) { - return this.refreshChangesSection(repository, { - includingStatus: true, - clearPartialState: false, -@@ -1276,10 +1599,10 @@ - /** This shouldn't be called directly. See `Dispatcher`. */ - public async _changeChangesSelection( - repository: Repository, -- selectedFile: WorkingDirectoryFileChange | null -+ selectedFiles: WorkingDirectoryFileChange[] - ): Promise { - this.updateChangesState(repository, state => ({ -- selectedFileID: selectedFile ? selectedFile.id : null, -+ selectedFileIDs: selectedFiles.map(file => file.id), - diff: null, - })) - this.emitUpdate() -@@ -1297,15 +1620,23 @@ - ): Promise { - const stateBeforeLoad = this.getRepositoryState(repository) - const changesStateBeforeLoad = stateBeforeLoad.changesState -- const selectedFileIDBeforeLoad = changesStateBeforeLoad.selectedFileID -- if (!selectedFileIDBeforeLoad) { -+ const selectedFileIDsBeforeLoad = changesStateBeforeLoad.selectedFileIDs -+ -+ // We only render diffs when a single file is selected. -+ if (selectedFileIDsBeforeLoad.length !== 1) { -+ if (changesStateBeforeLoad.diff !== null) { -+ this.updateChangesState(repository, state => ({ diff: null })) -+ this.emitUpdate() -+ } - return - } - -+ const selectedFileIdBeforeLoad = selectedFileIDsBeforeLoad[0] - const selectedFileBeforeLoad = changesStateBeforeLoad.workingDirectory.findFileWithID( -- selectedFileIDBeforeLoad -+ selectedFileIdBeforeLoad - ) -- if (!selectedFileBeforeLoad) { -+ -+ if (selectedFileBeforeLoad === null) { - return - } - -@@ -1316,21 +1647,24 @@ - - const stateAfterLoad = this.getRepositoryState(repository) - const changesState = stateAfterLoad.changesState -- const selectedFileID = changesState.selectedFileID - -- // A different file could have been selected while we were loading the diff -- // in which case we no longer care about the diff we just loaded. -- if (!selectedFileID) { -+ // A different file (or files) could have been selected while we were -+ // loading the diff in which case we no longer care about the diff we -+ // just loaded. -+ if (changesState.selectedFileIDs.length !== 1) { - return - } -- if (selectedFileID !== selectedFileIDBeforeLoad) { -+ -+ const selectedFileID = changesState.selectedFileIDs[0] -+ -+ if (selectedFileID !== selectedFileIdBeforeLoad) { - return - } - - const currentlySelectedFile = changesState.workingDirectory.findFileWithID( - selectedFileID - ) -- if (!currentlySelectedFile) { -+ if (currentlySelectedFile === null) { - return - } - -@@ -1453,8 +1787,8 @@ - ) - - const workingDirectory = WorkingDirectoryStatus.fromFiles(newFiles) -- const diff = state.selectedFileID ? state.diff : null -- return { workingDirectory, diff } -+ -+ return { workingDirectory } - }) - - this.emitUpdate() -@@ -1494,9 +1828,9 @@ - const section = state.selectedSection - let refreshSectionPromise: Promise - -- if (section === RepositorySection.History) { -+ if (section === RepositorySectionTab.History) { - refreshSectionPromise = this.refreshHistorySection(repository) -- } else if (section === RepositorySection.Changes) { -+ } else if (section === RepositorySectionTab.Changes) { - refreshSectionPromise = this.refreshChangesSection(repository, { - includingStatus: false, - clearPartialState: false, -@@ -1515,6 +1849,46 @@ - - this._updateCurrentPullRequest(repository) - this.updateMenuItemLabels(repository) -+ this._initializeCompare(repository) -+ this.refreshRepositoryState([repository]) -+ } -+ -+ public refreshAllRepositories() { -+ return this.refreshRepositoryState(this.repositories) -+ } -+ -+ private async refreshRepositoryState( -+ repositories: ReadonlyArray -+ ): Promise { -+ if (!enableRepoInfoIndicators()) { -+ return -+ } -+ -+ const promises = [] -+ -+ for (const repo of repositories) { -+ promises.push( -+ this.withAuthenticatingUser(repo, async (repo, account) => { -+ const gitStore = this.getGitStore(repo) -+ const lookup = this.localRepositoryStateLookup -+ if (this.shouldBackgroundFetch(repo)) { -+ await gitStore.fetch(account, true) -+ } -+ -+ const status = await gitStore.loadStatus() -+ if (status !== null) { -+ lookup.set(repo.id, { -+ aheadBehind: gitStore.aheadBehind, -+ changedFilesCount: status.workingDirectory.files.length, -+ }) -+ } -+ }) -+ ) -+ } -+ -+ await Promise.all(promises) -+ -+ this.emitUpdate() - } - - /** -@@ -1703,6 +2077,7 @@ - await this._refreshRepository(repository) - } finally { - this.updateCheckoutProgress(repository, null) -+ this._initializeCompare(repository, { kind: CompareActionKind.History }) - } - - return repository -@@ -1919,7 +2294,7 @@ - const refreshWeight = 0.1 - - // Scale pull and fetch weights to be between 0 and 0.9. -- const scale = 1 / (pushWeight + fetchWeight) * (1 - refreshWeight) -+ const scale = (1 / (pushWeight + fetchWeight)) * (1 - refreshWeight) - - pushWeight *= scale - fetchWeight *= scale -@@ -2103,7 +2478,7 @@ - const refreshWeight = 0.1 - - // Scale pull and fetch weights to be between 0 and 0.9. -- const scale = 1 / (pullWeight + fetchWeight) * (1 - refreshWeight) -+ const scale = (1 / (pullWeight + fetchWeight)) * (1 - refreshWeight) - - pullWeight *= scale - fetchWeight *= scale -@@ -2163,18 +2538,24 @@ - const currentBranchName = - tip.kind === TipState.Valid ? tip.branch.name : null - -- // A branch is only eligible for being fast forwarded if: -- // 1. It's local. -- // 2. It's not the current branch. -- // 3. It has an upstream. -- // 4. It's not ahead of its upstream. -- const eligibleBranches = branches.filter(b => { -- return ( -- b.type === BranchType.Local && -- b.name !== currentBranchName && -- b.upstream -+ let eligibleBranches = branches.filter(b => -+ eligibleForFastForward(b, currentBranchName) -+ ) -+ -+ if (eligibleBranches.length >= FastForwardBranchesThreshold) { -+ log.info( -+ `skipping fast-forward for all branches as there are ${ -+ eligibleBranches.length -+ } local branches - this will run again when there are less than ${FastForwardBranchesThreshold} local branches tracking remotes` - ) -- }) -+ -+ const defaultBranch = state.branchesState.defaultBranch -+ eligibleBranches = -+ defaultBranch != null && -+ eligibleForFastForward(defaultBranch, currentBranchName) -+ ? [defaultBranch] -+ : [] -+ } - - for (const branch of eligibleBranches) { - const aheadBehind = await getBranchAheadBehind(repository, branch) -@@ -2183,6 +2564,8 @@ - } - - const { ahead, behind } = aheadBehind -+ // Only perform the fast forward if the branch is behind it's upstream -+ // branch and has no local commits. - if (ahead === 0 && behind > 0) { - // At this point we're guaranteed this is non-null since we've filtered - // out any branches will null upstreams above when creating -@@ -2575,14 +2958,14 @@ - return shell.openExternal(url) - } - -- /** Takes a repository path and opens it using the user's configured editor */ -- public async _openInExternalEditor(path: string): Promise { -+ /** Open a path to a repository or file using the user's configured editor */ -+ public async _openInExternalEditor(fullPath: string): Promise { - const selectedExternalEditor = - this.getState().selectedExternalEditor || null - - try { - const match = await findEditorOrDefault(selectedExternalEditor) -- await launchExternalEditor(path, match) -+ await launchExternalEditor(fullPath, match) - } catch (error) { - this.emitError(error) - } -@@ -2668,6 +3051,18 @@ - this.emitUpdate() - } - -+ public _setDivergingBranchBannerVisibility(visible: boolean) { -+ if (this.isDivergingBranchBannerVisible !== visible) { -+ this.isDivergingBranchBannerVisible = visible -+ -+ if (visible) { -+ this._recordDivergingBranchBannerDisplayed() -+ } -+ -+ this.emitUpdate() -+ } -+ } -+ - public _reportStats() { - return this.statsStore.reportStats(this.accounts, this.repositories) - } -@@ -2676,7 +3071,10 @@ - return this.statsStore.recordLaunchStats(stats) - } - -- public async _ignore(repository: Repository, pattern: string): Promise { -+ public async _ignore( -+ repository: Repository, -+ pattern: string | string[] -+ ): Promise { - const repoSettingsStore = this.getRepositorySettingsStore(repository) - - await repoSettingsStore.ignore(pattern) -@@ -3283,16 +3681,25 @@ - head.gitHubRepository.cloneURL === gitHubRepository.cloneURL - - if (isRefInThisRepo) { -- // We need to fetch FIRST because someone may have created a PR since the last fetch - const defaultRemote = await getDefaultRemote(repository) -- // TODO: I think we could skip this fetch if we know that we have the branch locally -- // already. That way we'd match the behavior of checking out a branch. -- if (defaultRemote) { -- await this._fetchRemote( -- repository, -- defaultRemote, -- FetchType.UserInitiatedTask -- ) -+ // if we don't have a default remote here, it's probably going -+ // to just crash and burn on checkout, but that's okay -+ if (defaultRemote != null) { -+ // the remote ref will be something like `origin/my-cool-branch` -+ const remoteRef = `${defaultRemote.name}/${head.ref}` -+ const gitStore = this.getGitStore(repository) -+ -+ const remoteRefExists = -+ gitStore.allBranches.find(branch => branch.name === remoteRef) != null -+ -+ // only try a fetch here if we can't find the ref -+ if (!remoteRefExists) { -+ await this._fetchRemote( -+ repository, -+ defaultRemote, -+ FetchType.UserInitiatedTask -+ ) -+ } - } - await this._checkoutBranch(repository, head.ref) - } else if (head.gitHubRepository != null) { -@@ -3316,7 +3723,7 @@ - ) - - log.error(error.message) -- this.emitError(error) -+ return this.emitError(error) - } - - await this._fetchRemote(repository, remote, FetchType.UserInitiatedTask) -@@ -3338,6 +3745,8 @@ - - await this._checkoutBranch(repository, localBranchName) - } -+ -+ this.statsStore.recordPRBranchCheckout() - } - - /** -@@ -3365,8 +3774,104 @@ - this.getGitStore(repository).setCoAuthors(coAuthors) - return Promise.resolve() - } -+ -+ /** -+ * Increments the `mergeIntoCurrentBranchMenuCount` metric -+ */ -+ public _recordMenuInitiatedMerge() { -+ this.statsStore.recordMenuInitiatedMerge() -+ } -+ -+ /** -+ * Increments the `updateFromDefaultBranchMenuCount` metric -+ */ -+ public _recordMenuInitiatedUpdate() { -+ this.statsStore.recordMenuInitiatedUpdate() -+ } -+ -+ /** -+ * Increments the `mergesInitiatedFromComparison` metric -+ */ -+ public _recordCompareInitiatedMerge() { -+ this.statsStore.recordCompareInitiatedMerge() -+ } -+ -+ /** -+ * Set the application-wide theme -+ */ -+ public _setSelectedTheme(theme: ApplicationTheme) { -+ setPersistedTheme(theme) -+ this.selectedTheme = theme -+ this.emitUpdate() -+ -+ return Promise.resolve() -+ } -+ -+ /** -+ * Increments either the `repoWithIndicatorClicked` or -+ * the `repoWithoutIndicatorClicked` metric -+ */ -+ public _recordRepoClicked(repoHasIndicator: boolean) { -+ this.statsStore.recordRepoClicked(repoHasIndicator) -+ } -+ -+ /** The number of times the user dismisses the diverged branch notification -+ * Increments the `divergingBranchBannerDismissal` metric -+ */ -+ public _recordDivergingBranchBannerDismissal() { -+ this.statsStore.recordDivergingBranchBannerDismissal() -+ } -+ -+ /** -+ * Increments the `divergingBranchBannerDisplayed` metric -+ */ -+ public _recordDivergingBranchBannerDisplayed() { -+ this.statsStore.recordDivergingBranchBannerDisplayed() -+ } -+ -+ /** -+ * Increments the `divergingBranchBannerInitiatedCompare` metric -+ */ -+ public _recordDivergingBranchBannerInitiatedCompare() { -+ this.statsStore.recordDivergingBranchBannerInitiatedCompare() -+ } -+ -+ /** -+ * Increments the `divergingBranchBannerInfluencedMerge` metric -+ */ -+ public _recordDivergingBranchBannerInfluencedMerge() { -+ this.statsStore.recordDivergingBranchBannerInfluencedMerge() -+ } -+ -+ /** -+ * Increments the `divergingBranchBannerInitatedMerge` metric -+ */ -+ public _recordDivergingBranchBannerInitatedMerge() { -+ this.statsStore.recordDivergingBranchBannerInitatedMerge() -+ } - } - - function forkPullRequestRemoteName(remoteName: string) { - return `${ForkedRemotePrefix}${remoteName}` - } -+ -+/** -+ * Map the cached state of the compare view to an action -+ * to perform which is then used to compute the compare -+ * view contents. -+ */ -+function getInitialAction( -+ cachedState: IDisplayHistory | ICompareBranch -+): CompareAction { -+ if (cachedState.kind === ComparisonView.None) { -+ return { -+ kind: CompareActionKind.History, -+ } -+ } -+ -+ return { -+ kind: CompareActionKind.Branch, -+ branch: cachedState.comparisonBranch, -+ mode: cachedState.kind, -+ } -+} -merged - result 100644 f448ce132d5fa114bc19fbf191a3c0026b4e202a app/src/lib/stores/git-store.ts - our 100644 d3b2a0b254bf08c1768c0f56d4b7602873766d56 app/src/lib/stores/git-store.ts -@@ -3,11 +3,16 @@ - import { Disposable } from 'event-kit' - import { Repository } from '../../models/repository' - import { WorkingDirectoryFileChange, AppFileStatus } from '../../models/status' --import { Branch, BranchType } from '../../models/branch' -+import { -+ Branch, -+ BranchType, -+ IAheadBehind, -+ ICompareResult, -+} from '../../models/branch' - import { Tip, TipState } from '../../models/tip' - import { Commit } from '../../models/commit' - import { IRemote } from '../../models/remote' --import { IFetchProgress, IRevertProgress } from '../app-state' -+import { IFetchProgress, IRevertProgress, ComparisonView } from '../app-state' - - import { IAppShell } from '../app-shell' - import { ErrorWithMetadata, IErrorMetadata } from '../error-with-metadata' -@@ -24,7 +29,6 @@ - getRecentBranches, - getBranches, - deleteRef, -- IAheadBehind, - getCommits, - merge, - setRemoteURL, -@@ -47,6 +51,10 @@ - getTrailerSeparatorCharacters, - parseSingleUnfoldedTrailer, - isCoAuthoredByTrailer, -+ getAheadBehind, -+ revRange, -+ revSymmetricDifference, -+ getSymbolicRef, - } from '../git' - import { IGitAccount } from '../git/authentication' - import { RetryAction, RetryActionType } from '../retry-actions' -@@ -150,8 +158,10 @@ - - this.requestsInFight.add(LoadingHistoryRequestKey) - -+ const range = revRange('HEAD', mergeBase) -+ - const commits = await this.performFailableOperation(() => -- getCommits(this.repository, `HEAD..${mergeBase}`, CommitBatchSize) -+ getCommits(this.repository, range, CommitBatchSize) - ) - if (commits == null) { - return -@@ -173,11 +183,8 @@ - this._history = [...commits.map(c => c.sha), ...remainingHistory] - } - -- this.storeCommits(commits) -- -+ this.storeCommits(commits, true) - this.requestsInFight.delete(LoadingHistoryRequestKey) -- -- this.emitNewCommitsLoaded(commits) - this.emitUpdate() - } - -@@ -214,11 +221,8 @@ - } - - this._history = [...commits.map(c => c.sha), ...existingHistory] -- this.storeCommits(commits) -- -+ this.storeCommits(commits, true) - this.requestsInFight.delete(LoadingHistoryRequestKey) -- -- this.emitNewCommitsLoaded(commits) - this.emitUpdate() - } - -@@ -248,12 +252,35 @@ - } - - this._history = this._history.concat(commits.map(c => c.sha)) -- this.storeCommits(commits) -+ this.storeCommits(commits, true) -+ this.requestsInFight.delete(requestKey) -+ this.emitUpdate() -+ } -+ -+ /** Load a batch of commits from the repository, using the last known commit in the list. */ -+ public async loadCommitBatch(lastSHA: string) { -+ if (this.requestsInFight.has(LoadingHistoryRequestKey)) { -+ return null -+ } -+ -+ const requestKey = `history/compare/${lastSHA}` -+ if (this.requestsInFight.has(requestKey)) { -+ return null -+ } -+ -+ this.requestsInFight.add(requestKey) -+ -+ const commits = await this.performFailableOperation(() => -+ getCommits(this.repository, `${lastSHA}^`, CommitBatchSize) -+ ) - - this.requestsInFight.delete(requestKey) -+ if (!commits) { -+ return null -+ } - -- this.emitNewCommitsLoaded(commits) -- this.emitUpdate() -+ this.storeCommits(commits, false) -+ return commits.map(c => c.sha) - } - - /** The list of ordered SHAs. */ -@@ -332,24 +359,51 @@ - return allBranchesWithUpstream - } - -- private refreshDefaultBranch() { -- let defaultBranchName: string | null = 'master' -- const gitHubRepository = this.repository.gitHubRepository -- if (gitHubRepository && gitHubRepository.defaultBranch) { -- defaultBranchName = gitHubRepository.defaultBranch -+ private async refreshDefaultBranch() { -+ const defaultBranchName = await this.resolveDefaultBranch() -+ -+ // Find the default branch among all of our branches, giving -+ // priority to local branches by sorting them before remotes -+ this._defaultBranch = -+ this._allBranches -+ .filter(b => b.name === defaultBranchName) -+ .sort((x, y) => compare(x.type, y.type)) -+ .shift() || null -+ } -+ -+ /** -+ * Resolve the default branch name for the current repository, -+ * using the available API data, remote information or branch -+ * name conventionns. -+ */ -+ private async resolveDefaultBranch(): Promise { -+ const { gitHubRepository } = this.repository -+ if (gitHubRepository && gitHubRepository.defaultBranch != null) { -+ return gitHubRepository.defaultBranch - } - -- if (defaultBranchName) { -- // Find the default branch among all of our branches, giving -- // priority to local branches by sorting them before remotes -- this._defaultBranch = -- this._allBranches -- .filter(b => b.name === defaultBranchName) -- .sort((x, y) => compare(x.type, y.type)) -- .shift() || null -- } else { -- this._defaultBranch = null -+ if (this.remote != null) { -+ // the Git server should use [remote]/HEAD to advertise -+ // it's default branch, so see if it exists and matches -+ // a valid branch on the remote and attempt to use that -+ const remoteNamespace = `refs/remotes/${this.remote.name}/` -+ const match = await getSymbolicRef( -+ this.repository, -+ `${remoteNamespace}HEAD` -+ ) -+ if ( -+ match != null && -+ match.length > remoteNamespace.length && -+ match.startsWith(remoteNamespace) -+ ) { -+ // strip out everything related to the remote because this -+ // is likely to be a tracked branch locally -+ // e.g. `master`, `develop`, etc -+ return match.substr(remoteNamespace.length) -+ } - } -+ -+ return 'master' - } - - private refreshRecentBranches( -@@ -416,9 +470,9 @@ - - let localCommits: ReadonlyArray | undefined - if (branch.upstream) { -- const revRange = `${branch.upstream}..${branch.name}` -+ const range = revRange(branch.upstream, branch.name) - localCommits = await this.performFailableOperation(() => -- getCommits(this.repository, revRange, CommitBatchSize) -+ getCommits(this.repository, range, CommitBatchSize) - ) - } else { - localCommits = await this.performFailableOperation(() => -@@ -447,10 +501,17 @@ - } - - /** Store the given commits. */ -- private storeCommits(commits: ReadonlyArray) { -+ private storeCommits( -+ commits: ReadonlyArray, -+ emitUpdate: boolean = false -+ ) { - for (const commit of commits) { - this.commitLookup.set(commit.sha, commit) - } -+ -+ if (emitUpdate) { -+ this.emitNewCommitsLoaded(commits) -+ } - } - - private async undoFirstCommit( -@@ -1238,4 +1299,50 @@ - setRemoteURL(this.repository, UpstreamRemoteName, url) - ) - } -+ -+ /** -+ * Returns the commits associated with `branch` and ahead/behind info; -+ */ -+ public async getCompareCommits( -+ branch: Branch, -+ compareType: ComparisonView.Ahead | ComparisonView.Behind -+ ): Promise { -+ if (this.tip.kind !== TipState.Valid) { -+ return null -+ } -+ -+ const base = this.tip.branch -+ const aheadBehind = await getAheadBehind( -+ this.repository, -+ revSymmetricDifference(base.name, branch.name) -+ ) -+ -+ if (aheadBehind == null) { -+ return null -+ } -+ -+ const revisionRange = -+ compareType === ComparisonView.Ahead -+ ? revRange(branch.name, base.name) -+ : revRange(base.name, branch.name) -+ const commitsToLoad = -+ compareType === ComparisonView.Ahead -+ ? aheadBehind.ahead -+ : aheadBehind.behind -+ const commits = await getCommits( -+ this.repository, -+ revisionRange, -+ commitsToLoad -+ ) -+ -+ if (commits.length > 0) { -+ this.storeCommits(commits, true) -+ } -+ -+ return { -+ commits, -+ ahead: aheadBehind.ahead, -+ behind: aheadBehind.behind, -+ } -+ } - } -added in remote - their 100644 2f4ef7dade5922f6825e9c4d3b0dd19216a44bb3 app/src/lib/stores/helpers/ahead-behind-updater.ts -@@ -0,0 +1,125 @@ -+const queue: (config: QueueConfig) => Queue = require('queue') -+import { revSymmetricDifference } from '../../../lib/git' -+ -+// eslint-disable-next-line typescript/interface-name-prefix -+interface QueueConfig { -+ // Max number of jobs the queue should process concurrently, defaults to Infinity. -+ readonly concurrency: number -+ // Ensures the queue is always running if jobs are available. -+ // Useful in situations where you are using a queue only for concurrency control. -+ readonly autostart: boolean -+} -+ -+// eslint-disable-next-line typescript/interface-name-prefix -+interface Queue extends NodeJS.EventEmitter { -+ readonly length: number -+ -+ start(): void -+ end(): void -+ push( -+ func: (callback: (error: Error | null, result: T) => void) => void -+ ): void -+} -+ -+import { Repository } from '../../../models/repository' -+import { getAheadBehind } from '../../../lib/git' -+import { Branch, IAheadBehind } from '../../../models/branch' -+import { ComparisonCache } from '../../comparison-cache' -+ -+export class AheadBehindUpdater { -+ private comparisonCache = new ComparisonCache() -+ -+ private aheadBehindQueue = queue({ -+ concurrency: 1, -+ autostart: true, -+ }) -+ -+ public constructor( -+ private repository: Repository, -+ private onCacheUpdate: (cache: ComparisonCache) => void -+ ) {} -+ -+ public start() { -+ this.aheadBehindQueue.on('success', (result: IAheadBehind | null) => { -+ if (result != null) { -+ this.onCacheUpdate(this.comparisonCache) -+ } -+ }) -+ -+ this.aheadBehindQueue.on('error', (err: Error) => { -+ log.debug( -+ '[AheadBehindUpdater] an error with the queue was reported', -+ err -+ ) -+ }) -+ -+ this.aheadBehindQueue.on('end', (err?: Error) => { -+ if (err != null) { -+ log.debug(`[AheadBehindUpdater] ended with an error`, err) -+ } -+ }) -+ -+ this.aheadBehindQueue.start() -+ } -+ -+ public stop() { -+ this.aheadBehindQueue.end() -+ } -+ -+ private executeTask = ( -+ from: string, -+ to: string, -+ callback: (error: Error | null, result: IAheadBehind | null) => void -+ ) => { -+ if (this.comparisonCache.has(from, to)) { -+ return -+ } -+ -+ const range = revSymmetricDifference(from, to) -+ getAheadBehind(this.repository, range).then(result => { -+ if (result != null) { -+ this.comparisonCache.set(from, to, result) -+ } else { -+ log.debug( -+ `[AheadBehindUpdater] unable to cache '${range}' as no result returned` -+ ) -+ } -+ callback(null, result) -+ }) -+ } -+ -+ public insert(from: string, to: string, value: IAheadBehind) { -+ if (this.comparisonCache.has(from, to)) { -+ return -+ } -+ -+ this.comparisonCache.set(from, to, value) -+ } -+ -+ public schedule(currentBranch: Branch, branches: ReadonlyArray) { -+ // remove any queued work to prioritize this new set of tasks -+ this.aheadBehindQueue.end() -+ -+ const from = currentBranch.tip.sha -+ -+ const branchesNotInCache = branches -+ .map(b => b.tip.sha) -+ .filter(to => !this.comparisonCache.has(from, to)) -+ -+ const newRefsToCompare = new Set(branchesNotInCache) -+ -+ log.debug( -+ `[AheadBehindUpdater] - found ${ -+ newRefsToCompare.size -+ } comparisons to perform` -+ ) -+ -+ for (const sha of newRefsToCompare) { -+ this.aheadBehindQueue.push(callback => -+ requestIdleCallback(() => { -+ this.executeTask(from, sha, callback) -+ }) -+ ) -+ } -+ } -+} -added in remote - their 100644 6209dbef0a2ebc954b665597db7311541fdd197c app/src/lib/stores/helpers/infer-comparison-branch.ts -@@ -0,0 +1,149 @@ -+import { Branch } from '../../../models/branch' -+import { PullRequest } from '../../../models/pull-request' -+import { GitHubRepository } from '../../../models/github-repository' -+import { IRemote } from '../../../models/remote' -+import { Repository } from '../../../models/repository' -+import { ComparisonCache } from '../../comparison-cache' -+ -+type RemotesGetter = (repository: Repository) => Promise> -+ -+/** -+ * Infers which branch to use as the comparison branch -+ * -+ * The branch returned is determined by the following conditions: -+ * 1. Given a pull request -> target branch of PR -+ * 2. Given a forked repository -> default branch on `upstream` -+ * 3. Given a hosted repository -> default branch on `origin` -+ * 4. Fallback -> `master` branch -+ * -+ * @param repository The repository the branch belongs to -+ * @param branches The list of all branches for the repository -+ * @param currentPullRequest The pull request to use for finding the branch -+ * @param currentBranch The branch we want the parent of -+ * @param getRemotes callback used to get all remotes for the current repository -+ * @param comparisonCache cache used to get the number of commits ahead/behind the current branch is from another branch -+ */ -+export async function inferComparisonBranch( -+ repository: Repository, -+ branches: ReadonlyArray, -+ currentPullRequest: PullRequest | null, -+ currentBranch: Branch | null, -+ getRemotes: RemotesGetter, -+ comparisonCache: ComparisonCache -+): Promise { -+ if (currentPullRequest !== null) { -+ return getTargetBranchOfPullRequest(branches, currentPullRequest) -+ } -+ -+ const ghRepo = repository.gitHubRepository -+ if (ghRepo !== null) { -+ return ghRepo.fork === true && currentBranch !== null -+ ? getDefaultBranchOfFork( -+ repository, -+ branches, -+ currentBranch, -+ getRemotes, -+ comparisonCache -+ ) -+ : getDefaultBranchOfGitHubRepo(branches, ghRepo) -+ } -+ -+ return getMasterBranch(branches) -+} -+ -+function getMasterBranch(branches: ReadonlyArray): Branch | null { -+ return findBranch(branches, 'master') -+} -+ -+function getDefaultBranchOfGitHubRepo( -+ branches: ReadonlyArray, -+ ghRepository: GitHubRepository -+): Branch | null { -+ if (ghRepository.defaultBranch === null) { -+ return null -+ } -+ -+ return findBranch(branches, ghRepository.defaultBranch) -+} -+ -+function getTargetBranchOfPullRequest( -+ branches: ReadonlyArray, -+ pr: PullRequest -+): Branch | null { -+ return findBranch(branches, pr.base.ref) -+} -+ -+/** -+ * For `inferComparisonBranch` case where inferring for a forked repository -+ * -+ * Returns the default branch of the fork if it's ahead of `currentBranch`. -+ * Otherwise, the default branch of the parent is returned. -+ */ -+async function getDefaultBranchOfFork( -+ repository: Repository, -+ branches: ReadonlyArray, -+ currentBranch: Branch, -+ getRemotes: RemotesGetter, -+ comparisonCache: ComparisonCache -+): Promise { -+ // this is guaranteed to exist since this function -+ // is only called if the ghRepo is not null -+ const ghRepo = repository.gitHubRepository! -+ const defaultBranch = getDefaultBranchOfGitHubRepo(branches, ghRepo) -+ if (defaultBranch === null) { -+ return getMasterBranch(branches) -+ } -+ -+ const aheadBehind = comparisonCache.get( -+ currentBranch.tip.sha, -+ defaultBranch.tip.sha -+ ) -+ -+ // we want to return the default branch of the fork if it's ahead -+ // of the current branch; see https://github.com/desktop/desktop/issues/4766#issue-325764371 -+ if (aheadBehind !== null && aheadBehind.ahead > 0) { -+ return defaultBranch -+ } -+ -+ const potentialDefault = await getDefaultBranchOfForkedGitHubRepo( -+ repository, -+ branches, -+ getRemotes -+ ) -+ -+ return potentialDefault -+} -+ -+async function getDefaultBranchOfForkedGitHubRepo( -+ repository: Repository, -+ branches: ReadonlyArray, -+ getRemotes: RemotesGetter -+): Promise { -+ const parentRepo = -+ repository.gitHubRepository !== null -+ ? repository.gitHubRepository.parent -+ : null -+ -+ if (parentRepo === null) { -+ return null -+ } -+ -+ const remotes = await getRemotes(repository) -+ const remote = remotes.find(r => r.url === parentRepo.cloneURL) -+ -+ if (remote === undefined) { -+ log.warn(`Could not find remote with URL ${parentRepo.cloneURL}.`) -+ return null -+ } -+ -+ const branchToFind = `${remote.name}/${parentRepo.defaultBranch}` -+ -+ return findBranch(branches, branchToFind) -+} -+ -+function findBranch( -+ branches: ReadonlyArray, -+ name: string -+): Branch | null { -+ return branches.find(b => b.name === name) || null -+} -merged - result 100644 d9edf0247ea7c33ae2b508f876aa977d8a81d6d4 app/src/lib/stores/pull-request-store.ts - our 100644 1feeeb2600084a5b31ad70f91d96038d1c405539 app/src/lib/stores/pull-request-store.ts -@@ -67,7 +67,6 @@ - this.emitUpdate(githubRepo) - } catch (error) { - log.warn(`Error refreshing pull requests for '${repository.name}'`, error) -- this.emitError(error) - } finally { - this.updateActiveFetchCount(githubRepo, Decrement) - } -@@ -104,7 +103,11 @@ - ): Promise { - const prs = await this.fetchPullRequestsFromCache(repository) - -- await this.fetchAndCachePullRequestStatus(prs, repository, account) -+ try { -+ await this.fetchAndCachePullRequestStatus(prs, repository, account) -+ } catch (e) { -+ log.warn('Error updating pull request statuses', e) -+ } - } - - /** Gets the pull requests against the given repository. */ -@@ -293,6 +296,7 @@ - return { - id: x.id, - state: x.state, -+ description: x.description, - } - }) - -merged - result 100644 9eb2eaebe8b63f5219a301f0c68eb2d0a96d2fea app/src/lib/stores/repository-settings-store.ts - our 100644 ce2118f6066face1e430be4ad265a220a669fcf8 app/src/lib/stores/repository-settings-store.ts -@@ -75,12 +75,15 @@ - } - - /** Ignore the given path or pattern. */ -- public async ignore(pattern: string): Promise { -+ public async ignore(patterns: string | string[]): Promise { - const text = (await this.readGitIgnore()) || '' - const repository = this._repository - const currentContents = await formatGitIgnoreContents(text, repository) -+ -+ const newPatternText = -+ patterns instanceof Array ? patterns.join('\n') : patterns - const newText = await formatGitIgnoreContents( -- `${currentContents}${pattern}`, -+ `${currentContents}${newPatternText}`, - repository - ) - -merged - result 100644 f05a774461b4caac6f3ad908b6090078f0de8419 app/src/lib/tailer.ts - our 100644 08d5dbe9e54073674bb101a4c8c7c331eb5d1105 app/src/lib/tailer.ts -@@ -1,4 +1,4 @@ --import * as Fs from 'fs-extra' -+import * as Fs from 'fs' - import { Emitter, Disposable } from 'event-kit' - - interface ICurrentFileTailState { -merged - result 100644 d2fd1a247c9132a86ae1a23a948c51adff797eca app/src/main-process/log.ts - our 100644 74719f439d29c061cd698d7b7dc9b46127a6b326 app/src/main-process/log.ts -@@ -3,7 +3,7 @@ - - import { getLogDirectoryPath } from '../lib/logging/get-log-path' - import { LogLevel } from '../lib/logging/log-level' --import { mkdirIfNeeded } from '../lib/file-system' -+import { ensureDir } from 'fs-extra' - - require('winston-daily-rotate-file') - -@@ -73,7 +73,7 @@ - loggerPromise = new Promise((resolve, reject) => { - const logDirectory = getLogDirectoryPath() - -- mkdirIfNeeded(logDirectory) -+ ensureDir(logDirectory) - .then(() => { - try { - const logger = initializeWinston(getLogFilePath(logDirectory)) -merged - result 100644 946271baeebe98fdf6b79d970b68d6255fc40289 app/src/main-process/main.ts - our 100644 c5def55874da156c018edb81e03c9fc2e1ddbe90 app/src/main-process/main.ts -@@ -170,6 +170,13 @@ - } - } - -+if (process.env.GITHUB_DESKTOP_DISABLE_HARDWARE_ACCELERATION) { -+ log.info( -+ `GITHUB_DESKTOP_DISABLE_HARDWARE_ACCELERATION environment variable set, disabling hardware acceleration` -+ ) -+ app.disableHardwareAcceleration() -+} -+ - app.on('ready', () => { - if (isDuplicateInstance || handlingSquirrelEvent) { - return -@@ -400,14 +407,24 @@ - const window = new AppWindow() - - if (__DEV__) { -- const installer = require('electron-devtools-installer') -+ const { -+ default: installExtension, -+ REACT_DEVELOPER_TOOLS, -+ REACT_PERF, -+ } = require('electron-devtools-installer') -+ - require('electron-debug')({ showDevTools: true }) - -- const extensions = ['REACT_DEVELOPER_TOOLS', 'REACT_PERF'] -+ const ChromeLens = { -+ id: 'idikgljglpfilbhaboonnpnnincjhjkd', -+ electron: '>=1.2.1', -+ } -+ -+ const extensions = [REACT_DEVELOPER_TOOLS, REACT_PERF, ChromeLens] - -- for (const name of extensions) { -+ for (const extension of extensions) { - try { -- installer.default(installer[name]) -+ installExtension(extension) - } catch (e) {} - } - } -merged - result 100644 7ec8c001136d655a2ecce3d56b9a6804762172fa app/src/main-process/menu/build-default-menu.ts - our 100644 e23a8e9a3b6cd377b7be7cc89ec15dae2d4c6da2 app/src/main-process/menu/build-default-menu.ts -@@ -2,7 +2,7 @@ - import { ensureItemIds } from './ensure-item-ids' - import { MenuEvent } from './menu-event' - import { getLogDirectoryPath } from '../../lib/logging/get-log-path' --import { mkdirIfNeeded } from '../../lib/file-system' -+import { ensureDir } from 'fs-extra' - - import { log } from '../log' - import { openDirectorySafe } from '../shell' -@@ -114,7 +114,11 @@ - { role: 'cut', label: __DARWIN__ ? 'Cut' : 'Cu&t' }, - { role: 'copy', label: __DARWIN__ ? 'Copy' : '&Copy' }, - { role: 'paste', label: __DARWIN__ ? 'Paste' : '&Paste' }, -- { role: 'selectall', label: __DARWIN__ ? 'Select All' : 'Select &all' }, -+ { -+ label: __DARWIN__ ? 'Select All' : 'Select &all', -+ accelerator: 'CmdOrCtrl+A', -+ click: emit('select-all'), -+ }, - ], - }) - -@@ -125,13 +129,13 @@ - label: __DARWIN__ ? 'Show Changes' : '&Changes', - id: 'show-changes', - accelerator: 'CmdOrCtrl+1', -- click: emit('select-changes'), -+ click: emit('show-changes'), - }, - { - label: __DARWIN__ ? 'Show History' : '&History', - id: 'show-history', - accelerator: 'CmdOrCtrl+2', -- click: emit('select-history'), -+ click: emit('show-history'), - }, - { - label: __DARWIN__ ? 'Show Repository List' : 'Repository &list', -@@ -285,6 +289,12 @@ - click: emit('update-branch'), - }, - { -+ label: __DARWIN__ ? 'Compare to Branch' : '&Compare to branch', -+ id: 'compare-to-branch', -+ accelerator: 'CmdOrCtrl+Shift+B', -+ click: emit('compare-to-branch'), -+ }, -+ { - label: __DARWIN__ - ? 'Merge Into Current Branch…' - : '&Merge into current branch…', -@@ -294,10 +304,10 @@ - }, - separator, - { -- label: __DARWIN__ ? 'Compare on GitHub' : '&Compare on GitHub', -- id: 'compare-branch', -+ label: __DARWIN__ ? 'Compare on GitHub' : 'Compare on &GitHub', -+ id: 'compare-on-github', - accelerator: 'CmdOrCtrl+Shift+C', -- click: emit('compare-branch'), -+ click: emit('compare-on-github'), - }, - { - label: pullRequestLabel, -@@ -324,7 +334,7 @@ - const submitIssueItem: Electron.MenuItemConstructorOptions = { - label: __DARWIN__ ? 'Report Issue…' : 'Report issue…', - click() { -- shell.openExternal('https://github.com/desktop/desktop/issues/new') -+ shell.openExternal('https://github.com/desktop/desktop/issues/new/choose') - }, - } - -@@ -346,13 +356,15 @@ - - const showLogsLabel = __DARWIN__ - ? 'Show Logs in Finder' -- : __WIN32__ ? 'S&how logs in Explorer' : 'S&how logs in your File Manager' -+ : __WIN32__ -+ ? 'S&how logs in Explorer' -+ : 'S&how logs in your File Manager' - - const showLogsItem: Electron.MenuItemConstructorOptions = { - label: showLogsLabel, - click() { - const logPath = getLogDirectoryPath() -- mkdirIfNeeded(logPath) -+ ensureDir(logPath) - .then(() => { - openDirectorySafe(logPath) - }) -merged - result 100644 a0568e66362057b90a91743f0aa68d083d286744 app/src/main-process/menu/menu-event.ts - our 100644 530863955062bb7a426d8f4cb55b7ba2890f4294 app/src/main-process/menu/menu-event.ts -@@ -1,8 +1,8 @@ - export type MenuEvent = - | 'push' - | 'pull' -- | 'select-changes' -- | 'select-history' -+ | 'show-changes' -+ | 'show-history' - | 'add-local-repository' - | 'create-branch' - | 'show-branches' -@@ -14,10 +14,11 @@ - | 'choose-repository' - | 'open-working-directory' - | 'update-branch' -+ | 'compare-to-branch' - | 'merge-branch' - | 'show-repository-settings' - | 'open-in-shell' -- | 'compare-branch' -+ | 'compare-on-github' - | 'view-repository-on-github' - | 'clone-repository' - | 'show-about' -@@ -25,3 +26,4 @@ - | 'open-pull-request' - | 'install-cli' - | 'open-external-editor' -+ | 'select-all' -merged - result 100644 3435bb2d1a982289132aabf4d0bbfea55730c644 app/src/main-process/menu/menu-ids.ts - our 100644 016034d30cd14a867effcf1b5142c320e786aab6 app/src/main-process/menu/menu-ids.ts -@@ -5,7 +5,7 @@ - | 'update-branch' - | 'merge-branch' - | 'view-repository-on-github' -- | 'compare-branch' -+ | 'compare-on-github' - | 'open-in-shell' - | 'push' - | 'pull' -@@ -25,3 +25,4 @@ - | 'clone-repository' - | 'about' - | 'create-pull-request' -+ | 'compare-to-branch' -merged - result 100644 5f8bcfd5aa2b2f30f81fe1cd9a2973bcc9b9f14f app/src/main-process/squirrel-updater.ts - our 100644 d91124b5c21b55938e5e07f48cbf194bf6ba5df6 app/src/main-process/squirrel-updater.ts -@@ -1,7 +1,8 @@ --import * as ChildProcess from 'child_process' - import * as Path from 'path' - import * as Os from 'os' --import { pathExists, mkdirIfNeeded, writeFile } from '../lib/file-system' -+ -+import { pathExists, ensureDir, writeFile } from 'fs-extra' -+import { spawn, getPathSegments, setPathSegments } from '../lib/process/win32' - - const appFolder = Path.resolve(process.execPath, '..') - const rootAppDir = Path.resolve(appFolder, '..') -@@ -46,7 +47,7 @@ - - async function installCLI(): Promise { - const binPath = getBinPath() -- await mkdirIfNeeded(binPath) -+ await ensureDir(binPath) - await writeBatchScriptCLITrampoline(binPath) - await writeShellScriptCLITrampoline(binPath) - const paths = await getPathSegments() -@@ -79,7 +80,7 @@ - * rewrite the trampoline to point to the new, version-specific path. Bingo - * bango Bob's your uncle. - */ --async function writeBatchScriptCLITrampoline(binPath: string): Promise { -+function writeBatchScriptCLITrampoline(binPath: string): Promise { - const versionedPath = resolveVersionedPath( - binPath, - 'resources/app/static/github.bat' -@@ -91,7 +92,7 @@ - return writeFile(trampolinePath, trampoline) - } - --async function writeShellScriptCLITrampoline(binPath: string): Promise { -+function writeShellScriptCLITrampoline(binPath: string): Promise { - const versionedPath = resolveVersionedPath( - binPath, - 'resources/app/static/github.sh' -@@ -153,86 +154,3 @@ - return createShortcut(['StartMenu', 'Desktop']) - } - } -- --/** Get the path segments in the user's `Path`. */ --async function getPathSegments(): Promise> { -- let powershellPath: string -- const systemRoot = process.env['SystemRoot'] -- if (systemRoot) { -- const system32Path = Path.join(process.env.SystemRoot, 'System32') -- powershellPath = Path.join( -- system32Path, -- 'WindowsPowerShell', -- 'v1.0', -- 'powershell.exe' -- ) -- } else { -- powershellPath = 'powershell.exe' -- } -- -- const args = [ -- '-noprofile', -- '-ExecutionPolicy', -- 'RemoteSigned', -- '-command', -- // Set encoding and execute the command, capture the output, and return it -- // via .NET's console in order to have consistent UTF-8 encoding. -- // See http://stackoverflow.com/questions/22349139/utf-8-output-from-powershell -- // to address https://github.com/atom/atom/issues/5063 -- ` -- [Console]::OutputEncoding=[System.Text.Encoding]::UTF8 -- $output=[environment]::GetEnvironmentVariable('Path', 'User') -- [Console]::WriteLine($output) -- `, -- ] -- -- const stdout = await spawn(powershellPath, args) -- const pathOutput = stdout.replace(/^\s+|\s+$/g, '') -- return pathOutput.split(/;+/).filter(segment => segment.length) --} -- --/** Set the user's `Path`. */ --async function setPathSegments(paths: ReadonlyArray): Promise { -- let setxPath: string -- const systemRoot = process.env['SystemRoot'] -- if (systemRoot) { -- const system32Path = Path.join(systemRoot, 'System32') -- setxPath = Path.join(system32Path, 'setx.exe') -- } else { -- setxPath = 'setx.exe' -- } -- -- await spawn(setxPath, ['Path', paths.join(';')]) --} -- --/** Spawn a command with arguments and capture its output. */ --function spawn(command: string, args: ReadonlyArray): Promise { -- try { -- const child = ChildProcess.spawn(command, args as string[]) -- return new Promise((resolve, reject) => { -- let stdout = '' -- child.stdout.on('data', data => { -- stdout += data -- }) -- -- child.on('close', code => { -- if (code === 0) { -- resolve(stdout) -- } else { -- reject(new Error(`Command "${command} ${args}" failed: "${stdout}"`)) -- } -- }) -- -- child.on('error', (err: Error) => { -- reject(err) -- }) -- -- // This is necessary if using Powershell 2 on Windows 7 to get the events -- // to raise. -- // See http://stackoverflow.com/questions/9155289/calling-powershell-from-nodejs -- child.stdin.end() -- }) -- } catch (error) { -- return Promise.reject(error) -- } --} -merged - result 100644 f7e88ccf95c03ecb3df22ba8bbcd817652a83fe0 app/src/models/branch.ts - our 100644 1a16bdd23db314c080802efa3f454878ac0eae63 app/src/models/branch.ts -@@ -8,6 +8,39 @@ - Remote = 1, - } - -+/** The number of commits a revision range is ahead/behind. */ -+export interface IAheadBehind { -+ readonly ahead: number -+ readonly behind: number -+} -+ -+/** The result of comparing two refs in a repository. */ -+export interface ICompareResult extends IAheadBehind { -+ readonly commits: ReadonlyArray -+} -+ -+/** -+ * Check if a branch is eligible for beign fast forarded. -+ * -+ * Requirements: -+ * 1. It's local. -+ * 2. It's not the current branch. -+ * 3. It has an upstream. -+ * -+ * @param branch The branch to validate -+ * @param currentBranchName The current branch in the repository -+ */ -+export function eligibleForFastForward( -+ branch: Branch, -+ currentBranchName: string | null -+): boolean { -+ return ( -+ branch.type === BranchType.Local && -+ branch.name !== currentBranchName && -+ branch.upstream != null -+ ) -+} -+ - /** A branch as loaded from Git. */ - export class Branch { - /** The short name of the branch. E.g., `master`. */ -merged - result 100644 09b508aa3d46107e1f7bfdb7d23ec7e572146082 app/src/models/commit.ts - our 100644 a6eb444fb8650f5e8e351782b02aced729e4933b app/src/models/commit.ts -@@ -118,7 +118,7 @@ - - if (this.committer.name === 'GitHub Enterprise') { - const host = new URL(endpoint).host.toLowerCase() -- return email === `noreply@${host}` -+ return email.endsWith(`@${host}`) - } - - return false -added in remote - their 100644 25149364d06e0118a724af12a46e1d9e39fa94d6 app/src/models/diff/diff-data.ts -@@ -0,0 +1,100 @@ -+import { DiffHunk } from './raw-diff' -+import { Image } from './image' -+/** -+ * V8 has a limit on the size of string it can create, and unless we want to -+ * trigger an unhandled exception we need to do the encoding conversion by hand -+ */ -+export const maximumDiffStringSize = 268435441 -+ -+export enum DiffType { -+ /** Changes to a text file, which may be partially selected for commit */ -+ Text, -+ /** Changes to a file with a known extension, which can be viewed in the app */ -+ Image, -+ /** Changes to an unknown file format, which Git is unable to present in a human-friendly format */ -+ Binary, -+ /** Change to a repository which is included as a submodule of this repository */ -+ Submodule, -+ /** Diff is large enough to degrade ux if rendered */ -+ LargeText, -+ /** Diff that will not be rendered */ -+ Unrenderable, -+} -+ -+type LineEnding = 'CR' | 'LF' | 'CRLF' -+ -+export type LineEndingsChange = { -+ from: LineEnding -+ to: LineEnding -+} -+ -+/** Parse the line ending string into an enum value (or `null` if unknown) */ -+export function parseLineEndingText(text: string): LineEnding | null { -+ const input = text.trim() -+ switch (input) { -+ case 'CR': -+ return 'CR' -+ case 'LF': -+ return 'LF' -+ case 'CRLF': -+ return 'CRLF' -+ default: -+ return null -+ } -+} -+ -+/** -+ * Data returned as part of a textual diff from Desktop -+ */ -+interface ITextDiffData { -+ /** The unified text diff - including headers and context */ -+ readonly text: string -+ /** The diff contents organized by hunk - how the git CLI outputs to the caller */ -+ readonly hunks: ReadonlyArray -+ /** A warning from Git that the line endings have changed in this file and will affect the commit */ -+ readonly lineEndingsChange?: LineEndingsChange -+} -+ -+export interface ITextDiff extends ITextDiffData { -+ readonly kind: DiffType.Text -+} -+ -+/** -+ * Data returned as part of an image diff in Desktop -+ */ -+export interface IImageDiff { -+ readonly kind: DiffType.Image -+ -+ /** -+ * The previous image, if the file was modified or deleted -+ * -+ * Will be undefined for an added image -+ */ -+ readonly previous?: Image -+ /** -+ * The current image, if the file was added or modified -+ * -+ * Will be undefined for a deleted image -+ */ -+ readonly current?: Image -+} -+ -+export interface IBinaryDiff { -+ readonly kind: DiffType.Binary -+} -+ -+export interface ILargeTextDiff extends ITextDiffData { -+ readonly kind: DiffType.LargeText -+} -+ -+export interface IUnrenderableDiff { -+ readonly kind: DiffType.Unrenderable -+} -+ -+/** The union of diff types that can be rendered in Desktop */ -+export type IDiff = -+ | ITextDiff -+ | IImageDiff -+ | IBinaryDiff -+ | ILargeTextDiff -+ | IUnrenderableDiff -added in remote - their 100644 c67a37739d99c6a375e9f4e5675a3b48eb8031ea app/src/models/diff/diff-line.ts -@@ -0,0 +1,49 @@ -+/** indicate what a line in the diff represents */ -+export enum DiffLineType { -+ Context, -+ Add, -+ Delete, -+ Hunk, -+} -+ -+/** track details related to each line in the diff */ -+export class DiffLine { -+ public readonly text: string -+ public readonly type: DiffLineType -+ public readonly oldLineNumber: number | null -+ public readonly newLineNumber: number | null -+ public readonly noTrailingNewLine: boolean -+ -+ public constructor( -+ text: string, -+ type: DiffLineType, -+ oldLineNumber: number | null, -+ newLineNuber: number | null, -+ noTrailingNewLine: boolean = false -+ ) { -+ this.text = text -+ this.type = type -+ this.oldLineNumber = oldLineNumber -+ this.newLineNumber = newLineNuber -+ this.noTrailingNewLine = noTrailingNewLine -+ } -+ -+ public withNoTrailingNewLine(noTrailingNewLine: boolean): DiffLine { -+ return new DiffLine( -+ this.text, -+ this.type, -+ this.oldLineNumber, -+ this.newLineNumber, -+ noTrailingNewLine -+ ) -+ } -+ -+ public isIncludeableLine() { -+ return this.type === DiffLineType.Add || this.type === DiffLineType.Delete -+ } -+ -+ /** The content of the line, i.e., without the line type marker. */ -+ public get content(): string { -+ return this.text.substr(1) -+ } -+} -added in remote - their 100644 e93f04b45de5a0329772d8ff16c2b5a33afedc3f app/src/models/diff/diff-selection.ts -@@ -0,0 +1,291 @@ -+import { assertNever } from '../../lib/fatal-error' -+ -+/** -+ * The state of a file's diff selection -+ */ -+export enum DiffSelectionType { -+ /** The entire file should be committed */ -+ All, -+ /** A subset of lines in the file have been selected for committing */ -+ Partial, -+ /** The file should be excluded from committing */ -+ None, -+} -+ -+/** -+ * Utility function which determines whether a boolean selection state -+ * matches the given DiffSelectionType. A true selection state matches -+ * DiffSelectionType.All, a false selection state matches -+ * DiffSelectionType.None and if the selection type is partial there's -+ * never a match. -+ */ -+function typeMatchesSelection( -+ selectionType: DiffSelectionType, -+ selected: boolean -+): boolean { -+ switch (selectionType) { -+ case DiffSelectionType.All: -+ return selected -+ case DiffSelectionType.None: -+ return !selected -+ case DiffSelectionType.Partial: -+ return false -+ default: -+ return assertNever( -+ selectionType, -+ `Unknown selection type ${selectionType}` -+ ) -+ } -+} -+ -+/** -+ * An immutable, efficient, storage object for tracking selections of indexable -+ * lines. While general purpose by design this is currently used exclusively for -+ * tracking selected lines in modified files in the working directory. -+ * -+ * This class starts out with an initial (or default) selection state, ie -+ * either all lines are selected by default or no lines are selected by default. -+ * -+ * The selection can then be transformed by marking a line or a range of lines -+ * as selected or not selected. Internally the class maintains a list of lines -+ * whose selection state has diverged from the default selection state. -+ */ -+export class DiffSelection { -+ private readonly defaultSelectionType: -+ | DiffSelectionType.All -+ | DiffSelectionType.None -+ -+ /* Any line numbers where the selection differs from the default state. */ -+ private readonly divergingLines: Set | null -+ -+ /* Optional set of line numbers which can be selected. */ -+ private readonly selectableLines: Set | null -+ -+ /** -+ * Initialize a new selection instance where either all lines are selected by default -+ * or not lines are selected by default. -+ */ -+ public static fromInitialSelection( -+ initialSelection: DiffSelectionType.All | DiffSelectionType.None -+ ): DiffSelection { -+ if ( -+ initialSelection !== DiffSelectionType.All && -+ initialSelection !== DiffSelectionType.None -+ ) { -+ return assertNever( -+ initialSelection, -+ 'Can only instantiate a DiffSelection with All or None as the initial selection' -+ ) -+ } -+ -+ return new DiffSelection(initialSelection, null, null) -+ } -+ -+ private constructor( -+ defaultSelectionType: DiffSelectionType.All | DiffSelectionType.None, -+ divergingLines: Set | null, -+ selectableLines: Set | null -+ ) { -+ this.defaultSelectionType = defaultSelectionType -+ this.divergingLines = divergingLines || null -+ this.selectableLines = selectableLines || null -+ } -+ -+ /** Returns a value indicating the computed overall state of the selection */ -+ public getSelectionType(): DiffSelectionType { -+ const divergingLines = this.divergingLines -+ const selectableLines = this.selectableLines -+ -+ // No diverging lines, happy path. Either all lines are selected or none are. -+ if (!divergingLines) { -+ return this.defaultSelectionType -+ } -+ if (divergingLines.size === 0) { -+ return this.defaultSelectionType -+ } -+ -+ // If we know which lines are selectable we need to check that -+ // all lines are divergent and return the inverse of default selection. -+ // To avoid loopting through the set that often our happy path is -+ // if there's a size mismatch. -+ if (selectableLines && selectableLines.size === divergingLines.size) { -+ const allSelectableLinesAreDivergent = [...selectableLines].every(i => -+ divergingLines.has(i) -+ ) -+ -+ if (allSelectableLinesAreDivergent) { -+ return this.defaultSelectionType === DiffSelectionType.All -+ ? DiffSelectionType.None -+ : DiffSelectionType.All -+ } -+ } -+ -+ // Note that without any selectable lines we'll report partial selection -+ // as long as we have any diverging lines since we have no way of knowing -+ // if _all_ lines are divergent or not -+ return DiffSelectionType.Partial -+ } -+ -+ /** Returns a value indicating wether the given line number is selected or not */ -+ public isSelected(lineIndex: number): boolean { -+ const lineIsDivergent = -+ !!this.divergingLines && this.divergingLines.has(lineIndex) -+ -+ if (this.defaultSelectionType === DiffSelectionType.All) { -+ return !lineIsDivergent -+ } else if (this.defaultSelectionType === DiffSelectionType.None) { -+ return lineIsDivergent -+ } else { -+ return assertNever( -+ this.defaultSelectionType, -+ `Unknown base selection type ${this.defaultSelectionType}` -+ ) -+ } -+ } -+ -+ /** -+ * Returns a value indicating wether the given line number is selectable. -+ * A line not being selectable usually means it's a hunk header or a context -+ * line. -+ */ -+ public isSelectable(lineIndex: number): boolean { -+ return this.selectableLines ? this.selectableLines.has(lineIndex) : true -+ } -+ -+ /** -+ * Returns a copy of this selection instance with the provided -+ * line selection update. -+ * -+ * @param lineIndex The index (line number) of the line which should -+ * be selected or unselected. -+ * -+ * @param selected Whether the given line number should be marked -+ * as selected or not. -+ */ -+ public withLineSelection( -+ lineIndex: number, -+ selected: boolean -+ ): DiffSelection { -+ return this.withRangeSelection(lineIndex, 1, selected) -+ } -+ -+ /** -+ * Returns a copy of this selection instance with the provided -+ * line selection update. This is similar to the withLineSelection -+ * method except that it allows updating the selection state of -+ * a range of lines at once. Use this if you ever need to modify -+ * the selection state of more than one line at a time as it's -+ * more efficient. -+ * -+ * @param from The line index (inclusive) from where to start -+ * updating the line selection state. -+ * -+ * @param to The number of lines for which to update the -+ * selection state. A value of zero means no lines -+ * are updated and a value of 1 means only the -+ * line given by lineIndex will be updated. -+ * -+ * @param selected Whether the lines should be marked as selected -+ * or not. -+ */ -+ // Lower inclusive, upper exclusive. Same as substring -+ public withRangeSelection( -+ from: number, -+ length: number, -+ selected: boolean -+ ): DiffSelection { -+ const computedSelectionType = this.getSelectionType() -+ const to = from + length -+ -+ // Nothing for us to do here. This state is when all lines are already -+ // selected and we're being asked to select more or when no lines are -+ // selected and we're being asked to unselect something. -+ if (typeMatchesSelection(computedSelectionType, selected)) { -+ return this -+ } -+ -+ if (computedSelectionType === DiffSelectionType.Partial) { -+ const newDivergingLines = new Set(this.divergingLines!) -+ -+ if (typeMatchesSelection(this.defaultSelectionType, selected)) { -+ for (let i = from; i < to; i++) { -+ newDivergingLines.delete(i) -+ } -+ } else { -+ for (let i = from; i < to; i++) { -+ // Ensure it's selectable -+ if (this.isSelectable(i)) { -+ newDivergingLines.add(i) -+ } -+ } -+ } -+ -+ return new DiffSelection( -+ this.defaultSelectionType, -+ newDivergingLines.size === 0 ? null : newDivergingLines, -+ this.selectableLines -+ ) -+ } else { -+ const newDivergingLines = new Set() -+ for (let i = from; i < to; i++) { -+ if (this.isSelectable(i)) { -+ newDivergingLines.add(i) -+ } -+ } -+ -+ return new DiffSelection( -+ computedSelectionType, -+ newDivergingLines, -+ this.selectableLines -+ ) -+ } -+ } -+ -+ /** -+ * Returns a copy of this selection instance where the selection state -+ * of the specified line has been toggled (inverted). -+ * -+ * @param lineIndex The index (line number) of the line which should -+ * be selected or unselected. -+ */ -+ public withToggleLineSelection(lineIndex: number): DiffSelection { -+ return this.withLineSelection(lineIndex, !this.isSelected(lineIndex)) -+ } -+ -+ /** -+ * Returns a copy of this selection instance with all lines selected. -+ */ -+ public withSelectAll(): DiffSelection { -+ return new DiffSelection(DiffSelectionType.All, null, this.selectableLines) -+ } -+ -+ /** -+ * Returns a copy of this selection instance with no lines selected. -+ */ -+ public withSelectNone(): DiffSelection { -+ return new DiffSelection(DiffSelectionType.None, null, this.selectableLines) -+ } -+ -+ /** -+ * Returns a copy of this selection instance with a specified set of -+ * selecable lines. By default a DiffSelection instance allows selecting -+ * all lines (in fact, it has no notion of how many lines exists or what -+ * it is that is being selected). -+ * -+ * If the selection instance lacks a set of selectable lines it can not -+ * supply an accurate value from getSelectionType when the selection of -+ * all lines have diverged from the default state (since it doesn't know -+ * what all lines mean). -+ */ -+ public withSelectableLines(selectableLines: Set) { -+ const divergingLines = this.divergingLines -+ ? new Set([...this.divergingLines].filter(x => selectableLines.has(x))) -+ : null -+ -+ return new DiffSelection( -+ this.defaultSelectionType, -+ divergingLines, -+ selectableLines -+ ) -+ } -+} -added in remote - their 100644 ec1f951bc9326443ec440600c4c2edcf51e5f4f5 app/src/models/diff/image.ts -@@ -0,0 +1,25 @@ -+/** -+ * A container for holding an image for display in the application -+ */ -+export class Image { -+ /** -+ * The base64 encoded contents of the image -+ */ -+ public readonly contents: string -+ -+ /** -+ * The data URI media type, so the browser can render the image correctly -+ */ -+ public readonly mediaType: string -+ -+ /** -+ * Size of the file in bytes -+ */ -+ public readonly bytes: number -+ -+ public constructor(contents: string, mediaType: string, bytes: number) { -+ this.contents = contents -+ this.mediaType = mediaType -+ this.bytes = bytes -+ } -+} -added in remote - their 100644 ff04279f640811cae78963c899aa24f987d2bd30 app/src/models/diff/index.ts -@@ -0,0 +1,5 @@ -+export * from './diff-data' -+export * from './diff-line' -+export * from './diff-selection' -+export * from './image' -+export * from './raw-diff' -added in remote - their 100644 3182bf4a9cd153fa9d0a33937c7001a783ed140f app/src/models/diff/raw-diff.ts -@@ -0,0 +1,87 @@ -+import { DiffLine } from './diff-line' -+ -+/** each diff is made up of a number of hunks */ -+export class DiffHunk { -+ /** details from the diff hunk header about the line start and patch length */ -+ public readonly header: DiffHunkHeader -+ /** the contents - context and changes - of the diff setion */ -+ public readonly lines: ReadonlyArray -+ /** the diff hunk's start position in the overall file diff */ -+ public readonly unifiedDiffStart: number -+ /** the diff hunk's end position in the overall file diff */ -+ public readonly unifiedDiffEnd: number -+ -+ public constructor( -+ header: DiffHunkHeader, -+ lines: ReadonlyArray, -+ unifiedDiffStart: number, -+ unifiedDiffEnd: number -+ ) { -+ this.header = header -+ this.unifiedDiffStart = unifiedDiffStart -+ this.unifiedDiffEnd = unifiedDiffEnd -+ this.lines = lines -+ } -+} -+ -+/** details about the start and end of a diff hunk */ -+export class DiffHunkHeader { -+ /** The line in the old (or original) file where this diff hunk starts */ -+ public readonly oldStartLine: number -+ -+ /** The number of lines in the old (or original) file that this diff hunk covers */ -+ public readonly oldLineCount: number -+ -+ /** The line in the new file where this diff hunk starts */ -+ public readonly newStartLine: number -+ -+ /** The number of lines in the new file that this diff hunk covers */ -+ public readonly newLineCount: number -+ -+ public constructor( -+ oldStartLine: number, -+ oldLineCount: number, -+ newStartLine: number, -+ newLineCount: number, -+ sectionHeading?: string | null -+ ) { -+ this.oldStartLine = oldStartLine -+ this.oldLineCount = oldLineCount -+ this.newStartLine = newStartLine -+ this.newLineCount = newLineCount -+ } -+} -+ -+/** the contents of a diff generated by Git */ -+export interface IRawDiff { -+ /** -+ * The plain text contents of the diff header. This contains -+ * everything from the start of the diff up until the first -+ * hunk header starts. Note that this does not include a trailing -+ * newline. -+ */ -+ readonly header: string -+ -+ /** -+ * The plain text contents of the diff. This contains everything -+ * after the diff header until the last character in the diff. -+ * -+ * Note that this does not include a trailing newline nor does -+ * it include diff 'no newline at end of file' comments. For -+ * no-newline information, consult the DiffLine noTrailingNewLine -+ * property. -+ */ -+ readonly contents: string -+ -+ /** -+ * Each hunk in the diff with information about start, and end -+ * positions, lines and line statuses. -+ */ -+ readonly hunks: ReadonlyArray -+ -+ /** -+ * Whether or not the unified diff indicates that the contents -+ * could not be diffed due to one of the versions being binary. -+ */ -+ readonly isBinary: boolean -+} -removed in remote - base 100644 a87d16ff4a97dc592dfabe66a69a340629d70ea8 app/src/models/diff.ts - our 100644 a87d16ff4a97dc592dfabe66a69a340629d70ea8 app/src/models/diff.ts -@@ -1,571 +0,0 @@ --import { assertNever } from '../lib/fatal-error' -- --/** -- * V8 has a limit on the size of string it can create, and unless we want to -- * trigger an unhandled exception we need to do the encoding conversion by hand -- */ --export const maximumDiffStringSize = 268435441 -- --/** -- * A container for holding an image for display in the application -- */ --export class Image { -- /** -- * The base64 encoded contents of the image -- */ -- public readonly contents: string -- -- /** -- * The data URI media type, so the browser can render the image correctly -- */ -- public readonly mediaType: string -- -- public constructor(contents: string, mediaType: string) { -- this.contents = contents -- this.mediaType = mediaType -- } --} -- --/** each diff is made up of a number of hunks */ --export class DiffHunk { -- /** details from the diff hunk header about the line start and patch length */ -- public readonly header: DiffHunkHeader -- /** the contents - context and changes - of the diff setion */ -- public readonly lines: ReadonlyArray -- /** the diff hunk's start position in the overall file diff */ -- public readonly unifiedDiffStart: number -- /** the diff hunk's end position in the overall file diff */ -- public readonly unifiedDiffEnd: number -- -- public constructor( -- header: DiffHunkHeader, -- lines: ReadonlyArray, -- unifiedDiffStart: number, -- unifiedDiffEnd: number -- ) { -- this.header = header -- this.unifiedDiffStart = unifiedDiffStart -- this.unifiedDiffEnd = unifiedDiffEnd -- this.lines = lines -- } --} -- --export enum DiffType { -- /** Changes to a text file, which may be partially selected for commit */ -- Text, -- /** Changes to files of a known format, which can be viewed in the app */ -- Image, -- /** Changes to an unknown file format, which Git is unable to present in a human-friendly format */ -- Binary, -- /** Change to a repository which is included as a submodule of this repository */ -- Submodule, -- /** Diff is large enough to degrade ux if rendered */ -- LargeText, -- /** Diff that will not be rendered */ -- Unrenderable, --} -- --/** indicate what a line in the diff represents */ --export enum DiffLineType { -- Context, -- Add, -- Delete, -- Hunk, --} -- --type LineEnding = 'CR' | 'LF' | 'CRLF' -- --export type LineEndingsChange = { -- from: LineEnding -- to: LineEnding --} -- --/** Parse the line ending string into an enum value (or `null` if unknown) */ --export function parseLineEndingText(text: string): LineEnding | null { -- const input = text.trim() -- switch (input) { -- case 'CR': -- return 'CR' -- case 'LF': -- return 'LF' -- case 'CRLF': -- return 'CRLF' -- default: -- return null -- } --} -- --export interface ITextDiff { -- readonly kind: DiffType.Text -- /** The unified text diff - including headers and context */ -- readonly text: string -- /** The diff contents organized by hunk - how the git CLI outputs to the caller */ -- readonly hunks: ReadonlyArray -- /** A warning from Git that the line endings have changed in this file and will affect the commit */ -- readonly lineEndingsChange?: LineEndingsChange --} -- --export interface IImageDiff { -- readonly kind: DiffType.Image -- /** -- * The previous image, if the file was modified or deleted -- * -- * Will be undefined for an added image -- */ -- readonly previous?: Image -- /** -- * The current image, if the file was added or modified -- * -- * Will be undefined for a deleted image -- */ -- readonly current?: Image --} -- --export interface IBinaryDiff { -- readonly kind: DiffType.Binary --} -- --export interface ILargeTextDiff { -- readonly kind: DiffType.LargeText -- /** The unified text diff - including headers and context */ -- readonly text: string -- /** The diff contents organized by hunk - how the git CLI outputs to the caller */ -- readonly hunks: ReadonlyArray -- /** A warning from Git that the line endings have changed in this file and will affect the commit */ -- readonly lineEndingsChange?: LineEndingsChange --} -- --export interface IUnrenderableDiff { -- readonly kind: DiffType.Unrenderable --} -- --/** The union of diff types that can be rendered in Desktop */ --export type IDiff = -- | ITextDiff -- | IImageDiff -- | IBinaryDiff -- | ILargeTextDiff -- | IUnrenderableDiff -- --/** track details related to each line in the diff */ --export class DiffLine { -- public readonly text: string -- public readonly type: DiffLineType -- public readonly oldLineNumber: number | null -- public readonly newLineNumber: number | null -- public readonly noTrailingNewLine: boolean -- -- public constructor( -- text: string, -- type: DiffLineType, -- oldLineNumber: number | null, -- newLineNuber: number | null, -- noTrailingNewLine: boolean = false -- ) { -- this.text = text -- this.type = type -- this.oldLineNumber = oldLineNumber -- this.newLineNumber = newLineNuber -- this.noTrailingNewLine = noTrailingNewLine -- } -- -- public withNoTrailingNewLine(noTrailingNewLine: boolean): DiffLine { -- return new DiffLine( -- this.text, -- this.type, -- this.oldLineNumber, -- this.newLineNumber, -- noTrailingNewLine -- ) -- } -- -- public isIncludeableLine() { -- return this.type === DiffLineType.Add || this.type === DiffLineType.Delete -- } -- -- /** The content of the line, i.e., without the line type marker. */ -- public get content(): string { -- return this.text.substr(1) -- } --} -- --/** details about the start and end of a diff hunk */ --export class DiffHunkHeader { -- /** The line in the old (or original) file where this diff hunk starts */ -- public readonly oldStartLine: number -- -- /** The number of lines in the old (or original) file that this diff hunk covers */ -- public readonly oldLineCount: number -- -- /** The line in the new file where this diff hunk starts */ -- public readonly newStartLine: number -- -- /** The number of lines in the new file that this diff hunk covers */ -- public readonly newLineCount: number -- -- public constructor( -- oldStartLine: number, -- oldLineCount: number, -- newStartLine: number, -- newLineCount: number, -- sectionHeading?: string | null -- ) { -- this.oldStartLine = oldStartLine -- this.oldLineCount = oldLineCount -- this.newStartLine = newStartLine -- this.newLineCount = newLineCount -- } --} -- --export class FileSummary { -- /** -- * The number of lines added as part of this change. -- * -- * If the file is a binary change, this value is undefined. -- */ -- public readonly added?: number -- /** -- * The number of lines removed as part of this change. -- * -- * If the file is a binary change, this value is undefined. -- */ -- public readonly removed?: number -- -- /** -- * The path to this change, relative to the submodule root -- */ -- public readonly path: string -- -- public constructor( -- path: string, -- added: number | undefined, -- removed: number | undefined -- ) { -- this.path = path -- this.added = added -- this.removed = removed -- } -- -- /** An ID for the file change. */ -- public get id(): string { -- return `${this.added}+${this.removed}+${this.path}` -- } --} -- --/** the contents of a diff generated by Git */ --export interface IRawDiff { -- /** -- * The plain text contents of the diff header. This contains -- * everything from the start of the diff up until the first -- * hunk header starts. Note that this does not include a trailing -- * newline. -- */ -- readonly header: string -- -- /** -- * The plain text contents of the diff. This contains everything -- * after the diff header until the last character in the diff. -- * -- * Note that this does not include a trailing newline nor does -- * it include diff 'no newline at end of file' comments. For -- * no-newline information, consult the DiffLine noTrailingNewLine -- * property. -- */ -- readonly contents: string -- -- /** -- * Each hunk in the diff with information about start, and end -- * positions, lines and line statuses. -- */ -- readonly hunks: ReadonlyArray -- -- /** -- * Whether or not the unified diff indicates that the contents -- * could not be diffed due to one of the versions being binary. -- */ -- readonly isBinary: boolean --} -- --export enum DiffSelectionType { -- All, -- Partial, -- None, --} -- --/** -- * Utility function which determines whether a boolean selection state -- * matches the given DiffSelectionType. A true selection state matches -- * DiffSelectionType.All, a false selection state matches -- * DiffSelectionType.None and if the selection type is partial there's -- * never a match. -- */ --function typeMatchesSelection( -- selectionType: DiffSelectionType, -- selected: boolean --): boolean { -- switch (selectionType) { -- case DiffSelectionType.All: -- return selected -- case DiffSelectionType.None: -- return !selected -- case DiffSelectionType.Partial: -- return false -- default: -- return assertNever( -- selectionType, -- `Unknown selection type ${selectionType}` -- ) -- } --} -- --/** -- * An immutable, efficient, storage object for tracking selections of indexable -- * lines. While general purpose by design this is currently used exclusively for -- * tracking selected lines in modified files in the working directory. -- * -- * This class starts out with an initial (or default) selection state, ie -- * either all lines are selected by default or no lines are selected by default. -- * -- * The selection can then be transformed by marking a line or a range of lines -- * as selected or not selected. Internally the class maintains a list of lines -- * whose selection state has diverged from the default selection state. -- */ --export class DiffSelection { -- private readonly defaultSelectionType: -- | DiffSelectionType.All -- | DiffSelectionType.None -- -- /* Any line numbers where the selection differs from the default state. */ -- private readonly divergingLines: Set | null -- -- /* Optional set of line numbers which can be selected. */ -- private readonly selectableLines: Set | null -- -- /** -- * Initialize a new selection instance where either all lines are selected by default -- * or not lines are selected by default. -- */ -- public static fromInitialSelection( -- initialSelection: DiffSelectionType.All | DiffSelectionType.None -- ): DiffSelection { -- if ( -- initialSelection !== DiffSelectionType.All && -- initialSelection !== DiffSelectionType.None -- ) { -- return assertNever( -- initialSelection, -- 'Can only instantiate a DiffSelection with All or None as the initial selection' -- ) -- } -- -- return new DiffSelection(initialSelection, null, null) -- } -- -- private constructor( -- defaultSelectionType: DiffSelectionType.All | DiffSelectionType.None, -- divergingLines: Set | null, -- selectableLines: Set | null -- ) { -- this.defaultSelectionType = defaultSelectionType -- this.divergingLines = divergingLines || null -- this.selectableLines = selectableLines || null -- } -- -- /** Returns a value indicating the computed overall state of the selection */ -- public getSelectionType(): DiffSelectionType { -- const divergingLines = this.divergingLines -- const selectableLines = this.selectableLines -- -- // No diverging lines, happy path. Either all lines are selected or none are. -- if (!divergingLines) { -- return this.defaultSelectionType -- } -- if (divergingLines.size === 0) { -- return this.defaultSelectionType -- } -- -- // If we know which lines are selectable we need to check that -- // all lines are divergent and return the inverse of default selection. -- // To avoid loopting through the set that often our happy path is -- // if there's a size mismatch. -- if (selectableLines && selectableLines.size === divergingLines.size) { -- const allSelectableLinesAreDivergent = [...selectableLines].every(i => -- divergingLines.has(i) -- ) -- -- if (allSelectableLinesAreDivergent) { -- return this.defaultSelectionType === DiffSelectionType.All -- ? DiffSelectionType.None -- : DiffSelectionType.All -- } -- } -- -- // Note that without any selectable lines we'll report partial selection -- // as long as we have any diverging lines since we have no way of knowing -- // if _all_ lines are divergent or not -- return DiffSelectionType.Partial -- } -- -- /** Returns a value indicating wether the given line number is selected or not */ -- public isSelected(lineIndex: number): boolean { -- const lineIsDivergent = -- !!this.divergingLines && this.divergingLines.has(lineIndex) -- -- if (this.defaultSelectionType === DiffSelectionType.All) { -- return !lineIsDivergent -- } else if (this.defaultSelectionType === DiffSelectionType.None) { -- return lineIsDivergent -- } else { -- return assertNever( -- this.defaultSelectionType, -- `Unknown base selection type ${this.defaultSelectionType}` -- ) -- } -- } -- -- /** -- * Returns a value indicating wether the given line number is selectable. -- * A line not being selectable usually means it's a hunk header or a context -- * line. -- */ -- public isSelectable(lineIndex: number): boolean { -- return this.selectableLines ? this.selectableLines.has(lineIndex) : true -- } -- -- /** -- * Returns a copy of this selection instance with the provided -- * line selection update. -- * -- * @param lineIndex The index (line number) of the line which should -- * be selected or unselected. -- * -- * @param selected Whether the given line number should be marked -- * as selected or not. -- */ -- public withLineSelection( -- lineIndex: number, -- selected: boolean -- ): DiffSelection { -- return this.withRangeSelection(lineIndex, 1, selected) -- } -- -- /** -- * Returns a copy of this selection instance with the provided -- * line selection update. This is similar to the withLineSelection -- * method except that it allows updating the selection state of -- * a range of lines at once. Use this if you ever need to modify -- * the selection state of more than one line at a time as it's -- * more efficient. -- * -- * @param from The line index (inclusive) from where to start -- * updating the line selection state. -- * -- * @param to The number of lines for which to update the -- * selection state. A value of zero means no lines -- * are updated and a value of 1 means only the -- * line given by lineIndex will be updated. -- * -- * @param selected Whether the lines should be marked as selected -- * or not. -- */ -- // Lower inclusive, upper exclusive. Same as substring -- public withRangeSelection( -- from: number, -- length: number, -- selected: boolean -- ): DiffSelection { -- const computedSelectionType = this.getSelectionType() -- const to = from + length -- -- // Nothing for us to do here. This state is when all lines are already -- // selected and we're being asked to select more or when no lines are -- // selected and we're being asked to unselect something. -- if (typeMatchesSelection(computedSelectionType, selected)) { -- return this -- } -- -- if (computedSelectionType === DiffSelectionType.Partial) { -- const newDivergingLines = new Set(this.divergingLines!) -- -- if (typeMatchesSelection(this.defaultSelectionType, selected)) { -- for (let i = from; i < to; i++) { -- newDivergingLines.delete(i) -- } -- } else { -- for (let i = from; i < to; i++) { -- // Ensure it's selectable -- if (this.isSelectable(i)) { -- newDivergingLines.add(i) -- } -- } -- } -- -- return new DiffSelection( -- this.defaultSelectionType, -- newDivergingLines.size === 0 ? null : newDivergingLines, -- this.selectableLines -- ) -- } else { -- const newDivergingLines = new Set() -- for (let i = from; i < to; i++) { -- if (this.isSelectable(i)) { -- newDivergingLines.add(i) -- } -- } -- -- return new DiffSelection( -- computedSelectionType, -- newDivergingLines, -- this.selectableLines -- ) -- } -- } -- -- /** -- * Returns a copy of this selection instance where the selection state -- * of the specified line has been toggled (inverted). -- * -- * @param lineIndex The index (line number) of the line which should -- * be selected or unselected. -- */ -- public withToggleLineSelection(lineIndex: number): DiffSelection { -- return this.withLineSelection(lineIndex, !this.isSelected(lineIndex)) -- } -- -- /** -- * Returns a copy of this selection instance with all lines selected. -- */ -- public withSelectAll(): DiffSelection { -- return new DiffSelection(DiffSelectionType.All, null, this.selectableLines) -- } -- -- /** -- * Returns a copy of this selection instance with no lines selected. -- */ -- public withSelectNone(): DiffSelection { -- return new DiffSelection(DiffSelectionType.None, null, this.selectableLines) -- } -- -- /** -- * Returns a copy of this selection instance with a specified set of -- * selecable lines. By default a DiffSelection instance allows selecting -- * all lines (in fact, it has no notion of how many lines exists or what -- * it is that is being selected). -- * -- * If the selection instance lacks a set of selectable lines it can not -- * supply an accurate value from getSelectionType when the selection of -- * all lines have diverged from the default state (since it doesn't know -- * what all lines mean). -- */ -- public withSelectableLines(selectableLines: Set) { -- const divergingLines = this.divergingLines -- ? new Set([...this.divergingLines].filter(x => selectableLines.has(x))) -- : null -- -- return new DiffSelection( -- this.defaultSelectionType, -- divergingLines, -- selectableLines -- ) -- } --} -merged - result 100644 60eb2b935fefe06923b8c583082cb80e3d1ab546 app/src/models/preferences.ts - our 100644 1e6d2e9845d5a06be700bd1a32d3c3d9f9624450 app/src/models/preferences.ts -@@ -1,5 +1,6 @@ - export enum PreferencesTab { - Accounts = 0, -- Git, -- Advanced, -+ Git = 1, -+ Appearance = 2, -+ Advanced = 3, - } -merged - result 100644 45aab006e858dbd9f456c01363c261af3c19e3d1 app/src/models/pull-request.ts - our 100644 a9a31a307d1ff252471481ad1b74adc64164f566 app/src/models/pull-request.ts -@@ -29,6 +29,7 @@ - export interface ICommitStatus { - readonly id: number - readonly state: APIRefState -+ readonly description: string - } - - export class PullRequestStatus { -merged - result 100644 6a4b61f9fe2be4768d09c5ba220b92bac6e36e4a app/src/models/repository.ts - our 100644 0602a86788419c4d0be13a0de4f8c5ac6b37a368 app/src/models/repository.ts -@@ -1,6 +1,19 @@ - import * as Path from 'path' - - import { GitHubRepository } from './github-repository' -+import { IAheadBehind } from './branch' -+ -+function getBaseName(path: string): string { -+ const baseName = Path.basename(path) -+ -+ if (baseName.length === 0) { -+ // the repository is at the root of the drive -+ // -> show the full path here to show _something_ -+ return path -+ } -+ -+ return baseName -+} - - /** A local repository. */ - export class Repository { -@@ -21,8 +34,7 @@ - ) { - this.path = path - this.gitHubRepository = gitHubRepository -- this.name = -- (gitHubRepository && gitHubRepository.name) || Path.basename(path) -+ this.name = (gitHubRepository && gitHubRepository.name) || getBaseName(path) - this.id = id - this.missing = missing - } -@@ -40,3 +52,18 @@ - ${this.name}` - } - } -+ -+/** -+ * A snapshot for the local state for a given repository -+ */ -+export interface ILocalRepositoryState { -+ /** -+ * The ahead/behind count for the current branch, or `null` if no tracking -+ * branch found. -+ */ -+ readonly aheadBehind: IAheadBehind | null -+ /** -+ * The number of uncommitted changes currently in the repository. -+ */ -+ readonly changedFilesCount: number -+} -merged - result 100644 54aa27904efa1f49453cd0037982138833b7f1cb app/src/models/status.ts - our 100644 c3c2f71e62048e24ae2152ec5bb51a37b4ec08b7 app/src/models/status.ts -@@ -144,15 +144,14 @@ - /** the status of the change to the file */ - public readonly status: AppFileStatus - -+ /** An ID for the file change. */ -+ public readonly id: string -+ - public constructor(path: string, status: AppFileStatus, oldPath?: string) { - this.path = path - this.status = status - this.oldPath = oldPath -- } -- -- /** An ID for the file change. */ -- public get id(): string { -- return `${this.status}+${this.path}` -+ this.id = `${this.status}+${this.path}` - } - } - -@@ -222,9 +221,9 @@ - /** - * The list of changes in the repository's working directory - */ -- public readonly files: ReadonlyArray = new Array< -- WorkingDirectoryFileChange -- >() -+ public readonly files: ReadonlyArray = [] -+ -+ private readonly fileIxById = new Map() - - /** - * Update the include checkbox state of the form -@@ -245,6 +244,8 @@ - includeAll: boolean | null - ) { - this.files = files -+ files.forEach((f, ix) => this.fileIxById.set(f.id, ix)) -+ - this.includeAll = includeAll - } - -@@ -258,7 +259,14 @@ - - /** Find the file with the given ID. */ - public findFileWithID(id: string): WorkingDirectoryFileChange | null { -- return this.files.find(f => f.id === id) || null -+ const ix = this.fileIxById.get(id) -+ return ix !== undefined ? this.files[ix] || null : null -+ } -+ -+ /** Find the index of the file with the given ID. Returns -1 if not found */ -+ public findFileIndexByID(id: string): number { -+ const ix = this.fileIxById.get(id) -+ return ix !== undefined ? ix : -1 - } - } - -merged - result 100644 0211c0b5855afc22280ee81441d290e4daf89f0e app/src/ui/add-repository/create-repository.tsx - our 100644 3d86dfd7278adf32d3ce543d8f78f9c4f6933522 app/src/ui/add-repository/create-repository.tsx -@@ -28,7 +28,6 @@ - import { Octicon, OcticonSymbol } from '../octicons' - import { LinkButton } from '../lib/link-button' - import { PopupType } from '../../lib/app-state' --import { pathExists } from '../../lib/file-system' - - /** The sentinel value used to indicate no gitignore should be used. */ - const NoGitIgnoreValue = 'None' -@@ -150,25 +149,13 @@ - this.setState({ isRepository, path }) - } - -- private ensureDirectory(directory: string): Promise { -- return new Promise((resolve, reject) => { -- FSE.ensureDir(directory, err => { -- if (err) { -- return reject(err) -- } -- -- return resolve() -- }) -- }) -- } -- - private resolveRepositoryRoot = async (): Promise => { - const currentPath = this.state.path - if (this.props.initialPath && this.props.initialPath === currentPath) { - // if the user provided an initial path and didn't change it, we should - // validate it is an existing path and use that for the repository - try { -- await this.ensureDirectory(currentPath) -+ await FSE.ensureDir(currentPath) - return currentPath - } catch {} - } -@@ -180,7 +167,7 @@ - const fullPath = await this.resolveRepositoryRoot() - - try { -- await this.ensureDirectory(fullPath) -+ await FSE.ensureDir(fullPath) - this.setState({ isValidPath: true }) - } catch (e) { - if (e.code === 'EACCES' && e.errno === -13) { -@@ -274,7 +261,7 @@ - - try { - const gitAttributes = Path.join(fullPath, '.gitattributes') -- const gitAttributesExists = await pathExists(gitAttributes) -+ const gitAttributesExists = await FSE.pathExists(gitAttributes) - if (!gitAttributesExists) { - await writeGitAttributes(fullPath) - } -merged - result 100644 b273f0970ff626d4e8860c494a658b879c78503a app/src/ui/add-repository/git-attributes.ts - our 100644 d7e6abfb0bd7eeaaa62ff68f64385814404a2cf4 app/src/ui/add-repository/git-attributes.ts -@@ -1,21 +1,12 @@ --import * as FS from 'fs' --import * as Path from 'path' -+import { writeFile } from 'fs-extra' -+import { join } from 'path' - - /** - * Write the .gitAttributes file to the given repository - */ --export function writeGitAttributes(path: string): Promise { -- return new Promise((resolve, reject) => { -- const fullPath = Path.join(path, '.gitattributes') -- const contents = -- '# Auto detect text files and perform LF normalization\n* text=auto\n' -- -- FS.writeFile(fullPath, contents, err => { -- if (err) { -- reject(err) -- } else { -- resolve() -- } -- }) -- }) -+export async function writeGitAttributes(path: string): Promise { -+ const fullPath = join(path, '.gitattributes') -+ const contents = -+ '# Auto detect text files and perform LF normalization\n* text=auto\n' -+ await writeFile(fullPath, contents) - } -merged - result 100644 50809884f9200b94ab3e33a7b9ca96211cb72a25 app/src/ui/add-repository/gitignores.ts - our 100644 14b5e0408ca2ae8146e03d585d52e9f963963607 app/src/ui/add-repository/gitignores.ts -@@ -1,5 +1,5 @@ - import * as Path from 'path' --import * as Fs from 'fs' -+import { readdir, writeFile, readFile } from 'fs-extra' - - const GitIgnoreExtension = '.gitignore' - -@@ -7,31 +7,22 @@ - - let cachedGitIgnores: Map | null = null - --function getCachedGitIgnores(): Promise> { -- if (cachedGitIgnores) { -- return Promise.resolve(cachedGitIgnores) -+async function getCachedGitIgnores(): Promise> { -+ if (cachedGitIgnores != null) { -+ return cachedGitIgnores - } else { -- return new Promise((resolve, reject) => { -- Fs.readdir(root, (err, files) => { -- if (err) { -- reject(err) -- } else { -- const ignoreFiles = files.filter(file => -- file.endsWith(GitIgnoreExtension) -- ) -- -- cachedGitIgnores = new Map() -- for (const file of ignoreFiles) { -- cachedGitIgnores.set( -- Path.basename(file, GitIgnoreExtension), -- Path.join(root, file) -- ) -- } -+ const files = await readdir(root) -+ const ignoreFiles = files.filter(file => file.endsWith(GitIgnoreExtension)) -+ -+ cachedGitIgnores = new Map() -+ for (const file of ignoreFiles) { -+ cachedGitIgnores.set( -+ Path.basename(file, GitIgnoreExtension), -+ Path.join(root, file) -+ ) -+ } - -- resolve(cachedGitIgnores) -- } -- }) -- }) -+ return cachedGitIgnores - } - } - -@@ -45,25 +36,14 @@ - async function getGitIgnoreText(name: string): Promise { - const gitIgnores = await getCachedGitIgnores() - -- return new Promise((resolve, reject) => { -- const path = gitIgnores.get(name) -- if (!path) { -- reject( -- new Error( -- `Unknown gitignore: ${name}. Only names returned from getGitIgnoreNames() can be used.` -- ) -- ) -- return -- } -+ const path = gitIgnores.get(name) -+ if (!path) { -+ throw new Error( -+ `Unknown gitignore: ${name}. Only names returned from getGitIgnoreNames() can be used.` -+ ) -+ } - -- Fs.readFile(path, 'utf8', (err, data) => { -- if (err) { -- reject(err) -- } else { -- resolve(data) -- } -- }) -- }) -+ return await readFile(path, 'utf8') - } - - /** Write the named gitignore to the repository. */ -@@ -72,16 +52,6 @@ - name: string - ): Promise { - const fullPath = Path.join(repositoryPath, '.gitignore') -- - const text = await getGitIgnoreText(name) -- -- return new Promise((resolve, reject) => { -- Fs.writeFile(fullPath, text, err => { -- if (err) { -- reject(err) -- } else { -- resolve() -- } -- }) -- }) -+ await writeFile(fullPath, text) - } -merged - result 100644 5bde560824e8c0b373e32c78a53dbc59473a8bdf app/src/ui/add-repository/licenses.ts - our 100644 faaef147afa4701451223362977b28ce2faa385f app/src/ui/add-repository/licenses.ts -@@ -1,32 +1,13 @@ - import * as Path from 'path' --import * as Fs from 'fs' -- --interface IFrontMatterResult { -- readonly attributes: T -- readonly body: string --} -- --const frontMatter: ( -- path: string --) => IFrontMatterResult = require('front-matter') -- --interface IChooseALicense { -- readonly title: string -- readonly nickname?: string -- readonly featured?: boolean -- readonly hidden?: boolean --} -+import { writeFile, readFile } from 'fs-extra' - - export interface ILicense { - /** The human-readable name. */ - readonly name: string -- - /** Is the license featured? */ - readonly featured: boolean -- - /** The actual text of the license. */ - readonly body: string -- - /** Whether to hide the license from the standard list */ - readonly hidden: boolean - } -@@ -39,65 +20,32 @@ - readonly year: string - } - --const root = Path.join(__dirname, 'static', 'choosealicense.com', '_licenses') -- - let cachedLicenses: ReadonlyArray | null = null - --function readFileAsync(path: string): Promise { -- return new Promise((resolve, reject) => { -- Fs.readFile(path, 'utf8', (err, data) => { -- if (err) { -- reject(err) -- } else { -- resolve(data) -- } -- }) -- }) --} -- - /** Get the available licenses. */ --export function getLicenses(): Promise> { -- if (cachedLicenses) { -- return Promise.resolve(cachedLicenses) -+export async function getLicenses(): Promise> { -+ if (cachedLicenses != null) { -+ return cachedLicenses - } else { -- return new Promise((resolve, reject) => { -- Fs.readdir(root, async (err, files) => { -- if (err) { -- reject(err) -- } else { -- const licenses = new Array() -- for (const file of files) { -- const fullPath = Path.join(root, file) -- const contents = await readFileAsync(fullPath) -- const result = frontMatter(contents) -- const license: ILicense = { -- name: result.attributes.nickname || result.attributes.title, -- featured: result.attributes.featured || false, -- hidden: -- result.attributes.hidden === undefined || -- result.attributes.hidden, -- body: result.body.trim(), -- } -- -- if (!license.hidden) { -- licenses.push(license) -- } -- } -- -- cachedLicenses = licenses.sort((a, b) => { -- if (a.featured) { -- return -1 -- } -- if (b.featured) { -- return 1 -- } -- return a.name.localeCompare(b.name) -- }) -- -- resolve(cachedLicenses) -- } -- }) -+ const licensesMetadataPath = Path.join( -+ __dirname, -+ 'static', -+ 'available-licenses.json' -+ ) -+ const json = await readFile(licensesMetadataPath, 'utf8') -+ const licenses: Array = JSON.parse(json) -+ -+ cachedLicenses = licenses.sort((a, b) => { -+ if (a.featured) { -+ return -1 -+ } -+ if (b.featured) { -+ return 1 -+ } -+ return a.name.localeCompare(b.name) - }) -+ -+ return cachedLicenses - } - } - -@@ -127,29 +75,21 @@ - } - - /** Write the license to the the repository at the given path. */ --export function writeLicense( -+export async function writeLicense( - repositoryPath: string, - license: ILicense, - fields: ILicenseFields - ): Promise { - const fullPath = Path.join(repositoryPath, 'LICENSE') - -- return new Promise((resolve, reject) => { -- const tokens: ReadonlyArray = [ -- 'fullname', -- 'email', -- 'project', -- 'description', -- 'year', -- ] -- const body = replaceTokens(license.body, tokens, fields) -+ const tokens: ReadonlyArray = [ -+ 'fullname', -+ 'email', -+ 'project', -+ 'description', -+ 'year', -+ ] - -- Fs.writeFile(fullPath, body, err => { -- if (err) { -- reject(err) -- } else { -- resolve() -- } -- }) -- }) -+ const body = replaceTokens(license.body, tokens, fields) -+ await writeFile(fullPath, body) - } -merged - result 100644 f05ce45411eea70997e13c55b77d039e2aa1aa8a app/src/ui/add-repository/write-default-readme.ts - our 100644 a9ee5d9ef7fc5782a321218da5ad12f8d34d00d3 app/src/ui/add-repository/write-default-readme.ts -@@ -1,4 +1,4 @@ --import * as FS from 'fs' -+import { writeFile } from 'fs-extra' - import * as Path from 'path' - - const DefaultReadmeName = 'README.md' -@@ -10,16 +10,11 @@ - /** - * Write the default README to the repository with the given name at the path. - */ --export function writeDefaultReadme(path: string, name: string): Promise { -- return new Promise((resolve, reject) => { -- const fullPath = Path.join(path, DefaultReadmeName) -- const contents = defaultReadmeContents(name) -- FS.writeFile(fullPath, contents, err => { -- if (err) { -- reject(err) -- } else { -- resolve() -- } -- }) -- }) -+export async function writeDefaultReadme( -+ path: string, -+ name: string -+): Promise { -+ const fullPath = Path.join(path, DefaultReadmeName) -+ const contents = defaultReadmeContents(name) -+ await writeFile(fullPath, contents) - } -merged - result 100644 6a7921a17b2a7c87f83e400e06329fc525ad046e app/src/ui/app-menu/menu-pane.tsx - our 100644 d7e43d00cd07bd5561699a12da541ef471cb3b55 app/src/ui/app-menu/menu-pane.tsx -@@ -180,7 +180,7 @@ - } - } - -- private onSelectionChanged = (row: number, source: SelectionSource) => { -+ private onSelectedRowChanged = (row: number, source: SelectionSource) => { - const item = this.state.items[row] - this.props.onSelectionChanged(this.props.depth, item, source) - } -@@ -276,9 +276,9 @@ - rowCount={this.state.items.length} - rowHeight={this.rowHeight} - rowRenderer={this.renderMenuItem} -- selectedRow={this.state.selectedIndex} -+ selectedRows={[this.state.selectedIndex]} - onRowClick={this.onRowClick} -- onSelectionChanged={this.onSelectionChanged} -+ onSelectedRowChanged={this.onSelectedRowChanged} - canSelectRow={this.canSelectRow} - onRowKeyDown={this.onRowKeyDown} - invalidationProps={this.state.items} -added in remote - their 100644 eab8b92d267a41b8ab8c40c65e3237393641ccfc app/src/ui/app-theme.tsx -@@ -0,0 +1,59 @@ -+import * as React from 'react' -+import { ApplicationTheme, getThemeName } from './lib/application-theme' -+ -+interface IAppThemeProps { -+ readonly theme: ApplicationTheme -+} -+ -+/** -+ * A pseudo-component responsible for adding the applicable CSS -+ * class names to the body tag in order to apply the currently -+ * selected theme. -+ * -+ * This component is a PureComponent, meaning that it'll only -+ * render when its props changes (shallow comparison). -+ * -+ * This component does not render anything into the DOM, it's -+ * purely (a)busing the component lifecycle to manipulate the -+ * body class list. -+ */ -+export class AppTheme extends React.PureComponent { -+ public componentDidMount() { -+ this.ensureTheme() -+ } -+ -+ public componentDidUpdate() { -+ this.ensureTheme() -+ } -+ -+ public componentWillUnmount() { -+ this.clearThemes() -+ } -+ -+ private ensureTheme() { -+ const newThemeClassName = `theme-${getThemeName(this.props.theme)}` -+ const body = document.body -+ -+ if (body.classList.contains(newThemeClassName)) { -+ return -+ } -+ -+ this.clearThemes() -+ -+ body.classList.add(newThemeClassName) -+ } -+ -+ private clearThemes() { -+ const body = document.body -+ -+ for (const className of body.classList) { -+ if (className.startsWith('theme-')) { -+ body.classList.remove(className) -+ } -+ } -+ } -+ -+ public render() { -+ return null -+ } -+} -merged - result 100644 7355227d8f5b8d4c7153b94c7da59781e776bd0d app/src/ui/app.tsx - our 100644 0349874c603d03e5db59f73672f53d9b9f74f464 app/src/ui/app.tsx -@@ -1,14 +1,15 @@ - import * as React from 'react' --import { ipcRenderer } from 'electron' -+import { ipcRenderer, remote } from 'electron' - import { CSSTransitionGroup } from 'react-transition-group' - - import { - IAppState, -- RepositorySection, -+ RepositorySectionTab, - Popup, - PopupType, - FoldoutType, - SelectionType, -+ CompareActionKind, - } from '../lib/app-state' - import { Dispatcher } from '../lib/dispatcher' - import { AppStore } from '../lib/stores' -@@ -85,12 +86,17 @@ - import { InitializeLFS, AttributeMismatch } from './lfs' - import { UpstreamAlreadyExists } from './upstream-already-exists' - import { DeletePullRequest } from './delete-branch/delete-pull-request-dialog' -+import { MergeConflictsWarning } from './merge-conflicts' -+import { AppTheme } from './app-theme' -+import { ApplicationTheme } from './lib/application-theme' - - /** The interval at which we should check for updates. */ - const UpdateCheckInterval = 1000 * 60 * 60 * 4 - - const SendStatsInterval = 1000 * 60 * 60 * 4 - -+const updateRepoInfoInterval = 1000 * 60 * 5 -+ - interface IAppProps { - readonly dispatcher: Dispatcher - readonly appStore: AppStore -@@ -145,6 +151,10 @@ - }, - { timeout: ReadyDelay } - ) -+ -+ window.setInterval(() => { -+ this.props.appStore.refreshAllRepositories() -+ }, updateRepoInfoInterval) - }) - - this.state = props.appStore.getState() -@@ -241,10 +251,10 @@ - return this.push() - case 'pull': - return this.pull() -- case 'select-changes': -- return this.selectChanges() -- case 'select-history': -- return this.selectHistory() -+ case 'show-changes': -+ return this.showChanges() -+ case 'show-history': -+ return this.showHistory() - case 'choose-repository': - return this.chooseRepository() - case 'add-local-repository': -@@ -265,16 +275,23 @@ - return this.props.dispatcher.showPopup({ type: PopupType.Preferences }) - case 'open-working-directory': - return this.openCurrentRepositoryWorkingDirectory() -- case 'update-branch': -+ case 'update-branch': { -+ this.props.dispatcher.recordMenuInitiatedUpdate() - return this.updateBranch() -- case 'merge-branch': -+ } -+ case 'compare-to-branch': { -+ return this.showHistory(true) -+ } -+ case 'merge-branch': { -+ this.props.dispatcher.recordMenuInitiatedMerge() - return this.mergeBranch() -+ } - case 'show-repository-settings': - return this.showRepositorySettings() - case 'view-repository-on-github': - return this.viewRepositoryOnGitHub() -- case 'compare-branch': -- return this.compareBranch() -+ case 'compare-on-github': -+ return this.compareBranchOnDotcom() - case 'open-in-shell': - return this.openCurrentRepositoryInShell() - case 'clone-repository': -@@ -290,11 +307,31 @@ - return this.props.dispatcher.installCLI() - case 'open-external-editor': - return this.openCurrentRepositoryInExternalEditor() -+ case 'select-all': -+ return this.selectAll() - } - - return assertNever(name, `Unknown menu event name: ${name}`) - } - -+ /** -+ * Handler for the 'select-all' menu event, dispatches -+ * a custom DOM event originating from the element which -+ * currently has keyboard focus. Components have a chance -+ * to intercept this event and implement their own 'select -+ * all' logic. -+ */ -+ private selectAll() { -+ const event = new CustomEvent('select-all', { -+ bubbles: true, -+ cancelable: true, -+ }) -+ -+ if (document.activeElement.dispatchEvent(event)) { -+ remote.getCurrentWebContents().selectAll() -+ } -+ } -+ - private boomtown() { - setImmediate(() => { - throw new Error('Boomtown!') -@@ -360,7 +397,7 @@ - }) - } - -- private compareBranch() { -+ private compareBranchOnDotcom() { - const htmlURL = this.getCurrentRepositoryGitHubURL() - if (!htmlURL) { - return -@@ -461,20 +498,30 @@ - this.props.dispatcher.showPopup({ type: PopupType.About }) - } - -- private selectChanges() { -+ private async showHistory(showBranchList: boolean = false) { - const state = this.state.selectedState - if (state == null || state.type !== SelectionType.Repository) { - return - } - -- this.props.dispatcher.closeCurrentFoldout() -- this.props.dispatcher.changeRepositorySection( -+ await this.props.dispatcher.closeCurrentFoldout() -+ -+ await this.props.dispatcher.initializeCompare(state.repository, { -+ kind: CompareActionKind.History, -+ }) -+ -+ await this.props.dispatcher.changeRepositorySection( - state.repository, -- RepositorySection.Changes -+ RepositorySectionTab.History - ) -+ -+ await this.props.dispatcher.updateCompareForm(state.repository, { -+ filterText: '', -+ showBranchList, -+ }) - } - -- private selectHistory() { -+ private showChanges() { - const state = this.state.selectedState - if (state == null || state.type !== SelectionType.Repository) { - return -@@ -483,7 +530,7 @@ - this.props.dispatcher.closeCurrentFoldout() - this.props.dispatcher.changeRepositorySection( - state.repository, -- RepositorySection.History -+ RepositorySectionTab.Changes - ) - } - -@@ -934,6 +981,11 @@ - /> - ) - case PopupType.ConfirmDiscardChanges: -+ const showSetting = -+ popup.showDiscardChangesSetting === undefined -+ ? true -+ : popup.showDiscardChangesSetting -+ - return ( - -@@ -965,10 +1018,11 @@ - enterpriseAccount={this.getEnterpriseAccount()} - onDismissed={this.onPopupDismissed} - selectedShell={this.state.selectedShell} -+ selectedTheme={this.state.selectedTheme} - /> - ) - case PopupType.MergeBranch: { -- const repository = popup.repository -+ const { repository, branch } = popup - const state = this.props.appStore.getRepositoryState(repository) - - const tip = state.branchesState.tip -@@ -983,6 +1037,7 @@ - defaultBranch={state.branchesState.defaultBranch} - recentBranches={state.branchesState.recentBranches} - currentBranch={currentBranch} -+ initialBranch={branch} - onDismissed={this.onPopupDismissed} - /> - ) -@@ -1204,6 +1259,14 @@ - pullRequest={popup.pullRequest} - /> - ) -+ case PopupType.MergeConflicts: -+ return ( -+ -+ ) - default: - return assertNever(popup, `Unknown popup type: ${popup}`) - } -@@ -1337,12 +1400,17 @@ - selectedRepository={selectedRepository} - onSelectionChanged={this.onSelectionChanged} - repositories={this.state.repositories} -+ localRepositoryStateLookup={this.state.localRepositoryStateLookup} -+ askForConfirmationOnRemoveRepository={ -+ this.state.askForConfirmationOnRepositoryRemoval -+ } - onRemoveRepository={this.removeRepository} - onOpenInShell={this.openInShell} - onShowRepository={this.showRepository} - onOpenInExternalEditor={this.openInExternalEditor} - externalEditorLabel={externalEditorLabel} - shellLabel={shellLabel} -+ dispatcher={this.props.dispatcher} - /> - ) - } -@@ -1355,8 +1423,8 @@ - this.props.dispatcher.openShell(repository.path) - } - -- private openFileInExternalEditor = (path: string) => { -- this.props.dispatcher.openInExternalEditor(path) -+ private openFileInExternalEditor = (fullPath: string) => { -+ this.props.dispatcher.openInExternalEditor(fullPath) - } - - private openInExternalEditor = ( -@@ -1409,6 +1477,8 @@ - - const currentState: DropdownState = isOpen ? 'open' : 'closed' - -+ const tooltip = repository && !isOpen ? repository.path : undefined -+ - const foldoutStyle: React.CSSProperties = { - position: 'absolute', - marginLeft: 0, -@@ -1422,6 +1492,7 @@ - icon={icon} - title={title} - description={__DARWIN__ ? 'Current Repository' : 'Current repository'} -+ tooltip={tooltip} - foldoutStyle={foldoutStyle} - onDropdownStateChanged={this.onRepositoryDropdownStateChanged} - dropdownContentRenderer={this.renderRepositoryList} -@@ -1594,26 +1665,27 @@ - } - - if (selectedState.type === SelectionType.Repository) { -- const externalEditorLabel = this.state.selectedExternalEditor -+ const externalEditorLabel = state.selectedExternalEditor - - return ( - - ) - } else if (selectedState.type === SelectionType.CloningRepository) { -@@ -1652,8 +1724,13 @@ - - const className = this.state.appIsFocused ? 'focused' : 'blurred' - -+ const currentTheme = this.state.showWelcomeFlow -+ ? ApplicationTheme.Light -+ : this.state.selectedTheme -+ - return ( -
-+ - {this.renderTitlebar()} - {this.state.showWelcomeFlow - ? this.renderWelcomeFlow() -merged - result 100644 ffb19e643f39201e7668941e3125223f6319fdd7 app/src/ui/autocompletion/autocompleting-text-input.tsx - our 100644 fa4fe8265157ad6e485388bac030717e2e634543 app/src/ui/autocompletion/autocompleting-text-input.tsx -@@ -1,5 +1,10 @@ - import * as React from 'react' --import { List, SelectionSource } from '../lib/list' -+import { -+ List, -+ SelectionSource, -+ findNextSelectableRow, -+ SelectionDirection, -+} from '../lib/list' - import { IAutocompletionProvider } from './index' - import { fatalError } from '../../lib/fatal-error' - import * as classNames from 'classnames' -@@ -28,6 +33,9 @@ - /** Disabled state for input field. */ - readonly disabled?: boolean - -+ /** Indicates if input field should be required */ -+ readonly isRequired?: boolean -+ - /** - * Called when the user changes the value in the input field. - */ -@@ -96,7 +104,6 @@ - IAutocompletingTextInputState - > { - private element: ElementType | null = null -- private autocompletionList: List | null = null - - /** The identifier for each autocompletion request. */ - private autocompletionRequestID = 0 -@@ -122,10 +129,6 @@ - ) - } - -- private storeAutocompletionListRef = (ref: List | null) => { -- this.autocompletionList = ref -- } -- - private renderAutocompletions() { - const state = this.state.autocompletionState - if (!state) { -@@ -180,17 +183,16 @@ - return ( -
- -
-@@ -211,7 +213,7 @@ - } - } - -- private onSelectionChanged = (row: number, source: SelectionSource) => { -+ private onSelectedRowChanged = (row: number, source: SelectionSource) => { - const currentAutoCompletionState = this.state.autocompletionState - - if (!currentAutoCompletionState) { -@@ -270,6 +272,7 @@ - onBlur: this.onBlur, - onContextMenu: this.onContextMenu, - disabled: this.props.disabled, -+ 'aria-required': this.props.isRequired ? true : false, - } - - return React.createElement, ElementType>( -@@ -363,7 +366,7 @@ - - private getMovementDirection( - event: React.KeyboardEvent -- ): 'up' | 'down' | null { -+ ): SelectionDirection | null { - switch (event.key) { - case 'ArrowUp': - return 'up' -@@ -401,11 +404,12 @@ - const direction = this.getMovementDirection(event) - if (direction) { - event.preventDefault() -+ const rowCount = currentAutoCompletionState.items.length - -- const nextRow = this.autocompletionList!.nextSelectableRow( -+ const nextRow = findNextSelectableRow(rowCount, { - direction, -- selectedRow -- ) -+ row: selectedRow, -+ }) - - if (nextRow !== null) { - const newSelectedItem = currentAutoCompletionState.items[nextRow] -added in remote - their 100644 474f18ccb67239743953eda7f33488769a615c05 app/src/ui/branches/branch-list-item.tsx -@@ -0,0 +1,49 @@ -+import * as React from 'react' -+import * as moment from 'moment' -+ -+import { IMatches } from '../../lib/fuzzy-find' -+ -+import { Octicon, OcticonSymbol } from '../octicons' -+import { HighlightText } from '../lib/highlight-text' -+ -+interface IBranchListItemProps { -+ /** The name of the branch */ -+ readonly name: string -+ -+ /** Specifies whether this item is currently selected */ -+ readonly isCurrentBranch: boolean -+ -+ /** The date may be null if we haven't loaded the tip commit yet. */ -+ readonly lastCommitDate: Date | null -+ -+ /** The characters in the branch name to highlight */ -+ readonly matches: IMatches -+} -+ -+/** The branch component. */ -+export class BranchListItem extends React.Component { -+ public render() { -+ const lastCommitDate = this.props.lastCommitDate -+ const isCurrentBranch = this.props.isCurrentBranch -+ const name = this.props.name -+ -+ const date = lastCommitDate ? moment(lastCommitDate).fromNow() : '' -+ const icon = isCurrentBranch ? OcticonSymbol.check : OcticonSymbol.gitBranch -+ const infoTitle = isCurrentBranch -+ ? 'Current branch' -+ : lastCommitDate -+ ? lastCommitDate.toString() -+ : '' -+ return ( -+
-+ -+
-+ -+
-+
-+ {date} -+
-+
-+ ) -+ } -+} -merged - result 100644 d64fb68c7b730c7a0bbccfb64e4a8acf364fd5e9 app/src/ui/branches/branch-list.tsx - our 100644 32bcadc42b0cd4c81a0fadc6da4c43b862a2c902 app/src/ui/branches/branch-list.tsx -@@ -1,27 +1,24 @@ - import * as React from 'react' -+ - import { Branch } from '../../models/branch' --import { -- groupBranches, -- IBranchListItem, -- BranchGroupIdentifier, --} from './group-branches' --import { BranchListItem } from './branch' -+ -+import { assertNever } from '../../lib/fatal-error' -+ - import { - FilterList, - IFilterListGroup, - SelectionSource, - } from '../lib/filter-list' --import { assertNever } from '../../lib/fatal-error' -+import { IMatches } from '../../lib/fuzzy-find' - import { Button } from '../lib/button' --import { NoBranches } from './no-branches' -+import { TextBox } from '../lib/text-box' - --/** -- * TS can't parse generic specialization in JSX, so we have to alias it here -- * with the generic type. See https://github.com/Microsoft/TypeScript/issues/6395. -- */ --const BranchesFilterList: new () => FilterList< -- IBranchListItem --> = FilterList as any -+import { -+ groupBranches, -+ IBranchListItem, -+ BranchGroupIdentifier, -+} from './group-branches' -+import { NoBranches } from './no-branches' - - const RowHeight = 30 - -@@ -91,6 +88,16 @@ - * to prepopulate the new branch name field. - */ - readonly onCreateNewBranch?: (name: string) => void -+ -+ readonly textbox?: TextBox -+ -+ /** -+ * Render function to apply to each branch in the list -+ */ -+ readonly renderBranch: ( -+ item: IBranchListItem, -+ matches: IMatches -+ ) => JSX.Element - } - - interface IBranchListState { -@@ -138,30 +145,77 @@ - IBranchListProps, - IBranchListState - > { -+ private branchFilterList: FilterList | null = null -+ - public constructor(props: IBranchListProps) { - super(props) - this.state = createState(props) - } - -- private renderItem = ( -- item: IBranchListItem, -- matches: ReadonlyArray -- ) => { -- const branch = item.branch -- const commit = branch.tip -- const currentBranchName = this.props.currentBranch -- ? this.props.currentBranch.name -- : null -+ public componentWillReceiveProps(nextProps: IBranchListProps) { -+ this.setState(createState(nextProps)) -+ } -+ -+ public selectFirstItem(focus: boolean = false) { -+ if (this.branchFilterList !== null) { -+ this.branchFilterList.selectFirstItem(focus) -+ } -+ } -+ -+ public render() { - return ( -- -+ ref={this.onBranchesFilterListRef} -+ className="branches-list" -+ rowHeight={RowHeight} -+ filterText={this.props.filterText} -+ onFilterTextChanged={this.props.onFilterTextChanged} -+ onFilterKeyDown={this.props.onFilterKeyDown} -+ selectedItem={this.state.selectedItem} -+ renderItem={this.renderItem} -+ renderGroupHeader={this.renderGroupHeader} -+ onItemClick={this.onItemClick} -+ onSelectionChanged={this.onSelectionChanged} -+ groups={this.state.groups} -+ invalidationProps={this.props.allBranches} -+ renderPostFilter={this.onRenderNewButton} -+ renderNoItems={this.onRenderNoItems} -+ filterTextBox={this.props.textbox} - /> - ) - } - -+ private onBranchesFilterListRef = ( -+ filterList: FilterList | null -+ ) => { -+ this.branchFilterList = filterList -+ } -+ -+ private renderItem = (item: IBranchListItem, matches: IMatches) => { -+ return this.props.renderBranch(item, matches) -+ } -+ -+ private parseHeader(label: string): BranchGroupIdentifier | null { -+ switch (label) { -+ case 'default': -+ case 'recent': -+ case 'other': -+ return label -+ default: -+ return null -+ } -+ } -+ -+ private renderGroupHeader = (label: string) => { -+ const identifier = this.parseHeader(label) -+ -+ return identifier !== null ? ( -+
-+ {this.getGroupLabel(identifier)} -+
-+ ) : null -+ } -+ - private getGroupLabel(identifier: BranchGroupIdentifier) { - if (identifier === 'default') { - return __DARWIN__ ? 'Default Branch' : 'Default branch' -@@ -174,15 +228,23 @@ - } - } - -- private renderGroupHeader = (id: string) => { -- const identifier = id as BranchGroupIdentifier -+ private onRenderNoItems = () => { - return ( --
-- {this.getGroupLabel(identifier)} --
-+ - ) - } - -+ private onRenderNewButton = () => { -+ return this.props.canCreateNewBranch ? ( -+ -+ ) : null -+ } -+ - private onItemClick = (item: IBranchListItem) => { - if (this.props.onItemClick) { - this.props.onItemClick(item.branch) -@@ -201,52 +263,6 @@ - } - } - -- public componentWillReceiveProps(nextProps: IBranchListProps) { -- this.setState(createState(nextProps)) -- } -- -- public render() { -- return ( -- -- ) -- } -- -- private renderNoItems = () => { -- return ( -- -- ) -- } -- -- private renderNewButton = () => { -- if (this.props.canCreateNewBranch) { -- return ( -- -- ) -- } else { -- return null -- } -- } -- - private onCreateNewBranch = () => { - if (this.props.onCreateNewBranch) { - this.props.onCreateNewBranch(this.props.filterText) -added in remote - their 100644 dd27f7b0f40a3be55aa8a51cd83f116cf289c7e6 app/src/ui/branches/branch-renderer.tsx -@@ -0,0 +1,25 @@ -+import * as React from 'react' -+ -+import { Branch } from '../../models/branch' -+ -+import { IBranchListItem } from './group-branches' -+import { BranchListItem } from './branch-list-item' -+import { IMatches } from '../../lib/fuzzy-find' -+ -+export function renderDefaultBranch( -+ item: IBranchListItem, -+ matches: IMatches, -+ currentBranch: Branch | null -+): JSX.Element { -+ const branch = item.branch -+ const commit = branch.tip -+ const currentBranchName = currentBranch ? currentBranch.name : null -+ return ( -+ -+ ) -+} -removed in remote - base 100644 a0b819ee744d244551744b38bdf6cc5ab5cfd9bf app/src/ui/branches/branch.tsx - our 100644 a0b819ee744d244551744b38bdf6cc5ab5cfd9bf app/src/ui/branches/branch.tsx -@@ -1,42 +0,0 @@ --import * as React from 'react' --import * as moment from 'moment' -- --import { Octicon, OcticonSymbol } from '../octicons' --import { HighlightText } from '../lib/highlight-text' -- --interface IBranchProps { -- readonly name: string -- readonly isCurrentBranch: boolean -- -- /** The date may be null if we haven't loaded the tip commit yet. */ -- readonly lastCommitDate: Date | null -- -- /** The characters in the branch name to highlight */ -- readonly matches: ReadonlyArray --} -- --/** The branch component. */ --export class BranchListItem extends React.Component { -- public render() { -- const lastCommitDate = this.props.lastCommitDate -- const isCurrentBranch = this.props.isCurrentBranch -- const name = this.props.name -- -- const date = lastCommitDate ? moment(lastCommitDate).fromNow() : '' -- const icon = isCurrentBranch ? OcticonSymbol.check : OcticonSymbol.gitBranch -- const infoTitle = isCurrentBranch -- ? 'Current branch' -- : lastCommitDate ? lastCommitDate.toString() : '' -- return ( --
-- --
-- --
--
-- {date} --
--
-- ) -- } --} -merged - result 100644 13f691705648f0b7a0f7303372de8f2db79f3d76 app/src/ui/branches/branches-container.tsx - our 100644 2f69f46fba8a6dfaa8628742c9c00631c32b24c3 app/src/ui/branches/branches-container.tsx -@@ -1,16 +1,23 @@ - import * as React from 'react' --import { Dispatcher } from '../../lib/dispatcher' --import { FoldoutType, PopupType } from '../../lib/app-state' -+import { CSSTransitionGroup } from 'react-transition-group' -+ -+import { PullRequest } from '../../models/pull-request' - import { Repository } from '../../models/repository' - import { Branch } from '../../models/branch' --import { BranchList } from './branch-list' --import { TabBar } from '../tab-bar' - import { BranchesTab } from '../../models/branches-tab' -+ -+import { Dispatcher } from '../../lib/dispatcher' -+import { FoldoutType, PopupType } from '../../lib/app-state' - import { assertNever } from '../../lib/fatal-error' -+ -+import { TabBar } from '../tab-bar' -+ -+import { BranchList } from './branch-list' - import { PullRequestList } from './pull-request-list' - import { PullRequestsLoading } from './pull-requests-loading' --import { PullRequest } from '../../models/pull-request' --import { CSSTransitionGroup } from 'react-transition-group' -+import { IBranchListItem } from './group-branches' -+import { renderDefaultBranch } from './branch-renderer' -+import { IMatches } from '../../lib/fuzzy-find' - - const PullRequestsLoadingCrossFadeInTimeout = 300 - const PullRequestsLoadingCrossFadeOutTimeout = 200 -@@ -91,6 +98,10 @@ - ) - } - -+ private renderBranch = (item: IBranchListItem, matches: IMatches) => { -+ return renderDefaultBranch(item, matches, this.props.currentBranch) -+ } -+ - private renderSelectedTab() { - let tab = this.props.selectedTab - if (!this.props.repository.gitHubRepository) { -@@ -112,6 +123,7 @@ - onSelectionChanged={this.onBranchSelectionChanged} - canCreateNewBranch={true} - onCreateNewBranch={this.onCreateBranchWithName} -+ renderBranch={this.renderBranch} - /> - ) - -merged - result 100644 7451fb01e997e0bfbc31e57c3e69d5f34ae179ea app/src/ui/branches/ci-status.tsx - our 100644 1f7ff2736a141923c6fb9112cfd5f398896acf1e app/src/ui/branches/ci-status.tsx -@@ -4,6 +4,7 @@ - import { assertNever } from '../../lib/fatal-error' - import * as classNames from 'classnames' - import { PullRequestStatus } from '../../models/pull-request' -+import { getPRStatusSummary } from './pull-request-status' - - interface ICIStatusProps { - /** The classname for the underlying element. */ -@@ -17,7 +18,7 @@ - export class CIStatus extends React.Component { - public render() { - const status = this.props.status -- const ciTitle = generateStatusHistory(status) -+ const title = getPRStatusSummary(status) - const state = status.state - - return ( -@@ -28,25 +29,12 @@ - this.props.className - )} - symbol={getSymbolForState(state)} -- title={ciTitle} -+ title={title} - /> - ) - } - } - --function generateStatusHistory(prStatus: PullRequestStatus): string { -- const statusCount = prStatus.statuses.length || 0 -- -- if (statusCount === 0) { -- return prStatus.state.toUpperCase() -- } else { -- const successCount = prStatus.statuses.filter(x => x.state === 'success') -- .length -- -- return `${successCount}/${statusCount} checks OK` -- } --} -- - function getSymbolForState(state: APIRefState): OcticonSymbol { - switch (state) { - case 'pending': -merged - result 100644 f4953500cb984957451e61da094929c0254c811d app/src/ui/branches/group-branches.ts - our 100644 2fd74251410406f3439b9e4e709abb36b13b8dd8 app/src/ui/branches/group-branches.ts -@@ -4,7 +4,7 @@ - export type BranchGroupIdentifier = 'default' | 'recent' | 'other' - - export interface IBranchListItem extends IFilterListItem { -- readonly text: string -+ readonly text: ReadonlyArray - readonly id: string - readonly branch: Branch - } -@@ -22,7 +22,7 @@ - identifier: 'default', - items: [ - { -- text: defaultBranch.name, -+ text: [defaultBranch.name], - id: defaultBranch.name, - branch: defaultBranch, - }, -@@ -40,7 +40,7 @@ - - for (const branch of recentBranchesWithoutDefault) { - recentBranches.push({ -- text: branch.name, -+ text: [branch.name], - id: branch.name, - branch, - }) -@@ -57,7 +57,7 @@ - b => b.name !== defaultBranchName && !recentBranchNames.has(b.name) - ) - const remainingItems = remainingBranches.map(b => ({ -- text: b.name, -+ text: [b.name], - id: b.name, - branch: b, - })) -merged - result 100644 bcb647c13a47252579f1da58a3632ba021373dd8 app/src/ui/branches/index.ts - our 100644 a62107b46da20b86867baa54600fa7cbc8f9eb41 app/src/ui/branches/index.ts -@@ -2,4 +2,6 @@ - export { BranchList } from './branch-list' - export { BranchesContainer } from './branches-container' - export { PullRequestBadge } from './pull-request-badge' --export { groupBranches } from './group-branches' -+export { groupBranches, IBranchListItem } from './group-branches' -+export { BranchListItem } from './branch-list-item' -+export { renderDefaultBranch } from './branch-renderer' -merged - result 100644 65a3baac5401a65b19efd6017970323efc6fc8fa app/src/ui/branches/no-branches.tsx - our 100644 b6f86111727f7f6fb160bb9f2a6ed052d339dca8 app/src/ui/branches/no-branches.tsx -@@ -43,13 +43,7 @@ - ) - } - -- return ( --
-- -- --
Sorry, I can't find that branch
--
-- ) -+ return
Sorry, I can't find that branch
- } - - private renderShortcut() { -merged - result 100644 075b2904f501296734519cbb19ed658a9f168a05 app/src/ui/branches/pull-request-list-item.tsx - our 100644 b89deea91855c4909ea7801c74d3978b0e398d1a app/src/ui/branches/pull-request-list-item.tsx -@@ -5,6 +5,7 @@ - import { CIStatus } from './ci-status' - import { PullRequestStatus } from '../../models/pull-request' - import { HighlightText } from '../lib/highlight-text' -+import { IMatches } from '../../lib/fuzzy-find' - - export interface IPullRequestListItemProps { - /** The title. */ -@@ -32,7 +33,7 @@ - readonly loading?: boolean - - /** The characters in the PR title to highlight */ -- readonly matches: ReadonlyArray -+ readonly matches: IMatches - } - - /** Pull requests as rendered in the Pull Requests list. */ -@@ -51,7 +52,7 @@ - public render() { - const title = this.props.loading === true ? undefined : this.props.title - const subtitle = this.getSubtitle() -- -+ const matches = this.props.matches - const className = classNames('pull-request-item', { - loading: this.props.loading === true, - }) -@@ -61,10 +62,10 @@ - -
-
-- -+ -
-
-- {subtitle} -+ -
-
- {this.renderPullRequestStatus()} -merged - result 100644 484112784b83cd0d9be46284b3a1fb1b877894b2 app/src/ui/branches/pull-request-list.tsx - our 100644 1f9009ad85604378e350167422ee4056fad94c1c app/src/ui/branches/pull-request-list.tsx -@@ -1,4 +1,5 @@ - import * as React from 'react' -+import * as moment from 'moment' - import { - FilterList, - IFilterListGroup, -@@ -8,21 +9,14 @@ - import { PullRequestListItem } from './pull-request-list-item' - import { PullRequest, PullRequestStatus } from '../../models/pull-request' - import { NoPullRequests } from './no-pull-requests' -+import { IMatches } from '../../lib/fuzzy-find' - - interface IPullRequestListItem extends IFilterListItem { - readonly id: string -- readonly text: string -+ readonly text: ReadonlyArray - readonly pullRequest: PullRequest - } - --/** -- * TS can't parse generic specialization in JSX, so we have to alias it here -- * with the generic type. See https://github.com/Microsoft/TypeScript/issues/6395. -- */ --const PullRequestFilterList: new () => FilterList< -- IPullRequestListItem --> = FilterList as any -- - export const RowHeight = 47 - - interface IPullRequestListProps { -@@ -126,7 +120,7 @@ - - public render() { - return ( -- - className="pull-request-list" - rowHeight={RowHeight} - groups={this.state.groupedItems} -@@ -157,7 +151,7 @@ - - private renderPullRequest = ( - item: IPullRequestListItem, -- matches: ReadonlyArray -+ matches: IMatches - ) => { - const pr = item.pullRequest - const refStatuses = pr.status != null ? pr.status.statuses : [] -@@ -203,11 +197,16 @@ - } - } - -+function getSubtitle(pr: PullRequest) { -+ const timeAgo = moment(pr.created).fromNow() -+ return `#${pr.number} opened ${timeAgo} by ${pr.author}` -+} -+ - function createListItems( - pullRequests: ReadonlyArray - ): IFilterListGroup { - const items = pullRequests.map(pr => ({ -- text: pr.title, -+ text: [pr.title, getSubtitle(pr)], - id: pr.number.toString(), - pullRequest: pr, - })) -added in remote - their 100644 54db06f6493895ecd48deef8273b206d613d60e2 app/src/ui/branches/pull-request-status.ts -@@ -0,0 +1,48 @@ -+import { PullRequestStatus, ICommitStatus } from '../../models/pull-request' -+import { APIRefState } from '../../lib/api' -+import { assertNever } from '../../lib/fatal-error' -+ -+function formatState(state: APIRefState): string { -+ switch (state) { -+ case 'failure': -+ return 'Commit status: failed' -+ case 'pending': -+ case 'success': -+ return `Commit status: ${state}` -+ -+ default: -+ return assertNever(state, `Unknown APIRefState value: ${state}`) -+ } -+} -+ -+function formatSingleStatus(status: ICommitStatus) { -+ const word = status.state -+ const sentenceCaseWord = -+ word.charAt(0).toUpperCase() + word.substring(1, word.length) -+ -+ return `${sentenceCaseWord}: ${status.description}` -+} -+ -+/** -+ * Convert the Pull Request status to an app-friendly string. -+ * -+ * If the pull request contains commit statuses, this method will compute -+ * the number of successful statuses. Oteherwise, it will fall back -+ * to the `state` value reported by the GitHub API. -+ */ -+export function getPRStatusSummary(prStatus: PullRequestStatus): string { -+ const statusCount = prStatus.statuses.length || 0 -+ -+ if (statusCount === 0) { -+ return formatState(prStatus.state) -+ } -+ -+ if (statusCount === 1) { -+ return formatSingleStatus(prStatus.statuses[0]) -+ } -+ -+ const successCount = prStatus.statuses.filter(x => x.state === 'success') -+ .length -+ -+ return `${successCount}/${statusCount} checks OK` -+} -merged - result 100644 6965fcba858e40dc9bebce9bd3f18f369bde8ae3 app/src/ui/branches/pull-requests-loading.tsx - our 100644 55f55e50c3c466ac8f51c62622a11dae48b16ea1 app/src/ui/branches/pull-requests-loading.tsx -@@ -8,21 +8,13 @@ - - const FacadeCount = 6 - --/** -- * TS can't parse generic specialization in JSX, so we have to alias it here -- * with the generic type. See https://github.com/Microsoft/TypeScript/issues/6395. -- */ --const PullRequestsLoadingList: new () => FilterList< -- IFilterListItem --> = FilterList as any -- - const prLoadingItemProps: IPullRequestListItemProps = { - loading: true, - author: '', - created: new Date(0), - number: 0, - title: '', -- matches: [], -+ matches: { title: [], subtitle: [] }, - status: { - sha: '4b825dc642cb6eb9a060e54bf8d69288fbee4904', - totalCount: 1, -@@ -38,7 +30,7 @@ - const items: Array = [] - for (let i = 0; i < FacadeCount; i++) { - items.push({ -- text: '', -+ text: [''], - id: i.toString(), - }) - } -@@ -51,7 +43,7 @@ - ] - - return ( -- - className="pull-request-list" - rowHeight={RowHeight} - groups={groups} -merged - result 100644 5e20b50a00f1033a845d4faf66cd584088157811 app/src/ui/changes/changed-file.tsx - our 100644 3bb750a806ac20d6733638b383d80bd8dc9719b6 app/src/ui/changes/changed-file.tsx -@@ -17,7 +17,7 @@ - readonly onContextMenu: ( - path: string, - status: AppFileStatus, -- event: React.MouseEvent -+ event: React.MouseEvent - ) => void - } - -merged - result 100644 e92f60ef1e0ceb5edca52df2ec9a0ba4f404eee8 app/src/ui/changes/changes-list.tsx - our 100644 0519a49d3e52c4ce4be705f752ca036f6160faf6 app/src/ui/changes/changes-list.tsx -@@ -1,39 +1,44 @@ - import * as React from 'react' - import * as Path from 'path' - --import { CommitMessage } from './commit-message' --import { ChangedFile } from './changed-file' --import { List, ClickSource } from '../lib/list' -+import { ICommitMessage } from '../../lib/app-state' -+import { IGitHubUser } from '../../lib/databases' -+import { Dispatcher } from '../../lib/dispatcher' -+import { ITrailer } from '../../lib/git/interpret-trailers' -+import { IMenuItem } from '../../lib/menu-item' -+import { revealInFileManager } from '../../lib/app-shell' - import { -+ AppFileStatus, - WorkingDirectoryStatus, - WorkingDirectoryFileChange, -- AppFileStatus, - } from '../../models/status' - import { DiffSelectionType } from '../../models/diff' - import { CommitIdentity } from '../../models/commit-identity' -+import { Repository } from '../../models/repository' -+import { IAuthor } from '../../models/author' -+import { List, ClickSource } from '../lib/list' - import { Checkbox, CheckboxValue } from '../lib/checkbox' --import { ICommitMessage } from '../../lib/app-state' --import { IGitHubUser } from '../../lib/databases' --import { Dispatcher } from '../../lib/dispatcher' -+import { -+ isSafeFileExtension, -+ DefaultEditorLabel, -+ RevealInFileManagerLabel, -+ OpenWithDefaultProgramLabel, -+} from '../lib/context-menu' -+import { CommitMessage } from './commit-message' -+import { ChangedFile } from './changed-file' - import { IAutocompletionProvider } from '../autocompletion' --import { Repository } from '../../models/repository' - import { showContextualMenu } from '../main-process-proxy' --import { IAuthor } from '../../models/author' --import { ITrailer } from '../../lib/git/interpret-trailers' --import { IMenuItem } from '../../lib/menu-item' -+import { arrayEquals } from '../../lib/equality' - - const RowHeight = 29 --const RestrictedFileExtensions = ['.cmd', '.exe', '.bat', '.sh'] --const defaultEditorLabel = __DARWIN__ -- ? 'Open in External Editor' -- : 'Open in external editor' -+ - const GitIgnoreFileName = '.gitignore' - - interface IChangesListProps { - readonly repository: Repository - readonly workingDirectory: WorkingDirectoryStatus -- readonly selectedFileID: string | null -- readonly onFileSelectionChanged: (row: number) => void -+ readonly selectedFileIDs: string[] -+ readonly onFileSelectionChanged: (rows: ReadonlyArray) => void - readonly onIncludeChanged: (path: string, include: boolean) => void - readonly onSelectAll: (selectAll: boolean) => void - readonly onCreateCommit: ( -@@ -42,17 +47,12 @@ - trailers?: ReadonlyArray - ) => Promise - readonly onDiscardChanges: (file: WorkingDirectoryFileChange) => void -+ readonly askForConfirmationOnDiscardChanges: boolean - readonly onDiscardAllChanges: ( - files: ReadonlyArray - ) => void - - /** -- * Called to reveal a file in the native file manager. -- * @param path The path of the file relative to the root of the repository -- */ -- readonly onRevealInFileManager: (path: string) => void -- -- /** - * Called to open a file it its default application - * @param path The path of the file relative to the root of the repository - */ -@@ -69,7 +69,6 @@ - * List Props for documentation. - */ - readonly onRowClick?: (row: number, source: ClickSource) => void -- - readonly commitMessage: ICommitMessage | null - readonly contextualCommitMessage: ICommitMessage | null - -@@ -77,7 +76,7 @@ - readonly autocompletionProviders: ReadonlyArray> - - /** Called when the given pattern should be ignored. */ -- readonly onIgnore: (pattern: string) => void -+ readonly onIgnore: (pattern: string | string[]) => void - - /** - * Whether or not to show a field for adding co-authors to -@@ -98,13 +97,58 @@ - readonly externalEditorLabel?: string - - /** -- * Called to open a file using the user's configured applications -- * @param path The path of the file relative to the root of the repository -+ * Callback to open a selected file using the configured external editor -+ * -+ * @param fullPath The full path to the file on disk - */ -- readonly onOpenInExternalEditor: (path: string) => void -+ readonly onOpenInExternalEditor: (fullPath: string) => void - } - --export class ChangesList extends React.Component { -+interface IChangesState { -+ readonly selectedRows: ReadonlyArray -+} -+ -+function getSelectedRowsFromProps( -+ props: IChangesListProps -+): ReadonlyArray { -+ const selectedFileIDs = props.selectedFileIDs -+ const selectedRows = [] -+ -+ for (const id of selectedFileIDs) { -+ const ix = props.workingDirectory.findFileIndexByID(id) -+ if (ix !== -1) { -+ selectedRows.push(ix) -+ } -+ } -+ -+ return selectedRows -+} -+ -+export class ChangesList extends React.Component< -+ IChangesListProps, -+ IChangesState -+> { -+ public constructor(props: IChangesListProps) { -+ super(props) -+ this.state = { -+ selectedRows: getSelectedRowsFromProps(props), -+ } -+ } -+ -+ public componentWillReceiveProps(nextProps: IChangesListProps) { -+ // No need to update state unless we haven't done it yet or the -+ // selected file id list has changed. -+ if ( -+ !arrayEquals(nextProps.selectedFileIDs, this.props.selectedFileIDs) || -+ !arrayEquals( -+ nextProps.workingDirectory.files, -+ this.props.workingDirectory.files -+ ) -+ ) { -+ this.setState({ selectedRows: getSelectedRowsFromProps(nextProps) }) -+ } -+ } -+ - private onIncludeAllChanged = (event: React.FormEvent) => { - const include = event.currentTarget.checked - this.props.onSelectAll(include) -@@ -117,7 +161,9 @@ - const includeAll = - selection === DiffSelectionType.All - ? true -- : selection === DiffSelectionType.None ? false : null -+ : selection === DiffSelectionType.None -+ ? false -+ : null - - return ( - - ) - } -@@ -148,14 +194,43 @@ - this.props.onDiscardAllChanges(this.props.workingDirectory.files) - } - -- private onDiscardChanges = (path: string) => { -+ private onDiscardChanges = (files: ReadonlyArray) => { - const workingDirectory = this.props.workingDirectory -- const file = workingDirectory.files.find(f => f.path === path) -- if (!file) { -- return -+ -+ if (files.length === 1) { -+ const modifiedFile = workingDirectory.files.find(f => f.path === files[0]) -+ -+ if (modifiedFile != null) { -+ this.props.onDiscardChanges(modifiedFile) -+ } -+ } else { -+ const modifiedFiles = new Array() -+ -+ files.forEach(file => { -+ const modifiedFile = workingDirectory.files.find(f => f.path === file) -+ -+ if (modifiedFile != null) { -+ modifiedFiles.push(modifiedFile) -+ } -+ }) -+ -+ if (modifiedFiles.length > 0) { -+ this.props.onDiscardAllChanges(modifiedFiles) -+ } - } -+ } - -- this.props.onDiscardChanges(file) -+ private getDiscardChangesMenuItemLabel = (files: ReadonlyArray) => { -+ const label = -+ files.length === 1 -+ ? __DARWIN__ -+ ? `Discard Changes` -+ : `Discard changes` -+ : __DARWIN__ -+ ? `Discard ${files.length} Selected Changes` -+ : `Discard ${files.length} selected changes` -+ -+ return this.props.askForConfirmationOnDiscardChanges ? `${label}…` : label - } - - private onContextMenu = (event: React.MouseEvent) => { -@@ -175,64 +250,97 @@ - private onItemContextMenu = ( - path: string, - status: AppFileStatus, -- event: React.MouseEvent -+ event: React.MouseEvent - ) => { - event.preventDefault() - - const extension = Path.extname(path) -- const fileName = Path.basename(path) -- const isSafeExtension = __WIN32__ -- ? RestrictedFileExtensions.indexOf(extension.toLowerCase()) === -1 -- : true -- const revealInFileManagerLabel = __DARWIN__ -- ? 'Reveal in Finder' -- : __WIN32__ ? 'Show in Explorer' : 'Show in your File Manager' -+ const isSafeExtension = isSafeFileExtension(extension) - const openInExternalEditor = this.props.externalEditorLabel - ? `Open in ${this.props.externalEditorLabel}` -- : defaultEditorLabel -+ : DefaultEditorLabel -+ -+ const wd = this.props.workingDirectory -+ const selectedFiles = new Array() -+ const paths = new Array() -+ const extensions = new Set() -+ -+ this.props.selectedFileIDs.forEach(fileID => { -+ const newFile = wd.findFileWithID(fileID) -+ if (newFile) { -+ selectedFiles.push(newFile) -+ paths.push(newFile.path) -+ -+ const extension = Path.extname(newFile.path) -+ if (extension.length) { -+ extensions.add(extension) -+ } -+ } -+ }) -+ - const items: IMenuItem[] = [ - { -- label: __DARWIN__ ? 'Discard Changes…' : 'Discard changes…', -- action: () => this.onDiscardChanges(path), -+ label: this.getDiscardChangesMenuItemLabel(paths), -+ action: () => this.onDiscardChanges(paths), - }, - { - label: __DARWIN__ ? 'Discard All Changes…' : 'Discard all changes…', - action: () => this.onDiscardAllChanges(), - }, - { type: 'separator' }, -- { -- label: 'Ignore', -- action: () => this.props.onIgnore(path), -- enabled: fileName !== GitIgnoreFileName, -- }, - ] - -- if (extension.length) { -+ if (paths.length === 1) { -+ items.push({ -+ label: __DARWIN__ ? 'Ignore File' : 'Ignore file', -+ action: () => this.props.onIgnore(path), -+ enabled: Path.basename(path) !== GitIgnoreFileName, -+ }) -+ } else if (paths.length > 1) { - items.push({ -- label: __DARWIN__ -- ? `Ignore All ${extension} Files` -- : `Ignore all ${extension} files`, -- action: () => this.props.onIgnore(`*${extension}`), -- enabled: fileName !== GitIgnoreFileName, -+ label: `Ignore ${paths.length} selected files`, -+ action: () => { -+ // Filter out any .gitignores that happens to be selected, ignoring -+ // those doesn't make sense. -+ this.props.onIgnore( -+ paths.filter(path => Path.basename(path) !== GitIgnoreFileName) -+ ) -+ }, -+ // Enable this action as long as there's something selected which isn't -+ // a .gitignore file. -+ enabled: paths.some(path => Path.basename(path) !== GitIgnoreFileName), - }) - } - -+ // Five menu items should be enough for everyone -+ Array.from(extensions) -+ .slice(0, 5) -+ .forEach(extension => { -+ items.push({ -+ label: __DARWIN__ -+ ? `Ignore All ${extension} Files` -+ : `Ignore all ${extension} files`, -+ action: () => this.props.onIgnore(`*${extension}`), -+ }) -+ }) -+ - items.push( - { type: 'separator' }, - { -- label: revealInFileManagerLabel, -- action: () => this.props.onRevealInFileManager(path), -+ label: RevealInFileManagerLabel, -+ action: () => revealInFileManager(this.props.repository, path), - enabled: status !== AppFileStatus.Deleted, - }, - { - label: openInExternalEditor, -- action: () => this.props.onOpenInExternalEditor(path), -+ action: () => { -+ const fullPath = Path.join(this.props.repository.path, path) -+ this.props.onOpenInExternalEditor(fullPath) -+ }, - enabled: isSafeExtension && status !== AppFileStatus.Deleted, - }, - { -- label: __DARWIN__ -- ? 'Open with Default Program' -- : 'Open with default program', -+ label: OpenWithDefaultProgramLabel, - action: () => this.props.onOpenItem(path), - enabled: isSafeExtension && status !== AppFileStatus.Deleted, - } -@@ -243,9 +351,6 @@ - - public render() { - const fileList = this.props.workingDirectory.files -- const selectedRow = fileList.findIndex( -- file => file.id === this.props.selectedFileID -- ) - const fileCount = fileList.length - const filesPlural = fileCount === 1 ? 'file' : 'files' - const filesDescription = `${fileCount} changed ${filesPlural}` -@@ -268,7 +373,8 @@ - rowCount={this.props.workingDirectory.files.length} - rowHeight={RowHeight} - rowRenderer={this.renderRow} -- selectedRow={selectedRow} -+ selectedRows={this.state.selectedRows} -+ selectionMode="multi" - onSelectionChanged={this.props.onFileSelectionChanged} - invalidationProps={this.props.workingDirectory} - onRowClick={this.props.onRowClick} -merged - result 100644 0a0e18fc9f4c8956a648726827dc496f3d5f98db app/src/ui/changes/commit-message.tsx - our 100644 5ea583fb1898ce0a5637a81c7d29dfcf835f8309 app/src/ui/changes/commit-message.tsx -@@ -343,8 +343,12 @@ - - private get toggleCoAuthorsText(): string { - return this.props.showCoAuthoredBy -- ? __DARWIN__ ? 'Remove Co-Authors' : 'Remove co-authors' -- : __DARWIN__ ? 'Add Co-Authors' : 'Add co-authors' -+ ? __DARWIN__ -+ ? 'Remove Co-Authors' -+ : 'Remove co-authors' -+ : __DARWIN__ -+ ? 'Add Co-Authors' -+ : 'Add co-authors' - } - - private getAddRemoveCoAuthorsMenuItem(): IMenuItem { -@@ -491,8 +495,9 @@ - {this.renderAvatar()} - - { -+ public render() { -+ const filesChangedCount = this.props.filesChangedCount -+ const badgeCount = -+ filesChangedCount > MaximumChangesCount -+ ? `${MaximumChangesCount}+` -+ : filesChangedCount -+ -+ return {badgeCount} -+ } -+} -added in remote - their 100644 185bc1b81106f809ad63e79d4b3adf97946f68ce app/src/ui/changes/multiple-selection.tsx -@@ -0,0 +1,26 @@ -+import * as React from 'react' -+import { encodePathAsUrl } from '../../lib/path' -+ -+const BlankSlateImage = encodePathAsUrl( -+ __dirname, -+ 'static/multiple-files-selected.svg' -+) -+ -+interface IMultipleSelectionProps { -+ /** Called when the user chooses to open the repository. */ -+ readonly count: number -+} -+/** The component to display when there are no local changes. */ -+export class MultipleSelection extends React.Component< -+ IMultipleSelectionProps, -+ {} -+> { -+ public render() { -+ return ( -+
-+ -+
{this.props.count} files selected
-+
-+ ) -+ } -+} -merged - result 100644 090ffa423a170c926a8b7fdcd04748ff3bd2d416 app/src/ui/changes/no-changes.tsx - our 100644 0184f2d912257317c527a0b019d070ee191f17c4 app/src/ui/changes/no-changes.tsx -@@ -1,6 +1,9 @@ - import * as React from 'react' --import { LinkButton } from '../lib/link-button' -+ - import { encodePathAsUrl } from '../../lib/path' -+import { revealInFileManager } from '../../lib/app-shell' -+import { Repository } from '../../models/repository' -+import { LinkButton } from '../lib/link-button' - - const BlankSlateImage = encodePathAsUrl( - __dirname, -@@ -8,8 +11,7 @@ - ) - - interface INoChangesProps { -- /** Called when the user chooses to open the repository. */ -- readonly onOpenRepository: () => void -+ readonly repository: Repository - } - - /** The component to display when there are no local changes. */ -@@ -17,7 +19,9 @@ - public render() { - const opener = __DARWIN__ - ? 'Finder' -- : __WIN32__ ? 'Explorer' : 'your File Manager' -+ : __WIN32__ -+ ? 'Explorer' -+ : 'your File Manager' - return ( -
- -@@ -33,6 +37,6 @@ - } - - private open = () => { -- this.props.onOpenRepository() -+ revealInFileManager(this.props.repository, '') - } - } -merged - result 100644 ff1760bbd4b1a3d5ea8ac084b1282e99b2ea288b app/src/ui/changes/sidebar.tsx - our 100644 c6fc23660a5320772101aa310315dc9bca822d5c app/src/ui/changes/sidebar.tsx -@@ -52,10 +52,11 @@ - readonly externalEditorLabel?: string - - /** -- * Called to open a file using the user's configured applications -- * @param path The path of the file relative to the root of the repository -+ * Callback to open a selected file using the configured external editor -+ * -+ * @param fullPath The full path to the file on disk - */ -- readonly onOpenInExternalEditor: (path: string) => void -+ readonly onOpenInExternalEditor: (fullPath: string) => void - } - - export class ChangesSidebar extends React.Component { -@@ -124,9 +125,9 @@ - ) - } - -- private onFileSelectionChanged = (row: number) => { -- const file = this.props.changes.workingDirectory.files[row] -- this.props.dispatcher.changeChangesSelection(this.props.repository, file) -+ private onFileSelectionChanged = (rows: ReadonlyArray) => { -+ const files = rows.map(i => this.props.changes.workingDirectory.files[i]) -+ this.props.dispatcher.changeChangesSelection(this.props.repository, files) - } - - private onIncludeChanged = (path: string, include: boolean) => { -@@ -169,30 +170,19 @@ - private onDiscardAllChanges = ( - files: ReadonlyArray - ) => { -- if (!this.props.askForConfirmationOnDiscardChanges) { -- this.props.dispatcher.discardChanges(this.props.repository, files) -- } else { -- this.props.dispatcher.showPopup({ -- type: PopupType.ConfirmDiscardChanges, -- repository: this.props.repository, -- files, -- }) -- } -+ this.props.dispatcher.showPopup({ -+ type: PopupType.ConfirmDiscardChanges, -+ repository: this.props.repository, -+ showDiscardChangesSetting: false, -+ files, -+ }) - } - -- private onIgnore = (pattern: string) => { -+ private onIgnore = (pattern: string | string[]) => { - this.props.dispatcher.ignore(this.props.repository, pattern) - } - - /** -- * Reveals a file from a repository in the native file manager. -- * @param path The path of the file relative to the root of the repository -- */ -- private onRevealInFileManager = (path: string) => { -- this.props.dispatcher.revealInFileManager(this.props.repository, path) -- } -- -- /** - * Open file with default application. - * @param path The path of the file relative to the root of the repository - */ -@@ -229,11 +219,18 @@ - * Handles click events from the List item container, note that this is - * Not the same thing as the element returned by the row renderer in ChangesList - */ -- private onChangedItemClick = (row: number, source: ClickSource) => { -+ private onChangedItemClick = ( -+ rows: number | number[], -+ source: ClickSource -+ ) => { - // Toggle selection when user presses the spacebar or enter while focused -- // on a list item -+ // on a list item or on the list's container - if (source.kind === 'keyboard') { -- this.onToggleInclude(row) -+ if (rows instanceof Array) { -+ rows.forEach(row => this.onToggleInclude(row)) -+ } else { -+ this.onToggleInclude(rows) -+ } - } - } - -@@ -274,7 +271,7 @@ - - public render() { - const changesState = this.props.changes -- const selectedFileID = changesState.selectedFileID -+ const selectedFileIDs = changesState.selectedFileIDs - - // TODO: I think user will expect the avatar to match that which - // they have configured in GitHub.com as well as GHE so when we add -@@ -292,14 +289,16 @@ - dispatcher={this.props.dispatcher} - repository={this.props.repository} - workingDirectory={changesState.workingDirectory} -- selectedFileID={selectedFileID} -+ selectedFileIDs={selectedFileIDs} - onFileSelectionChanged={this.onFileSelectionChanged} - onCreateCommit={this.onCreateCommit} - onIncludeChanged={this.onIncludeChanged} - onSelectAll={this.onSelectAll} - onDiscardChanges={this.onDiscardChanges} -+ askForConfirmationOnDiscardChanges={ -+ this.props.askForConfirmationOnDiscardChanges -+ } - onDiscardAllChanges={this.onDiscardAllChanges} -- onRevealInFileManager={this.onRevealInFileManager} - onOpenItem={this.onOpenItem} - onRowClick={this.onChangedItemClick} - commitAuthor={this.props.commitAuthor} -merged - result 100644 81bb2d3dc71f42c419af98460238b7063d80badd app/src/ui/clone-repository/clone-github-repository.tsx - our 100644 e546634cdd499994bb68f6f3ed1d56e956b4bc45 app/src/ui/clone-repository/clone-github-repository.tsx -@@ -10,6 +10,7 @@ - import { FilterList } from '../lib/filter-list' - import { API } from '../../lib/api' - import { IFilterListGroup } from '../lib/filter-list' -+import { IMatches } from '../../lib/fuzzy-find' - import { - ICloneableRepositoryListItem, - groupRepositories, -@@ -204,13 +205,13 @@ - - private renderItem = ( - item: ICloneableRepositoryListItem, -- matches: ReadonlyArray -+ matches: IMatches - ) => { - return ( -
- --
-- -+
-+ -
-
- ) -merged - result 100644 e8132c67eee073fe0faec333fa15a273e811d960 app/src/ui/clone-repository/clone-repository.tsx - our 100644 b4e9cbd7caed04fee894293ace81b6f332f1b6ea app/src/ui/clone-repository/clone-repository.tsx -@@ -1,6 +1,8 @@ - import * as Path from 'path' - import * as React from 'react' - import { remote } from 'electron' -+import { pathExists } from 'fs-extra' -+ - import { Button } from '../lib/button' - import { ButtonGroup } from '../lib/button-group' - import { Dispatcher } from '../../lib/dispatcher' -@@ -17,7 +19,7 @@ - import { CloneRepositoryTab } from '../../models/clone-repository-tab' - import { CloneGenericRepository } from './clone-generic-repository' - import { CloneGithubRepository } from './clone-github-repository' --import { pathExists } from '../../lib/file-system' -+ - import { assertNever } from '../../lib/fatal-error' - import { CallToAction } from '../lib/call-to-action' - -merged - result 100644 b7412f2d5dd94cba15f7a987e719915969a75f6e app/src/ui/clone-repository/group-repositories.ts - our 100644 d14189ae128a22845dc39ec28b62ae2e108a42ba app/src/ui/clone-repository/group-repositories.ts -@@ -11,7 +11,7 @@ - readonly id: string - - /** The search text. */ -- readonly text: string -+ readonly text: ReadonlyArray - - /** The name of the repository. */ - readonly name: string -@@ -43,7 +43,7 @@ - - return { - id: repo.html_url, -- text: `${repo.owner.login}/${repo.name}`, -+ text: [`${repo.owner.login}/${repo.name}`], - url: repo.clone_url, - name: repo.name, - icon, -merged - result 100644 9f7be035e77bad03025c737279092ba7598a0816 app/src/ui/diff/binary-file.tsx - our 100644 81c0dcd6e5fe3e4fd3fec3e5a8dcdff5b3167656 app/src/ui/diff/binary-file.tsx -@@ -5,6 +5,8 @@ - import { openFile } from '../../lib/open-file' - import { Dispatcher } from '../../lib/dispatcher/dispatcher' - -+import { LinkButton } from '../lib/link-button' -+ - interface IBinaryFileProps { - readonly repository: Repository - readonly path: string -@@ -13,7 +15,7 @@ - - /** represents the default view for a file that we cannot render a diff for */ - export class BinaryFile extends React.Component { -- private handleClick = (e: React.MouseEvent) => { -+ private open = () => { - const fullPath = Path.join(this.props.repository.path, this.props.path) - openFile(fullPath, this.props.dispatcher) - } -@@ -23,9 +25,9 @@ -
-
This binary file has changed.
- -
- ) -merged - result 100644 dc40c8309be3d5fb88ce7c549d18e0a218138062 app/src/ui/diff/diff-explorer.ts - our 100644 3ee24b252827ef7e376d781a6925ef1d1bf00a40 app/src/ui/diff/diff-explorer.ts -@@ -1,13 +1,13 @@ --import { DiffLine, DiffHunk, ITextDiff } from '../../models/diff' -+import { DiffLine, DiffHunk } from '../../models/diff' - - /** - * Locate the diff hunk for the given (absolute) line number in the diff. - */ - export function diffHunkForIndex( -- diff: ITextDiff, -+ hunks: ReadonlyArray, - index: number - ): DiffHunk | null { -- const hunk = diff.hunks.find(h => { -+ const hunk = hunks.find(h => { - return index >= h.unifiedDiffStart && index <= h.unifiedDiffEnd - }) - return hunk || null -@@ -17,10 +17,10 @@ - * Locate the diff line for the given (absolute) line number in the diff. - */ - export function diffLineForIndex( -- diff: ITextDiff, -+ hunks: ReadonlyArray, - index: number - ): DiffLine | null { -- const hunk = diffHunkForIndex(diff, index) -+ const hunk = diffHunkForIndex(hunks, index) - if (!hunk) { - return null - } -@@ -31,10 +31,10 @@ - /** Get the line number as represented in the diff text itself. */ - export function lineNumberForDiffLine( - diffLine: DiffLine, -- diff: ITextDiff -+ hunks: ReadonlyArray - ): number { - let lineOffset = 0 -- for (const hunk of diff.hunks) { -+ for (const hunk of hunks) { - const index = hunk.lines.indexOf(diffLine) - if (index > -1) { - return index + lineOffset -@@ -51,10 +51,10 @@ - * should be displayed as interactive, as a hunk is not granular enough - */ - export function findInteractiveDiffRange( -- diff: ITextDiff, -+ hunks: ReadonlyArray, - index: number - ): { start: number; end: number } | null { -- const hunk = diffHunkForIndex(diff, index) -+ const hunk = diffHunkForIndex(hunks, index) - if (!hunk) { - return null - } -merged - result 100644 fc770e214454b6980005a0f84ae50a9a1ca5d322 app/src/ui/diff/diff-line-gutter.tsx - our 100644 352915a1f60aafefce6fe604e3b32b325148ae69 app/src/ui/diff/diff-line-gutter.tsx -@@ -1,5 +1,5 @@ - import * as React from 'react' --import { ITextDiff, DiffLine, DiffLineType } from '../../models/diff' -+import { DiffHunk, DiffLine, DiffLineType } from '../../models/diff' - import { diffHunkForIndex, findInteractiveDiffRange } from './diff-explorer' - import { hoverCssClass, selectedLineClass } from './selection/selection' - import { assertNever } from '../../lib/fatal-error' -@@ -30,7 +30,7 @@ - /** - * The diff currently displayed in the app - */ -- readonly diff: ITextDiff -+ readonly hunks: ReadonlyArray - - /** - * Callback to apply hover effect to specific lines in the diff -@@ -55,7 +55,7 @@ - */ - readonly onMouseDown: ( - index: number, -- diff: ITextDiff, -+ hunks: ReadonlyArray, - isRangeSelection: boolean - ) => void - -@@ -183,7 +183,7 @@ - - private updateHoverState(isRangeSelection: boolean, isActive: boolean) { - if (isRangeSelection) { -- const range = findInteractiveDiffRange(this.props.diff, this.props.index) -+ const range = findInteractiveDiffRange(this.props.hunks, this.props.index) - if (!range) { - console.error('unable to find range for given index in diff') - return -@@ -210,7 +210,7 @@ - private mouseMoveHandler = (ev: MouseEvent) => { - ev.preventDefault() - -- const hunk = diffHunkForIndex(this.props.diff, this.props.index) -+ const hunk = diffHunkForIndex(this.props.hunks, this.props.index) - if (!hunk) { - console.error('unable to find hunk for given line in diff') - return -@@ -219,7 +219,7 @@ - const isRangeSelection = isMouseCursorNearEdge(ev) - const isSelectionActive = this.props.isSelectionEnabled() - -- const range = findInteractiveDiffRange(this.props.diff, this.props.index) -+ const range = findInteractiveDiffRange(this.props.hunks, this.props.index) - if (!range) { - console.error('unable to find range for given index in diff') - return -@@ -241,7 +241,7 @@ - private mouseDownHandler = (ev: MouseEvent) => { - ev.preventDefault() - const isRangeSelection = isMouseCursorNearEdge(ev) -- this.props.onMouseDown(this.props.index, this.props.diff, isRangeSelection) -+ this.props.onMouseDown(this.props.index, this.props.hunks, isRangeSelection) - } - - private applyEventHandlers = (elem: HTMLSpanElement | null) => { -merged - result 100644 f36e0e4c22d67391c497dcea94021c47fbbc6a61 app/src/ui/diff/diff-syntax-mode.ts - our 100644 d4f02e6c2ed4f9295eef2dbf64aba1c0ec9cfc74 app/src/ui/diff/diff-syntax-mode.ts -@@ -1,4 +1,4 @@ --import { ITextDiff, DiffLine } from '../../models/diff' -+import { DiffHunk, DiffLine } from '../../models/diff' - import * as CodeMirror from 'codemirror' - import { diffLineForIndex } from './diff-explorer' - import { ITokens } from '../../lib/highlighter/types' -@@ -9,7 +9,7 @@ - /** - * The unified diff representing the change - */ -- readonly diff: ITextDiff -+ readonly hunks: ReadonlyArray - - /** - * Tokens returned from the highlighter for the 'before' -@@ -80,16 +80,16 @@ - export class DiffSyntaxMode { - public static readonly ModeName = 'github-diff-syntax' - -- private readonly diff?: ITextDiff -+ private readonly hunks?: ReadonlyArray - private readonly oldTokens?: ITokens - private readonly newTokens?: ITokens - - public constructor( -- diff?: ITextDiff, -+ hunks?: ReadonlyArray, - oldTokens?: ITokens, - newTokens?: ITokens - ) { -- this.diff = diff -+ this.hunks = hunks - this.oldTokens = oldTokens - this.newTokens = newTokens - } -@@ -125,11 +125,11 @@ - // This happens when the mode is running without tokens, in this - // case there's really nothing more for us to do than what we've - // already done above to deal with the diff line marker. -- if (!this.diff) { -+ if (this.hunks == null) { - return skipLine(stream, state) - } - -- const diffLine = diffLineForIndex(this.diff, state.diffLineIndex) -+ const diffLine = diffLineForIndex(this.hunks, state.diffLineIndex) - - if (!diffLine) { - return skipLine(stream, state) -@@ -181,7 +181,7 @@ - } - - return new DiffSyntaxMode( -- modeOptions.diff, -+ modeOptions.hunks, - modeOptions.oldTokens, - modeOptions.newTokens - ) -merged - result 100644 7c53bfbb331587afae9c40fa77ad4a1849862f53 app/src/ui/diff/image-diffs/deleted-image-diff.tsx - our 100644 100c204b222ee1c211c495cf5774d61af6e9a9f1 app/src/ui/diff/image-diffs/deleted-image-diff.tsx -@@ -1,7 +1,7 @@ - import * as React from 'react' - - import { Image } from '../../../models/diff' --import { DiffImage } from './diff-image' -+import { ImageContainer } from './image-container' - - interface IDeletedImageDiffProps { - readonly previous: Image -@@ -17,7 +17,7 @@ -
-
-
Deleted
-- -+ -
-
- ) -removed in remote - base 100644 67ff04efa95b3fe39f2e6d791501325575a01dda app/src/ui/diff/image-diffs/diff-image.tsx - our 100644 67ff04efa95b3fe39f2e6d791501325575a01dda app/src/ui/diff/image-diffs/diff-image.tsx -@@ -1,28 +0,0 @@ --import * as React from 'react' -- --import { Image } from '../../../models/diff' -- --interface IImageProps { -- readonly image: Image -- -- readonly style?: React.CSSProperties -- -- readonly onElementLoad?: (img: HTMLImageElement) => void --} -- --export class DiffImage extends React.Component { -- public render() { -- const image = this.props.image -- const imageSource = `data:${image.mediaType};base64,${image.contents}` -- -- return ( -- -- ) -- } -- -- private onLoad = (e: React.SyntheticEvent) => { -- if (this.props.onElementLoad) { -- this.props.onElementLoad(e.currentTarget) -- } -- } --} -merged - result 100644 a5bf0078cc777a1299e2fd0a994ea22e7f4e2ee4 app/src/ui/diff/image-diffs/difference-blend.tsx - our 100644 a2e1e7a2bd40cd3103502b06e735ac8d0e05be7a app/src/ui/diff/image-diffs/difference-blend.tsx -@@ -1,5 +1,5 @@ - import * as React from 'react' --import { DiffImage } from './diff-image' -+import { ImageContainer } from './image-container' - import { ICommonImageDiffProperties } from './modified-image-diff' - - export class DifferenceBlend extends React.Component< -@@ -22,7 +22,7 @@ -
-
-
-- - -
-- void -+} -+ -+export class ImageContainer extends React.Component { -+ public render() { -+ const image = this.props.image -+ const imageSource = `data:${image.mediaType};base64,${image.contents}` -+ -+ return ( -+ -+ ) -+ } -+ -+ private onLoad = (e: React.SyntheticEvent) => { -+ if (this.props.onElementLoad) { -+ this.props.onElementLoad(e.currentTarget) -+ } -+ } -+} -merged - result 100644 72df75e401ac62f8a6dd1db8febe5c703e2719f4 app/src/ui/diff/image-diffs/new-image-diff.tsx - our 100644 2f089e3cea9dc0357a79e44e705e11b5f56ff5b3 app/src/ui/diff/image-diffs/new-image-diff.tsx -@@ -1,7 +1,7 @@ - import * as React from 'react' - - import { Image } from '../../../models/diff' --import { DiffImage } from './diff-image' -+import { ImageContainer } from './image-container' - - interface INewImageDiffProps { - readonly current: Image -@@ -14,7 +14,7 @@ -
-
-
Added
-- -+ -
-
- ) -merged - result 100644 4e23bc6c3f0c1317cb751c3767325753b2e108ba app/src/ui/diff/image-diffs/onion-skin.tsx - our 100644 fd55c2e19b5edb2849cf28c270f109f2c5e29b6a app/src/ui/diff/image-diffs/onion-skin.tsx -@@ -1,6 +1,6 @@ - import * as React from 'react' - import { ICommonImageDiffProperties } from './modified-image-diff' --import { DiffImage } from './diff-image' -+import { ImageContainer } from './image-container' - - interface IOnionSkinState { - readonly crossfade: number -@@ -32,7 +32,7 @@ -
-
-
-- -- -
-
-- -
-- { -+ const diff = Math.round((100 * (current - previous)) / previous) -+ const sign = diff > 0 ? '+' : '' -+ return sign + diff + '%' -+ } - - const zeroSize = { width: 0, height: 0 } - const previousImageSize = this.props.previousImageSize || zeroSize - const currentImageSize = this.props.currentImageSize || zeroSize -+ const diffPercent = percentDiff( -+ this.props.previous.bytes, -+ this.props.current.bytes -+ ) -+ const diffBytes = this.props.current.bytes - this.props.previous.bytes - - return ( --
--
--
Deleted
-- -+
-+
-+
-+
Deleted
-+ - --
-- W: {previousImageSize.width}px |{' '} -- H: {previousImageSize.height}px -+
-+ W: {previousImageSize.width}px |{' '} -+ H: {previousImageSize.height}px |{' '} -+ Size:{' '} -+ {formatBytes(this.props.previous.bytes)} -+
-
--
- --
--
Added
-- -+
-+
Added
-+ - --
-- W: {currentImageSize.width}px |{' '} -- H: {currentImageSize.height}px -+
-+ W: {currentImageSize.width}px |{' '} -+ H: {currentImageSize.height}px |{' '} -+ Size:{' '} -+ {formatBytes(this.props.current.bytes)} -+
-
-
-+
-+ Diff:{' '} -+ 0, -+ removed: diffBytes < 0, -+ })} -+ > -+ {diffBytes !== 0 -+ ? `${formatBytes(diffBytes, Sign.Forced)} (${diffPercent})` -+ : 'No size difference'} -+ -+
-
- ) - } -merged - result 100644 8695c640dc0a5184c74a112f131a2e2a07ef572d app/src/ui/diff/index.tsx - our 100644 4c035cd8232f41eb5911c3407db12ac26112844d app/src/ui/diff/index.tsx -@@ -1,22 +1,12 @@ --import { clipboard } from 'electron' - import * as React from 'react' --import * as ReactDOM from 'react-dom' --import * as Path from 'path' --import { Disposable } from 'event-kit' -+import { Editor } from 'codemirror' - - import { assertNever } from '../../lib/fatal-error' --import { -- NewImageDiff, -- ModifiedImageDiff, -- DeletedImageDiff, --} from './image-diffs' --import { BinaryFile } from './binary-file' -- --import { Editor } from 'codemirror' --import { CodeMirrorHost } from './code-mirror-host' --import { Repository } from '../../models/repository' - import { encodePathAsUrl } from '../../lib/path' - import { ImageDiffType } from '../../lib/app-state' -+import { Dispatcher } from '../../lib/dispatcher/dispatcher' -+ -+import { Repository } from '../../models/repository' - import { - CommittedFileChange, - WorkingDirectoryFileChange, -@@ -28,257 +18,29 @@ - IDiff, - IImageDiff, - ITextDiff, -- DiffLine, -- DiffLineType, - ILargeTextDiff, - } from '../../models/diff' --import { Dispatcher } from '../../lib/dispatcher/dispatcher' -- --import { -- diffLineForIndex, -- diffHunkForIndex, -- findInteractiveDiffRange, -- lineNumberForDiffLine, --} from './diff-explorer' --import { DiffLineGutter } from './diff-line-gutter' --import { IEditorConfigurationExtra } from './editor-configuration-extra' --import { ISelectionStrategy } from './selection/selection-strategy' --import { DragDropSelection } from './selection/drag-drop-selection-strategy' --import { RangeSelection } from './selection/range-selection-strategy' --import { Octicon, OcticonSymbol } from '../octicons' -- --import { fatalError } from '../../lib/fatal-error' - --import { RangeSelectionSizePixels } from './edge-detection' --import { relativeChanges } from './changed-range' --import { getPartialBlobContents } from '../../lib/git/show' --import { readPartialFile } from '../../lib/file-system' -- --import { DiffSyntaxMode, IDiffSyntaxModeSpec } from './diff-syntax-mode' --import { highlight } from '../../lib/highlighter/worker' --import { ITokens } from '../../lib/highlighter/types' - import { Button } from '../lib/button' - --/** The longest line for which we'd try to calculate a line diff. */ --const MaxIntraLineDiffStringLength = 4096 -- --/** The maximum number of bytes we'll process for highlighting. */ --const MaxHighlightContentLength = 256 * 1024 -+import { -+ NewImageDiff, -+ ModifiedImageDiff, -+ DeletedImageDiff, -+} from './image-diffs' -+import { BinaryFile } from './binary-file' -+import { diffLineForIndex } from './diff-explorer' -+import { DiffLineGutter } from './diff-line-gutter' -+import { DiffSyntaxMode } from './diff-syntax-mode' - --// This is a custom version of the no-newline octicon that's exactly as --// tall as it needs to be (8px) which helps with aligning it on the line. --const narrowNoNewlineSymbol = new OcticonSymbol( -- 16, -- 8, -- 'm 16,1 0,3 c 0,0.55 -0.45,1 -1,1 l -3,0 0,2 -3,-3 3,-3 0,2 2,0 0,-2 2,0 z M 8,4 C 8,6.2 6.2,8 4,8 1.8,8 0,6.2 0,4 0,1.8 1.8,0 4,0 6.2,0 8,1.8 8,4 Z M 1.5,5.66 5.66,1.5 C 5.18,1.19 4.61,1 4,1 2.34,1 1,2.34 1,4 1,4.61 1.19,5.17 1.5,5.66 Z M 7,4 C 7,3.39 6.81,2.83 6.5,2.34 L 2.34,6.5 C 2.82,6.81 3.39,7 4,7 5.66,7 7,5.66 7,4 Z' --) -+import { ISelectionStrategy } from './selection/selection-strategy' -+import { TextDiff } from './text-diff' - - // image used when no diff is displayed - const NoDiffImage = encodePathAsUrl(__dirname, 'static/ufo-alert.svg') - - type ChangedFile = WorkingDirectoryFileChange | CommittedFileChange - --interface ILineFilters { -- readonly oldLineFilter: Array -- readonly newLineFilter: Array --} -- --interface IFileContents { -- readonly file: ChangedFile -- readonly oldContents: Buffer -- readonly newContents: Buffer --} -- --interface IFileTokens { -- readonly oldTokens: ITokens -- readonly newTokens: ITokens --} -- --async function getOldFileContent( -- repository: Repository, -- file: ChangedFile --): Promise { -- if (file.status === AppFileStatus.New) { -- return new Buffer(0) -- } -- -- let commitish -- -- if (file instanceof WorkingDirectoryFileChange) { -- // If we pass an empty string here we get the contents -- // that are in the index. But since we call diff with -- // --no-index (see diff.ts) we need to look at what's -- // actually committed to get the appropriate content. -- commitish = 'HEAD' -- } else if (file instanceof CommittedFileChange) { -- commitish = `${file.commitish}^` -- } else { -- return assertNever(file, 'Unknown file change type') -- } -- -- return getPartialBlobContents( -- repository, -- commitish, -- file.oldPath || file.path, -- MaxHighlightContentLength -- ) --} -- --async function getNewFileContent( -- repository: Repository, -- file: ChangedFile --): Promise { -- if (file.status === AppFileStatus.Deleted) { -- return new Buffer(0) -- } -- -- if (file instanceof WorkingDirectoryFileChange) { -- return readPartialFile( -- Path.join(repository.path, file.path), -- 0, -- MaxHighlightContentLength - 1 -- ) -- } else if (file instanceof CommittedFileChange) { -- return getPartialBlobContents( -- repository, -- file.commitish, -- file.path, -- MaxHighlightContentLength -- ) -- } -- -- return assertNever(file, 'Unknown file change type') --} -- --async function getFileContents( -- repo: Repository, -- file: ChangedFile, -- lineFilters: ILineFilters --): Promise { -- const oldContentsPromise = lineFilters.oldLineFilter.length -- ? getOldFileContent(repo, file) -- : Promise.resolve(new Buffer(0)) -- -- const newContentsPromise = lineFilters.newLineFilter.length -- ? getNewFileContent(repo, file) -- : Promise.resolve(new Buffer(0)) -- -- const [oldContents, newContents] = await Promise.all([ -- oldContentsPromise.catch(e => { -- log.error('Could not load old contents for syntax highlighting', e) -- return new Buffer(0) -- }), -- newContentsPromise.catch(e => { -- log.error('Could not load new contents for syntax highlighting', e) -- return new Buffer(0) -- }), -- ]) -- -- return { file, oldContents, newContents } --} -- --/** -- * Figure out which lines we need to have tokenized in -- * both the old and new version of the file. -- */ --function getLineFilters(diff: ITextDiff): ILineFilters { -- const oldLineFilter = new Array() -- const newLineFilter = new Array() -- -- const diffLines = new Array() -- -- let anyAdded = false -- let anyDeleted = false -- -- for (const hunk of diff.hunks) { -- for (const line of hunk.lines) { -- anyAdded = anyAdded || line.type === DiffLineType.Add -- anyDeleted = anyDeleted || line.type === DiffLineType.Delete -- diffLines.push(line) -- } -- } -- -- for (const line of diffLines) { -- // So this might need a little explaining. What we're trying -- // to achieve here is if the diff contains only additions or -- // only deletions we'll source all the highlighted lines from -- // either the before or after file. That way we can completely -- // disregard loading, and highlighting, the other version. -- if (line.oldLineNumber !== null && line.newLineNumber !== null) { -- if (anyAdded && !anyDeleted) { -- newLineFilter.push(line.newLineNumber - 1) -- } else { -- oldLineFilter.push(line.oldLineNumber - 1) -- } -- } else { -- // If there's a mix (meaning we'll have to read from both -- // anyway) we'll prioritize the old version since -- // that's immutable and less likely to be the subject of a -- // race condition when someone rapidly modifies the file on -- // disk. -- if (line.oldLineNumber !== null) { -- oldLineFilter.push(line.oldLineNumber - 1) -- } else if (line.newLineNumber !== null) { -- newLineFilter.push(line.newLineNumber - 1) -- } -- } -- } -- -- return { oldLineFilter, newLineFilter } --} -- --async function highlightContents( -- contents: IFileContents, -- tabSize: number, -- lineFilters: ILineFilters --): Promise { -- const { file, oldContents, newContents } = contents -- -- const [oldTokens, newTokens] = await Promise.all([ -- highlight( -- oldContents.toString('utf8'), -- Path.extname(file.oldPath || file.path), -- tabSize, -- lineFilters.oldLineFilter -- ).catch(e => { -- log.error('Highlighter worked failed for old contents', e) -- return {} -- }), -- highlight( -- newContents.toString('utf8'), -- Path.extname(file.path), -- tabSize, -- lineFilters.newLineFilter -- ).catch(e => { -- log.error('Highlighter worked failed for new contents', e) -- return {} -- }), -- ]) -- -- return { oldTokens, newTokens } --} -- --/** -- * Checks to see if any key parameters in the props object that are used -- * when performing highlighting has changed. This is used to determine -- * whether highlighting should abort in between asynchronous operations -- * due to some factor (like which file is currently selected) have changed -- * and thus rendering the in-flight highlighting data useless. -- */ --function highlightParametersEqual(newProps: IDiffProps, prevProps: IDiffProps) { -- if (newProps === prevProps) { -- return true -- } -- -- return ( -- newProps.file.path === prevProps.file.path && -- newProps.file.oldPath === prevProps.file.oldPath && -- newProps.diff.kind === DiffType.Text && -- prevProps.diff.kind === DiffType.Text && -- newProps.diff.text === prevProps.diff.text -- ) --} -- - /** The props for the Diff component. */ - interface IDiffProps { - readonly repository: Repository -@@ -313,21 +75,6 @@ - /** A component which renders a diff for a file. */ - export class Diff extends React.Component { - private codeMirror: Editor | null = null -- private gutterWidth: number | null = null -- -- /** -- * We store the scroll position before reloading the same diff so that we can -- * restore it when we're done. If we're not reloading the same diff, this'll -- * be null. -- */ -- private scrollPositionToRestore: { left: number; top: number } | null = null -- -- /** -- * A mapping from CodeMirror line handles to disposables which, when disposed -- * cleans up any line gutter components and events associated with that line. -- * See renderLine for more information. -- */ -- private readonly lineCleanup = new Map() - - /** - * Maintain the current state of the user interacting with the diff gutter -@@ -348,27 +95,7 @@ - } - - public componentWillReceiveProps(nextProps: IDiffProps) { -- // If we're reloading the same file, we want to save the current scroll -- // position and restore it after the diff's been updated. -- const sameFile = -- nextProps.file && -- this.props.file && -- nextProps.file.id === this.props.file.id -- -- // Happy path, if the text hasn't changed we won't re-render -- // and subsequently won't have to restore the scroll position. -- const textHasChanged = nextProps.diff !== this.props.diff -- - const codeMirror = this.codeMirror -- if (codeMirror && sameFile && textHasChanged) { -- const scrollInfo = codeMirror.getScrollInfo() -- this.scrollPositionToRestore = { -- left: scrollInfo.left, -- top: scrollInfo.top, -- } -- } else { -- this.scrollPositionToRestore = null -- } - - if ( - codeMirror && -@@ -394,8 +121,6 @@ - return - } - -- this.gutterWidth = null -- - const diff = nextProps.diff - this.cachedGutterElements.forEach((element, index) => { - if (!element) { -@@ -404,7 +129,7 @@ - } - - if (diff.kind === DiffType.Text) { -- const line = diffLineForIndex(diff, index) -+ const line = diffLineForIndex(diff.hunks, index) - const isIncludable = line ? line.isIncludeableLine() : false - const isSelected = selection.isSelected(index) && isIncludable - element.setSelected(isSelected) -@@ -413,179 +138,26 @@ - } - } - -- public componentWillUnmount() { -- this.dispose() -- } -- -- public componentDidUpdate(prevProps: IDiffProps) { -- const diff = this.props.diff -- if (diff === prevProps.diff) { -- return -- } -- -- if ( -- prevProps.diff.kind === DiffType.Text && -- diff.kind === DiffType.Text && -- diff.text === prevProps.diff.text -- ) { -- return -- } -- -- if (diff.kind === DiffType.Text && this.codeMirror) { -- this.codeMirror.setOption('mode', { name: DiffSyntaxMode.ModeName }) -- } -- -- this.initDiffSyntaxMode() -- } -- -- public componentDidMount() { -- if (this.props.diff.kind === DiffType.Text) { -- this.initDiffSyntaxMode() -- } -- } -- - public render() { -- return this.renderDiff(this.props.diff) -- } -- -- public async initDiffSyntaxMode() { -- const cm = this.codeMirror -- const file = this.props.file - const diff = this.props.diff -- const repo = this.props.repository -- -- if (!cm || diff.kind !== DiffType.Text) { -- return -- } -- -- // Store the current props to that we can see if anything -- // changes from underneath us as we're making asynchronous -- // operations that makes our data stale or useless. -- const propsSnapshot = this.props -- -- const lineFilters = getLineFilters(diff) -- const contents = await getFileContents(repo, file, lineFilters) -- -- if (!highlightParametersEqual(this.props, propsSnapshot)) { -- return -- } -- -- const tsOpt = cm.getOption('tabSize') -- const tabSize = typeof tsOpt === 'number' ? tsOpt : 4 -- -- const tokens = await highlightContents(contents, tabSize, lineFilters) -- -- if (!highlightParametersEqual(this.props, propsSnapshot)) { -- return -- } - -- const spec: IDiffSyntaxModeSpec = { -- name: DiffSyntaxMode.ModeName, -- diff, -- oldTokens: tokens.oldTokens, -- newTokens: tokens.newTokens, -- } -- -- cm.setOption('mode', spec) -- } -- -- private dispose() { -- this.codeMirror = null -- -- this.lineCleanup.forEach(disposable => disposable.dispose()) -- this.lineCleanup.clear() -- -- document.removeEventListener('mouseup', this.onDocumentMouseUp) -- } -- -- /** -- * compute the diff gutter width based on what's been rendered in the browser -- */ -- private getAndCacheGutterWidth = (): number | null => { -- if (this.gutterWidth) { -- return this.gutterWidth -- } -- -- if (this.codeMirror) { -- // as getWidth will return 0 for elements that are offscreen, this code -- // will look for the first row of the current viewport, which should be -- // onscreen -- const viewport = this.codeMirror.getScrollInfo() -- const top = viewport.top -- -- const row = this.codeMirror.lineAtHeight(top, 'local') -- const element = this.cachedGutterElements.get(row) -- -- if (!element) { -- console.error( -- `unable to find element at ${row}, should probably look into that` -- ) -- return null -- } -- -- this.gutterWidth = element.getWidth() -- -- if (this.gutterWidth === 0) { -- console.error( -- `element at row ${row} does not have a width, should probably look into that` -- ) -- } -- } -- -- return this.gutterWidth -- } -- -- private updateRangeHoverState = ( -- start: number, -- end: number, -- show: boolean -- ) => { -- for (let i = start; i <= end; i++) { -- this.hoverLine(i, show) -- } -- } -- -- private hoverLine = (row: number, include: boolean) => { -- const element = this.cachedGutterElements.get(row) -- -- // element may not be drawn by the editor, so updating it isn't necessary -- if (element) { -- element.setHover(include) -- } -- } -- -- /** -- * start a selection gesture based on the current interation -- */ -- private startSelection = ( -- file: WorkingDirectoryFileChange, -- diff: ITextDiff, -- index: number, -- isRangeSelection: boolean -- ) => { -- const snapshot = file.selection -- const selected = snapshot.isSelected(index) -- const desiredSelection = !selected -- -- if (isRangeSelection) { -- const range = findInteractiveDiffRange(diff, index) -- if (!range) { -- console.error('unable to find range for given line in diff') -- return -+ switch (diff.kind) { -+ case DiffType.Text: -+ return this.renderText(diff) -+ case DiffType.Binary: -+ return this.renderBinaryFile() -+ case DiffType.Image: -+ return this.renderImage(diff) -+ case DiffType.LargeText: { -+ return this.state.forceShowLargeDiff -+ ? this.renderLargeText(diff) -+ : this.renderLargeTextDiff() - } -- -- this.selection = new RangeSelection( -- range.start, -- range.end, -- desiredSelection, -- snapshot -- ) -- } else { -- this.selection = new DragDropSelection(index, desiredSelection, snapshot) -+ case DiffType.Unrenderable: -+ return this.renderUnrenderableDiff() -+ default: -+ return assertNever(diff, `Unsupported diff type: ${diff}`) - } -- -- this.selection.paint(this.cachedGutterElements) -- document.addEventListener('mouseup', this.onDocumentMouseUp) - } - - /** -@@ -618,332 +190,6 @@ - this.selection = null - } - -- private onGutterMouseDown = ( -- index: number, -- diff: ITextDiff, -- isRangeSelection: boolean -- ) => { -- if (!(this.props.file instanceof WorkingDirectoryFileChange)) { -- fatalError( -- 'must not start selection when selected file is not a WorkingDirectoryFileChange' -- ) -- return -- } -- -- if (isRangeSelection) { -- const hunk = diffHunkForIndex(diff, index) -- if (!hunk) { -- console.error('unable to find hunk for given line in diff') -- } -- } -- this.startSelection(this.props.file, diff, index, isRangeSelection) -- } -- -- private onGutterMouseMove = (index: number) => { -- if (!this.selection) { -- return -- } -- -- this.selection.update(index) -- this.selection.paint(this.cachedGutterElements) -- } -- -- private onDiffTextMouseMove = ( -- ev: MouseEvent, -- diff: ITextDiff, -- index: number -- ) => { -- const isActive = this.isMouseCursorNearGutter(ev) -- if (isActive === null) { -- return -- } -- -- const diffLine = diffLineForIndex(diff, index) -- if (!diffLine) { -- return -- } -- -- if (!diffLine.isIncludeableLine()) { -- return -- } -- -- const range = findInteractiveDiffRange(diff, index) -- if (!range) { -- console.error('unable to find range for given index in diff') -- return -- } -- -- this.updateRangeHoverState(range.start, range.end, isActive) -- } -- -- private onDiffTextMouseDown = ( -- ev: MouseEvent, -- diff: ITextDiff, -- index: number -- ) => { -- const isActive = this.isMouseCursorNearGutter(ev) -- -- if (isActive) { -- // this line is important because it prevents the codemirror editor -- // from handling the event and resetting the scroll position. -- // it doesn't do this when you click on elements in the gutter, -- // which is an amazing joke to have placed upon me right now -- ev.preventDefault() -- -- if (!(this.props.file instanceof WorkingDirectoryFileChange)) { -- fatalError( -- 'must not start selection when selected file is not a WorkingDirectoryFileChange' -- ) -- return -- } -- -- this.startSelection(this.props.file, diff, index, true) -- } -- } -- -- private onDiffTextMouseLeave = ( -- ev: MouseEvent, -- diff: ITextDiff, -- index: number -- ) => { -- const range = findInteractiveDiffRange(diff, index) -- if (!range) { -- console.error('unable to find range for given index in diff') -- return -- } -- -- this.updateRangeHoverState(range.start, range.end, false) -- } -- -- private isMouseCursorNearGutter = (ev: MouseEvent): boolean | null => { -- const width = this.getAndCacheGutterWidth() -- -- if (!width) { -- // should fail earlier than this with a helpful error message -- return null -- } -- -- const deltaX = ev.layerX - width -- return deltaX >= 0 && deltaX <= RangeSelectionSizePixels -- } -- -- private renderLine = (instance: any, line: any, element: HTMLElement) => { -- const existingLineDisposable = this.lineCleanup.get(line) -- -- // If we can find the line in our cleanup list that means the line is -- // being re-rendered. Agains, CodeMirror doesn't fire the 'delete' event -- // when this happens. -- if (existingLineDisposable) { -- existingLineDisposable.dispose() -- this.lineCleanup.delete(line) -- } -- -- const diff = this.props.diff -- if (diff.kind !== DiffType.Text) { -- return -- } -- -- const index = instance.getLineNumber(line) as number -- -- const diffLine = diffLineForIndex(diff, index) -- if (diffLine) { -- const diffLineElement = element.children[0] as HTMLSpanElement -- -- let noNewlineReactContainer: HTMLSpanElement | null = null -- -- if (diffLine.noTrailingNewLine) { -- noNewlineReactContainer = document.createElement('span') -- noNewlineReactContainer.setAttribute( -- 'title', -- 'No newline at end of file' -- ) -- ReactDOM.render( -- , -- noNewlineReactContainer -- ) -- diffLineElement.appendChild(noNewlineReactContainer) -- } -- -- const gutterReactContainer = document.createElement('span') -- -- let isIncluded = false -- if (this.props.file instanceof WorkingDirectoryFileChange) { -- isIncluded = this.props.file.selection.isSelected(index) -- } -- -- const cache = this.cachedGutterElements -- -- ReactDOM.render( -- , -- gutterReactContainer, -- function(this: DiffLineGutter) { -- if (this !== undefined) { -- cache.set(index, this) -- } -- } -- ) -- -- const onMouseMoveLine: (ev: MouseEvent) => void = ev => { -- this.onDiffTextMouseMove(ev, diff, index) -- } -- -- const onMouseDownLine: (ev: MouseEvent) => void = ev => { -- this.onDiffTextMouseDown(ev, diff, index) -- } -- -- const onMouseLeaveLine: (ev: MouseEvent) => void = ev => { -- this.onDiffTextMouseLeave(ev, diff, index) -- } -- -- if (!this.props.readOnly) { -- diffLineElement.addEventListener('mousemove', onMouseMoveLine) -- diffLineElement.addEventListener('mousedown', onMouseDownLine) -- diffLineElement.addEventListener('mouseleave', onMouseLeaveLine) -- } -- -- element.insertBefore(gutterReactContainer, diffLineElement) -- -- // Hack(ish?). In order to be a real good citizen we need to unsubscribe from -- // the line delete event once we've been called once or the component has been -- // unmounted. In the latter case it's _probably_ not strictly necessary since -- // the only thing gc rooted by the event should be isolated and eligble for -- // collection. But let's be extra cautious I guess. -- // -- // The only way to unsubscribe is to pass the exact same function given to the -- // 'on' function to the 'off' so we need a reference to ourselves, basically. -- let deleteHandler: () => void // eslint-disable-line prefer-const -- -- // Since we manually render a react component we have to take care of unmounting -- // it or else we'll leak memory. This disposable will unmount the component. -- // -- // See https://facebook.github.io/react/blog/2015/10/01/react-render-and-top-level-api.html -- const gutterCleanup = new Disposable(() => { -- this.cachedGutterElements.delete(index) -- -- ReactDOM.unmountComponentAtNode(gutterReactContainer) -- -- if (noNewlineReactContainer) { -- ReactDOM.unmountComponentAtNode(noNewlineReactContainer) -- } -- -- if (!this.props.readOnly) { -- diffLineElement.removeEventListener('mousemove', onMouseMoveLine) -- diffLineElement.removeEventListener('mousedown', onMouseDownLine) -- diffLineElement.removeEventListener('mouseleave', onMouseLeaveLine) -- } -- -- line.off('delete', deleteHandler) -- }) -- -- // Add the cleanup disposable to our list of disposables so that we clean up when -- // this component is unmounted or when the line is re-rendered. When either of that -- // happens the line 'delete' event doesn't fire. -- this.lineCleanup.set(line, gutterCleanup) -- -- // If the line delete event fires we dispose of the disposable (disposing is -- // idempotent) -- deleteHandler = () => { -- const disp = this.lineCleanup.get(line) -- if (disp) { -- this.lineCleanup.delete(line) -- disp.dispose() -- } -- } -- line.on('delete', deleteHandler) -- } -- } -- -- private isSelectionEnabled = () => { -- return this.selection == null -- } -- -- private restoreScrollPosition(cm: Editor) { -- const scrollPosition = this.scrollPositionToRestore -- if (cm && scrollPosition) { -- cm.scrollTo(scrollPosition.left, scrollPosition.top) -- } -- } -- -- private markIntraLineChanges(codeMirror: Editor, diff: ITextDiff) { -- for (const hunk of diff.hunks) { -- const additions = hunk.lines.filter(l => l.type === DiffLineType.Add) -- const deletions = hunk.lines.filter(l => l.type === DiffLineType.Delete) -- if (additions.length !== deletions.length) { -- continue -- } -- -- for (let i = 0; i < additions.length; i++) { -- const addLine = additions[i] -- const deleteLine = deletions[i] -- if ( -- addLine.text.length > MaxIntraLineDiffStringLength || -- deleteLine.text.length > MaxIntraLineDiffStringLength -- ) { -- continue -- } -- -- const changeRanges = relativeChanges( -- addLine.content, -- deleteLine.content -- ) -- const addRange = changeRanges.stringARange -- if (addRange.length > 0) { -- const addLineNumber = lineNumberForDiffLine(addLine, diff) -- if (addLineNumber > -1) { -- const addFrom = { -- line: addLineNumber, -- ch: addRange.location + 1, -- } -- const addTo = { -- line: addLineNumber, -- ch: addRange.location + addRange.length + 1, -- } -- codeMirror -- .getDoc() -- .markText(addFrom, addTo, { className: 'cm-diff-add-inner' }) -- } -- } -- -- const deleteRange = changeRanges.stringBRange -- if (deleteRange.length > 0) { -- const deleteLineNumber = lineNumberForDiffLine(deleteLine, diff) -- if (deleteLineNumber > -1) { -- const deleteFrom = { -- line: deleteLineNumber, -- ch: deleteRange.location + 1, -- } -- const deleteTo = { -- line: deleteLineNumber, -- ch: deleteRange.location + deleteRange.length + 1, -- } -- codeMirror.getDoc().markText(deleteFrom, deleteTo, { -- className: 'cm-diff-delete-inner', -- }) -- } -- } -- } -- } -- } -- -- private onChanges = (cm: Editor) => { -- this.restoreScrollPosition(cm) -- -- const diff = this.props.diff -- if (diff.kind === DiffType.Text) { -- this.markIntraLineChanges(cm, diff) -- } -- } -- - private onChangeImageDiffType = (type: ImageDiffType) => { - this.props.dispatcher.changeImageDiffType(type) - } -@@ -977,7 +223,7 @@ - private renderLargeTextDiff() { - return ( -
-- -+ -

- The diff is too large to be displayed by default. -
-@@ -1003,8 +249,8 @@ - private renderLargeText(diff: ILargeTextDiff) { - // guaranteed to be set since this function won't be called if text or hunks are null - const textDiff: ITextDiff = { -- text: diff.text!, -- hunks: diff.hunks!, -+ text: diff.text, -+ hunks: diff.hunks, - kind: DiffType.Text, - lineEndingsChange: diff.lineEndingsChange, - } -@@ -1043,107 +289,18 @@ - } - - private renderTextDiff(diff: ITextDiff) { -- const options: IEditorConfigurationExtra = { -- lineNumbers: false, -- readOnly: true, -- showCursorWhenSelecting: false, -- cursorBlinkRate: -1, -- lineWrapping: true, -- mode: { name: DiffSyntaxMode.ModeName }, -- // Make sure CodeMirror doesn't capture Tab and thus destroy tab navigation -- extraKeys: { Tab: false }, -- scrollbarStyle: __DARWIN__ ? 'simple' : 'native', -- styleSelectedText: true, -- lineSeparator: '\n', -- specialChars: /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff]/, -- } -- -- // If the text looks like it could have been formatted using Windows -- // line endings (\r\n) we need to massage it a bit before we hand it -- // off to CodeMirror. That's because CodeMirror has two ways of splitting -- // lines, one is the built in which splits on \n, \r\n and \r. The last -- // one is important because that will match carriage return characters -- // inside a diff line. The other way is when consumers supply the -- // lineSeparator option. That option only takes a string meaning we can -- // either make it split on '\r\n', '\n' or '\r' but not what we would like -- // to do, namely '\r?\n'. We want to keep CR characters inside of a diff -- // line so that we can mark them using the specialChars attribute so -- // we convert all \r\n to \n and remove any trailing \r character. -- const text = -- diff.text.indexOf('\r') !== -1 -- ? diff.text -- // Capture the \r if followed by (positive lookahead) a \n or -- // the end of the string. Note that this does not capture the \n. -- .replace(/\r(?=\n|$)/g, '') -- : diff.text -- - return ( -- - ) - } - -- private onCopy = (editor: CodeMirror.Editor, event: Event) => { -- event.preventDefault() -- -- // Remove the diff line markers from the copied text. The beginning of the -- // selection might start within a line, in which case we don't have to trim -- // the diff type marker. But for selections that span multiple lines, we'll -- // trim it. -- const doc = editor.getDoc() -- const lines = doc.getSelections() -- const selectionRanges = doc.listSelections() -- const lineContent: Array = [] -- -- for (let i = 0; i < lines.length; i++) { -- const range = selectionRanges[i] -- const content = lines[i] -- const contentLines = content.split('\n') -- for (const [i, line] of contentLines.entries()) { -- if (i === 0 && range.head.ch > 0) { -- lineContent.push(line) -- } else { -- lineContent.push(line.substr(1)) -- } -- } -- -- const textWithoutMarkers = lineContent.join('\n') -- clipboard.writeText(textWithoutMarkers) -- } -- } -- -- private getAndStoreCodeMirrorInstance = (cmh: CodeMirrorHost | null) => { -- this.codeMirror = cmh === null ? null : cmh.getEditor() -- } -- -- private renderDiff(diff: IDiff): JSX.Element | null { -- switch (diff.kind) { -- case DiffType.Text: -- return this.renderText(diff) -- case DiffType.Binary: -- return this.renderBinaryFile() -- case DiffType.Image: -- return this.renderImage(diff) -- case DiffType.LargeText: { -- return this.state.forceShowLargeDiff -- ? this.renderLargeText(diff) -- : this.renderLargeTextDiff() -- } -- case DiffType.Unrenderable: -- return this.renderUnrenderableDiff() -- default: -- return assertNever(diff, `Unsupported diff type: ${diff}`) -- } -- } -- - private showLargeDiff = () => { - this.setState({ forceShowLargeDiff: true }) - } -added in remote - their 100644 1ece0b9f0ed9655b30e1319e0b541d63d81d049c app/src/ui/diff/syntax-highlighting/index.ts -@@ -0,0 +1,201 @@ -+import * as Path from 'path' -+ -+import { assertNever } from '../../../lib/fatal-error' -+ -+import { getPartialBlobContents } from '../../../lib/git/show' -+import { readPartialFile } from '../../../lib/file-system' -+import { highlight } from '../../../lib/highlighter/worker' -+import { ITokens } from '../../../lib/highlighter/types' -+ -+import { -+ CommittedFileChange, -+ WorkingDirectoryFileChange, -+ AppFileStatus, -+} from '../../../models/status' -+import { Repository } from '../../../models/repository' -+import { DiffHunk, DiffLineType, DiffLine } from '../../../models/diff' -+ -+/** The maximum number of bytes we'll process for highlighting. */ -+const MaxHighlightContentLength = 256 * 1024 -+ -+type ChangedFile = WorkingDirectoryFileChange | CommittedFileChange -+ -+interface ILineFilters { -+ readonly oldLineFilter: Array -+ readonly newLineFilter: Array -+} -+ -+interface IFileContents { -+ readonly file: ChangedFile -+ readonly oldContents: Buffer -+ readonly newContents: Buffer -+} -+ -+interface IFileTokens { -+ readonly oldTokens: ITokens -+ readonly newTokens: ITokens -+} -+ -+async function getOldFileContent( -+ repository: Repository, -+ file: ChangedFile -+): Promise { -+ if (file.status === AppFileStatus.New) { -+ return new Buffer(0) -+ } -+ -+ let commitish -+ -+ if (file instanceof WorkingDirectoryFileChange) { -+ // If we pass an empty string here we get the contents -+ // that are in the index. But since we call diff with -+ // --no-index (see diff.ts) we need to look at what's -+ // actually committed to get the appropriate content. -+ commitish = 'HEAD' -+ } else if (file instanceof CommittedFileChange) { -+ commitish = `${file.commitish}^` -+ } else { -+ return assertNever(file, 'Unknown file change type') -+ } -+ -+ return getPartialBlobContents( -+ repository, -+ commitish, -+ file.oldPath || file.path, -+ MaxHighlightContentLength -+ ) -+} -+ -+async function getNewFileContent( -+ repository: Repository, -+ file: ChangedFile -+): Promise { -+ if (file.status === AppFileStatus.Deleted) { -+ return new Buffer(0) -+ } -+ -+ if (file instanceof WorkingDirectoryFileChange) { -+ return readPartialFile( -+ Path.join(repository.path, file.path), -+ 0, -+ MaxHighlightContentLength - 1 -+ ) -+ } else if (file instanceof CommittedFileChange) { -+ return getPartialBlobContents( -+ repository, -+ file.commitish, -+ file.path, -+ MaxHighlightContentLength -+ ) -+ } -+ -+ return assertNever(file, 'Unknown file change type') -+} -+ -+export async function getFileContents( -+ repo: Repository, -+ file: ChangedFile, -+ lineFilters: ILineFilters -+): Promise { -+ const oldContentsPromise = lineFilters.oldLineFilter.length -+ ? getOldFileContent(repo, file) -+ : Promise.resolve(new Buffer(0)) -+ -+ const newContentsPromise = lineFilters.newLineFilter.length -+ ? getNewFileContent(repo, file) -+ : Promise.resolve(new Buffer(0)) -+ -+ const [oldContents, newContents] = await Promise.all([ -+ oldContentsPromise.catch(e => { -+ log.error('Could not load old contents for syntax highlighting', e) -+ return new Buffer(0) -+ }), -+ newContentsPromise.catch(e => { -+ log.error('Could not load new contents for syntax highlighting', e) -+ return new Buffer(0) -+ }), -+ ]) -+ -+ return { file, oldContents, newContents } -+} -+ -+/** -+ * Figure out which lines we need to have tokenized in -+ * both the old and new version of the file. -+ */ -+export function getLineFilters(hunks: ReadonlyArray): ILineFilters { -+ const oldLineFilter = new Array() -+ const newLineFilter = new Array() -+ -+ const diffLines = new Array() -+ -+ let anyAdded = false -+ let anyDeleted = false -+ -+ for (const hunk of hunks) { -+ for (const line of hunk.lines) { -+ anyAdded = anyAdded || line.type === DiffLineType.Add -+ anyDeleted = anyDeleted || line.type === DiffLineType.Delete -+ diffLines.push(line) -+ } -+ } -+ -+ for (const line of diffLines) { -+ // So this might need a little explaining. What we're trying -+ // to achieve here is if the diff contains only additions or -+ // only deletions we'll source all the highlighted lines from -+ // either the before or after file. That way we can completely -+ // disregard loading, and highlighting, the other version. -+ if (line.oldLineNumber !== null && line.newLineNumber !== null) { -+ if (anyAdded && !anyDeleted) { -+ newLineFilter.push(line.newLineNumber - 1) -+ } else { -+ oldLineFilter.push(line.oldLineNumber - 1) -+ } -+ } else { -+ // If there's a mix (meaning we'll have to read from both -+ // anyway) we'll prioritize the old version since -+ // that's immutable and less likely to be the subject of a -+ // race condition when someone rapidly modifies the file on -+ // disk. -+ if (line.oldLineNumber !== null) { -+ oldLineFilter.push(line.oldLineNumber - 1) -+ } else if (line.newLineNumber !== null) { -+ newLineFilter.push(line.newLineNumber - 1) -+ } -+ } -+ } -+ -+ return { oldLineFilter, newLineFilter } -+} -+ -+export async function highlightContents( -+ contents: IFileContents, -+ tabSize: number, -+ lineFilters: ILineFilters -+): Promise { -+ const { file, oldContents, newContents } = contents -+ -+ const [oldTokens, newTokens] = await Promise.all([ -+ highlight( -+ oldContents.toString('utf8'), -+ Path.extname(file.oldPath || file.path), -+ tabSize, -+ lineFilters.oldLineFilter -+ ).catch(e => { -+ log.error('Highlighter worked failed for old contents', e) -+ return {} -+ }), -+ highlight( -+ newContents.toString('utf8'), -+ Path.extname(file.path), -+ tabSize, -+ lineFilters.newLineFilter -+ ).catch(e => { -+ log.error('Highlighter worked failed for new contents', e) -+ return {} -+ }), -+ ]) -+ -+ return { oldTokens, newTokens } -+} -added in remote - their 100644 6fec151426449ef33b9603d5c070b906db0d39ce app/src/ui/diff/text-diff.tsx -@@ -0,0 +1,767 @@ -+import * as React from 'react' -+import * as ReactDOM from 'react-dom' -+import { clipboard } from 'electron' -+import { Editor } from 'codemirror' -+import { Disposable } from 'event-kit' -+ -+import { fatalError } from '../../lib/fatal-error' -+ -+import { DiffHunk, DiffLineType, DiffSelection } from '../../models/diff' -+import { -+ WorkingDirectoryFileChange, -+ CommittedFileChange, -+} from '../../models/status' -+ -+import { Octicon, OcticonSymbol } from '../octicons' -+ -+import { IEditorConfigurationExtra } from './editor-configuration-extra' -+import { DiffSyntaxMode, IDiffSyntaxModeSpec } from './diff-syntax-mode' -+import { CodeMirrorHost } from './code-mirror-host' -+import { DiffLineGutter } from './diff-line-gutter' -+import { -+ diffLineForIndex, -+ diffHunkForIndex, -+ findInteractiveDiffRange, -+ lineNumberForDiffLine, -+} from './diff-explorer' -+import { RangeSelectionSizePixels } from './edge-detection' -+ -+import { ISelectionStrategy } from './selection/selection-strategy' -+import { RangeSelection } from './selection/range-selection-strategy' -+import { DragDropSelection } from './selection/drag-drop-selection-strategy' -+ -+import { -+ getLineFilters, -+ getFileContents, -+ highlightContents, -+} from './syntax-highlighting' -+import { relativeChanges } from './changed-range' -+import { Repository } from '../../models/repository' -+ -+/** The longest line for which we'd try to calculate a line diff. */ -+const MaxIntraLineDiffStringLength = 4096 -+ -+// This is a custom version of the no-newline octicon that's exactly as -+// tall as it needs to be (8px) which helps with aligning it on the line. -+const narrowNoNewlineSymbol = new OcticonSymbol( -+ 16, -+ 8, -+ 'm 16,1 0,3 c 0,0.55 -0.45,1 -1,1 l -3,0 0,2 -3,-3 3,-3 0,2 2,0 0,-2 2,0 z M 8,4 C 8,6.2 6.2,8 4,8 1.8,8 0,6.2 0,4 0,1.8 1.8,0 4,0 6.2,0 8,1.8 8,4 Z M 1.5,5.66 5.66,1.5 C 5.18,1.19 4.61,1 4,1 2.34,1 1,2.34 1,4 1,4.61 1.19,5.17 1.5,5.66 Z M 7,4 C 7,3.39 6.81,2.83 6.5,2.34 L 2.34,6.5 C 2.82,6.81 3.39,7 4,7 5.66,7 7,5.66 7,4 Z' -+) -+ -+type ChangedFile = WorkingDirectoryFileChange | CommittedFileChange -+ -+/** -+ * Checks to see if any key parameters in the props object that are used -+ * when performing highlighting has changed. This is used to determine -+ * whether highlighting should abort in between asynchronous operations -+ * due to some factor (like which file is currently selected) have changed -+ * and thus rendering the in-flight highlighting data useless. -+ */ -+function highlightParametersEqual( -+ newProps: ITextDiffProps, -+ prevProps: ITextDiffProps -+) { -+ if (newProps === prevProps) { -+ return true -+ } -+ -+ return ( -+ newProps.file.path === prevProps.file.path && -+ newProps.file.oldPath === prevProps.file.oldPath && -+ newProps.text === prevProps.text -+ ) -+} -+ -+interface ITextDiffProps { -+ readonly repository: Repository -+ readonly file: ChangedFile -+ readonly readOnly: boolean -+ readonly onIncludeChanged?: (diffSelection: DiffSelection) => void -+ readonly text: string -+ readonly hunks: ReadonlyArray -+} -+ -+export class TextDiff extends React.Component { -+ private codeMirror: Editor | null = null -+ -+ private gutterWidth: number | null = null -+ -+ /** -+ * We store the scroll position before reloading the same diff so that we can -+ * restore it when we're done. If we're not reloading the same diff, this'll -+ * be null. -+ */ -+ private scrollPositionToRestore: { left: number; top: number } | null = null -+ -+ /** -+ * A mapping from CodeMirror line handles to disposables which, when disposed -+ * cleans up any line gutter components and events associated with that line. -+ * See renderLine for more information. -+ */ -+ private readonly lineCleanup = new Map() -+ -+ /** -+ * a local cache of gutter elements, keyed by the row in the diff -+ */ -+ private cachedGutterElements = new Map() -+ -+ /** -+ * Maintain the current state of the user interacting with the diff gutter -+ */ -+ private selection: ISelectionStrategy | null = null -+ -+ private async initDiffSyntaxMode() { -+ const cm = this.codeMirror -+ const file = this.props.file -+ const hunks = this.props.hunks -+ const repo = this.props.repository -+ -+ if (!cm) { -+ return -+ } -+ -+ // Store the current props to that we can see if anything -+ // changes from underneath us as we're making asynchronous -+ // operations that makes our data stale or useless. -+ const propsSnapshot = this.props -+ -+ const lineFilters = getLineFilters(hunks) -+ const contents = await getFileContents(repo, file, lineFilters) -+ -+ if (!highlightParametersEqual(this.props, propsSnapshot)) { -+ return -+ } -+ -+ const tsOpt = cm.getOption('tabSize') -+ const tabSize = typeof tsOpt === 'number' ? tsOpt : 4 -+ -+ const tokens = await highlightContents(contents, tabSize, lineFilters) -+ -+ if (!highlightParametersEqual(this.props, propsSnapshot)) { -+ return -+ } -+ -+ const spec: IDiffSyntaxModeSpec = { -+ name: DiffSyntaxMode.ModeName, -+ hunks: this.props.hunks, -+ oldTokens: tokens.oldTokens, -+ newTokens: tokens.newTokens, -+ } -+ -+ cm.setOption('mode', spec) -+ } -+ -+ private dispose() { -+ this.codeMirror = null -+ -+ this.lineCleanup.forEach(disposable => disposable.dispose()) -+ this.lineCleanup.clear() -+ -+ document.removeEventListener('mouseup', this.onDocumentMouseUp) -+ } -+ -+ /** -+ * compute the diff gutter width based on what's been rendered in the browser -+ */ -+ private getAndCacheGutterWidth = (): number | null => { -+ if (this.gutterWidth) { -+ return this.gutterWidth -+ } -+ -+ if (this.codeMirror) { -+ // as getWidth will return 0 for elements that are offscreen, this code -+ // will look for the first row of the current viewport, which should be -+ // onscreen -+ const viewport = this.codeMirror.getScrollInfo() -+ const top = viewport.top -+ -+ const row = this.codeMirror.lineAtHeight(top, 'local') -+ const element = this.cachedGutterElements.get(row) -+ -+ if (!element) { -+ console.error( -+ `unable to find element at ${row}, should probably look into that` -+ ) -+ return null -+ } -+ -+ this.gutterWidth = element.getWidth() -+ -+ if (this.gutterWidth === 0) { -+ console.error( -+ `element at row ${row} does not have a width, should probably look into that` -+ ) -+ } -+ } -+ -+ return this.gutterWidth -+ } -+ -+ private updateRangeHoverState = ( -+ start: number, -+ end: number, -+ show: boolean -+ ) => { -+ for (let i = start; i <= end; i++) { -+ this.hoverLine(i, show) -+ } -+ } -+ -+ private hoverLine = (row: number, include: boolean) => { -+ const element = this.cachedGutterElements.get(row) -+ -+ // element may not be drawn by the editor, so updating it isn't necessary -+ if (element) { -+ element.setHover(include) -+ } -+ } -+ -+ /** -+ * start a selection gesture based on the current interation -+ */ -+ private startSelection = ( -+ file: WorkingDirectoryFileChange, -+ hunks: ReadonlyArray, -+ index: number, -+ isRangeSelection: boolean -+ ) => { -+ const snapshot = file.selection -+ const selected = snapshot.isSelected(index) -+ const desiredSelection = !selected -+ -+ if (isRangeSelection) { -+ const range = findInteractiveDiffRange(hunks, index) -+ if (!range) { -+ console.error('unable to find range for given line in diff') -+ return -+ } -+ -+ this.selection = new RangeSelection( -+ range.start, -+ range.end, -+ desiredSelection, -+ snapshot -+ ) -+ } else { -+ this.selection = new DragDropSelection(index, desiredSelection, snapshot) -+ } -+ -+ this.selection.paint(this.cachedGutterElements) -+ document.addEventListener('mouseup', this.onDocumentMouseUp) -+ } -+ -+ /** -+ * Helper event listener, registered when starting a selection by -+ * clicking anywhere on or near the gutter. Immediately removes itself -+ * from the mouseup event on the document element and ends any current -+ * selection. -+ * -+ * TODO: Once Electron upgrades to Chrome 55 we can drop this in favor -+ * of the 'once' option in addEventListener, see -+ * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener -+ */ -+ private onDocumentMouseUp = (ev: MouseEvent) => { -+ ev.preventDefault() -+ document.removeEventListener('mouseup', this.onDocumentMouseUp) -+ this.endSelection() -+ } -+ -+ /** -+ * complete the selection gesture and apply the change to the diff -+ */ -+ private endSelection = () => { -+ if (!this.props.onIncludeChanged || !this.selection) { -+ return -+ } -+ -+ this.props.onIncludeChanged(this.selection.done()) -+ -+ // operation is completed, clean this up -+ this.selection = null -+ } -+ -+ private onGutterMouseDown = ( -+ index: number, -+ hunks: ReadonlyArray, -+ isRangeSelection: boolean -+ ) => { -+ if (!(this.props.file instanceof WorkingDirectoryFileChange)) { -+ fatalError( -+ 'must not start selection when selected file is not a WorkingDirectoryFileChange' -+ ) -+ return -+ } -+ -+ if (isRangeSelection) { -+ const hunk = diffHunkForIndex(hunks, index) -+ if (!hunk) { -+ console.error('unable to find hunk for given line in diff') -+ } -+ } -+ this.startSelection(this.props.file, hunks, index, isRangeSelection) -+ } -+ -+ private onGutterMouseMove = (index: number) => { -+ if (!this.selection) { -+ return -+ } -+ -+ this.selection.update(index) -+ this.selection.paint(this.cachedGutterElements) -+ } -+ -+ private onDiffTextMouseMove = ( -+ ev: MouseEvent, -+ hunks: ReadonlyArray, -+ index: number -+ ) => { -+ const isActive = this.isMouseCursorNearGutter(ev) -+ if (isActive === null) { -+ return -+ } -+ -+ const diffLine = diffLineForIndex(hunks, index) -+ if (!diffLine) { -+ return -+ } -+ -+ if (!diffLine.isIncludeableLine()) { -+ return -+ } -+ -+ const range = findInteractiveDiffRange(hunks, index) -+ if (!range) { -+ console.error('unable to find range for given index in diff') -+ return -+ } -+ -+ this.updateRangeHoverState(range.start, range.end, isActive) -+ } -+ -+ private onDiffTextMouseDown = ( -+ ev: MouseEvent, -+ hunks: ReadonlyArray, -+ index: number -+ ) => { -+ const isActive = this.isMouseCursorNearGutter(ev) -+ -+ if (isActive) { -+ // this line is important because it prevents the codemirror editor -+ // from handling the event and resetting the scroll position. -+ // it doesn't do this when you click on elements in the gutter, -+ // which is an amazing joke to have placed upon me right now -+ ev.preventDefault() -+ -+ if (!(this.props.file instanceof WorkingDirectoryFileChange)) { -+ fatalError( -+ 'must not start selection when selected file is not a WorkingDirectoryFileChange' -+ ) -+ return -+ } -+ -+ this.startSelection(this.props.file, hunks, index, true) -+ } -+ } -+ -+ private onDiffTextMouseLeave = ( -+ ev: MouseEvent, -+ hunks: ReadonlyArray, -+ index: number -+ ) => { -+ const range = findInteractiveDiffRange(hunks, index) -+ if (!range) { -+ console.error('unable to find range for given index in diff') -+ return -+ } -+ -+ this.updateRangeHoverState(range.start, range.end, false) -+ } -+ -+ private isMouseCursorNearGutter = (ev: MouseEvent): boolean | null => { -+ const width = this.getAndCacheGutterWidth() -+ -+ if (!width) { -+ // should fail earlier than this with a helpful error message -+ return null -+ } -+ -+ const deltaX = ev.layerX - width -+ return deltaX >= 0 && deltaX <= RangeSelectionSizePixels -+ } -+ -+ private isSelectionEnabled = () => { -+ return this.selection == null -+ } -+ -+ private restoreScrollPosition(cm: Editor) { -+ const scrollPosition = this.scrollPositionToRestore -+ if (cm && scrollPosition) { -+ cm.scrollTo(scrollPosition.left, scrollPosition.top) -+ } -+ } -+ -+ private renderLine = (instance: any, line: any, element: HTMLElement) => { -+ const existingLineDisposable = this.lineCleanup.get(line) -+ -+ // If we can find the line in our cleanup list that means the line is -+ // being re-rendered. Agains, CodeMirror doesn't fire the 'delete' event -+ // when this happens. -+ if (existingLineDisposable) { -+ existingLineDisposable.dispose() -+ this.lineCleanup.delete(line) -+ } -+ -+ const index = instance.getLineNumber(line) as number -+ -+ const diffLine = diffLineForIndex(this.props.hunks, index) -+ if (diffLine) { -+ const diffLineElement = element.children[0] as HTMLSpanElement -+ -+ let noNewlineReactContainer: HTMLSpanElement | null = null -+ -+ if (diffLine.noTrailingNewLine) { -+ noNewlineReactContainer = document.createElement('span') -+ noNewlineReactContainer.setAttribute( -+ 'title', -+ 'No newline at end of file' -+ ) -+ ReactDOM.render( -+ , -+ noNewlineReactContainer -+ ) -+ diffLineElement.appendChild(noNewlineReactContainer) -+ } -+ -+ const gutterReactContainer = document.createElement('span') -+ -+ let isIncluded = false -+ if (this.props.file instanceof WorkingDirectoryFileChange) { -+ isIncluded = this.props.file.selection.isSelected(index) -+ } -+ -+ const cache = this.cachedGutterElements -+ -+ const hunks = this.props.hunks -+ -+ ReactDOM.render( -+ , -+ gutterReactContainer, -+ function(this: DiffLineGutter) { -+ if (this !== undefined) { -+ cache.set(index, this) -+ } -+ } -+ ) -+ -+ const onMouseMoveLine: (ev: MouseEvent) => void = ev => { -+ this.onDiffTextMouseMove(ev, hunks, index) -+ } -+ -+ const onMouseDownLine: (ev: MouseEvent) => void = ev => { -+ this.onDiffTextMouseDown(ev, hunks, index) -+ } -+ -+ const onMouseLeaveLine: (ev: MouseEvent) => void = ev => { -+ this.onDiffTextMouseLeave(ev, hunks, index) -+ } -+ -+ if (!this.props.readOnly) { -+ diffLineElement.addEventListener('mousemove', onMouseMoveLine) -+ diffLineElement.addEventListener('mousedown', onMouseDownLine) -+ diffLineElement.addEventListener('mouseleave', onMouseLeaveLine) -+ } -+ -+ element.insertBefore(gutterReactContainer, diffLineElement) -+ -+ // Hack(ish?). In order to be a real good citizen we need to unsubscribe from -+ // the line delete event once we've been called once or the component has been -+ // unmounted. In the latter case it's _probably_ not strictly necessary since -+ // the only thing gc rooted by the event should be isolated and eligble for -+ // collection. But let's be extra cautious I guess. -+ // -+ // The only way to unsubscribe is to pass the exact same function given to the -+ // 'on' function to the 'off' so we need a reference to ourselves, basically. -+ let deleteHandler: () => void // eslint-disable-line prefer-const -+ -+ // Since we manually render a react component we have to take care of unmounting -+ // it or else we'll leak memory. This disposable will unmount the component. -+ // -+ // See https://facebook.github.io/react/blog/2015/10/01/react-render-and-top-level-api.html -+ const gutterCleanup = new Disposable(() => { -+ this.cachedGutterElements.delete(index) -+ -+ ReactDOM.unmountComponentAtNode(gutterReactContainer) -+ -+ if (noNewlineReactContainer) { -+ ReactDOM.unmountComponentAtNode(noNewlineReactContainer) -+ } -+ -+ if (!this.props.readOnly) { -+ diffLineElement.removeEventListener('mousemove', onMouseMoveLine) -+ diffLineElement.removeEventListener('mousedown', onMouseDownLine) -+ diffLineElement.removeEventListener('mouseleave', onMouseLeaveLine) -+ } -+ -+ line.off('delete', deleteHandler) -+ }) -+ -+ // Add the cleanup disposable to our list of disposables so that we clean up when -+ // this component is unmounted or when the line is re-rendered. When either of that -+ // happens the line 'delete' event doesn't fire. -+ this.lineCleanup.set(line, gutterCleanup) -+ -+ // If the line delete event fires we dispose of the disposable (disposing is -+ // idempotent) -+ deleteHandler = () => { -+ const disp = this.lineCleanup.get(line) -+ if (disp) { -+ this.lineCleanup.delete(line) -+ disp.dispose() -+ } -+ } -+ line.on('delete', deleteHandler) -+ } -+ } -+ -+ private getAndStoreCodeMirrorInstance = (cmh: CodeMirrorHost | null) => { -+ this.codeMirror = cmh === null ? null : cmh.getEditor() -+ } -+ -+ private onCopy = (editor: Editor, event: Event) => { -+ event.preventDefault() -+ -+ // Remove the diff line markers from the copied text. The beginning of the -+ // selection might start within a line, in which case we don't have to trim -+ // the diff type marker. But for selections that span multiple lines, we'll -+ // trim it. -+ const doc = editor.getDoc() -+ const lines = doc.getSelections() -+ const selectionRanges = doc.listSelections() -+ const lineContent: Array = [] -+ -+ for (let i = 0; i < lines.length; i++) { -+ const range = selectionRanges[i] -+ const content = lines[i] -+ const contentLines = content.split('\n') -+ for (const [i, line] of contentLines.entries()) { -+ if (i === 0 && range.head.ch > 0) { -+ lineContent.push(line) -+ } else { -+ lineContent.push(line.substr(1)) -+ } -+ } -+ -+ const textWithoutMarkers = lineContent.join('\n') -+ clipboard.writeText(textWithoutMarkers) -+ } -+ } -+ -+ private markIntraLineChanges( -+ codeMirror: Editor, -+ hunks: ReadonlyArray -+ ) { -+ for (const hunk of hunks) { -+ const additions = hunk.lines.filter(l => l.type === DiffLineType.Add) -+ const deletions = hunk.lines.filter(l => l.type === DiffLineType.Delete) -+ if (additions.length !== deletions.length) { -+ continue -+ } -+ -+ for (let i = 0; i < additions.length; i++) { -+ const addLine = additions[i] -+ const deleteLine = deletions[i] -+ if ( -+ addLine.text.length > MaxIntraLineDiffStringLength || -+ deleteLine.text.length > MaxIntraLineDiffStringLength -+ ) { -+ continue -+ } -+ -+ const changeRanges = relativeChanges( -+ addLine.content, -+ deleteLine.content -+ ) -+ const addRange = changeRanges.stringARange -+ if (addRange.length > 0) { -+ const addLineNumber = lineNumberForDiffLine(addLine, hunks) -+ if (addLineNumber > -1) { -+ const addFrom = { -+ line: addLineNumber, -+ ch: addRange.location + 1, -+ } -+ const addTo = { -+ line: addLineNumber, -+ ch: addRange.location + addRange.length + 1, -+ } -+ codeMirror -+ .getDoc() -+ .markText(addFrom, addTo, { className: 'cm-diff-add-inner' }) -+ } -+ } -+ -+ const deleteRange = changeRanges.stringBRange -+ if (deleteRange.length > 0) { -+ const deleteLineNumber = lineNumberForDiffLine(deleteLine, hunks) -+ if (deleteLineNumber > -1) { -+ const deleteFrom = { -+ line: deleteLineNumber, -+ ch: deleteRange.location + 1, -+ } -+ const deleteTo = { -+ line: deleteLineNumber, -+ ch: deleteRange.location + deleteRange.length + 1, -+ } -+ codeMirror.getDoc().markText(deleteFrom, deleteTo, { -+ className: 'cm-diff-delete-inner', -+ }) -+ } -+ } -+ } -+ } -+ } -+ -+ private onChanges = (cm: Editor) => { -+ this.restoreScrollPosition(cm) -+ -+ this.markIntraLineChanges(cm, this.props.hunks) -+ } -+ -+ public componentWillReceiveProps(nextProps: ITextDiffProps) { -+ // If we're reloading the same file, we want to save the current scroll -+ // position and restore it after the diff's been updated. -+ const sameFile = -+ nextProps.file && -+ this.props.file && -+ nextProps.file.id === this.props.file.id -+ -+ // Happy path, if the text hasn't changed we won't re-render -+ // and subsequently won't have to restore the scroll position. -+ const textHasChanged = nextProps.text !== this.props.text -+ -+ const codeMirror = this.codeMirror -+ if (codeMirror && sameFile && textHasChanged) { -+ const scrollInfo = codeMirror.getScrollInfo() -+ this.scrollPositionToRestore = { -+ left: scrollInfo.left, -+ top: scrollInfo.top, -+ } -+ } else { -+ this.scrollPositionToRestore = null -+ } -+ -+ if (codeMirror && this.props.text !== nextProps.text) { -+ codeMirror.setOption('mode', { name: DiffSyntaxMode.ModeName }) -+ } -+ -+ // HACK: This entire section is a hack. Whenever we receive -+ // props we update all currently visible gutter elements with -+ // the selection state from the file. -+ if (nextProps.file instanceof WorkingDirectoryFileChange) { -+ const selection = nextProps.file.selection -+ const oldSelection = -+ this.props.file instanceof WorkingDirectoryFileChange -+ ? this.props.file.selection -+ : null -+ -+ // Nothing has changed -+ if (oldSelection === selection) { -+ return -+ } -+ -+ this.gutterWidth = null -+ -+ const hunks = nextProps.hunks -+ this.cachedGutterElements.forEach((element, index) => { -+ if (!element) { -+ console.error('expected DOM element for diff gutter not found') -+ return -+ } -+ -+ const line = diffLineForIndex(hunks, index) -+ const isIncludable = line ? line.isIncludeableLine() : false -+ const isSelected = selection.isSelected(index) && isIncludable -+ element.setSelected(isSelected) -+ }) -+ } -+ } -+ -+ public componentWillUnmount() { -+ this.dispose() -+ } -+ -+ public componentDidUpdate(prevProps: ITextDiffProps) { -+ if (this.props.text === prevProps.text) { -+ return -+ } -+ -+ if (this.codeMirror) { -+ this.codeMirror.setOption('mode', { name: DiffSyntaxMode.ModeName }) -+ } -+ -+ this.initDiffSyntaxMode() -+ } -+ -+ public componentDidMount() { -+ this.initDiffSyntaxMode() -+ } -+ -+ public render() { -+ const options: IEditorConfigurationExtra = { -+ lineNumbers: false, -+ readOnly: true, -+ showCursorWhenSelecting: false, -+ cursorBlinkRate: -1, -+ lineWrapping: true, -+ mode: { name: DiffSyntaxMode.ModeName }, -+ // Make sure CodeMirror doesn't capture Tab and thus destroy tab navigation -+ extraKeys: { Tab: false }, -+ scrollbarStyle: __DARWIN__ ? 'simple' : 'native', -+ styleSelectedText: true, -+ lineSeparator: '\n', -+ specialChars: /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff]/, -+ } -+ -+ // If the text looks like it could have been formatted using Windows -+ // line endings (\r\n) we need to massage it a bit before we hand it -+ // off to CodeMirror. That's because CodeMirror has two ways of splitting -+ // lines, one is the built in which splits on \n, \r\n and \r. The last -+ // one is important because that will match carriage return characters -+ // inside a diff line. The other way is when consumers supply the -+ // lineSeparator option. That option only takes a string meaning we can -+ // either make it split on '\r\n', '\n' or '\r' but not what we would like -+ // to do, namely '\r?\n'. We want to keep CR characters inside of a diff -+ // line so that we can mark them using the specialChars attribute so -+ // we convert all \r\n to \n and remove any trailing \r character. -+ const text = -+ this.props.text.indexOf('\r') !== -1 -+ ? this.props.text -+ // Capture the \r if followed by (positive lookahead) a \n or -+ // the end of the string. Note that this does not capture the \n. -+ .replace(/\r(?=\n|$)/g, '') -+ : this.props.text -+ -+ return ( -+ -+ ) -+ } -+} -merged - result 100644 2554a2b18a26273423e0c5b405f02cfc870a00e4 app/src/ui/discard-changes/discard-changes-dialog.tsx - our 100644 78b4d51f4ee8816a057066d15e425e65833d4ef1 app/src/ui/discard-changes/discard-changes-dialog.tsx -@@ -15,6 +15,12 @@ - readonly dispatcher: Dispatcher - readonly files: ReadonlyArray - readonly confirmDiscardChanges: boolean -+ /** -+ * Determines whether to show the option -+ * to ask for confirmation when discarding -+ * changes -+ */ -+ readonly showDiscardChangesSetting: boolean - readonly onDismissed: () => void - readonly onConfirmDiscardChangesChanged: (optOut: boolean) => void - } -@@ -65,15 +71,7 @@ -

- Changes can be restored by retrieving them from the {trashName}. -

-- -+ {this.renderConfirmDiscardChanges()} - - - -@@ -88,6 +86,27 @@ - ) - } - -+ private renderConfirmDiscardChanges() { -+ if (this.props.showDiscardChangesSetting) { -+ return ( -+ -+ ) -+ } else { -+ // since we ignore the users option to not show -+ // confirmation, we don't want to show a checkbox -+ // that will have no effect -+ return null -+ } -+ } -+ - private renderFileList() { - if (this.props.files.length > MaxFilesToList) { - return ( -@@ -126,7 +145,9 @@ - this.props.onDismissed() - } - -- private onCheckboxChanged = (event: React.FormEvent) => { -+ private onConfirmDiscardChangesChanged = ( -+ event: React.FormEvent -+ ) => { - const value = !event.currentTarget.checked - - this.setState({ confirmDiscardChanges: value }) -merged - result 100644 3e0e90eccd5a8894b7cce153c15009fe732a39cc app/src/ui/history/commit-list.tsx - our 100644 a440227b4ebc22b52f57595a0c3e68129de6bfdf app/src/ui/history/commit-list.tsx -@@ -12,7 +12,7 @@ - readonly gitHubRepository: GitHubRepository | null - - /** The list of commits SHAs to display, in order. */ -- readonly commits: ReadonlyArray -+ readonly commitSHAs: ReadonlyArray - - /** The commits loaded, keyed by their full SHA. */ - readonly commitLookup: Map -@@ -29,6 +29,9 @@ - /** The list of known local commits for the current branch */ - readonly localCommitSHAs: ReadonlyArray - -+ /** The message to display inside the list when no results are displayed */ -+ readonly emptyListMessage: JSX.Element | string -+ - /** Callback which fires when a commit has been selected in the list */ - readonly onCommitSelected: (commit: Commit) => void - -@@ -45,7 +48,7 @@ - /** A component which displays the list of commits. */ - export class CommitList extends React.Component { - private renderCommit = (row: number) => { -- const sha = this.props.commits[row] -+ const sha = this.props.commitSHAs[row] - const commit = this.props.commitLookup.get(sha) - - if (commit == null) { -@@ -73,8 +76,8 @@ - ) - } - -- private onRowChanged = (row: number) => { -- const sha = this.props.commits[row] -+ private onSelectedRowChanged = (row: number) => { -+ const sha = this.props.commitSHAs[row] - const commit = this.props.commitLookup.get(sha) - if (commit) { - this.props.onCommitSelected(commit) -@@ -94,25 +97,27 @@ - return -1 - } - -- return this.props.commits.findIndex(s => s === sha) -+ return this.props.commitSHAs.findIndex(s => s === sha) - } - - public render() { -- if (this.props.commits.length === 0) { -- return
No history
-+ if (this.props.commitSHAs.length === 0) { -+ return ( -+
{this.props.emptyListMessage}
-+ ) - } - - return ( -
- -added in remote - their 100644 16d4efb540d90ba9514f7b5da356f9fa5372e2f6 app/src/ui/history/compare-branch-list-item.tsx -@@ -0,0 +1,58 @@ -+import * as React from 'react' -+ -+import { Octicon, OcticonSymbol } from '../octicons' -+import { HighlightText } from '../lib/highlight-text' -+import { Branch, IAheadBehind } from '../../models/branch' -+import { IMatches } from '../../lib/fuzzy-find' -+ -+interface ICompareBranchListItemProps { -+ readonly branch: Branch -+ -+ /** Specifies whether this item is currently selected */ -+ readonly isCurrentBranch: boolean -+ -+ /** The characters in the branch name to highlight */ -+ readonly matches: IMatches -+ -+ readonly aheadBehind: IAheadBehind | null -+} -+ -+export class CompareBranchListItem extends React.Component< -+ ICompareBranchListItemProps, -+ {} -+> { -+ public render() { -+ const isCurrentBranch = this.props.isCurrentBranch -+ const branch = this.props.branch -+ const icon = isCurrentBranch ? OcticonSymbol.check : OcticonSymbol.gitBranch -+ -+ const aheadBehind = this.props.aheadBehind -+ -+ const aheadBehindElement = aheadBehind ? ( -+
-+ -+ {aheadBehind.behind} -+ -+ -+ -+ -+ {aheadBehind.ahead} -+ -+ -+
-+ ) : null -+ -+ return ( -+
-+ -+
-+ -+
-+ {aheadBehindElement} -+
-+ ) -+ } -+} -added in remote - their 100644 bcdf27db5507a5d1393fd75a4a3d177d41a3e81c app/src/ui/history/compare.tsx -@@ -0,0 +1,576 @@ -+import * as React from 'react' -+import { CSSTransitionGroup } from 'react-transition-group' -+ -+import { IGitHubUser } from '../../lib/databases' -+import { Commit } from '../../models/commit' -+import { -+ ComparisonView, -+ ICompareState, -+ CompareActionKind, -+ ICompareBranch, -+} from '../../lib/app-state' -+import { CommitList } from './commit-list' -+import { Repository } from '../../models/repository' -+import { Branch } from '../../models/branch' -+import { Dispatcher } from '../../lib/dispatcher' -+import { ThrottledScheduler } from '../lib/throttled-scheduler' -+import { BranchList } from '../branches' -+import { TextBox } from '../lib/text-box' -+import { IBranchListItem } from '../branches/group-branches' -+import { TabBar } from '../tab-bar' -+import { CompareBranchListItem } from './compare-branch-list-item' -+import { FancyTextBox } from '../lib/fancy-text-box' -+import { OcticonSymbol } from '../octicons' -+import { SelectionSource } from '../lib/filter-list' -+import { IMatches } from '../../lib/fuzzy-find' -+import { Ref } from '../lib/ref' -+import { -+ NewCommitsBanner, -+ DismissalReason, -+} from '../notification/new-commits-banner' -+import { enableNotificationOfBranchUpdates } from '../../lib/feature-flag' -+import { MergeCallToAction } from './merge-call-to-action' -+ -+interface ICompareSidebarProps { -+ readonly repository: Repository -+ readonly compareState: ICompareState -+ readonly gitHubUsers: Map -+ readonly emoji: Map -+ readonly commitLookup: Map -+ readonly localCommitSHAs: ReadonlyArray -+ readonly dispatcher: Dispatcher -+ readonly currentBranch: Branch | null -+ readonly isDivergingBranchBannerVisible: boolean -+ readonly onRevertCommit: (commit: Commit) => void -+ readonly onViewCommitOnGitHub: (sha: string) => void -+} -+ -+interface ICompareSidebarState { -+ /** -+ * This branch should only be used when tracking interactions that the user is performing. -+ * -+ * For all other cases, use the prop -+ */ -+ readonly focusedBranch: Branch | null -+ readonly selectedCommit: Commit | null -+ -+ /** -+ * Flag that tracks whether the user interacted with one of the notification's -+ * "call to action" buttons -+ */ -+ readonly hasConsumedNotification: boolean -+} -+ -+/** If we're within this many rows from the bottom, load the next history batch. */ -+const CloseToBottomThreshold = 10 -+ -+export class CompareSidebar extends React.Component< -+ ICompareSidebarProps, -+ ICompareSidebarState -+> { -+ private textbox: TextBox | null = null -+ private readonly loadChangedFilesScheduler = new ThrottledScheduler(200) -+ private branchList: BranchList | null = null -+ private loadingMoreCommitsPromise: Promise | null = null -+ -+ public constructor(props: ICompareSidebarProps) { -+ super(props) -+ -+ this.state = { -+ focusedBranch: null, -+ selectedCommit: null, -+ hasConsumedNotification: false, -+ } -+ } -+ -+ public componentWillReceiveProps(nextProps: ICompareSidebarProps) { -+ const newFormState = nextProps.compareState.formState -+ const oldFormState = this.props.compareState.formState -+ -+ if (this.textbox !== null) { -+ if ( -+ !this.props.compareState.showBranchList && -+ nextProps.compareState.showBranchList -+ ) { -+ // showBranchList changes from false -> true -+ // -> ensure the textbox has focus -+ this.textbox.focus() -+ } else if ( -+ this.props.compareState.showBranchList && -+ !nextProps.compareState.showBranchList -+ ) { -+ // showBranchList changes from true -> false -+ // -> ensure the textbox no longer has focus -+ this.textbox.blur() -+ } -+ } -+ -+ if ( -+ newFormState.kind !== oldFormState.kind && -+ newFormState.kind === ComparisonView.None -+ ) { -+ this.setState({ -+ focusedBranch: null, -+ }) -+ return -+ } -+ -+ if ( -+ newFormState.kind !== ComparisonView.None && -+ oldFormState.kind !== ComparisonView.None -+ ) { -+ const oldBranch = oldFormState.comparisonBranch -+ const newBranch = newFormState.comparisonBranch -+ -+ if (oldBranch.name !== newBranch.name) { -+ // ensure the focused branch is in sync with the chosen branch -+ this.setState({ -+ focusedBranch: newBranch, -+ }) -+ } -+ } -+ } -+ -+ public componentWillMount() { -+ this.props.dispatcher.initializeCompare(this.props.repository) -+ } -+ -+ public componentWillUnmount() { -+ this.textbox = null -+ } -+ -+ public render() { -+ const { allBranches, filterText, showBranchList } = this.props.compareState -+ const placeholderText = getPlaceholderText(this.props.compareState) -+ const DivergingBannerAnimationTimeout = 300 -+ -+ return ( -+
-+ -+ {this.renderNotificationBanner()} -+ -+ -+
-+ -+
-+ -+ {showBranchList ? this.renderFilterList() : this.renderCommits()} -+
-+ ) -+ } -+ -+ private onBranchesListRef = (branchList: BranchList | null) => { -+ this.branchList = branchList -+ } -+ -+ private renderNotificationBanner() { -+ if (!enableNotificationOfBranchUpdates()) { -+ return null -+ } -+ -+ if (!this.props.isDivergingBranchBannerVisible) { -+ return null -+ } -+ -+ const { inferredComparisonBranch } = this.props.compareState -+ -+ return inferredComparisonBranch.branch !== null && -+ inferredComparisonBranch.aheadBehind !== null && -+ inferredComparisonBranch.aheadBehind.behind > 0 ? ( -+
-+ -+
-+ ) : null -+ } -+ -+ private renderCommits() { -+ const formState = this.props.compareState.formState -+ return ( -+
-+ {formState.kind === ComparisonView.None -+ ? this.renderCommitList() -+ : this.renderTabBar(formState)} -+
-+ ) -+ } -+ -+ private viewHistoryForBranch = () => { -+ this.props.dispatcher.executeCompare(this.props.repository, { -+ kind: CompareActionKind.History, -+ }) -+ -+ this.props.dispatcher.updateCompareForm(this.props.repository, { -+ showBranchList: false, -+ }) -+ } -+ -+ private renderCommitList() { -+ const { formState, commitSHAs } = this.props.compareState -+ const selectedCommit = this.state.selectedCommit -+ -+ let emptyListMessage: string | JSX.Element -+ if (formState.kind === ComparisonView.None) { -+ emptyListMessage = 'No history' -+ } else { -+ const currentlyComparedBranchName = formState.comparisonBranch.name -+ -+ emptyListMessage = -+ formState.kind === ComparisonView.Ahead ? ( -+

-+ The compared branch ({currentlyComparedBranchName}) is up -+ to date with your branch -+

-+ ) : ( -+

-+ Your branch is up to date with the compared branch ( -+ {currentlyComparedBranchName} -+ ) -+

-+ ) -+ } -+ -+ return ( -+ -+ ) -+ } -+ -+ private renderActiveTab() { -+ const formState = this.props.compareState.formState -+ return ( -+
-+ {this.renderCommitList()} -+ {formState.kind === ComparisonView.Behind -+ ? this.renderMergeCallToAction(formState) -+ : null} -+
-+ ) -+ } -+ -+ private renderFilterList() { -+ const { -+ defaultBranch, -+ allBranches, -+ recentBranches, -+ filterText, -+ } = this.props.compareState -+ -+ return ( -+ -+ ) -+ } -+ -+ private renderMergeCallToAction(formState: ICompareBranch) { -+ if (this.props.currentBranch == null) { -+ return null -+ } -+ -+ return ( -+ -+ ) -+ } -+ -+ private onTabClicked = (index: number) => { -+ const formState = this.props.compareState.formState -+ -+ if (formState.kind === ComparisonView.None) { -+ return -+ } -+ -+ const mode = index === 0 ? ComparisonView.Behind : ComparisonView.Ahead -+ const branch = formState.comparisonBranch -+ -+ this.props.dispatcher.executeCompare(this.props.repository, { -+ kind: CompareActionKind.Branch, -+ branch, -+ mode, -+ }) -+ } -+ -+ private renderTabBar(formState: ICompareBranch) { -+ const selectedTab = formState.kind === ComparisonView.Behind ? 0 : 1 -+ -+ return ( -+
-+ -+ {`Behind (${formState.aheadBehind.behind})`} -+ {`Ahead (${formState.aheadBehind.ahead})`} -+ -+ {this.renderActiveTab()} -+
-+ ) -+ } -+ -+ private renderCompareBranchListItem = ( -+ item: IBranchListItem, -+ matches: IMatches -+ ) => { -+ const currentBranch = this.props.currentBranch -+ -+ const currentBranchName = currentBranch != null ? currentBranch.name : null -+ const branch = item.branch -+ -+ const aheadBehind = currentBranch -+ ? this.props.compareState.aheadBehindCache.get( -+ currentBranch.tip.sha, -+ branch.tip.sha -+ ) -+ : null -+ -+ return ( -+ -+ ) -+ } -+ -+ private onBranchFilterKeyDown = ( -+ event: React.KeyboardEvent -+ ) => { -+ const key = event.key -+ -+ if (key === 'Enter') { -+ if (this.props.compareState.filterText.length === 0) { -+ this.handleEscape() -+ } else { -+ if (this.state.focusedBranch == null) { -+ this.viewHistoryForBranch() -+ } else { -+ const branch = this.state.focusedBranch -+ -+ this.props.dispatcher.executeCompare(this.props.repository, { -+ kind: CompareActionKind.Branch, -+ branch, -+ mode: ComparisonView.Behind, -+ }) -+ -+ this.props.dispatcher.updateCompareForm(this.props.repository, { -+ filterText: branch.name, -+ }) -+ } -+ -+ if (this.textbox) { -+ this.textbox.blur() -+ } -+ } -+ } else if (key === 'Escape') { -+ this.handleEscape() -+ } else if (key === 'ArrowDown') { -+ if (this.branchList !== null) { -+ this.branchList.selectFirstItem(true) -+ } -+ } -+ } -+ -+ private handleEscape = () => { -+ this.clearFilterState() -+ if (this.textbox) { -+ this.textbox.blur() -+ } -+ } -+ -+ private onCommitSelected = (commit: Commit) => { -+ this.props.dispatcher.changeHistoryCommitSelection( -+ this.props.repository, -+ commit.sha -+ ) -+ -+ this.loadChangedFilesScheduler.queue(() => { -+ this.props.dispatcher.loadChangedFilesForCurrentSelection( -+ this.props.repository -+ ) -+ }) -+ -+ this.setState({ selectedCommit: commit }) -+ } -+ -+ private onScroll = (start: number, end: number) => { -+ const compareState = this.props.compareState -+ const formState = compareState.formState -+ -+ if (formState.kind !== ComparisonView.None) { -+ // as the app is currently comparing the current branch to some other -+ // branch, everything needed should be loaded -+ return -+ } -+ -+ const commits = compareState.commitSHAs -+ if (commits.length - end <= CloseToBottomThreshold) { -+ if (this.loadingMoreCommitsPromise != null) { -+ // as this callback fires for any scroll event we need to guard -+ // against re-entrant calls to loadNextHistoryBatch -+ return -+ } -+ -+ this.loadingMoreCommitsPromise = this.props.dispatcher -+ .loadNextHistoryBatch(this.props.repository) -+ .then(() => { -+ // deferring unsetting this flag to some time _after_ the commits -+ // have been appended to prevent eagerly adding more commits due -+ // to scroll events (which fire indiscriminately) -+ window.setTimeout(() => { -+ this.loadingMoreCommitsPromise = null -+ }, 500) -+ }) -+ } -+ } -+ -+ private onBranchFilterTextChanged = (filterText: string) => { -+ if (filterText.length === 0) { -+ this.setState({ focusedBranch: null }) -+ } -+ -+ this.props.dispatcher.updateCompareForm(this.props.repository, { -+ filterText, -+ }) -+ } -+ -+ private clearFilterState = () => { -+ this.setState({ -+ focusedBranch: null, -+ }) -+ -+ this.props.dispatcher.updateCompareForm(this.props.repository, { -+ filterText: '', -+ }) -+ -+ this.viewHistoryForBranch() -+ } -+ -+ private onBranchItemClicked = (branch: Branch) => { -+ this.props.dispatcher.executeCompare(this.props.repository, { -+ branch, -+ kind: CompareActionKind.Branch, -+ mode: ComparisonView.Behind, -+ }) -+ -+ this.setState({ -+ focusedBranch: null, -+ }) -+ -+ this.props.dispatcher.updateCompareForm(this.props.repository, { -+ filterText: branch.name, -+ showBranchList: false, -+ }) -+ } -+ -+ private onSelectionChanged = ( -+ branch: Branch | null, -+ source: SelectionSource -+ ) => { -+ if (source.kind === 'mouseclick' && branch != null) { -+ this.props.dispatcher.executeCompare(this.props.repository, { -+ branch, -+ kind: CompareActionKind.Branch, -+ mode: ComparisonView.Behind, -+ }) -+ } -+ -+ this.setState({ -+ focusedBranch: branch, -+ }) -+ } -+ -+ private onTextBoxFocused = () => { -+ this.props.dispatcher.updateCompareForm(this.props.repository, { -+ showBranchList: true, -+ }) -+ } -+ -+ private onTextBoxRef = (textbox: TextBox) => { -+ this.textbox = textbox -+ } -+ -+ private onNotificationBannerDismissed = (reason: DismissalReason) => { -+ this.props.dispatcher.setDivergingBranchBannerVisibility(false) -+ this.props.dispatcher.recordDivergingBranchBannerDismissal() -+ -+ switch (reason) { -+ case 'close': -+ this.setState({ hasConsumedNotification: false }) -+ break -+ case 'compare': -+ case 'merge': -+ this.setState({ hasConsumedNotification: true }) -+ break -+ } -+ } -+ -+ private onMerge = () => { -+ if (this.state.hasConsumedNotification) { -+ this.props.dispatcher.recordDivergingBranchBannerInfluencedMerge() -+ } -+ } -+} -+ -+function getPlaceholderText(state: ICompareState) { -+ const { allBranches, formState } = state -+ -+ if (allBranches.length === 0) { -+ return __DARWIN__ ? 'No Branches to Compare' : 'No branches to compare' -+ } else if (formState.kind === ComparisonView.None) { -+ return __DARWIN__ -+ ? 'Select Branch to Compare...' -+ : 'Select branch to compare...' -+ } else { -+ return undefined -+ } -+} -merged - result 100644 1089df377346334f2f773b466948b625f3c4cab3 app/src/ui/history/file-list.tsx - our 100644 458d1749d658b33d17f3dfc497271a59131f9345 app/src/ui/history/file-list.tsx -@@ -1,18 +1,53 @@ - import * as React from 'react' -+import * as Path from 'path' -+import { pathExists } from 'fs-extra' -+import { revealInFileManager } from '../../lib/app-shell' -+ - import { FileChange, mapStatus, iconForStatus } from '../../models/status' -+import { Repository } from '../../models/repository' -+ - import { PathLabel } from '../lib/path-label' --import { Octicon } from '../octicons' -+import { -+ isSafeFileExtension, -+ DefaultEditorLabel, -+ RevealInFileManagerLabel, -+ OpenWithDefaultProgramLabel, -+} from '../lib/context-menu' - import { List } from '../lib/list' - -+import { Octicon } from '../octicons' -+import { showContextualMenu } from '../main-process-proxy' -+ - interface IFileListProps { - readonly files: ReadonlyArray - readonly selectedFile: FileChange | null - readonly onSelectedFileChanged: (file: FileChange) => void - readonly availableWidth: number -+ -+ /** -+ * Called to open a file with its default application -+ * @param path The path of the file relative to the root of the repository -+ */ -+ readonly onOpenItem: (path: string) => void -+ -+ /** The name of the currently selected external editor */ -+ readonly externalEditorLabel?: string -+ -+ /** -+ * Called to open a file using the user's configured applications -+ * @param path The path of the file relative to the root of the repository -+ */ -+ readonly onOpenInExternalEditor: (path: string) => void -+ -+ /** -+ * Repository that we use to get the base path and build -+ * full path for the file in commit to check for file existence -+ */ -+ readonly repository: Repository - } - - export class FileList extends React.Component { -- private onSelectionChanged = (row: number) => { -+ private onSelectedRowChanged = (row: number) => { - const file = this.props.files[row] - this.props.onSelectedFileChanged(file) - } -@@ -32,7 +67,7 @@ - statusWidth - - return ( --
-+
- -
- ) - } -+ -+ private onContextMenu = async (event: React.MouseEvent) => { -+ event.preventDefault() -+ -+ if (this.props.selectedFile == null) { -+ return -+ } -+ -+ const filePath = this.props.selectedFile.path -+ const fullPath = Path.join(this.props.repository.path, filePath) -+ const fileExistsOnDisk = await pathExists(fullPath) -+ if (!fileExistsOnDisk) { -+ showContextualMenu([ -+ { -+ label: __DARWIN__ -+ ? 'File Does Not Exist on Disk' -+ : 'File does not exist on disk', -+ enabled: false, -+ }, -+ ]) -+ return -+ } -+ -+ const extension = Path.extname(filePath) -+ -+ const isSafeExtension = isSafeFileExtension(extension) -+ const openInExternalEditor = this.props.externalEditorLabel -+ ? `Open in ${this.props.externalEditorLabel}` -+ : DefaultEditorLabel -+ -+ const items = [ -+ { -+ label: RevealInFileManagerLabel, -+ action: () => revealInFileManager(this.props.repository, filePath), -+ enabled: fileExistsOnDisk, -+ }, -+ { -+ label: openInExternalEditor, -+ action: () => this.props.onOpenInExternalEditor(fullPath), -+ enabled: isSafeExtension && fileExistsOnDisk, -+ }, -+ { -+ label: OpenWithDefaultProgramLabel, -+ action: () => this.props.onOpenItem(filePath), -+ enabled: isSafeExtension && fileExistsOnDisk, -+ }, -+ ] -+ showContextualMenu(items) -+ } - } -removed in remote - base 100644 7d1e09aa5b1ea18dda23f94daadcfe54a2491b42 app/src/ui/history/history.tsx - our 100644 7d1e09aa5b1ea18dda23f94daadcfe54a2491b42 app/src/ui/history/history.tsx -@@ -1,178 +0,0 @@ --import * as React from 'react' --import { CommitSummary } from './commit-summary' --import { Diff } from '../diff' --import { FileList } from './file-list' --import { Repository } from '../../models/repository' --import { CommittedFileChange, FileChange } from '../../models/status' --import { Commit } from '../../models/commit' --import { Dispatcher } from '../../lib/dispatcher' --import { -- IHistoryState as IAppHistoryState, -- ImageDiffType, --} from '../../lib/app-state' --import { encodePathAsUrl } from '../../lib/path' --import { ThrottledScheduler } from '../lib/throttled-scheduler' --import { IGitHubUser } from '../../lib/databases' --import { Resizable } from '../resizable' -- --interface IHistoryProps { -- readonly repository: Repository -- readonly dispatcher: Dispatcher -- readonly history: IAppHistoryState -- readonly emoji: Map -- readonly commits: Map -- readonly commitSummaryWidth: number -- readonly gitHubUsers: Map -- readonly imageDiffType: ImageDiffType --} -- --interface IHistoryState { -- readonly isExpanded: boolean --} -- --/** The History component. Contains the commit list, commit summary, and diff. */ --export class History extends React.Component { -- private readonly loadChangedFilesScheduler = new ThrottledScheduler(200) -- -- public constructor(props: IHistoryProps) { -- super(props) -- -- this.state = { -- isExpanded: false, -- } -- } -- -- private onFileSelected = (file: FileChange) => { -- this.props.dispatcher.changeHistoryFileSelection( -- this.props.repository, -- file as CommittedFileChange -- ) -- } -- -- public componentWillUpdate(nextProps: IHistoryProps) { -- // Reset isExpanded if we're switching commits. -- if (nextProps.history.selection.sha !== this.props.history.selection.sha) { -- if (this.state.isExpanded) { -- this.setState({ isExpanded: false }) -- } -- } -- } -- -- public componentWillUnmount() { -- this.loadChangedFilesScheduler.clear() -- } -- -- private renderDiff(commit: Commit | null) { -- const files = this.props.history.changedFiles -- const file = this.props.history.selection.file -- const diff = this.props.history.diff -- -- if (!diff || !file) { -- // don't show both 'empty' messages -- const message = files.length === 0 ? '' : 'No file selected' -- -- return ( --
-- {message} --
-- ) -- } -- -- return ( -- -- ) -- } -- -- private renderCommitSummary(commit: Commit) { -- return ( -- -- ) -- } -- -- private onExpandChanged = (isExpanded: boolean) => { -- this.setState({ isExpanded }) -- } -- -- private onCommitSummaryReset = () => { -- this.props.dispatcher.resetCommitSummaryWidth() -- } -- -- private onCommitSummaryResize = (width: number) => { -- this.props.dispatcher.setCommitSummaryWidth(width) -- } -- -- private renderFileList() { -- const files = this.props.history.changedFiles -- if (files.length === 0) { -- return
No files in commit
-- } -- -- // -1 for right hand side border -- const availableWidth = this.props.commitSummaryWidth - 1 -- -- return ( -- -- ) -- } -- -- public render() { -- const sha = this.props.history.selection.sha -- const commit = sha ? this.props.commits.get(sha) || null : null -- -- if (!sha || !commit) { -- return -- } -- -- const className = this.state.isExpanded ? 'expanded' : 'collapsed' -- -- return ( --
-- {this.renderCommitSummary(commit)} --
-- -- {this.renderFileList()} -- -- {this.renderDiff(commit)} --
--
-- ) -- } --} -- --function NoCommitSelected() { -- const BlankSlateImage = encodePathAsUrl( -- __dirname, -- 'static/empty-no-commit.svg' -- ) -- -- return ( --
-- -- No commit selected --
-- ) --} -merged - result 100644 5314aa21a17e6eaad7f73ab8e92c99e6e83f2108 app/src/ui/history/index.ts - our 100644 caa18019759a791f9a4e2b42c02a348a0cf36a0d app/src/ui/history/index.ts -@@ -1,2 +1,2 @@ --export { HistorySidebar } from './sidebar' --export { History } from './history' -+export { SelectedCommit } from './selected-commit' -+export { CompareSidebar } from './compare' -added in remote - their 100644 f43d04c4253b198fd579a2e189a03c4aa13ce472 app/src/ui/history/merge-call-to-action.tsx -@@ -0,0 +1,87 @@ -+import * as React from 'react' -+ -+import { CompareActionKind, ICompareBranch } from '../../lib/app-state' -+import { Repository } from '../../models/repository' -+import { Branch } from '../../models/branch' -+import { Dispatcher } from '../../lib/dispatcher' -+import { Button } from '../lib/button' -+ -+interface IMergeCallToActionProps { -+ readonly repository: Repository -+ readonly dispatcher: Dispatcher -+ readonly currentBranch: Branch -+ readonly formState: ICompareBranch -+ -+ /** -+ * Callback to execute after a merge has been performed -+ */ -+ readonly onMerged: () => void -+} -+ -+export class MergeCallToAction extends React.Component< -+ IMergeCallToActionProps, -+ {} -+> { -+ public render() { -+ const count = this.props.formState.aheadBehind.behind -+ -+ return ( -+
-+ -+ -+ {this.renderMergeDetails( -+ this.props.formState, -+ this.props.currentBranch -+ )} -+
-+ ) -+ } -+ -+ private renderMergeDetails(formState: ICompareBranch, currentBranch: Branch) { -+ const branch = formState.comparisonBranch -+ const count = formState.aheadBehind.behind -+ -+ if (count > 0) { -+ const pluralized = count === 1 ? 'commit' : 'commits' -+ return ( -+
-+ This will merge -+ {` ${count} ${pluralized}`} -+ {` `}from{` `} -+ {branch.name} -+ {` `}into{` `} -+ {currentBranch.name} -+
-+ ) -+ } -+ -+ return null -+ } -+ -+ private onMergeClicked = async (event: React.MouseEvent) => { -+ const formState = this.props.formState -+ -+ this.props.dispatcher.recordCompareInitiatedMerge() -+ -+ await this.props.dispatcher.mergeBranch( -+ this.props.repository, -+ formState.comparisonBranch.name -+ ) -+ -+ this.props.dispatcher.executeCompare(this.props.repository, { -+ kind: CompareActionKind.History, -+ }) -+ -+ this.props.dispatcher.updateCompareForm(this.props.repository, { -+ showBranchList: false, -+ filterText: '', -+ }) -+ this.props.onMerged() -+ } -+} -added in remote - their 100644 70a7fdc0fff924c282d71feffe17b638f50a18fd app/src/ui/history/selected-commit.tsx -@@ -0,0 +1,211 @@ -+import * as React from 'react' -+import * as Path from 'path' -+ -+import { CommitSummary } from './commit-summary' -+import { Diff } from '../diff' -+import { FileList } from './file-list' -+import { Repository } from '../../models/repository' -+import { CommittedFileChange, FileChange } from '../../models/status' -+import { Commit } from '../../models/commit' -+import { Dispatcher } from '../../lib/dispatcher' -+import { ImageDiffType } from '../../lib/app-state' -+import { encodePathAsUrl } from '../../lib/path' -+import { ThrottledScheduler } from '../lib/throttled-scheduler' -+import { IGitHubUser } from '../../lib/databases' -+import { Resizable } from '../resizable' -+import { openFile } from '../../lib/open-file' -+import { IDiff } from '../../models/diff' -+ -+interface ISelectedCommitProps { -+ readonly repository: Repository -+ readonly dispatcher: Dispatcher -+ readonly emoji: Map -+ readonly selectedCommit: Commit | null -+ readonly changedFiles: ReadonlyArray -+ readonly selectedFile: CommittedFileChange | null -+ readonly currentDiff: IDiff | null -+ readonly commitSummaryWidth: number -+ readonly gitHubUsers: Map -+ readonly selectedDiffType: ImageDiffType -+ /** The name of the currently selected external editor */ -+ readonly externalEditorLabel?: string -+ -+ /** -+ * Called to open a file using the user's configured applications -+ * @param path The path of the file relative to the root of the repository -+ */ -+ readonly onOpenInExternalEditor: (path: string) => void -+} -+ -+interface ISelectedCommitState { -+ readonly isExpanded: boolean -+} -+ -+/** The History component. Contains the commit list, commit summary, and diff. */ -+export class SelectedCommit extends React.Component< -+ ISelectedCommitProps, -+ ISelectedCommitState -+> { -+ private readonly loadChangedFilesScheduler = new ThrottledScheduler(200) -+ -+ public constructor(props: ISelectedCommitProps) { -+ super(props) -+ -+ this.state = { -+ isExpanded: false, -+ } -+ } -+ -+ private onFileSelected = (file: FileChange) => { -+ this.props.dispatcher.changeHistoryFileSelection( -+ this.props.repository, -+ file as CommittedFileChange -+ ) -+ } -+ -+ public componentWillUpdate(nextProps: ISelectedCommitProps) { -+ // reset isExpanded if we're switching commits. -+ const currentValue = this.props.selectedCommit -+ ? this.props.selectedCommit.sha -+ : undefined -+ const nextValue = nextProps.selectedCommit -+ ? nextProps.selectedCommit.sha -+ : undefined -+ -+ if ((currentValue || nextValue) && currentValue !== nextValue) { -+ if (this.state.isExpanded) { -+ this.setState({ isExpanded: false }) -+ } -+ } -+ } -+ -+ public componentWillUnmount() { -+ this.loadChangedFilesScheduler.clear() -+ } -+ -+ private renderDiff() { -+ const file = this.props.selectedFile -+ const diff = this.props.currentDiff -+ -+ if (file == null || diff == null) { -+ // don't show both 'empty' messages -+ const message = -+ this.props.changedFiles.length === 0 ? '' : 'No file selected' -+ -+ return ( -+
-+ {message} -+
-+ ) -+ } -+ -+ return ( -+ -+ ) -+ } -+ -+ private renderCommitSummary(commit: Commit) { -+ return ( -+ -+ ) -+ } -+ -+ private onExpandChanged = (isExpanded: boolean) => { -+ this.setState({ isExpanded }) -+ } -+ -+ private onCommitSummaryReset = () => { -+ this.props.dispatcher.resetCommitSummaryWidth() -+ } -+ -+ private onCommitSummaryResize = (width: number) => { -+ this.props.dispatcher.setCommitSummaryWidth(width) -+ } -+ -+ private renderFileList() { -+ const files = this.props.changedFiles -+ if (files.length === 0) { -+ return
No files in commit
-+ } -+ -+ // -1 for right hand side border -+ const availableWidth = this.props.commitSummaryWidth - 1 -+ -+ return ( -+ -+ ) -+ } -+ -+ /** -+ * Open file with default application. -+ * @param path The path of the file relative to the root of the repository -+ */ -+ private onOpenItem = (path: string) => { -+ const fullPath = Path.join(this.props.repository.path, path) -+ openFile(fullPath, this.props.dispatcher) -+ } -+ -+ public render() { -+ const commit = this.props.selectedCommit -+ -+ if (commit == null) { -+ return -+ } -+ -+ const className = this.state.isExpanded ? 'expanded' : 'collapsed' -+ -+ return ( -+
-+ {this.renderCommitSummary(commit)} -+
-+ -+ {this.renderFileList()} -+ -+ {this.renderDiff()} -+
-+
-+ ) -+ } -+} -+ -+function NoCommitSelected() { -+ const BlankSlateImage = encodePathAsUrl( -+ __dirname, -+ 'static/empty-no-commit.svg' -+ ) -+ -+ return ( -+
-+ -+ No commit selected -+
-+ ) -+} -removed in remote - base 100644 5c5a20826435e372f8786d01a203be39bc2046cb app/src/ui/history/sidebar.tsx - our 100644 5c5a20826435e372f8786d01a203be39bc2046cb app/src/ui/history/sidebar.tsx -@@ -1,70 +0,0 @@ --import * as React from 'react' --import { CommitList } from './commit-list' --import { Repository } from '../../models/repository' --import { Commit } from '../../models/commit' --import { Dispatcher } from '../../lib/dispatcher' --import { IGitHubUser } from '../../lib/databases' --import { IHistoryState } from '../../lib/app-state' --import { ThrottledScheduler } from '../lib/throttled-scheduler' -- --/** If we're within this many rows from the bottom, load the next history batch. */ --const CloseToBottomThreshold = 10 -- --interface IHistorySidebarProps { -- readonly repository: Repository -- readonly dispatcher: Dispatcher -- readonly history: IHistoryState -- readonly gitHubUsers: Map -- readonly emoji: Map -- readonly commitLookup: Map -- readonly localCommitSHAs: ReadonlyArray -- readonly onRevertCommit: (commit: Commit) => void -- readonly onViewCommitOnGitHub: (sha: string) => void --} -- --/** The History component. Contains the commit list, commit summary, and diff. */ --export class HistorySidebar extends React.Component { -- private readonly loadChangedFilesScheduler = new ThrottledScheduler(200) -- -- private onCommitSelected = (commit: Commit) => { -- this.props.dispatcher.changeHistoryCommitSelection( -- this.props.repository, -- commit.sha -- ) -- -- this.loadChangedFilesScheduler.queue(() => { -- this.props.dispatcher.loadChangedFilesForCurrentSelection( -- this.props.repository -- ) -- }) -- } -- -- private onScroll = (start: number, end: number) => { -- const history = this.props.history.history -- if (history.length - end <= CloseToBottomThreshold) { -- this.props.dispatcher.loadNextHistoryBatch(this.props.repository) -- } -- } -- -- public componentWillUnmount() { -- this.loadChangedFilesScheduler.clear() -- } -- -- public render() { -- return ( -- -- ) -- } --} -merged - result 100644 e09719d3d34c3169bd68c26a84f6b7040c4d34a1 app/src/ui/index.tsx - our 100644 68dedd34f265a41733b16e76f0ce3b07e05f865e app/src/ui/index.tsx -@@ -12,6 +12,7 @@ - gitAuthenticationErrorHandler, - externalEditorErrorHandler, - openShellErrorHandler, -+ mergeConflictHandler, - lfsAttributeMismatchHandler, - defaultErrorHandler, - missingRepositoryHandler, -@@ -138,6 +139,7 @@ - dispatcher.registerErrorHandler(upstreamAlreadyExistsHandler) - dispatcher.registerErrorHandler(externalEditorErrorHandler) - dispatcher.registerErrorHandler(openShellErrorHandler) -+dispatcher.registerErrorHandler(mergeConflictHandler) - dispatcher.registerErrorHandler(lfsAttributeMismatchHandler) - dispatcher.registerErrorHandler(gitAuthenticationErrorHandler) - dispatcher.registerErrorHandler(pushNeedsPullHandler) -added in remote - their 100644 ea7e335764dce50a5697270ad74ac61d4df250d3 app/src/ui/lib/application-theme.ts -@@ -0,0 +1,56 @@ -+import { assertNever } from '../../lib/fatal-error' -+ -+/** -+ * A set of the user-selectable appearances (aka themes) -+ */ -+export enum ApplicationTheme { -+ Light, -+ Dark, -+} -+ -+/** -+ * Gets the friendly name of an application theme for use -+ * in persisting to storage and/or calculating the required -+ * body class name to set in order to apply the theme. -+ */ -+export function getThemeName(theme: ApplicationTheme): string { -+ switch (theme) { -+ case ApplicationTheme.Light: -+ return 'light' -+ case ApplicationTheme.Dark: -+ return 'dark' -+ default: -+ return assertNever(theme, `Unknown theme ${theme}`) -+ } -+} -+ -+// The key under which the currently selected theme is persisted -+// in localStorage. -+const applicationThemeKey = 'theme' -+ -+/** -+ * Load the currently selected theme from the persistent -+ * store (localStorage). If no theme is selected the default -+ * theme will be returned. -+ */ -+export function getPersistedTheme(): ApplicationTheme { -+ return localStorage.getItem(applicationThemeKey) === 'dark' -+ ? ApplicationTheme.Dark -+ : ApplicationTheme.Light -+} -+ -+/** -+ * Load the name of the currently selected theme from the persistent -+ * store (localStorage). If no theme is selected the default -+ * theme name will be returned. -+ */ -+export function getPersistedThemeName(): string { -+ return getThemeName(getPersistedTheme()) -+} -+ -+/** -+ * Store the given theme in the persistent store (localStorage). -+ */ -+export function setPersistedTheme(theme: ApplicationTheme) { -+ localStorage.setItem(applicationThemeKey, getThemeName(theme)) -+} -merged - result 100644 fc57454845110cf3f68a914d768fbd7c0fcb7334 app/src/ui/lib/author-input.tsx - our 100644 ce2ac281f54bee2dd43287b02559765a97896d98 app/src/ui/lib/author-input.tsx -@@ -174,17 +174,6 @@ - return scanWhile(doc, start, (doc, pos) => !predicate(doc, pos), iter) - } - --/** -- * Given a cursor position, expand it into a range covering as -- * long of an autocompletable string as possible. -- */ --function getHintRangeFromCursor(doc: Doc, cursor: Position) { -- return { -- from: scanUntil(doc, cursor, isMarkOrWhitespace, prevPosition), -- to: scanUntil(doc, cursor, isMarkOrWhitespace, nextPosition), -- } --} -- - function appendTextMarker( - cm: Editor, - text: string, -@@ -635,7 +624,10 @@ - const doc = cm.getDoc() - const cursor = doc.getCursor() as Readonly - -- const { from, to } = getHintRangeFromCursor(doc, cursor) -+ // expand the current cursor position into a range covering as -+ // long of an autocompletable string as possible. -+ const from = scanUntil(doc, cursor, isMarkOrWhitespace, prevPosition) -+ const to = scanUntil(doc, cursor, isMarkOrWhitespace, nextPosition) - - const word = doc.getRange(from, to) - -merged - result 100644 e67fec4d040e5e4975cb0ae8992ec28f6683df0e app/src/ui/lib/branch-name-warnings.tsx - our 100644 f5d37c46294aebe893fe8c432c70b78e9297a20b app/src/ui/lib/branch-name-warnings.tsx -@@ -1,4 +1,5 @@ - import * as React from 'react' -+import { Branch } from '../../models/branch' - - import { Row } from './row' - import { Octicon, OcticonSymbol } from '../octicons' -@@ -30,3 +31,18 @@ - return null - } - } -+export function renderBranchHasRemoteWarning(branch: Branch) { -+ if (branch.upstream != null) { -+ return ( -+ -+ -+

-+ This branch is tracking {branch.upstream} and renaming this -+ branch will not change the branch name on the remote. -+

-+
-+ ) -+ } else { -+ return null -+ } -+} -added in remote - their 100644 3700c8d5f94db7df3f64d2b73d4da9ae0dcad379 app/src/ui/lib/bytes.ts -@@ -0,0 +1,27 @@ -+/** -+ * Number sign display mode -+ */ -+export const enum Sign { -+ Normal, -+ Forced, -+} -+ -+/** -+ * Display bytes in human readable format like: -+ * 23GB -+ * -43B -+ * It's also possible to force sign in order to get the -+ * plus sign in case of positive numbers like: -+ * +23GB -+ * -43B -+ */ -+export const formatBytes = (bytes: number, signType: Sign = Sign.Normal) => { -+ if (!Number.isFinite(bytes)) { -+ return 'Unknown' -+ } -+ const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'] -+ const sizeIndex = Math.floor(Math.log(Math.abs(bytes)) / Math.log(1024)) -+ const sign = signType === Sign.Forced && bytes > 0 ? '+' : '' -+ const value = Math.round(bytes / Math.pow(1024, sizeIndex)) -+ return `${sign}${value}${sizes[sizeIndex]}` -+} -added in remote - their 100644 8e64852c77aab8327ec82aee0e7504fd934abe7b app/src/ui/lib/context-menu.ts -@@ -0,0 +1,21 @@ -+const RestrictedFileExtensions = ['.cmd', '.exe', '.bat', '.sh'] -+export const DefaultEditorLabel = __DARWIN__ -+ ? 'Open in External Editor' -+ : 'Open in external editor' -+ -+export const RevealInFileManagerLabel = __DARWIN__ -+ ? 'Reveal in Finder' -+ : __WIN32__ -+ ? 'Show in Explorer' -+ : 'Show in your File Manager' -+ -+export const OpenWithDefaultProgramLabel = __DARWIN__ -+ ? 'Open with Default Program' -+ : 'Open with default program' -+ -+export function isSafeFileExtension(extension: string): boolean { -+ if (__WIN32__) { -+ return RestrictedFileExtensions.indexOf(extension.toLowerCase()) === -1 -+ } -+ return true -+} -added in remote - their 100644 7e0e709f0e2c042f8e122480dc6f4a05460633d4 app/src/ui/lib/fancy-text-box.tsx -@@ -0,0 +1,73 @@ -+import * as React from 'react' -+import { Octicon, OcticonSymbol } from '../octicons' -+import { TextBox, ITextBoxProps } from './text-box' -+import * as classNames from 'classnames' -+ -+interface IFancyTextBoxProps extends ITextBoxProps { -+ /** Icon to render */ -+ readonly symbol: OcticonSymbol -+ -+ /** Callback used to get a reference to internal TextBox */ -+ readonly onRef: (textbox: TextBox) => void -+} -+ -+interface IFancyTextBoxState { -+ readonly isFocused: boolean -+} -+ -+export class FancyTextBox extends React.Component< -+ IFancyTextBoxProps, -+ IFancyTextBoxState -+> { -+ public constructor(props: IFancyTextBoxProps) { -+ super(props) -+ -+ this.state = { isFocused: false } -+ } -+ -+ public render() { -+ const componentCSS = classNames( -+ 'fancy-text-box-component', -+ this.props.className, -+ { disabled: this.props.disabled }, -+ { focused: this.state.isFocused } -+ ) -+ const octiconCSS = classNames('fancy-octicon') -+ -+ return ( -+
-+ -+ -+
-+ ) -+ } -+ -+ private onFocus = () => { -+ if (this.props.onFocus !== undefined) { -+ this.props.onFocus() -+ } -+ -+ this.setState({ isFocused: true }) -+ } -+ -+ private onBlur = () => { -+ if (this.props.onBlur !== undefined) { -+ this.props.onBlur() -+ } -+ -+ this.setState({ isFocused: false }) -+ } -+} -merged - result 100644 c845440dc0449aaf6b81f86a7a77eb0d3d8d1a8f app/src/ui/lib/filter-list.tsx - our 100644 b9bb01a8b42988979f70713fba1d5035438fda4d app/src/ui/lib/filter-list.tsx -@@ -1,16 +1,20 @@ - import * as React from 'react' - import * as classnames from 'classnames' - --import { List, SelectionSource as ListSelectionSource } from '../lib/list' -+import { -+ List, -+ SelectionSource as ListSelectionSource, -+ findNextSelectableRow, -+} from '../lib/list' - import { TextBox } from '../lib/text-box' - import { Row } from '../lib/row' - --import { match, IMatch } from '../../lib/fuzzy-find' -+import { match, IMatch, IMatches } from '../../lib/fuzzy-find' - - /** An item in the filter list. */ - export interface IFilterListItem { - /** The text which represents the item. This is used for filtering. */ -- readonly text: string -+ readonly text: ReadonlyArray - - /** A unique identifier for the item. */ - readonly id: string -@@ -34,7 +38,7 @@ - readonly kind: 'item' - readonly item: T - /** Array of indexes in `item.text` that should be highlighted */ -- readonly matches: ReadonlyArray -+ readonly matches: IMatches - } - - /** -@@ -59,10 +63,7 @@ - readonly selectedItem: T | null - - /** Called to render each visible item. */ -- readonly renderItem: ( -- item: T, -- matches: ReadonlyArray -- ) => JSX.Element | null -+ readonly renderItem: (item: T, matches: IMatches) => JSX.Element | null - - /** Called to render header for the group with the given identifier. */ - readonly renderGroupHeader?: (identifier: string) => JSX.Element | null -@@ -117,6 +118,14 @@ - - /** Called when there are no items to render. */ - readonly renderNoItems?: () => JSX.Element | null -+ -+ /** -+ * A reference to a TextBox that will be used to control this component. -+ * -+ * See https://github.com/desktop/desktop/issues/4317 for refactoring work to -+ * make this more composable which should make this unnecessary. -+ */ -+ readonly filterTextBox?: TextBox - } - - interface IFilterListState { -@@ -151,6 +160,12 @@ - this.state = createStateUpdate(props) - } - -+ public componentWillMount() { -+ if (this.props.filterTextBox !== undefined) { -+ this.filterTextBox = this.props.filterTextBox -+ } -+ } -+ - public componentWillReceiveProps(nextProps: IFilterListProps) { - this.setState(createStateUpdate(nextProps)) - } -@@ -189,29 +204,34 @@ - } - - public componentDidMount() { -- if (this.filterTextBox != null) { -+ if (this.filterTextBox !== null) { - this.filterTextBox.selectAll() - } - } - -+ public renderTextBox() { -+ return ( -+ -+ ) -+ } -+ - public render() { - return ( -
- {this.props.renderPreList ? this.props.renderPreList() : null} - - -- -- -+ {this.props.filterTextBox === undefined ? this.renderTextBox() : null} - {this.props.renderPostFilter ? this.props.renderPostFilter() : null} - - -@@ -220,6 +240,29 @@ - ) - } - -+ public selectFirstItem(focus: boolean = false) { -+ if (this.list === null) { -+ return -+ } -+ -+ const next = findNextSelectableRow( -+ this.state.rows.length, -+ { -+ direction: 'down', -+ row: -1, -+ }, -+ this.canSelectRow -+ ) -+ -+ if (next !== null) { -+ this.setState({ selectedRow: next }, () => { -+ if (focus && this.list !== null) { -+ this.list.focus() -+ } -+ }) -+ } -+ } -+ - private renderContent() { - if (this.state.rows.length === 0 && this.props.renderNoItems) { - return this.props.renderNoItems() -@@ -230,8 +273,8 @@ - rowCount={this.state.rows.length} - rowRenderer={this.renderRow} - rowHeight={this.props.rowHeight} -- selectedRow={this.state.selectedRow} -- onSelectionChanged={this.onSelectionChanged} -+ selectedRows={[this.state.selectedRow]} -+ onSelectedRowChanged={this.onSelectedRowChanged} - onRowClick={this.onRowClick} - onRowKeyDown={this.onRowKeyDown} - canSelectRow={this.canSelectRow} -@@ -269,7 +312,7 @@ - } - } - -- private onSelectionChanged = (index: number, source: SelectionSource) => { -+ private onSelectedRowChanged = (index: number, source: SelectionSource) => { - this.setState({ selectedRow: index }) - - if (this.props.onSelectionChanged) { -@@ -305,8 +348,19 @@ - return - } - -- const firstSelectableRow = list.nextSelectableRow('down', -1) -- const lastSelectableRow = list.nextSelectableRow('up', 0) -+ const rowCount = this.state.rows.length -+ -+ const firstSelectableRow = findNextSelectableRow( -+ rowCount, -+ { direction: 'down', row: -1 }, -+ this.canSelectRow -+ ) -+ const lastSelectableRow = findNextSelectableRow( -+ rowCount, -+ { direction: 'up', row: 0 }, -+ this.canSelectRow -+ ) -+ - let shouldFocus = false - - if (event.key === 'ArrowUp' && row === firstSelectableRow) { -@@ -341,9 +395,15 @@ - return - } - -+ const rowCount = this.state.rows.length -+ - if (key === 'ArrowDown') { -- if (this.state.rows.length > 0) { -- const selectedRow = list.nextSelectableRow('down', -1) -+ if (rowCount > 0) { -+ const selectedRow = findNextSelectableRow( -+ rowCount, -+ { direction: 'down', row: -1 }, -+ this.canSelectRow -+ ) - if (selectedRow != null) { - this.setState({ selectedRow }, () => { - list.focus() -@@ -353,8 +413,12 @@ - - event.preventDefault() - } else if (key === 'ArrowUp') { -- if (this.state.rows.length > 0) { -- const selectedRow = list.nextSelectableRow('up', 0) -+ if (rowCount > 0) { -+ const selectedRow = findNextSelectableRow( -+ rowCount, -+ { direction: 'up', row: 0 }, -+ this.canSelectRow -+ ) - if (selectedRow != null) { - this.setState({ selectedRow }, () => { - list.focus() -@@ -365,7 +429,7 @@ - event.preventDefault() - } else if (key === 'Enter') { - // no repositories currently displayed, bail out -- if (!this.state.rows.length) { -+ if (rowCount === 0) { - return event.preventDefault() - } - -@@ -375,15 +439,25 @@ - return event.preventDefault() - } - -- const row = list.nextSelectableRow('down', -1) -+ const row = findNextSelectableRow( -+ rowCount, -+ { direction: 'down', row: -1 }, -+ this.canSelectRow -+ ) - -- if (row) { -+ if (row != null) { - this.onRowClick(row) - } - } - } - } - -+export function getText( -+ item: T -+): ReadonlyArray { -+ return item['text'] -+} -+ - function createStateUpdate( - props: IFilterListProps - ) { -@@ -392,8 +466,12 @@ - - for (const group of props.groups) { - const items: ReadonlyArray> = filter -- ? match(filter, group.items, 'text') -- : group.items.map(item => ({ score: 1, matches: [], item })) -+ ? match(filter, group.items, getText) -+ : group.items.map(item => ({ -+ score: 1, -+ matches: { title: [], subtitle: [] }, -+ item, -+ })) - - if (!items.length) { - continue -merged - result 100644 709940e3ff06be4683e739ccf2696ae16823aaa8 app/src/ui/lib/focus-container.tsx - our 100644 8b8d3c828c4c092d1c07ade684131afd70e763a0 app/src/ui/lib/focus-container.tsx -@@ -4,6 +4,10 @@ - interface IFocusContainerProps { - readonly className?: string - readonly onClick?: (event: React.MouseEvent) => void -+ readonly onKeyDown?: (event: React.KeyboardEvent) => void -+ -+ /** Callback used when focus is within container */ -+ readonly onFocusWithinChanged?: (focusWithin: boolean) => void - } - - interface IFocusContainerState { -@@ -26,20 +30,43 @@ - IFocusContainerState - > { - private wrapperRef: HTMLDivElement | null = null -+ private focusWithinChangedTimeoutId: number | null = null - - public constructor(props: IFocusContainerProps) { - super(props) - this.state = { focusWithin: false } - } - -+ /** -+ * Update the focus state of the container, aborting any in-flight animation -+ * -+ * @param focusWithin the new focus state of the control -+ */ -+ private onFocusWithinChanged(focusWithin: boolean) { -+ this.setState({ focusWithin }) -+ -+ if (this.focusWithinChangedTimeoutId !== null) { -+ cancelAnimationFrame(this.focusWithinChangedTimeoutId) -+ this.focusWithinChangedTimeoutId = null -+ } -+ -+ this.focusWithinChangedTimeoutId = requestAnimationFrame(() => { -+ if (this.props.onFocusWithinChanged) { -+ this.props.onFocusWithinChanged(focusWithin) -+ } -+ -+ this.focusWithinChangedTimeoutId = null -+ }) -+ } -+ - private onWrapperRef = (elem: HTMLDivElement) => { - if (elem) { - elem.addEventListener('focusin', () => { -- this.setState({ focusWithin: true }) -+ this.onFocusWithinChanged(true) - }) - - elem.addEventListener('focusout', () => { -- this.setState({ focusWithin: false }) -+ this.onFocusWithinChanged(false) - }) - } - -@@ -52,6 +79,12 @@ - } - } - -+ private onKeyDown = (e: React.KeyboardEvent) => { -+ if (this.props.onKeyDown) { -+ this.props.onKeyDown(e) -+ } -+ } -+ - private onMouseDown = (e: React.MouseEvent) => { - // If someone is clicking on the focuscontainer itself we'll - // cancel it, that saves us from having a focusout/in cycle -@@ -72,6 +105,7 @@ - ref={this.onWrapperRef} - onClick={this.onClick} - onMouseDown={this.onMouseDown} -+ onKeyDown={this.onKeyDown} - > - {this.props.children} -
-merged - result 100644 861d4a732ccab52dda47589ad6904afbdd204d56 app/src/ui/lib/list/index.ts - our 100644 c1edf1e2d209c6b876ba5deb92af9d75fa5be1a6 app/src/ui/lib/list/index.ts -@@ -1 +1,2 @@ - export * from './list' -+export * from './selection' -merged - result 100644 e534ebfd72eb9026d47bcdcd9e3077b295db520a app/src/ui/lib/list/list.tsx - our 100644 b802d39f208620ff995e34fe62a149883b81c618 app/src/ui/lib/list/list.tsx -@@ -1,9 +1,19 @@ - import * as React from 'react' - import * as ReactDOM from 'react-dom' - import { Grid, AutoSizer } from 'react-virtualized' --import { shallowEquals } from '../../../lib/equality' -+import { shallowEquals, arrayEquals } from '../../../lib/equality' -+import { FocusContainer } from '../../lib/focus-container' - import { ListRow } from './list-row' -+import { -+ findNextSelectableRow, -+ SelectionSource, -+ SelectionDirection, -+ IMouseClickSource, -+ IKeyboardSource, -+ ISelectAllSource, -+} from './selection' - import { createUniqueId, releaseUniqueId } from '../../lib/id-pool' -+import { range } from '../../../lib/range' - - /** - * Describe the first argument given to the cellRenderer, -@@ -28,37 +38,6 @@ - readonly style: React.CSSProperties - } - --/** -- * Interface describing a user initiated selection change event -- * originating from a pointer device clicking or pressing on an item. -- */ --export interface IMouseClickSource { -- readonly kind: 'mouseclick' -- readonly event: React.MouseEvent --} -- --/** -- * Interface describing a user initiated selection change event -- * originating from a pointer device hovering over an item. -- * Only applicable when selectedOnHover is set. -- */ --export interface IHoverSource { -- readonly kind: 'hover' -- readonly event: React.MouseEvent --} -- --/** -- * Interface describing a user initiated selection change event -- * originating from a keyboard -- */ --export interface IKeyboardSource { -- readonly kind: 'keyboard' -- readonly event: React.KeyboardEvent --} -- --/** A type union of possible sources of a selection changed event */ --export type SelectionSource = IMouseClickSource | IHoverSource | IKeyboardSource -- - export type ClickSource = IMouseClickSource | IKeyboardSource - - interface IListProps { -@@ -89,11 +68,11 @@ - readonly rowHeight: number | ((info: { index: number }) => number) - - /** -- * The currently selected row index. Used to attach a special -- * selection class on that row container as well as being used -+ * The currently selected rows indexes. Used to attach a special -+ * selection class on those row's containers as well as being used - * for keyboard selection. - */ -- readonly selectedRow: number -+ readonly selectedRows: ReadonlyArray - - /** - * This function will be called when a pointer device is pressed and then -@@ -111,16 +90,68 @@ - readonly onRowClick?: (row: number, soure: ClickSource) => void - - /** -+ * This prop defines the behaviour of the selection of items whithin this list. -+ * - 'single' : (default) single list-item selection. [shift] and [ctrl] have -+ * no effect. Use in combination with one of: -+ * onSelectedRowChanged(row: number) -+ * onSelectionChanged(rows: number[]) -+ * - 'range' : allows for selecting continuous ranges. [shift] can be used. -+ * [ctrl] has no effect. Use in combination with one of: -+ * onSelectedRangeChanged(start: number, end: number) -+ * onSelectionChanged(rows: number[]) -+ * - 'multi' : allows range and/or arbitrary selection. [shift] and [ctrl] -+ * can be used. Use in combination with: -+ * onSelectionChanged(rows: number[]) -+ */ -+ readonly selectionMode?: 'single' | 'range' | 'multi' -+ -+ /** - * This function will be called when the selection changes as a result of a - * user keyboard or mouse action (i.e. not when props change). This function - * will not be invoked when an already selected row is clicked on. -+ * Use this function when the selectionMode is 'single' - * - * @param row - The index of the row that was just selected - * @param source - The kind of user action that provoked the change, either - * a pointer device press, hover (if selectOnHover is set) or - * a keyboard event (arrow up/down) - */ -- readonly onSelectionChanged?: (row: number, source: SelectionSource) => void -+ readonly onSelectedRowChanged?: (row: number, source: SelectionSource) => void -+ -+ /** -+ * This function will be called when the selection changes as a result of a -+ * user keyboard or mouse action (i.e. not when props change). This function -+ * will not be invoked when an already selected row is clicked on. -+ * Index parameters are inclusive -+ * Use this function when the selectionMode is 'range' -+ * -+ * @param start - The index of the first selected row -+ * @param end - The index of the last selected row -+ * @param source - The kind of user action that provoked the change, either -+ * a pointer device press, hover (if selectOnHover is set) or -+ * a keyboard event (arrow up/down) -+ */ -+ readonly onSelectedRangeChanged?: ( -+ start: number, -+ end: number, -+ source: SelectionSource -+ ) => void -+ -+ /** -+ * This function will be called when the selection changes as a result of a -+ * user keyboard or mouse action (i.e. not when props change). This function -+ * will not be invoked when an already selected row is clicked on. -+ * Use this function for any selectionMode -+ * -+ * @param rows - The indexes of the row(s) that are part of the selection -+ * @param source - The kind of user action that provoked the change, either -+ * a pointer device press, hover (if selectOnHover is set) or -+ * a keyboard event (arrow up/down) -+ */ -+ readonly onSelectionChanged?: ( -+ rows: ReadonlyArray, -+ source: SelectionSource -+ ) => void - - /** - * A handler called whenever a key down event is received on the -@@ -185,6 +216,21 @@ - readonly rowIdPrefix?: string - } - -+/** -+ * Create an array with row indices between firstRow and lastRow (inclusive). -+ * -+ * This is essentially a range function with the explicit behavior of -+ * inclusive upper and lower bound. -+ */ -+function createSelectionBetween( -+ firstRow: number, -+ lastRow: number -+): ReadonlyArray { -+ // range is upper bound exclusive -+ const end = lastRow > firstRow ? lastRow + 1 : lastRow - 1 -+ return range(firstRow, end) -+} -+ - export class List extends React.Component { - private focusItem: HTMLDivElement | null = null - private fakeScroll: HTMLDivElement | null = null -@@ -254,13 +300,53 @@ - } - } - -+ private onSelectAll = (event: Event) => { -+ const selectionMode = this.props.selectionMode -+ -+ if (selectionMode !== 'range' && selectionMode !== 'multi') { -+ return -+ } -+ -+ event.preventDefault() -+ -+ if (this.props.rowCount <= 0) { -+ return -+ } -+ -+ const source: ISelectAllSource = { kind: 'select-all' } -+ const firstRow = 0 -+ const lastRow = this.props.rowCount - 1 -+ -+ if (this.props.onSelectionChanged) { -+ const newSelection = createSelectionBetween(firstRow, lastRow) -+ this.props.onSelectionChanged(newSelection, source) -+ } -+ -+ if (selectionMode === 'range' && this.props.onSelectedRangeChanged) { -+ this.props.onSelectedRangeChanged(firstRow, lastRow, source) -+ } -+ } -+ - private onRef = (element: HTMLDivElement | null) => { -+ if (element === null && this.list !== null) { -+ this.list.removeEventListener('select-all', this.onSelectAll) -+ } -+ - this.list = element - -+ if (element !== null) { -+ // This is a custom event that desktop emits through -+ // when the user selects the Edit > Select all menu item. We -+ // hijack it and select all list items rather than let it bubble -+ // to electron's default behavior which is to select all selectable -+ // text in the renderer. -+ element.addEventListener('select-all', this.onSelectAll) -+ } -+ - if (this.resizeObserver) { - this.resizeObserver.disconnect() - -- if (element) { -+ if (element !== null) { - this.resizeObserver.observe(element) - } else { - this.setState({ width: undefined, height: undefined }) -@@ -269,10 +355,11 @@ - } - - private handleKeyDown = (event: React.KeyboardEvent) => { -- const row = this.props.selectedRow -- if (row >= 0 && this.props.onRowKeyDown) { -- this.props.onRowKeyDown(row, event) -- } -+ this.props.selectedRows.forEach(row => { -+ if (this.props.onRowKeyDown) { -+ this.props.onRowKeyDown(row, event) -+ } -+ }) - - // The consumer is given a change to prevent the default behavior for - // keyboard navigation so that they can customize its behavior as needed. -@@ -281,10 +368,26 @@ - } - - if (event.key === 'ArrowDown') { -- this.moveSelection('down', event) -+ if ( -+ event.shiftKey && -+ this.props.selectionMode && -+ this.props.selectionMode !== 'single' -+ ) { -+ this.addSelection('down', event) -+ } else { -+ this.moveSelection('down', event) -+ } - event.preventDefault() - } else if (event.key === 'ArrowUp') { -- this.moveSelection('up', event) -+ if ( -+ event.shiftKey && -+ this.props.selectionMode && -+ this.props.selectionMode !== 'single' -+ ) { -+ this.addSelection('up', event) -+ } else { -+ this.moveSelection('up', event) -+ } - event.preventDefault() - } - } -@@ -300,18 +403,37 @@ - // We give consumers the power to prevent the onRowClick event by subscribing - // to the onRowKeyDown event and calling event.preventDefault. This lets - // consumers add their own semantics for keyboard presses. -- if (!event.defaultPrevented && this.props.onRowClick) { -- if (event.key === 'Enter' || event.key === ' ') { -- this.props.onRowClick(rowIndex, { kind: 'keyboard', event }) -- event.preventDefault() -- } -+ if ( -+ !event.defaultPrevented && -+ (event.key === 'Enter' || event.key === ' ') -+ ) { -+ this.toggleSelection(event) -+ event.preventDefault() -+ } -+ } -+ -+ private onKeyDown = (event: React.KeyboardEvent) => { -+ if (event.key === 'Enter' || event.key === ' ') { -+ this.toggleSelection(event) -+ event.preventDefault() - } - } - -+ private toggleSelection = (event: React.KeyboardEvent) => { -+ this.props.selectedRows.forEach(row => { -+ if (this.props.onRowClick) { -+ this.props.onRowClick(row, { kind: 'keyboard', event }) -+ } -+ }) -+ } -+ - private onRowMouseOver = (row: number, event: React.MouseEvent) => { - if (this.props.selectOnHover && this.canSelectRow(row)) { -- if (row !== this.props.selectedRow && this.props.onSelectionChanged) { -- this.props.onSelectionChanged(row, { kind: 'hover', event }) -+ if ( -+ this.props.selectedRows.includes(row) && -+ this.props.onSelectionChanged -+ ) { -+ this.props.onSelectionChanged([row], { kind: 'hover', event }) - // By calling scrollRowToVisible we ensure that hovering over a partially - // visible item at the top or bottom of the list scrolls it into view but - // more importantly `scrollRowToVisible` automatically manages focus so -@@ -322,54 +444,76 @@ - } - } - -- /** -- * Determine the next selectable row, given the direction and row. This will -- * take `canSelectRow` into account. -- * -- * Returns null if no row can be selected. -- */ -- public nextSelectableRow( -- direction: 'up' | 'down', -- row: number -- ): number | null { -- // If the row we're starting from is outside our list, make sure we start -- // walking from _just_ outside the list. We'll also need to walk one more -- // row than we normally would since the first step is just getting us into -- // the list. -- const baseRow = Math.min(Math.max(row, -1), this.props.rowCount) -- const startOutsideList = row < 0 || row >= this.props.rowCount -- const rowDelta = startOutsideList -- ? this.props.rowCount + 1 -- : this.props.rowCount -- -- for (let i = 1; i < rowDelta; i++) { -- const delta = direction === 'up' ? i * -1 : i -- // Modulo accounting for negative values, see https://stackoverflow.com/a/4467559 -- const nextRow = -- (baseRow + delta + this.props.rowCount) % this.props.rowCount -- -- if (this.canSelectRow(nextRow)) { -- return nextRow -- } -+ /** Convenience method for invoking canSelectRow callback when it exists */ -+ private canSelectRow = (rowIndex: number) => { -+ return this.props.canSelectRow ? this.props.canSelectRow(rowIndex) : true -+ } -+ -+ private addSelection( -+ direction: SelectionDirection, -+ event: React.KeyboardEvent -+ ) { -+ if (this.props.selectedRows.length === 0) { -+ return this.moveSelection(direction, event) - } - -- return null -- } -+ const lastSelection = this.props.selectedRows[ -+ this.props.selectedRows.length - 1 -+ ] - -- /** Convenience method for invoking canSelectRow callback when it exists */ -- private canSelectRow(rowIndex: number) { -- return this.props.canSelectRow ? this.props.canSelectRow(rowIndex) : true -+ const selectionOrigin = this.props.selectedRows[0] -+ -+ const newRow = findNextSelectableRow( -+ this.props.rowCount, -+ { direction, row: lastSelection, wrap: false }, -+ this.canSelectRow -+ ) -+ -+ if (newRow != null) { -+ if (this.props.onSelectionChanged) { -+ const newSelection = createSelectionBetween(selectionOrigin, newRow) -+ this.props.onSelectionChanged(newSelection, { kind: 'keyboard', event }) -+ } -+ -+ if ( -+ this.props.selectionMode === 'range' && -+ this.props.onSelectedRangeChanged -+ ) { -+ this.props.onSelectedRangeChanged(selectionOrigin, newRow, { -+ kind: 'keyboard', -+ event, -+ }) -+ } -+ -+ this.scrollRowToVisible(newRow) -+ } - } - - private moveSelection( -- direction: 'up' | 'down', -+ direction: SelectionDirection, - event: React.KeyboardEvent - ) { -- const newRow = this.nextSelectableRow(direction, this.props.selectedRow) -+ const lastSelection = -+ this.props.selectedRows.length > 0 -+ ? this.props.selectedRows[this.props.selectedRows.length - 1] -+ : -1 -+ -+ const newRow = findNextSelectableRow( -+ this.props.rowCount, -+ { direction, row: lastSelection }, -+ this.canSelectRow -+ ) - - if (newRow != null) { - if (this.props.onSelectionChanged) { -- this.props.onSelectionChanged(newRow, { kind: 'keyboard', event }) -+ this.props.onSelectionChanged([newRow], { kind: 'keyboard', event }) -+ } -+ -+ if (this.props.onSelectedRowChanged) { -+ this.props.onSelectedRowChanged(newRow, { -+ kind: 'keyboard', -+ event, -+ }) - } - - this.scrollRowToVisible(newRow) -@@ -407,8 +551,11 @@ - this.state.height !== prevState.height - - if (!gridHasUpdatedAlready) { -- const selectedRowChanged = -- prevProps.selectedRow !== this.props.selectedRow -+ const selectedRowChanged = !arrayEquals( -+ prevProps.selectedRows, -+ this.props.selectedRows -+ ) -+ - const invalidationPropsChanged = !shallowEquals( - prevProps.invalidationProps, - this.props.invalidationProps -@@ -452,13 +599,13 @@ - private renderRow = (params: IRowRendererParams) => { - const rowIndex = params.rowIndex - const selectable = this.canSelectRow(rowIndex) -- const selected = rowIndex === this.props.selectedRow -+ const selected = this.props.selectedRows.indexOf(rowIndex) !== -1 - const focused = rowIndex === this.focusRow - - // An unselectable row shouldn't be focusable - let tabIndex: number | undefined = undefined - if (selectable) { -- tabIndex = selected ? 0 : -1 -+ tabIndex = selected && this.props.selectedRows[0] === rowIndex ? 0 : -1 - } - - // We only need to keep a reference to the focused element -@@ -509,9 +656,12 @@ - ) - } - -+ // we select the last item from the selection array for this prop - const activeDescendant = -- this.props.selectedRow !== -1 && this.state.rowIdPrefix -- ? `${this.state.rowIdPrefix}-${this.props.selectedRow}` -+ this.props.selectedRows.length && this.state.rowIdPrefix -+ ? `${this.state.rowIdPrefix}-${ -+ this.props.selectedRows[this.props.selectedRows.length - 1] -+ }` - : undefined - - const role = this.props.ariaMode === 'menu' ? 'menu' : 'listbox' -@@ -534,13 +684,18 @@ - * Renders the react-virtualized Grid component and optionally - * a fake scroll bar component if running on Windows. - * -- * @param {width} - The width of the Grid as given by AutoSizer -- * @param {height} - The height of the Grid as given by AutoSizer -+ * @param width - The width of the Grid as given by AutoSizer -+ * @param height - The height of the Grid as given by AutoSizer - * - */ - private renderContents(width: number, height: number) { - if (__WIN32__) { -- return [this.renderGrid(width, height), this.renderFakeScroll(height)] -+ return ( -+ <> -+ {this.renderGrid(width, height)} -+ {this.renderFakeScroll(height)} -+ -+ ) - } - - return this.renderGrid(width, height) -@@ -557,8 +712,8 @@ - /** - * Renders the react-virtualized Grid component - * -- * @param {width} - The width of the Grid as given by AutoSizer -- * @param {height} - The height of the Grid as given by AutoSizer -+ * @param width - The width of the Grid as given by AutoSizer -+ * @param height - The height of the Grid as given by AutoSizer - */ - private renderGrid(width: number, height: number) { - let scrollToRow = this.props.scrollToRow -@@ -572,28 +727,32 @@ - // the list itself needs to be focusable so that you can reach - // it with keyboard navigation and select an item. - const tabIndex = -- this.props.selectedRow < 0 && this.props.rowCount > 0 ? 0 : -1 -+ this.props.selectedRows.length < 1 && this.props.rowCount > 0 ? 0 : -1 - - return ( -- -+ -+ -+ - ) - } - -@@ -608,7 +767,7 @@ - * be coupled with styling that hides scroll bars on Grid - * and accurately positions the fake scroll bar. - * -- * @param {height} - The height of the Grid as given by AutoSizer -+ * @param height The height of the Grid as given by AutoSizer - * - */ - private renderFakeScroll(height: number) { -@@ -624,7 +783,6 @@ - - return ( -
-+ if (this.props.selectedRows.includes(row)) { -+ // remove the ability to deselect the last item -+ if (this.props.selectedRows.length === 1) { -+ return -+ } -+ newSelection = this.props.selectedRows.filter(ix => ix !== row) -+ } else { -+ newSelection = [...this.props.selectedRows, row] -+ } -+ -+ this.props.onSelectionChanged(newSelection, { -+ kind: 'mouseclick', -+ event, -+ }) -+ } -+ } else if ( -+ this.props.selectedRows.length !== 1 || -+ (this.props.selectedRows.length === 1 && -+ row !== this.props.selectedRows[0]) -+ ) { -+ /* -+ * if no special key is pressed, and that the selection is different, -+ * single selection occurs -+ */ -+ if (this.props.onSelectionChanged) { -+ this.props.onSelectionChanged([row], { kind: 'mouseclick', event }) -+ } -+ if (this.props.onSelectedRangeChanged) { -+ this.props.onSelectedRangeChanged(row, row, { -+ kind: 'mouseclick', -+ event, -+ }) -+ } -+ if (this.props.onSelectedRowChanged) { -+ this.props.onSelectedRowChanged(row, { kind: 'mouseclick', event }) -+ } - } - } - } -@@ -717,10 +957,13 @@ - */ - public focus() { - if ( -- this.props.selectedRow >= 0 && -- this.props.selectedRow < this.props.rowCount -+ this.props.selectedRows.length > 0 && -+ this.props.selectedRows[this.props.selectedRows.length - 1] < -+ this.props.rowCount - ) { -- this.scrollRowToVisible(this.props.selectedRow) -+ this.scrollRowToVisible( -+ this.props.selectedRows[this.props.selectedRows.length - 1] -+ ) - } else { - if (this.grid) { - const element = ReactDOM.findDOMNode(this.grid) as HTMLDivElement -added in remote - their 100644 e508ad7bd721169b3f96558a76f7e5a32bcf8a71 app/src/ui/lib/list/selection.ts -@@ -0,0 +1,142 @@ -+import * as React from 'react' -+ -+export type SelectionDirection = 'up' | 'down' -+ -+interface ISelectRowAction { -+ /** -+ * The vertical direction use when searching for a selectable row. -+ */ -+ readonly direction: SelectionDirection -+ -+ /** -+ * The starting row index to search from. -+ */ -+ readonly row: number -+ -+ /** -+ * A flag to indicate or not to look beyond the last or first -+ * row (depending on direction) such that given the last row and -+ * a downward direction will consider the first row as a -+ * candidate or given the first row and an upward direction -+ * will consider the last row as a candidate. -+ * -+ * Defaults to true if not set. -+ */ -+ readonly wrap?: boolean -+} -+ -+/** -+ * Interface describing a user initiated selection change event -+ * originating from a pointer device clicking or pressing on an item. -+ */ -+export interface IMouseClickSource { -+ readonly kind: 'mouseclick' -+ readonly event: React.MouseEvent -+} -+ -+/** -+ * Interface describing a user initiated selection change event -+ * originating from a pointer device hovering over an item. -+ * Only applicable when selectedOnHover is set. -+ */ -+export interface IHoverSource { -+ readonly kind: 'hover' -+ readonly event: React.MouseEvent -+} -+ -+/** -+ * Interface describing a user initiated selection change event -+ * originating from a keyboard -+ */ -+export interface IKeyboardSource { -+ readonly kind: 'keyboard' -+ readonly event: React.KeyboardEvent -+} -+ -+/** -+ * Interface describing a user initiated selection of all list -+ * items (usually by clicking the Edit > Select all menu item in -+ * the application window). This is highly specific to GitHub Desktop -+ */ -+export interface ISelectAllSource { -+ readonly kind: 'select-all' -+} -+ -+/** A type union of possible sources of a selection changed event */ -+export type SelectionSource = -+ | IMouseClickSource -+ | IHoverSource -+ | IKeyboardSource -+ | ISelectAllSource -+ -+/** -+ * Determine the next selectable row, given the direction and a starting -+ * row index. Whether a row is selectable or not is determined using -+ * the `canSelectRow` function, which defaults to true if not provided. -+ * -+ * Returns null if no row can be selected or if the only selectable row is -+ * identical to the given row parameter. -+ */ -+export function findNextSelectableRow( -+ rowCount: number, -+ action: ISelectRowAction, -+ canSelectRow: (row: number) => boolean = row => true -+): number | null { -+ if (rowCount === 0) { -+ return null -+ } -+ -+ const { direction, row } = action -+ const wrap = action.wrap === undefined ? true : action.wrap -+ -+ // Ensure the row value is in the range between 0 and rowCount - 1 -+ // -+ // If the row falls outside this range, use the direction -+ // given to choose a suitable value: -+ // -+ // - move in an upward direction -> select last row -+ // - move in a downward direction -> select first row -+ // -+ let currentRow = -+ row < 0 || row >= rowCount ? (direction === 'up' ? rowCount - 1 : 0) : row -+ -+ // handle specific case from switching from filter text to list -+ // -+ // locking currentRow to [0,rowCount) above means that the below loops -+ // will skip over the first entry -+ if (direction === 'down' && row === -1) { -+ currentRow = -1 -+ } -+ -+ const delta = direction === 'up' ? -1 : 1 -+ -+ // Iterate through all rows (starting offset from the -+ // given row and ending on and including the given row) -+ for (let i = 0; i < rowCount; i++) { -+ currentRow += delta -+ -+ if (currentRow >= rowCount) { -+ // We've hit rock bottom, wrap around to the top -+ // if we're allowed to or give up. -+ if (wrap) { -+ currentRow = 0 -+ } else { -+ break -+ } -+ } else if (currentRow < 0) { -+ // We've reached the top, wrap around to the bottom -+ // if we're allowed to or give up -+ if (wrap) { -+ currentRow = rowCount - 1 -+ } else { -+ break -+ } -+ } -+ -+ if (row !== currentRow && canSelectRow(currentRow)) { -+ return currentRow -+ } -+ } -+ -+ return null -+} -merged - result 100644 d99f339f0d967a2ba0f2d644345ead21bc38e5ba app/src/ui/lib/text-box.tsx - our 100644 eb0d0735615b2dfce3311a6dae577bdf93ba84cb app/src/ui/lib/text-box.tsx -@@ -4,7 +4,7 @@ - import { LinkButton } from './link-button' - import { showContextualMenu } from '../main-process-proxy' - --interface ITextBoxProps { -+export interface ITextBoxProps { - /** The label for the input field. */ - readonly label?: string | JSX.Element - -@@ -74,6 +74,21 @@ - - /** The tab index of the input element. */ - readonly tabIndex?: number -+ -+ /** -+ * Callback used when the component is focused. -+ */ -+ readonly onFocus?: () => void -+ -+ /** -+ * Callback used when the component loses focus. -+ */ -+ readonly onBlur?: () => void -+ -+ /** -+ * Callback used when the user has cleared the search text. -+ */ -+ readonly onSearchCleared?: () => void - } - - interface ITextBoxState { -@@ -128,11 +143,18 @@ - * (i.e. if it's not disabled explicitly or implicitly through for example a fieldset). - */ - public focus() { -- if (this.inputElement === null) { -- return -+ if (this.inputElement !== null) { -+ this.inputElement.focus() - } -+ } - -- this.inputElement.focus() -+ /** -+ * Programmatically removes keyboard focus from the inner text input element -+ */ -+ public blur() { -+ if (this.inputElement !== null) { -+ this.inputElement.blur() -+ } - } - - private onChange = (event: React.FormEvent) => { -@@ -145,8 +167,33 @@ - }) - } - -+ private onSearchTextCleared = () => { -+ if (this.props.onSearchCleared != null) { -+ this.props.onSearchCleared() -+ } -+ } -+ -+ /** -+ * The search event here is a Chrome and Safari specific event that is -+ * only reported for input[type=search] elements. -+ * -+ * Source: http://help.dottoro.com/ljdvxmhr.php -+ * -+ * TODO: can we hook into the warning API of React to report on incorrect usage -+ * when you set a `onSearchCleared` callback prop but don't use a `type=search` -+ * input - because this won't set an event handler. -+ * -+ */ - private onInputRef = (element: HTMLInputElement | null) => { -+ if (this.inputElement != null && this.props.type === 'search') { -+ this.inputElement.removeEventListener('search', this.onSearchTextCleared) -+ } -+ - this.inputElement = element -+ -+ if (this.inputElement != null && this.props.type === 'search') { -+ this.inputElement.addEventListener('search', this.onSearchTextCleared) -+ } - } - - private renderLabelLink() { -@@ -184,8 +231,10 @@ - } - - private onKeyDown = (event: React.KeyboardEvent) => { -+ const value = this.state.value -+ - if ( -- this.state.value !== '' && -+ value !== '' && - this.props.type === 'search' && - event.key === 'Escape' - ) { -@@ -197,6 +246,17 @@ - if (this.props.onValueChanged) { - this.props.onValueChanged(value) - } -+ } else if ( -+ this.props.type === 'search' && -+ event.key === 'Escape' && -+ value === '' -+ ) { -+ if (this.props.onBlur) { -+ this.props.onBlur() -+ if (this.inputElement !== null) { -+ this.inputElement.blur() -+ } -+ } - } - - if (this.props.onKeyDown !== undefined) { -@@ -215,6 +275,8 @@ - - ) - } -+ -+ private onFocus = (event: React.FocusEvent) => { -+ if (!this.props.autoFocus && this.props.onFocus !== undefined) { -+ this.props.onFocus() -+ } -+ } -+ -+ private onBlur = (event: React.FocusEvent) => { -+ if (this.props.onBlur !== undefined) { -+ this.props.onBlur() -+ } -+ } - } -merged - result 100644 eb960cbb3550362276de8faca04b1ee76ceeeb7d app/src/ui/lib/throttled-scheduler.ts - our 100644 51483eacd05ac47e8e0f0294f02716133e190a78 app/src/ui/lib/throttled-scheduler.ts -@@ -6,7 +6,7 @@ - /** - * Initialize a new instance of the ThrottledScheduler class - * -- * @param {delay} - The minimum interval between invocations -+ * @param delay The minimum interval between invocations - * of callbacks. - */ - public constructor(delay: number) { -merged - result 100644 6a7e6976257ec16e58a7331db61b40096a9bde08 app/src/ui/merge-branch/merge.tsx - our 100644 ccf9cd14a0406216b970ab0f7e5a98bec880171d app/src/ui/merge-branch/merge.tsx -@@ -1,12 +1,18 @@ - import * as React from 'react' --import { Button } from '../lib/button' -+ -+import { getAheadBehind } from '../../lib/git' - import { Dispatcher } from '../../lib/dispatcher' -+ - import { Branch } from '../../models/branch' - import { Repository } from '../../models/repository' --import { getAheadBehind } from '../../lib/git' -+ -+import { Button } from '../lib/button' - import { ButtonGroup } from '../lib/button-group' -+ - import { Dialog, DialogContent, DialogFooter } from '../dialog' --import { BranchList } from '../branches' -+import { BranchList, IBranchListItem, renderDefaultBranch } from '../branches' -+import { revSymmetricDifference } from '../../lib/git' -+import { IMatches } from '../../lib/fuzzy-find' - - interface IMergeProps { - readonly dispatcher: Dispatcher -@@ -33,6 +39,11 @@ - readonly recentBranches: ReadonlyArray - - /** -+ * The branch to select when the merge dialog is opened -+ */ -+ readonly initialBranch?: Branch -+ -+ /** - * A function that's called when the dialog is dismissed by the user in the - * ways described in the Dialog component's dismissable prop. - */ -@@ -59,12 +70,10 @@ - public constructor(props: IMergeProps) { - super(props) - -- const currentBranch = props.currentBranch -- const defaultBranch = props.defaultBranch -+ const selectedBranch = this.resolveSelectedBranch() - - this.state = { -- // Select the default branch unless that's currently checked out -- selectedBranch: currentBranch === defaultBranch ? null : defaultBranch, -+ selectedBranch, - commitCount: undefined, - filterText: '', - } -@@ -128,6 +137,10 @@ - ) - } - -+ private renderBranch = (item: IBranchListItem, matches: IMatches) => { -+ return renderDefaultBranch(item, matches, this.props.currentBranch) -+ } -+ - public render() { - const selectedBranch = this.state.selectedBranch - const currentBranch = this.props.currentBranch -@@ -156,6 +169,7 @@ - selectedBranch={selectedBranch} - onSelectionChanged={this.onSelectionChanged} - canCreateNewBranch={false} -+ renderBranch={this.renderBranch} - /> - - -@@ -172,7 +186,7 @@ - } - - private async updateCommitCount(branch: Branch) { -- const range = `...${branch.name}` -+ const range = revSymmetricDifference('', branch.name) - const aheadBehind = await getAheadBehind(this.props.repository, range) - const commitCount = aheadBehind ? aheadBehind.behind : 0 - -@@ -193,4 +207,21 @@ - this.props.dispatcher.mergeBranch(this.props.repository, branch.name) - this.props.dispatcher.closePopup() - } -+ -+ /** -+ * Returns the branch to use as the selected branch -+ * -+ * The initial branch is used if passed -+ * otherwise, the default branch will be used iff it's -+ * not the currently checked out branch -+ */ -+ private resolveSelectedBranch() { -+ const { currentBranch, defaultBranch, initialBranch } = this.props -+ -+ if (initialBranch !== undefined) { -+ return initialBranch -+ } -+ -+ return currentBranch === defaultBranch ? null : defaultBranch -+ } - } -added in remote - their 100644 994e1b5f87e28b721ae596a604deb0ff02f5e377 app/src/ui/merge-conflicts/index.ts -@@ -0,0 +1 @@ -+export * from './merge-conflicts-warning' -added in remote - their 100644 866251dcc5479cdce56345e42689d894ad96e243 app/src/ui/merge-conflicts/merge-conflicts-warning.tsx -@@ -0,0 +1,54 @@ -+import * as React from 'react' -+import { Button } from '../lib/button' -+import { ButtonGroup } from '../lib/button-group' -+import { Dialog, DialogContent, DialogFooter } from '../dialog' -+import { Dispatcher } from '../../lib/dispatcher' -+import { RepositorySectionTab } from '../../lib/app-state' -+import { Repository } from '../../models/repository' -+ -+interface IMergeConflictsWarningProps { -+ readonly dispatcher: Dispatcher -+ readonly repository: Repository -+ readonly onDismissed: () => void -+} -+ -+export class MergeConflictsWarning extends React.Component< -+ IMergeConflictsWarningProps, -+ {} -+> { -+ private onSubmit = () => { -+ this.props.dispatcher.changeRepositorySection( -+ this.props.repository, -+ RepositorySectionTab.Changes -+ ) -+ this.props.onDismissed() -+ } -+ -+ public render() { -+ return ( -+ -+ -+

Conflicts were detected as part of the last merge operation.

-+

-+ You will need to view and resolve these conflicts via your editor or -+ shell before finishing and creating the merge commit. -+

-+
-+ -+ -+ -+ -+ -+ -+ -+
-+ ) -+ } -+} -added in remote - their 100644 292e9594562025347221742f225faa4c5188009d app/src/ui/notification/new-commits-banner.tsx -@@ -0,0 +1,119 @@ -+import * as React from 'react' -+import { Ref } from '../lib/ref' -+import { Octicon, OcticonSymbol } from '../octicons' -+import { Branch } from '../../models/branch' -+import { Button } from '../lib/button' -+import { Dispatcher } from '../../lib/dispatcher' -+import { Repository } from '../../models/repository' -+import { -+ CompareActionKind, -+ ComparisonView, -+ PopupType, -+} from '../../lib/app-state' -+ -+export type DismissalReason = 'close' | 'compare' | 'merge' -+ -+interface INewCommitsBannerProps { -+ readonly dispatcher: Dispatcher -+ -+ readonly repository: Repository -+ -+ /** -+ * The number of commits behind base branch -+ */ -+ readonly commitsBehindBaseBranch: number -+ -+ /** -+ * The target branch that will accept commits -+ * from the current branch -+ */ -+ readonly baseBranch: Branch -+ -+ /** -+ * Callback used to dismiss the banner -+ */ -+ readonly onDismiss: (reason: DismissalReason) => void -+} -+ -+/** -+ * Banner used to notify user that their branch is a number of commits behind the base branch -+ */ -+export class NewCommitsBanner extends React.Component< -+ INewCommitsBannerProps, -+ {} -+> { -+ public render() { -+ const pluralize = this.props.commitsBehindBaseBranch > 1 -+ -+ return ( -+
-+ -+ -+
-+
-+

-+ We have noticed that your branch is{' '} -+ -+ {this.props.commitsBehindBaseBranch} commit{pluralize -+ ? 's' -+ : ''} -+ {' '} -+ behind {this.props.baseBranch.name}. -+

-+
-+
-+ -+ -+
-+
-+ -+ -+ -+ -+
-+ ) -+ } -+ -+ private onDismissed = () => { -+ this.props.onDismiss('close') -+ } -+ -+ private onComparedClicked = () => { -+ const { repository, dispatcher } = this.props -+ -+ dispatcher.executeCompare(repository, { -+ kind: CompareActionKind.Branch, -+ branch: this.props.baseBranch, -+ mode: ComparisonView.Behind, -+ }) -+ dispatcher.recordDivergingBranchBannerInitiatedCompare() -+ this.props.onDismiss('compare') -+ } -+ -+ private onMergeClicked = () => { -+ const { repository, dispatcher } = this.props -+ -+ dispatcher.showPopup({ -+ type: PopupType.MergeBranch, -+ branch: this.props.baseBranch, -+ repository, -+ }) -+ dispatcher.recordDivergingBranchBannerInitatedMerge() -+ this.props.onDismiss('merge') -+ } -+} -added in remote - their 100644 461f079df545b3f64329fb9b73d8484c1ad0792d app/src/ui/preferences/appearance.tsx -@@ -0,0 +1,49 @@ -+import * as React from 'react' -+import { DialogContent } from '../dialog' -+import { -+ VerticalSegmentedControl, -+ ISegmentedItem, -+} from '../lib/vertical-segmented-control' -+import { ApplicationTheme } from '../lib/application-theme' -+import { fatalError } from '../../lib/fatal-error' -+ -+interface IAppearanceProps { -+ readonly selectedTheme: ApplicationTheme -+ readonly onSelectedThemeChanged: (theme: ApplicationTheme) => void -+} -+ -+const themes: ReadonlyArray = [ -+ { title: 'Light', description: 'The default theme of GitHub Desktop' }, -+ { -+ title: 'Dark (beta)', -+ description: -+ 'A beta version of our dark theme. Still under development. Please report any issues you may find to our issue tracker.', -+ }, -+] -+ -+export class Appearance extends React.Component { -+ private onSelectedThemeChanged = (index: number) => { -+ if (index === 0) { -+ this.props.onSelectedThemeChanged(ApplicationTheme.Light) -+ } else if (index === 1) { -+ this.props.onSelectedThemeChanged(ApplicationTheme.Dark) -+ } else { -+ fatalError(`Unknown theme index ${index}`) -+ } -+ } -+ -+ public render() { -+ const selectedIndex = -+ this.props.selectedTheme === ApplicationTheme.Dark ? 1 : 0 -+ -+ return ( -+ -+ -+ -+ ) -+ } -+} -merged - result 100644 95db24f350ede1c020f0629457aa6ff90b2b6d90 app/src/ui/preferences/preferences.tsx - our 100644 e26aab501de9210761f4d41ed2f05f1f7c516da8 app/src/ui/preferences/preferences.tsx -@@ -21,6 +21,8 @@ - import { Shell, getAvailableShells } from '../../lib/shells' - import { getAvailableEditors } from '../../lib/editors/lookup' - import { disallowedCharacters } from './identifier-rules' -+import { Appearance } from './appearance' -+import { ApplicationTheme } from '../lib/application-theme' - - interface IPreferencesProps { - readonly dispatcher: Dispatcher -@@ -33,6 +35,7 @@ - readonly confirmDiscardChanges: boolean - readonly selectedExternalEditor?: ExternalEditor - readonly selectedShell: Shell -+ readonly selectedTheme: ApplicationTheme - } - - interface IPreferencesState { -@@ -134,6 +137,7 @@ - > - Accounts - Git -+ Appearance - Advanced - - -@@ -203,6 +207,13 @@ - /> - ) - } -+ case PreferencesTab.Appearance: -+ return ( -+ -+ ) - case PreferencesTab.Advanced: { - return ( - { -+ this.props.dispatcher.setSelectedTheme(theme) -+ } -+ - private renderFooter() { - const hasDisabledError = this.state.disallowedCharactersMessage != null - - const index = this.state.selectedIndex - switch (index) { - case PreferencesTab.Accounts: -+ case PreferencesTab.Appearance: - return null - case PreferencesTab.Advanced: - case PreferencesTab.Git: { -merged - result 100644 ffbdef89f9f0f16e966a7d27c2db06bd897c3db6 app/src/ui/publish-repository/publish.tsx - our 100644 dbb16e8d0667b3c7f6a9514dda9d6ec8354fe75d app/src/ui/publish-repository/publish.tsx -@@ -13,7 +13,7 @@ - import { getDotComAPIEndpoint } from '../../lib/api' - import { assertNever, fatalError } from '../../lib/fatal-error' - import { CallToAction } from '../lib/call-to-action' --import { getGitDescription } from '../../lib/git/description' -+import { getGitDescription } from '../../lib/git' - - enum PublishTab { - DotCom = 0, -merged - result 100644 036558085db62e6798f39f0d0f7fdd38b7fca5f1 app/src/ui/rename-branch/rename-branch-dialog.tsx - our 100644 30deb34b0cdc3ac313cbdde5418abcc33bb4a22c app/src/ui/rename-branch/rename-branch-dialog.tsx -@@ -9,7 +9,10 @@ - import { Button } from '../lib/button' - import { ButtonGroup } from '../lib/button-group' - import { Dialog, DialogContent, DialogFooter } from '../dialog' --import { renderBranchNameWarning } from '../lib/branch-name-warnings' -+import { -+ renderBranchNameWarning, -+ renderBranchHasRemoteWarning, -+} from '../lib/branch-name-warnings' - - interface IRenameBranchProps { - readonly dispatcher: Dispatcher -@@ -54,6 +57,7 @@ - this.state.newName, - sanitizedBranchName(this.state.newName) - )} -+ {renderBranchHasRemoteWarning(this.props.branch)} - - - -merged - result 100644 9e6e38681ef352ce76fa65fea817492a6aef088f app/src/ui/repositories-list/group-repositories.ts - our 100644 18baeebd67753abfd4d4547921f30c8bef878511 app/src/ui/repositories-list/group-repositories.ts -@@ -1,22 +1,31 @@ --import { Repository } from '../../models/repository' -+import { Repository, ILocalRepositoryState } from '../../models/repository' - import { CloningRepository } from '../../models/cloning-repository' - import { getDotComAPIEndpoint } from '../../lib/api' - import { caseInsensitiveCompare } from '../../lib/compare' - import { IFilterListGroup, IFilterListItem } from '../lib/filter-list' -+import { IAheadBehind } from '../../models/branch' - - export type RepositoryGroupIdentifier = 'github' | 'enterprise' | 'other' - - export type Repositoryish = Repository | CloningRepository - - export interface IRepositoryListItem extends IFilterListItem { -- readonly text: string -+ readonly text: ReadonlyArray - readonly id: string - readonly repository: Repositoryish - readonly needsDisambiguation: boolean -+ readonly aheadBehind: IAheadBehind | null -+ readonly changedFilesCount: number -+} -+ -+const fallbackValue = { -+ changedFilesCount: 0, -+ aheadBehind: null, - } - - export function groupRepositories( -- repositories: ReadonlyArray -+ repositories: ReadonlyArray, -+ localRepositoryStateLookup: Map - ): ReadonlyArray> { - const grouped = new Map() - for (const repository of repositories) { -@@ -59,11 +68,15 @@ - repositories.sort((x, y) => caseInsensitiveCompare(x.name, y.name)) - const items: ReadonlyArray = repositories.map(r => { - const nameCount = names.get(r.name) || 0 -+ const { aheadBehind, changedFilesCount } = -+ localRepositoryStateLookup.get(r.id) || fallbackValue - return { -- text: r.name, -+ text: [r.name], - id: r.id.toString(), - repository: r, - needsDisambiguation: nameCount > 1, -+ aheadBehind, -+ changedFilesCount, - } - }) - -merged - result 100644 e4ca588b503842ff6df4517d209f5fc5537d4a11 app/src/ui/repositories-list/repositories-list.tsx - our 100644 07ff55df057daaa50bdeec7aaaaafce35d03d1a2 app/src/ui/repositories-list/repositories-list.tsx -@@ -8,23 +8,25 @@ - RepositoryGroupIdentifier, - } from './group-repositories' - import { FilterList } from '../lib/filter-list' -+import { IMatches } from '../../lib/fuzzy-find' - import { assertNever } from '../../lib/fatal-error' -- --/** -- * TS can't parse generic specialization in JSX, so we have to alias it here -- * with the generic type. See https://github.com/Microsoft/TypeScript/issues/6395. -- */ --const RepositoryFilterList: new () => FilterList< -- IRepositoryListItem --> = FilterList as any -+import { ILocalRepositoryState } from '../../models/repository' -+import { enableRepoInfoIndicators } from '../../lib/feature-flag' -+import { Dispatcher } from '../../lib/dispatcher' - - interface IRepositoriesListProps { - readonly selectedRepository: Repositoryish | null - readonly repositories: ReadonlyArray - -+ /** A cache of the latest repository state values, keyed by the repository id */ -+ readonly localRepositoryStateLookup: Map -+ - /** Called when a repository has been selected. */ - readonly onSelectionChanged: (repository: Repositoryish) => void - -+ /** Whether the user has enabled the setting to confirm removing a repository from the app */ -+ readonly askForConfirmationOnRemoveRepository: boolean -+ - /** Called when the repository should be removed. */ - readonly onRemoveRepository: (repository: Repositoryish) => void - -@@ -48,6 +50,8 @@ - - /** The text entered by the user to filter their repository list */ - readonly filterText: string -+ -+ readonly dispatcher: Dispatcher - } - - const RowHeight = 29 -@@ -57,16 +61,16 @@ - IRepositoriesListProps, - {} - > { -- private renderItem = ( -- item: IRepositoryListItem, -- matches: ReadonlyArray -- ) => { -+ private renderItem = (item: IRepositoryListItem, matches: IMatches) => { - const repository = item.repository - return ( - - ) - } -@@ -101,6 +107,14 @@ - } - - private onItemClick = (item: IRepositoryListItem) => { -+ if (enableRepoInfoIndicators()) { -+ const hasIndicator = -+ item.changedFilesCount > 0 || -+ (item.aheadBehind !== null -+ ? item.aheadBehind.ahead > 0 || item.aheadBehind.behind > 0 -+ : false) -+ this.props.dispatcher.recordRepoClicked(hasIndicator) -+ } - this.props.onSelectionChanged(item.repository) - } - -@@ -109,7 +123,10 @@ - return this.noRepositories() - } - -- const groups = groupRepositories(this.props.repositories) -+ const groups = groupRepositories( -+ this.props.repositories, -+ this.props.localRepositoryStateLookup -+ ) - - let selectedItem: IRepositoryListItem | null = null - const selectedRepository = this.props.selectedRepository -@@ -129,7 +146,7 @@ - - return ( -
-- - rowHeight={RowHeight} - selectedItem={selectedItem} - filterText={this.props.filterText} -merged - result 100644 6ca3c771c795eba242cc4b795e3a3b0bbb4c7488 app/src/ui/repositories-list/repository-list-item.tsx - our 100644 8a3459beeeb3be1978c9c1f3a4aefe8f497007fb app/src/ui/repositories-list/repository-list-item.tsx -@@ -1,10 +1,12 @@ - import * as React from 'react' - import { Repository } from '../../models/repository' --import { Octicon, iconForRepository } from '../octicons' -+import { Octicon, iconForRepository, OcticonSymbol } from '../octicons' - import { showContextualMenu } from '../main-process-proxy' - import { Repositoryish } from './group-repositories' - import { IMenuItem } from '../../lib/menu-item' - import { HighlightText } from '../lib/highlight-text' -+import { IMatches } from '../../lib/fuzzy-find' -+import { IAheadBehind } from '../../models/branch' - - const defaultEditorLabel = __DARWIN__ - ? 'Open in External Editor' -@@ -13,6 +15,9 @@ - interface IRepositoryListItemProps { - readonly repository: Repositoryish - -+ /** Whether the user has enabled the setting to confirm removing a repository from the app */ -+ readonly askForConfirmationOnRemoveRepository: boolean -+ - /** Called when the repository should be removed. */ - readonly onRemoveRepository: (repository: Repositoryish) => void - -@@ -35,7 +40,13 @@ - readonly shellLabel: string - - /** The characters in the repository name to highlight */ -- readonly matches: ReadonlyArray -+ readonly matches: IMatches -+ -+ /** Number of commits this local repo branch is behind or ahead of its remote brance */ -+ readonly aheadBehind: IAheadBehind | null -+ -+ /** Number of uncommitted changes */ -+ readonly changedFilesCount: number - } - - /** A repository item. */ -@@ -48,7 +59,37 @@ - const path = repository.path - const gitHubRepo = - repository instanceof Repository ? repository.gitHubRepository : null -- const tooltip = gitHubRepo -+ const hasChanges = this.props.changedFilesCount > 0 -+ const renderAheadBehindIndicator = () => { -+ if ( -+ !(repository instanceof Repository) || -+ this.props.aheadBehind === null -+ ) { -+ return null -+ } -+ const { ahead, behind } = this.props.aheadBehind -+ if (ahead === 0 && behind === 0) { -+ return null -+ } -+ const commitGrammar = (commitNum: number) => -+ `${commitNum} commit${commitNum > 1 ? 's' : ''}` // english is hard -+ const aheadBehindTooltip = -+ 'The currently checked out branch is' + -+ (behind ? ` ${commitGrammar(behind)} behind ` : '') + -+ (behind && ahead ? 'and' : '') + -+ (ahead ? ` ${commitGrammar(ahead)} ahead of ` : '') + -+ 'its tracked branch.' -+ -+ return ( -+
-+ {ahead > 0 ? : null} -+ {behind > 0 ? ( -+ -+ ) : null} -+
-+ ) -+ } -+ const repoTooltip = gitHubRepo - ? gitHubRepo.fullName + '\n' + gitHubRepo.htmlURL + '\n' + path - : path - -@@ -58,20 +99,30 @@ - } - - return ( --
-+
-+
-+ {hasChanges ? ( -+ -+ ) : null} -+
- -- --
-+
- {prefix ? {prefix} : null} - -
-+ -+ {renderAheadBehindIndicator()} -
- ) - } -@@ -101,7 +152,9 @@ - - const showRepositoryLabel = __DARWIN__ - ? 'Show in Finder' -- : __WIN32__ ? 'Show in Explorer' : 'Show in your File Manager' -+ : __WIN32__ -+ ? 'Show in Explorer' -+ : 'Show in your File Manager' - - const items: ReadonlyArray = [ - { -@@ -121,7 +174,9 @@ - }, - { type: 'separator' }, - { -- label: 'Remove', -+ label: this.props.askForConfirmationOnRemoveRepository -+ ? 'Remove…' -+ : 'Remove', - action: this.removeRepository, - }, - ] -merged - result 100644 e58c21864cb0ef80f8d9edc3a5f278674a560cdd app/src/ui/repository.tsx - our 100644 a96947579eba87694e2e84bfba57b1e4814b9ad6 app/src/ui/repository.tsx -@@ -5,26 +5,30 @@ - import { UiView } from './ui-view' - import { Changes, ChangesSidebar } from './changes' - import { NoChanges } from './changes/no-changes' --import { History, HistorySidebar } from './history' -+import { MultipleSelection } from './changes/multiple-selection' -+import { FilesChangedBadge } from './changes/files-changed-badge' -+import { SelectedCommit, CompareSidebar } from './history' - import { Resizable } from './resizable' - import { TabBar } from './tab-bar' - import { -- IRepositoryState as IRepositoryModelState, -- RepositorySection, -+ IRepositoryState, -+ RepositorySectionTab, - ImageDiffType, - } from '../lib/app-state' - import { Dispatcher } from '../lib/dispatcher' - import { IssuesStore, GitHubUserStore } from '../lib/stores' - import { assertNever } from '../lib/fatal-error' --import { Octicon, OcticonSymbol } from './octicons' - import { Account } from '../models/account' -+import { enableNotificationOfBranchUpdates } from '../lib/feature-flag' -+import { FocusContainer } from './lib/focus-container' -+import { OcticonSymbol, Octicon } from './octicons' - - /** The widest the sidebar can be with the minimum window size. */ - const MaxSidebarWidth = 495 - --interface IRepositoryProps { -+interface IRepositoryViewProps { - readonly repository: Repo -- readonly state: IRepositoryModelState -+ readonly state: IRepositoryState - readonly dispatcher: Dispatcher - readonly emoji: Map - readonly sidebarWidth: number -@@ -40,10 +44,21 @@ - readonly externalEditorLabel?: string - - /** -- * Called to open a file using the user's configured applications -- * @param path The path of the file relative to the root of the repository -+ * Callback to open a selected file using the configured external editor -+ * -+ * @param fullPath The full path to the file on disk - */ -- readonly onOpenInExternalEditor: (path: string) => void -+ readonly onOpenInExternalEditor: (fullPath: string) => void -+ -+ /** -+ * Determines if the notification banner and associated dot -+ * on this history tab will be rendered -+ */ -+ readonly isDivergingBranchBannerVisible: boolean -+} -+ -+interface IRepositoryViewState { -+ readonly sidebarHasFocusWithin: boolean - } - - const enum Tab { -@@ -51,12 +66,32 @@ - History = 1, - } - --export class RepositoryView extends React.Component { -+export class RepositoryView extends React.Component< -+ IRepositoryViewProps, -+ IRepositoryViewState -+> { -+ public constructor(props: IRepositoryViewProps) { -+ super(props) -+ -+ this.state = { -+ sidebarHasFocusWithin: false, -+ } -+ } -+ -+ private renderChangesBadge(): JSX.Element | null { -+ const filesChangedCount = this.props.state.changesState.workingDirectory -+ .files.length -+ -+ if (filesChangedCount <= 0) { -+ return null -+ } -+ -+ return -+ } -+ - private renderTabs(): JSX.Element { -- const hasChanges = -- this.props.state.changesState.workingDirectory.files.length > 0 - const selectedTab = -- this.props.state.selectedSection === RepositorySection.Changes -+ this.props.state.selectedSection === RepositorySectionTab.Changes - ? Tab.Changes - : Tab.History - -@@ -64,14 +99,19 @@ - - - Changes -- {hasChanges ? ( -+ {this.renderChangesBadge()} -+ -+ -+
-+ History -+ {enableNotificationOfBranchUpdates() && -+ this.props.isDivergingBranchBannerVisible ? ( - - ) : null} -- -- History -+
-
- ) - } -@@ -116,18 +156,25 @@ - ) - } - -- private renderHistorySidebar(): JSX.Element { -+ private renderCompareSidebar(): JSX.Element { -+ const tip = this.props.state.branchesState.tip -+ const currentBranch = tip.kind === TipState.Valid ? tip.branch : null -+ - return ( -- - ) - } -@@ -135,10 +182,10 @@ - private renderSidebarContents(): JSX.Element { - const selectedSection = this.props.state.selectedSection - -- if (selectedSection === RepositorySection.Changes) { -+ if (selectedSection === RepositorySectionTab.Changes) { - return this.renderChangesSidebar() -- } else if (selectedSection === RepositorySection.History) { -- return this.renderHistorySidebar() -+ } else if (selectedSection === RepositorySectionTab.History) { -+ return this.renderCompareSidebar() - } else { - return assertNever(selectedSection, 'Unknown repository section') - } -@@ -154,57 +201,92 @@ - - private renderSidebar(): JSX.Element { - return ( -- -- {this.renderTabs()} -- {this.renderSidebarContents()} -- -+ -+ -+ {this.renderTabs()} -+ {this.renderSidebarContents()} -+ -+ - ) - } - -- private renderContent(): JSX.Element { -+ private onSidebarFocusWithinChanged = (sidebarHasFocusWithin: boolean) => { -+ // this lets us know that focus is somewhere within the sidebar -+ this.setState({ sidebarHasFocusWithin }) -+ -+ if ( -+ sidebarHasFocusWithin === false && -+ this.props.state.selectedSection === RepositorySectionTab.History -+ ) { -+ this.props.dispatcher.updateCompareForm(this.props.repository, { -+ showBranchList: false, -+ }) -+ } -+ } -+ -+ private renderContent(): JSX.Element | null { - const selectedSection = this.props.state.selectedSection - -- if (selectedSection === RepositorySection.Changes) { -+ if (selectedSection === RepositorySectionTab.Changes) { - const changesState = this.props.state.changesState -- const selectedFileID = changesState.selectedFileID -- const selectedFile = selectedFileID -- ? changesState.workingDirectory.findFileWithID(selectedFileID) -- : null -- const diff = changesState.diff -+ const selectedFileIDs = changesState.selectedFileIDs -+ -+ if (selectedFileIDs.length > 1) { -+ return -+ } -+ - if ( -- !changesState.workingDirectory.files.length || -- !selectedFile || -- !diff -+ changesState.workingDirectory.files.length === 0 || -+ selectedFileIDs.length === 0 || -+ changesState.diff === null - ) { -- return -+ return - } else { -+ const workingDirectory = changesState.workingDirectory -+ const selectedFile = workingDirectory.findFileWithID(selectedFileIDs[0]) -+ -+ if (!selectedFile) { -+ return null -+ } -+ - return ( - - ) - } -- } else if (selectedSection === RepositorySection.History) { -+ } else if (selectedSection === RepositorySectionTab.History) { -+ const { historyState } = this.props.state -+ -+ const sha = historyState.selection.sha -+ -+ const selectedCommit = -+ sha != null ? this.props.state.commitLookup.get(sha) || null : null -+ - return ( -- - ) - } else { -@@ -221,10 +303,6 @@ - ) - } - -- private openRepository = () => { -- this.props.dispatcher.revealInFileManager(this.props.repository, '') -- } -- - private onRevertCommit = (commit: Commit) => { - this.props.dispatcher.revertCommit(this.props.repository, commit) - } -@@ -235,9 +313,9 @@ - // as there's only two tabs. - if (e.ctrlKey && e.key === 'Tab') { - const section = -- this.props.state.selectedSection === RepositorySection.History -- ? RepositorySection.Changes -- : RepositorySection.History -+ this.props.state.selectedSection === RepositorySectionTab.History -+ ? RepositorySectionTab.Changes -+ : RepositorySectionTab.History - - this.props.dispatcher.changeRepositorySection( - this.props.repository, -@@ -250,8 +328,9 @@ - private onTabClicked = (tab: Tab) => { - const section = - tab === Tab.History -- ? RepositorySection.History -- : RepositorySection.Changes -+ ? RepositorySectionTab.History -+ : RepositorySectionTab.Changes -+ - this.props.dispatcher.changeRepositorySection( - this.props.repository, - section -merged - result 100644 598a0cabc7864df6db50781101811dedf580a766 app/src/ui/resizable/resizable.tsx - our 100644 e565705f992ba7d7bd86bdcb4a577dec86ca0714 app/src/ui/resizable/resizable.tsx -@@ -9,8 +9,8 @@ - export class Resizable extends React.Component { - public static defaultProps: IResizableProps = { - width: 250, -- minimumWidth: 150, - maximumWidth: 350, -+ minimumWidth: 200, - } - - private startWidth: number | null = null -@@ -96,8 +96,8 @@ - public render() { - const style: React.CSSProperties = { - width: this.getCurrentWidth(), -- maximumWidth: this.props.maximumWidth, -- minimumWidth: this.props.minimumWidth, -+ maxWidth: this.props.maximumWidth, -+ minWidth: this.props.minimumWidth, - } - - return ( -merged - result 100644 ac499b9891bcd8714b42b66a5d2ff2a003a09a8f app/src/ui/toolbar/push-pull-button.tsx - our 100644 b2e039b53887ee7cc2d3325232edcfb08a70ed7e app/src/ui/toolbar/push-pull-button.tsx -@@ -1,9 +1,10 @@ - import * as React from 'react' - import { ToolbarButton, ToolbarButtonStyle } from './button' --import { IAheadBehind, Progress } from '../../lib/app-state' -+import { Progress } from '../../lib/app-state' - import { Dispatcher } from '../../lib/dispatcher' - import { Octicon, OcticonSymbol } from '../octicons' - import { Repository } from '../../models/repository' -+import { IAheadBehind } from '../../models/branch' - import { TipState } from '../../models/tip' - import { RelativeTime } from '../relative-time' - import { FetchType } from '../../lib/stores/index' -merged - result 100644 82f0e853181e3bf4cab092bd28785970c4c492d9 app/src/ui/updates/update-available.tsx - our 100644 3054daf31cb24e5c2f9804c31515163e7bbaad76 app/src/ui/updates/update-available.tsx -@@ -25,7 +25,10 @@ - An updated version of GitHub Desktop is available and will be - installed at the next launch. See{' '} - what's new{' '} -- or restart now. -+ or{' '} -+ -+ restart GitHub Desktop -+ . - - - -merged - result 160000 d247be923e48ba4d02cf76dba79f0460d2f1a9a8 app/static/common/choosealicense.com - our 160000 fe965f16f6f690d40a738e75a46fad3f41f5daa3 app/static/common/choosealicense.com -merged - result 160000 18e28746b0862059dbee8694fd366a679cb812fb app/static/common/gitignore - our 160000 690a433b668348c33087d34fafe2155ebe8bb4cf app/static/common/gitignore -added in remote - their 100644 b78f57622a54a50d820cb145c0f9a61a66bb9a39 app/static/common/multiple-files-selected.svg -@@ -0,0 +1 @@ -+ -\ No newline at end of file -merged - result 100644 b1af174b6d02934b6e9b5f29051ccc89c28454ad app/styles/_globals.scss - our 100644 bd56fae88ff49ce2925253e0e5444f48d93a6c5b app/styles/_globals.scss -@@ -115,6 +115,7 @@ - align-items: center; - justify-content: center; - text-align: center; -+ padding: var(--spacing); - } - - // Stretches an element to fill the entire window (such as an overlay) -merged - result 100644 2547663981e9047637d8e4edf9b40db74c9d5c51 app/styles/_mixins.scss - our 100644 2c54d4b7728a6487ddd3f6fd4ac7d7c641b10459 app/styles/_mixins.scss -@@ -3,3 +3,4 @@ - @import 'mixins/octicon-status'; - @import 'mixins/textboxish'; - @import 'mixins/checkboard-background'; -+@import 'mixins/close-button'; -merged - result 100644 fe75df3631a5a6b0a4f5c1fc08ec016a19917524 app/styles/_ui.scss - our 100644 bc30cbb3646a0a92d2c552e53b0bca7865ccd9f7 app/styles/_ui.scss -@@ -64,3 +64,5 @@ - @import 'ui/author-input'; - @import 'ui/avatar-stack'; - @import 'ui/commit-attribution'; -+@import 'ui/fancy-text-box'; -+@import 'ui/notification-banner'; -merged - result 100644 e9cb993ff22775125bb8a2e21a27d8b596619870 app/styles/_variables.scss - our 100644 120c6de98e0e7f66eb9d0d0fced3c8fcfbb627ea app/styles/_variables.scss -@@ -5,6 +5,12 @@ - // Primer colors, see https://github.com/primer/primer-css/blob/master/modules/primer-support/lib/variables/color-system.scss - @import '~primer-support/lib/variables/color-system.scss'; - -+// Extracted as a SCSS variable so that we can define the --overlay-background-color -+// on both the :root and the ::backdrop scope. The ::backdrop pseudo-element -+// doesn't inherit :root, see -+// https://bugs.chromium.org/p/chromium/issues/detail?id=594096 -+$overlay-background-color: rgba(0, 0, 0, 0.4); -+ - :root { - --color-new: $green; - --color-deleted: $red; -@@ -14,7 +20,6 @@ - - --text-color: $gray-900; - --text-secondary-color: $gray-500; -- --text-tertiary-color: $gray-400; - --background-color: $white; - - --button-height: 25px; -@@ -26,6 +31,7 @@ - --button-focus-border-color: $blue-600; - - --link-button-color: $blue; -+ --link-button-hover-color: $blue-600; - - --secondary-button-background: $gray-000; - --secondary-button-hover-background: $white; -@@ -36,11 +42,8 @@ - // Typography - // - // Font, line-height, and color for body text, headings, and more. -- --font-family-sans-serif: -apple-system, BlinkMacSystemFont, 'Segoe UI', -- 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', -- 'Helvetica Neue', Arial, sans-serif; -- --font-family-monospace: Menlo, Monaco, Consolas, 'Liberation Mono', -- 'Courier New', monospace; -+ --font-family-sans-serif: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', Arial, sans-serif; -+ --font-family-monospace: Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; - - /** - * Font weight to use for semibold text -@@ -86,12 +89,14 @@ - // or an item in a tab control header. It's up to each implementation - // to decide what states to support (active selection, selection, etc). - -+ --box-background-color: var(--background-color); - --box-alt-background-color: $gray-100; - - /** - * Background color for skeleton or "loading" boxes - */ - --box-skeleton-background-color: $gray-200; -+ --skeleton-background-gradient: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.5) 50%, rgba(255, 255, 255, 0) 100%); - - /** - * Border color for boxes. -@@ -145,6 +150,19 @@ - --box-selected-active-border-color: $gray-400; - - /** -+ * Gradient used to indicate that content is overflowing, intended -+ * for use when content can be expanded through other means than -+ * scrolling. -+ */ -+ --box-overflow-shadow-background: linear-gradient(180deg, rgba($white, 0) 0%, rgba($white, 1) 90%, rgba($white, 1) 100%); -+ -+ /** -+ * Author input (co-authors) -+ */ -+ --co-author-tag-background-color: $blue-000; -+ --co-author-tag-border-color: $blue-200; -+ -+ /** - * The height of the title bar area on Win32 platforms - * If changed, update titleBarHeight in 'app/src/ui/dialog/dialog.tsx' - */ -@@ -173,6 +191,7 @@ - --toolbar-height: 50px; - - --toolbar-background-color: $gray-900; -+ --toolbar-border-color: $gray-900; - --toolbar-text-color: $white; - --toolbar-text-secondary-color: $gray-300; - -@@ -196,10 +215,48 @@ - --toolbar-button-hover-progress-color: $gray-700; - --toolbar-dropdown-open-progress-color: $gray-200; - -+ /** -+ * App menu bar colors (Windows/Linux only) -+ */ -+ --app-menu-button-color: var(--toolbar-text-color); -+ --app-menu-button-hover-color: var(--toolbar-button-hover-color); -+ --app-menu-button-hover-background-color: var(--toolbar-button-hover-background-color); -+ --app-menu-button-active-color: var(--toolbar-button-active-color); -+ --app-menu-button-active-background-color: var(--toolbar-button-active-background-color); -+ --app-menu-pane-color: var(--text-color); -+ --app-menu-pane-secondary-color: var(--text-secondary-color); -+ --app-menu-pane-background-color: var(--toolbar-button-active-background-color); -+ --app-menu-divider-color: var(--box-border-color); -+ -+ /** -+ * Background color for badges inside of toolbar buttons. -+ * Examples of badges are the ahead/behind bubble in the -+ * push/pull button and the PR badge in the branch drop -+ * down button. -+ */ -+ --toolbar-badge-background-color: $gray-600; -+ --toolbar-badge-active-background-color: $gray-200; -+ - --tab-bar-height: 29px; - --tab-bar-active-color: $blue; - --tab-bar-background-color: $white; - -+ /** Count bubble colors when used inside of a tab bar item */ -+ --tab-bar-count-color: var(--text-color); -+ --tab-bar-count-background-color: $gray-200; -+ -+ /** -+ * Badge colors when used inside of list items. -+ * Example of this is the change indicators inside -+ * of the repository list. -+ */ -+ --list-item-badge-color: $gray-800; -+ --list-item-badge-background-color: $gray-200; -+ --list-item-selected-badge-color: $gray-900; -+ --list-item-selected-badge-background-color: $gray-300; -+ --list-item-selected-active-badge-color: $gray-900; -+ --list-item-selected-active-badge-background-color: $white; -+ - /** Win32 has custom scrol bars, see _scroll.scss */ - --win32-scroll-bar-size: 10px; - -@@ -215,6 +272,14 @@ - --popup-overlay-z-index: calc(var(--popup-z-index) - 1); - --foldout-z-index: calc(var(--popup-z-index) - 2); - -+ /** -+ * Toast notifications are shown temporarily for things like the zoom -+ * percentage changing or the app toggling between full screen and normal -+ * window mode. -+ */ -+ --toast-notification-color: $gray-000; -+ --toast-notification-background-color: rgba($gray-900, 0.6); -+ - /** The highlight color used for focus rings and focus box shadows */ - --focus-color: $blue; - -@@ -233,6 +298,7 @@ - --diff-text-color: $gray-900; - --diff-border-color: $gray-200; - --diff-gutter-color: $gray-200; -+ --diff-gutter-background-color: var(--background-color); - - --diff-line-number-color: $gray-700; - --diff-line-number-column-width: 50px; -@@ -277,30 +343,45 @@ - --diff-delete-hover-gutter-color: $red-300; - --diff-delete-hover-text-color: var(--text-color); - -+ // Syntax highlighting text colors -+ --syntax-variable-color: #6f42c1; -+ --syntax-alt-variable-color: #24292e; -+ --syntax-keyword-color: #d73a49; -+ --syntax-atom-color: #005cc5; -+ --syntax-string-color: #032f62; -+ --syntax-qualifier-color: #6f42c1; -+ --syntax-type-color: #d73a49; -+ --syntax-comment-color: $gray-500; -+ --syntax-tag-color: #22863a; -+ --syntax-attribute-color: #6f42c1; -+ --syntax-link-color: #032f62; -+ - // Note that this duration *must* match the `UndoCommitAnimationTimeout` - // specified in `changes/index.tsx`. - --undo-animation-duration: 500ms; - -- /** -- * Ahead/behind view -- */ -- --ahead-behind-background-color: $gray-500; -- - // Colors for form errors - --error-color: $red; - --form-error-background: $red-100; - --form-error-border-color: $red-200; - --form-error-text-color: $red-800; - -+ /** Overlay is used as a background for both modals and foldouts */ -+ --overlay-background-color: $overlay-background-color; -+ - /** Dialog */ - --dialog-warning-color: $yellow-600; -- --dialog-warning-text-color: $yellow-800; - --dialog-error-color: $red; - - /** Inline paths and code */ - --path-segment-background: $blue-000; - --path-segment-padding: var(--spacing-third); - -+ /** Diverging notification banner colors */ -+ --notification-banner-background: $blue-000; -+ --notification-banner-border-color: $blue-200; -+ --notification-ref-background: rgba(255, 255, 255, 0.75); -+ - // http://easings.net/#easeOutBack - --easing-ease-out-back: cubic-bezier(0.175, 0.885, 0.32, 1.275); - -@@ -310,3 +391,7 @@ - // http://easings.net/#easeOutQuint - --easing-ease-out-quint: cubic-bezier(0.23, 1, 0.32, 1); - } -+ -+::backdrop { -+ --overlay-background-color: $overlay-background-color; -+} -merged - result 100644 3a8c3b0ce9abb4b883fdc4f28ada9ac3a70b2f2e app/styles/desktop.scss - our 100644 4a9623e6216173633dc9aa838abbce73b361f6bb app/styles/desktop.scss -@@ -1,6 +1,8 @@ - @import 'vendor'; - - @import 'variables'; -+@import 'themes/dark'; -+ - @import 'mixins'; - - @import 'globals'; -added in remote - their 100644 e0bf14cbb8dd2a3366da0ad586f3b2bbb7cb1165 app/styles/mixins/_close-button.scss -@@ -0,0 +1,35 @@ -+@mixin close-button { -+ .close { -+ flex-shrink: 0; -+ -+ border: 0; -+ height: 16px; -+ width: 16px; -+ -+ // Set the left margin to auto so that flexbox positions the button -+ // on the right hand side of the dialog and add a -10px right hand -+ // side margin to put the button where it should be (we use a double -+ // margin for the header itself). -+ margin: 0 calc(var(--spacing) * -1) 0 auto; -+ padding: 0; -+ background: transparent; -+ -+ color: var(--text-secondary-color); -+ cursor: pointer; -+ -+ // Let the button deal with all mouse events. -+ // Without this the octicon resets the cursor when -+ // hovering over the . -+ .octicon { -+ pointer-events: none; -+ } -+ -+ &:hover { -+ color: var(--text-color); -+ } -+ -+ &:focus { -+ outline: 0; -+ } -+ } -+} -merged - result 100644 f470c0de0fc68ce5dbe838698274008bdd827ff1 app/styles/mixins/_textboxish.scss - our 100644 37764480c283ce673dca3c64fa4e317a88804cfc app/styles/mixins/_textboxish.scss -@@ -7,6 +7,7 @@ - @mixin textboxish { - border: 1px solid var(--box-border-color); - border-radius: var(--border-radius); -+ background: var(--box-background-color); - color: currentColor; - font-size: var(--font-size); - font-family: var(--font-family-sans-serif); -added in remote - their 100644 e26d91d058178a03378c4c4761703355f1aaff81 app/styles/themes/_dark.scss -@@ -0,0 +1,305 @@ -+// Variables -+// -+// This files contains CSS variables accessible to all selectors -+ -+// Primer colors, see https://github.com/primer/primer-css/blob/master/modules/primer-support/lib/variables/color-system.scss -+@import '~primer-support/lib/variables/color-system.scss'; -+ -+body.theme-dark { -+ --color-new: $green; -+ --color-deleted: $red; -+ --color-modified: $yellow-700; -+ --color-renamed: $blue; -+ --color-conflicted: $orange; -+ -+ --text-color: $gray-300; -+ --text-secondary-color: $gray-400; -+ --background-color: $gray-900; -+ -+ --button-background: $blue; -+ --button-hover-background: lighten($blue, 5%); -+ --button-text-color: $white; -+ --button-focus-border-color: $blue-600; -+ -+ --link-button-color: lighten($blue-400, 3%); -+ --link-button-hover-color: $blue-400; -+ -+ --secondary-button-background: $gray-800; -+ --secondary-button-hover-background: var(--secondary-button-background); -+ --secondary-button-text-color: var(--text-color); -+ --secondary-button-focus-shadow-color: rgba($gray-200, 0.75); -+ --secondary-button-focus-border-color: $gray-300; -+ -+ /** -+ * Background color for custom scroll bars. -+ * The color is applied to the thumb part of the scrollbar. -+ * -+ * Note: Only applies to win32 platforms -+ */ -+ --scroll-bar-thumb-background-color: rgba(0, 0, 0, 0.7); -+ -+ /** -+ * Background color for custom scroll bars in their active state. -+ * The color is applied to the thumb part of the scrollbar. -+ * -+ * Note: Only applies to win32 platforms -+ */ -+ --scroll-bar-thumb-background-color-active: rgba(0, 0, 0, 0.8); -+ -+ // Box -+ // -+ // We use the term 'box' here to refer to a very high-level generic -+ // component that fits many use cases. A 'box' might be a list item -+ // or an item in a tab control header. It's up to each implementation -+ // to decide what states to support (active selection, selection, etc). -+ -+ --box-background-color: darken($gray-900, 3%); -+ --box-alt-background-color: $gray-800; -+ -+ /** -+ * Background color for skeleton or "loading" boxes -+ */ -+ --box-skeleton-background-color: $gray-700; -+ --skeleton-background-gradient: -webkit-linear-gradient(left, rgba(36, 41, 46, 0) 0%, rgba(36, 41, 46, 0.5) 50%, rgba(36, 41, 46, 0) 100%); -+ -+ /** -+ * Border color for boxes. -+ */ -+ --box-border-color: #141414; -+ --box-border-accent-color: $blue; -+ -+ /** -+ * Background color for selected boxes without keyboard focus -+ */ -+ --box-selected-background-color: $gray-700; -+ -+ /** -+ * Text color for when a user hovers over a boxe with a -+ * pointing device. Should not be used by boxes that doesn't -+ * implement a hover state since this will conflict with -+ * selection and active selection -+ */ -+ --box-hover-text-color: var(--text-color); -+ -+ /** -+ * Background color for when a user hovers over a boxe with a -+ * pointing device. Should not be used by boxes that doesn't -+ * implement a hover state since this will conflict with -+ * selection and active selection -+ */ -+ -+ /** -+ * Text color for selected boxes without keyboard focus -+ */ -+ --box-selected-text-color: var(--text-color); -+ -+ /** -+ * Border color for selected boxes without keyboard focus -+ */ -+ --box-selected-border-color: $gray-400; -+ -+ /** -+ * Background color for selected boxes with active keyboard focus -+ */ -+ --box-selected-active-background-color: $blue; -+ -+ /** -+ * Text color for selected boxes with active keyboard focus -+ */ -+ --box-selected-active-text-color: $white; -+ -+ /** -+ * Border color for selected boxes with active keyboard focus -+ */ -+ --box-selected-active-border-color: $gray-400; -+ -+ /** -+ * Gradient used to indicate that content is overflowing, intended -+ * for use when content can be expanded through other means than -+ * scrolling. -+ */ -+ --box-overflow-shadow-background: linear-gradient(180deg, rgba($gray-900, 0) 0%, rgba($gray-900, 1) 90%, rgba($gray-900, 1) 100%); -+ -+ /** -+ * Author input (co-authors) -+ */ -+ --co-author-tag-background-color: $blue-800; -+ --co-author-tag-border-color: $blue-700; -+ -+ --base-border: 1px solid var(--box-border-color); -+ -+ --shadow-color: rgba(black, 0.5); -+ --base-box-shadow: 0 2px 7px var(--shadow-color); -+ -+ --toolbar-background-color: darken($gray-900, 3%); -+ --toolbar-border-color: var(--box-border-color); -+ --toolbar-text-color: var(--text-color); -+ --toolbar-text-secondary-color: var(--text-secondary-color); -+ -+ --toolbar-button-color: var(--toolbar-text-color); -+ --toolbar-button-background-color: transparent; -+ --toolbar-button-border-color: var(--box-border-color); -+ --toolbar-button-secondary-color: var(--toolbar-text-secondary-color); -+ -+ --toolbar-button-hover-color: $white; -+ --toolbar-button-hover-background-color: $gray-800; -+ --toolbar-button-hover-border-color: var(--toolbar-button-border-color); -+ -+ --toolbar-button-focus-background-color: $gray-800; -+ -+ --toolbar-button-active-color: var(--text-color); -+ --toolbar-button-active-background-color: var(--background-color); -+ --toolbar-button-active-border-color: var(--box-border-color); -+ -+ --toolbar-button-progress-color: $gray-800; -+ --toolbar-button-focus-progress-color: $gray-700; -+ --toolbar-button-hover-progress-color: $gray-700; -+ --toolbar-dropdown-open-progress-color: $gray-200; -+ -+ /** -+ * App menu bar colors (Windows/Linux only) -+ */ -+ --app-menu-button-color: var(--toolbar-text-color); -+ --app-menu-button-hover-color: var(--toolbar-button-hover-color); -+ --app-menu-button-hover-background-color: var(--toolbar-button-hover-background-color); -+ --app-menu-button-active-color: var(--text-color); -+ --app-menu-button-active-background-color: $gray-800; -+ --app-menu-pane-color: var(--text-color); -+ --app-menu-pane-secondary-color: var(--text-secondary-color); -+ --app-menu-pane-background-color: $gray-800; -+ --app-menu-divider-color: $gray-600; -+ -+ /** -+ * Background color for badges inside of toolbar buttons. -+ * Examples of badges are the ahead/behind bubble in the -+ * push/pull button and the PR badge in the branch drop -+ * down button. -+ */ -+ --toolbar-badge-background-color: $gray-700; -+ --toolbar-badge-active-background-color: $gray-700; -+ -+ --tab-bar-active-color: $blue; -+ --tab-bar-background-color: var(--box-background-color); -+ -+ /** Count bubble colors when used inside of a tab bar item */ -+ --tab-bar-count-color: var(--text-color); -+ --tab-bar-count-background-color: $gray-700; -+ -+ /** -+ * Badge colors when used inside of list items. -+ * Example of this is the ahead/behind indicators inside -+ * of the repository list. -+ */ -+ --list-item-badge-color: var(--text-color); -+ --list-item-badge-background-color: $gray-600; -+ --list-item-selected-badge-color: $white; -+ --list-item-selected-badge-background-color: $gray-500; -+ --list-item-selected-active-badge-color: $gray-900; -+ --list-item-selected-active-badge-background-color: $white; -+ -+ /** -+ * Toast notifications are shown temporarily for things like the zoom -+ * percentage changing or the app toggling between full screen and normal -+ * window mode. -+ */ -+ --toast-notification-color: var(--text-color); -+ --toast-notification-background-color: rgba(black, 0.8); -+ -+ /** The highlight color used for focus rings and focus box shadows */ -+ --focus-color: $blue; -+ -+ /** -+ * Variables for form elements -+ */ -+ --text-field-focus-shadow-color: rgba($blue, 0.25); -+ -+ /** -+ * Diff view -+ */ -+ -+ --diff-text-color: var(--text-color); -+ --diff-border-color: $gray-800; -+ --diff-gutter-color: $gray-800; -+ --diff-gutter-background-color: darken($gray-900, 3%); -+ -+ --diff-line-number-color: var(--text-secondary-color); -+ --diff-line-number-column-width: 50px; -+ -+ --diff-selected-background-color: $blue-700; -+ --diff-selected-border-color: $blue-600; -+ --diff-selected-gutter-color: $blue-600; -+ --diff-selected-text-color: var(--text-color); -+ -+ --diff-add-background-color: darken($green-900, 10%); -+ --diff-add-border-color: darken($green-900, 10%); -+ --diff-add-gutter-color: darken($green-900, 10%); -+ --diff-add-gutter-background-color: darken($green-900, 13%); -+ --diff-add-inner-background-color: $green-900; -+ --diff-add-text-color: var(--diff-text-color); -+ -+ --diff-delete-background-color: darken($red-900, 15%); -+ --diff-delete-border-color: darken($red-900, 10%); -+ --diff-delete-gutter-color: darken($red-900, 10%); -+ --diff-delete-gutter-background-color: darken($red-900, 20%); -+ --diff-delete-inner-background-color: $red-700; -+ --diff-delete-text-color: $red-100; -+ -+ --diff-hunk-background-color: darken($gray-900, 3%); -+ --diff-hunk-border-color: lighten($gray-900, 3%); -+ --diff-hunk-gutter-color: lighten($gray-900, 3%); -+ --diff-hunk-gutter-background-color: darken($gray-900, 6%); -+ --diff-hunk-text-color: var(--text-secondary-color); -+ -+ --diff-hover-background-color: $blue-500; -+ --diff-hover-border-color: $blue-400; -+ --diff-hover-gutter-color: $blue-400; -+ --diff-hover-text-color: var(--diff-text-color); -+ -+ --diff-add-hover-background-color: $green-900; -+ --diff-add-hover-border-color: $green-700; -+ --diff-add-hover-gutter-color: $green-700; -+ --diff-add-hover-text-color: var(--text-color); -+ -+ --diff-delete-hover-background-color: $red-800; -+ --diff-delete-hover-border-color: $red-700; -+ --diff-delete-hover-gutter-color: $red-700; -+ --diff-delete-hover-text-color: var(--text-color); -+ -+ // Syntax highlighting text colors -+ --syntax-variable-color: $purple-300; -+ --syntax-alt-variable-color: $blue-300; -+ --syntax-keyword-color: $red-300; -+ --syntax-atom-color: $blue-300; -+ --syntax-string-color: $orange-300; -+ --syntax-qualifier-color: $purple-300; -+ --syntax-type-color: $red-300; -+ --syntax-comment-color: $gray-400; -+ --syntax-tag-color: $green-400; -+ --syntax-attribute-color: $purple-300; -+ --syntax-link-color: $blue-300; -+ -+ // Colors for form errors -+ --error-color: $red; -+ --form-error-background: darken($red-900, 3%); -+ --form-error-border-color: $red-900; -+ --form-error-text-color: var(--text-color); -+ -+ /** Overlay is used as a background for both modals and foldouts */ -+ --overlay-background-color: rgba(0, 0, 0, 0.5); -+ -+ /** Dialog */ -+ --dialog-warning-color: $yellow-600; -+ --dialog-error-color: $red-600; -+ -+ /** Inline paths and code */ -+ --path-segment-background: $gray-700; -+ -+ .blankslate-image { -+ filter: #{'invert()'} grayscale(1) brightness(8) contrast(0.6); -+ } -+ -+ /** Diverging notification banner colors */ -+ --notification-banner-background: $gray-800; -+ --notification-banner-border-color: $gray-700; -+ --notification-ref-background: $gray-700; -+} -merged - result 100644 118f40d4344ca7c4768e080dc7c5efb558a6e508 app/styles/ui/_app-menu.scss - our 100644 3e0f853f19041341b3f99da4a54a9198c68956ba app/styles/ui/_app-menu.scss -@@ -116,6 +116,6 @@ - width: 100%; - border: none; - height: 1px; -- border-bottom: var(--base-border); -+ border-bottom: 1px solid var(--app-menu-divider-color); - } - } -merged - result 100644 c1acae40fa98cefd4b9acd874bc3f9564610a6b3 app/styles/ui/_author-input.scss - our 100644 7f410ba422cc224a1bf1a644770a555b04eacd29 app/styles/ui/_author-input.scss -@@ -24,8 +24,8 @@ - - .handle { - border-radius: 3px; -- border: 1px solid #c3e1ff; -- background: #f0f8ff; -+ border: 1px solid var(--co-author-tag-border-color); -+ background: var(--co-author-tag-background-color); - padding: 1px 1px; - margin: 0px 2px; - -merged - result 100644 b9a9ae211132ba7784f37322c2cb317e9c2aa871 app/styles/ui/_branches.scss - our 100644 8b437422d7971232a5209b075f6a7a4aac650780 app/styles/ui/_branches.scss -@@ -24,8 +24,8 @@ - .count { - display: flex; - -- background: $gray-200; -- color: var(--text-color); -+ background: var(--tab-bar-count-background-color); -+ color: var(--tab-bar-count-color); - - margin-left: var(--spacing-half); - -@@ -162,12 +162,7 @@ - } - - &::after { -- background: -webkit-linear-gradient( -- left, -- rgba(255, 255, 255, 0) 0%, -- rgba(255, 255, 255, 0.5) 50%, -- rgba(255, 255, 255, 0) 100% -- ); -+ background: var(--skeleton-background-gradient); - content: ''; - display: block; - height: 100%; -merged - result 100644 97ca39a21b639ebe4d0b8aa70608843319f304fb app/styles/ui/_button.scss - our 100644 584328bba42bf1267b5fc2b72da5863699ebe8e3 app/styles/ui/_button.scss -@@ -1,4 +1,7 @@ -+@import '../mixins'; -+ - .button-component { -+ @include ellipsis; - // Chrome on Windows ignores the body element - // font-family and uses Arial so we redefine - // it here -merged - result 100644 64c4ffecb0394f2d298707dc3791dd719539172b app/styles/ui/_codemirror.scss - our 100644 aa9c9bb39f6132a7a359f95ab612ed96c6442e09 app/styles/ui/_codemirror.scss -@@ -25,6 +25,15 @@ - background: inherit; - } - -+.CodeMirror-simplescroll-horizontal, -+.CodeMirror-simplescroll-vertical { -+ background: var(--box-alt-background-color); -+ div { -+ background: var(--scroll-bar-thumb-background-color); -+ border: none; -+ } -+} -+ - // Windows has custom scroll bars, see _scroll.scss - @include win32-context { - .CodeMirror { -merged - result 100644 94b86d54fb9b0314deb1ef48cc9e1466578ed390 app/styles/ui/_dialog.scss - our 100644 e496a16bd915366f9b11d9d0e63a21a8732099f4 app/styles/ui/_dialog.scss -@@ -53,7 +53,7 @@ - transition: transform 250ms var(--easing-ease-out-back); - - &::backdrop { -- opacity: 0.4; -+ opacity: 1; - transition: opacity 100ms ease-in; - } - } -@@ -64,15 +64,14 @@ - pointer-events: none; - - &::backdrop { -- opacity: 0.4; -+ opacity: 1; - } - } - - &-leave-active { - opacity: 0.01; - transform: scale(0.25); -- transition: opacity 100ms ease-in, -- transform 100ms var(--easing-ease-in-back); -+ transition: opacity 100ms ease-in, transform 100ms var(--easing-ease-in-back); - - &::backdrop { - opacity: 0.01; -@@ -82,8 +81,8 @@ - } - - &::backdrop { -- background: #000; -- opacity: 0.4; -+ background: var(--overlay-background-color); -+ opacity: 1; - } - - // The dialog embeds a fieldset as the first child of the form element -@@ -120,39 +119,7 @@ - @include ellipsis; - } - -- .close { -- flex-shrink: 0; -- -- border: 0; -- height: 16px; -- width: 16px; -- -- // Set the left margin to auto so that flexbox positions the button -- // on the right hand side of the dialog and add a -10px right hand -- // side margin to put the button where it should be (we use a double -- // margin for the header itself). -- margin: 0 calc(var(--spacing) * -1) 0 auto; -- padding: 0; -- background: transparent; -- -- color: var(--text-secondary-color); -- cursor: pointer; -- -- // Let the button deal with all mouse events. -- // Without this the octicon resets the cursor when -- // hovering over the . -- .octicon { -- pointer-events: none; -- } -- -- &:hover { -- color: var(--text-color); -- } -- -- &:focus { -- outline: 0; -- } -- } -+ @include close-button; - } - - &.warning, -@@ -168,10 +135,7 @@ - // Ensure that the dialog contents always have room for the icon, - // account for two double spacers at top and bottom plus the 5px - // icon offset (margin-top) and the size of the icon itself. -- min-height: calc( -- var(--spacing-double) * 2 + var(--spacing-half) + -- var(--dialog-icon-size) -- ); -+ min-height: calc(var(--spacing-double) * 2 + var(--spacing-half) + var(--dialog-icon-size)); - - // We're creating an opaque 24 by 24px div with the background color - // that we want the icon to appear in and then apply the icon path -merged - result 100644 8b9383b267f661b394b29143bae31d8f6d73aa73 app/styles/ui/_diff.scss - our 100644 3dca4de7170d06beb799c8fa23c07c350ca0afa9 app/styles/ui/_diff.scss -@@ -9,6 +9,7 @@ - .diff-code-mirror .CodeMirror { - height: 100%; - color: var(--diff-text-color); -+ background: var(--background-color); - font-size: var(--font-size-sm); - font-family: var(--font-family-monospace); - -@@ -61,6 +62,7 @@ - .diff-line-gutter { - display: flex; - height: 100%; -+ background: var(--diff-gutter-background-color); - - &.diff-add { - background: var(--diff-add-gutter-background-color); -@@ -95,8 +97,25 @@ - text-align: right; - } - --.diff-add { -- background: var(--diff-add-background-color); -+.CodeMirror-linebackground { -+ &.diff-add { -+ background: var(--diff-add-background-color); -+ } -+ -+ &.diff-delete { -+ background: var(--diff-delete-background-color); -+ } -+ -+ &.diff-context { -+ background: var(--background-color); -+ } -+ -+ &.diff-hunk { -+ background: var(--diff-hunk-background-color); -+ } -+} -+ -+.CodeMirror pre.diff-add { - color: var(--diff-add-text-color); - padding: 0; - -@@ -109,8 +128,7 @@ - } - } - --.diff-delete { -- background: var(--diff-delete-background-color); -+.CodeMirror pre.diff-delete { - color: var(--diff-delete-text-color); - padding: 0; - -@@ -123,9 +141,8 @@ - } - } - --.diff-context { -- background: var(--background-color); -- color: var(--diff-context-text-color); -+.CodeMirror pre.diff-context { -+ color: var(--diff-text-color); - padding: 0; - - .diff-line-number { -@@ -159,11 +176,10 @@ - } - - .cm-diff-context { -- color: var(--diff-context-text-color); -+ color: var(--diff-text-color); - } - --.diff-hunk { -- background: var(--diff-hunk-background-color); -+.CodeMirror pre.diff-hunk { - color: var(--diff-hunk-text-color); - padding: 0; - -@@ -176,7 +192,7 @@ - } - } - --.diff-line-selected { -+.CodeMirror pre.CodeMirror-line .diff-line-selected { - .diff-line-number { - background: var(--diff-selected-background-color); - border-color: var(--diff-selected-border-color); -@@ -188,7 +204,7 @@ - } - } - --.diff-line-hover { -+.CodeMirror pre.CodeMirror-line .diff-line-hover { - .diff-line-number { - background: var(--diff-hover-background-color); - border-color: var(--diff-hover-border-color); -@@ -246,15 +262,6 @@ - padding: 0; - } - // *************************************************************************************************************************** --#diff a { -- text-decoration: none; -- margin-left: var(--spacing-half); --} -- --#diff a:link { -- color: (orange); --} -- - .panel.image { - display: flex; - flex: 1; -@@ -295,17 +302,36 @@ - } - } - --.image-diff-two-up { -+.image-diff-container { - display: flex; - flex: 1; - justify-content: center; - align-items: center; -+ flex-direction: column; - -- .image-diff-previous { -- margin-right: 7.5px; -+ .image-diff-two-up { -+ display: flex; -+ align-items: center; -+ -+ .image-diff-previous { -+ margin-right: var(--spacing-half); -+ margin-bottom: var(--spacing-half); -+ } -+ .image-diff-current { -+ margin-left: var(--spacing-half); -+ margin-bottom: var(--spacing-half); -+ } - } -- .image-diff-current { -- margin-left: 7.5px; -+ -+ .image-diff-summary { -+ color: var(--text-secondary-color); -+ font-weight: var(--font-weight-semibold); -+ .added { -+ color: var(--color-new); -+ } -+ .removed { -+ color: var(--color-deleted); -+ } - } - } - -@@ -436,15 +462,15 @@ - // https://github.com/primer/github-syntax-light/blob/5aeffad2559647286080328436156c4904a9785b/lib/github-light.css - .cm-s-default { - .cm-variable { -- color: #6f42c1; -+ color: var(--syntax-variable-color); - } - - .cm-keyword { -- color: #d73a49; -+ color: var(--syntax-keyword-color); - } - - .cm-atom { -- color: #005cc5; -+ color: var(--syntax-atom-color); - } - .cm-number { - color: inherit; -@@ -456,25 +482,25 @@ - - .cm-variable-2, - .cm-variable-3 { -- color: #24292e; -+ color: var(--syntax-alt-variable-color); - } - .cm-comment, - .cm-meta { -- color: $gray-500; -+ color: var(--syntax-comment-color); - } - .cm-string, - .cm-string-2 { -- color: #032f62; -+ color: var(--syntax-string-color); - - &.cm-property { - color: inherit; - } - } - .cm-qualifier { -- color: #6f42c1; -+ color: var(--syntax-qualifier-color); - } - .cm-type { -- color: #d73a49; -+ color: var(--syntax-type-color); - } - .cm-builtin { - color: inherit; -@@ -483,17 +509,17 @@ - color: inherit; - } - .cm-tag { -- color: #22863a; -+ color: var(--syntax-tag-color); - } - .cm-attribute { -- color: #6f42c1; -+ color: var(--syntax-attribute-color); - } - .cm-hr { - color: inherit; - } - .cm-link { - text-decoration: underline; -- color: #032f62; -+ color: var(--syntax-link-color); - } - - // Intra line markings takes precedence over syntax highlighting. -@@ -507,19 +533,19 @@ - - .cm-m-css { - &.cm-property { -- color: #005cc5; -+ color: var(--syntax-atom-color); - } - } - - .cm-m-shell { - &.cm-builtin { -- color: #005cc5; -+ color: var(--syntax-atom-color); - } - } - - .cm-m-javascript { - &.cm-type { -- color: #6f42c1; -+ color: var(--syntax-variable-color); - } - } - } -added in remote - their 100644 479e9f6732ddc2b29c19b24585f4bb315001226a app/styles/ui/_fancy-text-box.scss -@@ -0,0 +1,41 @@ -+@import '../mixins'; -+ -+.fancy-text-box-component { -+ background: var(--box-background-color); -+ display: flex; -+ align-items: center; -+ border: var(--base-border); -+ border-radius: var(--border-radius); -+ -+ .fancy-octicon { -+ height: var(--text-field-height); -+ padding: var(--spacing-half) 0 var(--spacing-half) 7px; -+ border-right: none; -+ border-radius: var(--border-radius) 0 0 var(--border-radius); -+ opacity: 0.5; -+ transition: opacity 0.2s ease; -+ } -+ -+ &.focused { -+ @include textboxish-focus-styles; -+ -+ .fancy-octicon { -+ opacity: 1; -+ } -+ } -+ -+ input { -+ border-left: none; -+ border-radius: 0 var(--border-radius) var(--border-radius) 0; -+ border: none; -+ box-shadow: none; -+ -+ &:focus { -+ box-shadow: none; -+ } -+ } -+ -+ &.disabled { -+ background: var(--box-alt-background-color); -+ } -+} -merged - result 100644 8d0a73f26a35a260372d33c7dfe4ff8b5d1339a8 app/styles/ui/_file-list.scss - our 100644 e144976834ba00ee6d0a7f0840de601c6361830e app/styles/ui/_file-list.scss -@@ -11,12 +11,15 @@ - border-bottom: var(--base-border); - } - -- // Only use special colors for the change type icons when -- // the list item doesn't have active focus. If it does we -- // fall back to using the ambient foreground color of the -- // list item. -- .list-item:not(:focus) { -- @include octicon-status; -+ .list-focus-container { -+ // Default to using status aware colors for the change type -+ // octicons (i.e. green for added, yellowish for modified etc) -+ // but fall back to picking up the ambient text color when the -+ // list item is both focused and selected. -+ &.focus-within .list-item:not(.selected), -+ &:not(.focus-within) .list-item { -+ @include octicon-status; -+ } - } - - .file { -merged - result 100644 6d566f094b0851eb8e5875fc9b74a6ec847985e2 app/styles/ui/_foldout.scss - our 100644 862730a600bd4c8f8550cc85c363796164440dfa app/styles/ui/_foldout.scss -@@ -12,8 +12,7 @@ - box-shadow: none; - } - -- background: black; -- opacity: 0.4; -+ background: var(--overlay-background-color); - height: 100%; - } - -merged - result 100644 7b3fc84057d9f29f2c281fa3e52cb7eb6e066501 app/styles/ui/_list.scss - our 100644 1caa93d31e19fb970d33836afcdb72aebca4aad6 app/styles/ui/_list.scss -@@ -62,6 +62,17 @@ - } - } - -+.list-focus-container { -+ // The selected items must act as the focused element when inside -+ &.focus-within .list-item.selected { -+ --text-color: var(--box-selected-active-text-color); -+ --text-secondary-color: var(--box-selected-active-text-color); -+ -+ color: var(--text-color); -+ background-color: var(--box-selected-active-background-color); -+ } -+} -+ - .list-item { - display: flex; - flex-direction: row; -@@ -76,14 +87,6 @@ - - color: var(--text-color); - background-color: var(--box-selected-background-color); -- -- &:focus { -- --text-color: var(--box-selected-active-text-color); -- --text-secondary-color: var(--box-selected-active-text-color); -- -- color: var(--text-color); -- background-color: var(--box-selected-active-background-color); -- } - } - - &:focus { -added in remote - their 100644 ec2aae86b8d44d23f35f56cb9684489301016d6b app/styles/ui/_notification-banner.scss -@@ -0,0 +1,102 @@ -+@import '../mixins'; -+ -+.notification-banner + .compare-form { -+ border-top: var(--base-border); -+} -+ -+.notification-banner { -+ background: var(--notification-banner-background); -+ border: var(--base-border); -+ border-color: var(--notification-banner-border-color); -+ border-radius: var(--border-radius); -+ display: flex; -+ padding: var(--spacing); -+ position: relative; -+ -+ .notification-icon { -+ margin-right: var(--spacing-half); -+ } -+ -+ &-content { -+ display: flex; -+ flex-wrap: wrap; -+ -+ p { -+ flex-grow: 1; -+ font-size: var(--font-size-sm); -+ margin: 0; -+ padding-right: var(--spacing-double); // Extra space for the close button -+ -+ & + p { -+ margin-top: var(--spacing-half); -+ } -+ } -+ } -+ -+ @include close-button; -+ -+ .ref-component { -+ background: var(--notification-ref-background); -+ word-break: normal; -+ } -+ -+ .close { -+ position: absolute; -+ margin: 0; -+ top: var(--spacing); -+ right: var(--spacing); -+ text-align: center; -+ -+ .octicon { -+ height: 12px; -+ } -+ } -+} -+ -+.diverge-banner { -+ margin: var(--spacing-half); -+ overflow: hidden; -+ -+ &-enter { -+ max-height: 0; -+ opacity: 0; -+ -+ &-active { -+ max-height: 200px; -+ opacity: 1; -+ transition: all var(--undo-animation-duration) cubic-bezier(0, 0, 0.2, 1); -+ } -+ } -+ -+ &-leave { -+ max-height: 200px; -+ -+ &-active { -+ max-height: 0; -+ opacity: 1; -+ transition: max-height 300ms cubic-bezier(0.4, 0, 0.2, 1); -+ -+ .diverge-banner { -+ transform: translateX(-102%); -+ opacity: 0; -+ transition: all 180ms cubic-bezier(0.4, 0, 1, 1); -+ } -+ } -+ } -+ -+ &-wrapper { -+ overflow: hidden; -+ box-shadow: inset 0 -1px var(--box-border-color); -+ } -+} -+ -+.notification-banner-content-body { -+ margin-bottom: var(--spacing-half); -+} -+ -+.notification-banner-content { -+ .button-component { -+ margin-top: var(--spacing-half); -+ margin-right: var(--spacing-half); -+ } -+} -merged - result 100644 8f546e403848d75eee71d9c9cfadf10861721ea0 app/styles/ui/_octicons.scss - our 100644 215063877dc976dfb22c47f98829eb38c20d9bd1 app/styles/ui/_octicons.scss -@@ -6,4 +6,6 @@ - Forcing a width of 16px would result in some blurry icons showing up. - Instead, let's imply width: auto; instead. */ - height: 16px; -+ -+ flex-shrink: 0; - } -merged - result 100644 7a372fc2ba926c3532af77143dd008fa32fb4d3a app/styles/ui/_progress.scss - our 100644 0f1d4611ca18a0222d8408f2fba2f066fc73e2a5 app/styles/ui/_progress.scss -@@ -12,13 +12,7 @@ - } - - &:indeterminate { -- background-image: -webkit-linear-gradient( -- -45deg, -- transparent 33%, -- var(--text-color) 33%, -- var(--text-color) 66%, -- transparent 66% -- ); -+ background-image: -webkit-linear-gradient(-45deg, transparent 33%, var(--text-color) 33%, var(--text-color) 66%, transparent 66%); - background-size: 25px 10px, 100% 100%, 100% 100%; - - -webkit-animation: progress-indeterminate-animation 5s linear infinite; -merged - result 100644 babfdd92b2ced6ebdff2052231e4dea8a3d3b576 app/styles/ui/_pull-request-badge.scss - our 100644 479c5dc5f32bef83b9e68e7b8f2739733f4da45f app/styles/ui/_pull-request-badge.scss -@@ -1,9 +1,9 @@ - .toolbar-dropdown.open .pr-badge { -- background: $gray-200; -+ background: var(--toolbar-badge-active-background-color); - } - - .toolbar-dropdown:not(.open) .pr-badge { -- background: $gray-700; -+ background: var(--toolbar-badge-background-color); - } - - .pr-badge { -merged - result 100644 eddec3b4d0f749f111f14d559b64cb6d06e2a97f app/styles/ui/_ref.scss - our 100644 6c6ae06ccf808f2fbe03949d3ac21f696563a97d app/styles/ui/_ref.scss -@@ -5,4 +5,5 @@ - border: var(--path-segment-background); - border-radius: var(--border-radius); - padding: var(--path-segment-padding); -+ word-break: break-all; - } -merged - result 100644 157e36f8a6d1951007c2c6c8f17b69d30f96b0c7 app/styles/ui/_repository-list.scss - our 100644 14dc39f723c7e6750bd1aeb7eca236863e48a320 app/styles/ui/_repository-list.scss -@@ -50,7 +50,7 @@ - @include ellipsis; - - .prefix { -- color: var(--text-tertiary-color); -+ color: var(--text-secondary-color); - } - - /* Used to highlight substring matches in filtered lists */ -@@ -61,6 +61,43 @@ - color: currentColor; - } - } -+ -+ .change-indicator { -+ color: var(--tab-bar-active-color); -+ margin-right: 0; -+ width: auto; -+ } -+ -+ .change-indicator-wrapper { -+ display: flex; -+ min-width: 12px; -+ } -+ -+ .ahead-behind { -+ height: 16px; -+ background: var(--list-item-badge-background-color); -+ color: var(--list-item-badge-color); -+ align-items: center; -+ margin-left: auto; -+ -+ // Perfectly round semi circle ends with real tight -+ // padding on either side. Now in two flavors! -+ @include darwin { -+ height: 12px; -+ line-height: 12px; -+ } -+ -+ @include win32 { -+ height: 13px; -+ line-height: 13px; -+ } -+ -+ .octicon { -+ margin: 0; -+ height: 20px; -+ width: 12px; -+ } -+ } - } - - .sidebar-message { -@@ -71,3 +108,31 @@ - text-align: center; - } - } -+ -+.list-focus-container { -+ /** Ahead/behind badge colors when list item is selected but not focused */ -+ .list-item.selected { -+ .repository-list-item { -+ .ahead-behind { -+ background: var(--list-item-selected-badge-background-color); -+ color: var(--list-item-selected-badge-color); -+ } -+ } -+ } -+ -+ &.focus-within { -+ /** Ahead/behind badge colors when list item is selected and focused */ -+ .list-item.selected { -+ .repository-list-item { -+ .ahead-behind { -+ background: var(--list-item-selected-active-badge-background-color); -+ color: var(--list-item-selected-active-badge-color); -+ } -+ } -+ } -+ -+ .change-indicator { -+ color: var(--text-color); -+ } -+ } -+} -merged - result 100644 19452e95365b7649095eb5dec6929dfbcf0a56ed app/styles/ui/_repository.scss - our 100644 7bc7ca7f0af55bf92b7abef8be065dadcfe5e06e app/styles/ui/_repository.scss -@@ -6,6 +6,10 @@ - flex-direction: row; - flex: 1; - -+ > .focus-container { -+ display: flex; -+ } -+ - &-sidebar { - display: flex; - flex-direction: column; -merged - result 100644 d03e102280205b3d5932443b87f86ae495b967c8 app/styles/ui/_select.scss - our 100644 49aaeff05480031aef8493b66d05c59ae970ecc0 app/styles/ui/_select.scss -@@ -10,27 +10,16 @@ - margin-bottom: var(--spacing-third); - } - -- // Select boxes look absolutely horrible on Windows so we'll make them -- // look as good as we possibly can. There's nothing we can do about the -- // drop down itself but at least we can style the base element a bit. -- @include win32 { -- select { -- // Get rid of all default UA styling, we can do better -- -webkit-appearance: none; -+ // Custom styles for select components because a) they look horrible -+ // on Windows and b) because we need them to inherit colors and other -+ // appearance from our global variables. Therefore we treat them more -+ // or less exactly as a text box. -+ select { -+ // Make the select look like a text box. -+ @include textboxish; -+ @include textboxish-disabled; - -- // Make the select look like a text box. -- @include textboxish; -- @include textboxish-disabled; -- -- // Add back the arrow that got removed with appearance: none. -- // This is a custom version of the triangle-down octicon that was -- // adapted to be 8 by 5px. The gif is in 2x and the background-size -- // scales it back down so that we can have crisp arrows on high-dpi -- // displays. The path is M 0,0 4,5 8,0 Z and the color is #6a737d. -- background-image: url('data:image/gif;base64,R0lGODlhEAAKAMQAAGpzff///8PHy6arsXqCi46UnN7g4vHy8/v7+253gYuSmm12gO/w8dve4Pz8/KassniAicfLzwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAAAAAALAAAAAAQAAoAAAUw4ACMZFk+TmGugIIEB8GSEBPcRjIvze1HM4FvKDI9hsNUyYUcxka1JjLHkzYFwmYIADs='); -- background-size: 8px 5px; -- background-repeat: no-repeat; -- background-position: right var(--spacing-half) center; -- } -+ // Don't include the default padding from textboxish, it's too much -+ padding: 0; - } - } -merged - result 100644 43d02373aff313ef9b39f22eb06c69042edeae78 app/styles/ui/_tab-bar.scss - our 100644 1bffcaff9a286153de4d40b1384bc42499839078 app/styles/ui/_tab-bar.scss -@@ -51,6 +51,17 @@ - margin-left: 4px; - margin-top: 1px; - } -+ -+ .counter { -+ color: var(--tab-bar-count-color); -+ background-color: var(--tab-bar-count-background-color); -+ margin-left: 4px; -+ padding: 2px 5px; -+ font-size: var(--font-size-xs); -+ font-weight: var(--font-weight-semibold); -+ border-radius: 20px; -+ line-height: 1; -+ } - } - - &.switch &-item { -merged - result 100644 94ed12c8ef668212eaa0f41d6f741a8cc444b2da app/styles/ui/changes/_changes-view.scss - our 100644 65c5af2ea88cf23e747e2b83a4de02734e02ec5a app/styles/ui/changes/_changes-view.scss -@@ -59,6 +59,10 @@ - margin: var(--spacing-double); - text-align: center; - justify-content: initial; -+ -+ .blankslate-image { -+ max-height: 150px; -+ } - } - } - } -merged - result 100644 44b4d80ba3b31ba74550bd24a221b8b5a30b162c app/styles/ui/changes/_commit-message.scss - our 100644 68a0917a3d144cf8e5d26609b5abc54013f7d66e app/styles/ui/changes/_commit-message.scss -@@ -45,18 +45,18 @@ - } - - .co-authors-toggle { -- color: $gray-500; -+ color: var(--text-secondary-color); - - &:hover { -- color: $gray-900; -+ color: var(--text-color); - } - } - - &.with-co-authors .co-authors-toggle { -- color: $blue-400; -+ color: var(--link-button-color); - - &:hover { -- color: $blue-600; -+ color: var(--link-button-hover-color); - } - } - -@@ -91,11 +91,7 @@ - width: 100%; - bottom: 0px; - height: 5px; -- background: linear-gradient( -- to bottom, -- rgba(0, 0, 0, 0) 0%, -- rgba(0, 0, 0, 0.1) 100% -- ); -+ background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.1) 100%); - border-bottom: var(--base-border); - } - } -@@ -119,6 +115,7 @@ - - .action-bar { - padding: var(--spacing-half); -+ background: var(--box-background-color); - - // We're not faking being a textbox any more - cursor: default; -merged - result 100644 afc47457356923945b1b56e34a7eb176b19e7adb app/styles/ui/history/_commit-summary.scss - our 100644 da6d9942c041f863fd8e5aa0dc74a2e8a8788277 app/styles/ui/history/_commit-summary.scss -@@ -41,6 +41,21 @@ - .commit-summary-description { - padding-right: 100px; - } -+ -+ // When the description area can be, but isn't yet, expanded -+ // we'll add a small shadow towards the bottom to hint that -+ // there's more content available. -+ &:not(.expanded) { -+ .commit-summary-description:before { -+ content: ''; -+ background: var(--box-overflow-shadow-background); -+ position: absolute; -+ height: 30px; -+ bottom: 0px; -+ width: 100%; -+ pointer-events: none; -+ } -+ } - } - } - -@@ -76,21 +91,6 @@ - // The extra pixel makes the space align up with the commit list. - max-height: 61px; - flex: 1; -- -- &:before { -- content: ''; -- background: linear-gradient( -- 180deg, -- rgba(255, 255, 255, 0) 0px, -- rgba(255, 255, 255, 0) 40px, -- rgba(255, 255, 255, 0.5) 40px, -- white 60px -- ); -- position: absolute; -- height: 100%; -- width: 100%; -- pointer-events: none; -- } - } - - // Enable text selection inside the title and description elements. -merged - result 100644 58cea508b02182fa4f45daf88643d33c3b2dd020 app/styles/ui/history/_history.scss - our 100644 4e36c11fb44d43f2f8a8cb661820f2143f0f513c app/styles/ui/history/_history.scss -@@ -46,6 +46,114 @@ - margin: var(--spacing-double); - text-align: center; - justify-content: initial; -+ -+ .blankslate-image { -+ max-height: 150px; -+ } -+ } -+ } -+} -+ -+#compare-view { -+ display: flex; -+ flex-direction: column; -+ flex: 1; -+ -+ .compare-form { -+ background: var(--box-alt-background-color); -+ flex: initial; -+ padding: var(--spacing-half); -+ border-bottom: var(--base-border); -+ } -+ -+ .compare-commit-list { -+ flex: 1; -+ display: flex; -+ flex-direction: column; -+ } -+ -+ .merge-cta { -+ border-top: var(--base-border); -+ display: flex; -+ flex-direction: column; -+ font-size: var(--font-size-sm); -+ text-align: center; -+ padding: var(--spacing); -+ } -+ -+ .merge-message { -+ margin-top: var(--spacing); -+ } -+ -+ .no-branches { -+ color: var(--text-secondary-color); -+ margin-top: var(--spacing-double); -+ } -+ -+ .branch-commit-counter { -+ color: var(--text-secondary-color); -+ display: flex; -+ justify-content: flex-end; -+ flex: 1; -+ font-size: var(--font-size-sm); -+ -+ &-item { -+ display: flex; -+ align-items: center; -+ -+ &:first-child { -+ margin-right: var(--spacing-half); -+ } -+ } -+ -+ .octicon { -+ fill: var(--text-secondary-color); -+ width: 8px; -+ margin-left: 1px; -+ -+ &:last-child { -+ margin-right: 0; -+ } -+ } -+ } -+ -+ .tab-bar { -+ padding: var(--spacing-half); -+ border-bottom: var(--base-border); -+ height: initial; -+ -+ &-item { -+ box-shadow: none; -+ background: var(--tab-bar-background-color); -+ border: var(--base-border); -+ -+ &:first-of-type { -+ border-radius: var(--border-radius) 0 0 var(--border-radius); -+ } -+ -+ &:last-of-type { -+ border-radius: 0 var(--border-radius) var(--border-radius) 0; -+ } -+ -+ &.selected { -+ background: var(--box-selected-active-background-color); -+ border-color: var(--box-border-accent-color); -+ color: var(--box-selected-active-text-color); -+ } -+ } -+ } -+ -+ .select-component { -+ flex-grow: 0; -+ } -+ -+ .compare-content { -+ display: flex; -+ height: 100%; -+ flex-direction: column; -+ -+ .ref-component { -+ word-break: break-word; - } - } - } -merged - result 100644 5cf34011a143e1112e833a2ba33f5d35a182088a app/styles/ui/toolbar/_toolbar.scss - our 100644 15433dbad68211b728ccfe0accfc3dc90955c1cf app/styles/ui/toolbar/_toolbar.scss -@@ -3,6 +3,7 @@ - /** A React component holding the main application toolbar component. */ - #desktop-app-toolbar { - height: var(--toolbar-height); -+ border-bottom: 1px solid var(--toolbar-border-color); - - display: flex; - flex-direction: row; -@@ -63,7 +64,7 @@ - .ahead-behind { - display: flex; - -- background: var(--ahead-behind-background-color); -+ background: var(--toolbar-badge-background-color); - - // Perfectly round semi circle ends with real tight - // padding on either side. Now in two flavors! -merged - result 100644 419ec0bccd48a36eeace41e2a86c10861ebb2943 app/styles/ui/window/_app-menu-bar.scss - our 100644 dee56f6f0fff77036d78caa38bafeb385e572bf4 app/styles/ui/window/_app-menu-bar.scss -@@ -10,12 +10,19 @@ - } - } - -+ .toolbar-dropdown.open > .toolbar-button > button { -+ background-color: var(--app-menu-button-active-background-color); -+ color: var(--app-menu-button-active-color); -+ } -+ - .toolbar-dropdown:not(.open) > .toolbar-button > button { -- color: var(--toolbar-text-color); -+ color: var(--app-menu-button-color); -+ background: transparent; - - &:hover, - &:focus { -- color: var(--toolbar-button-color); -+ color: var(--app-menu-button-hover-color); -+ background: var(--app-menu-button-hover-background-color); - } - } - -@@ -39,8 +46,25 @@ - pointer-events: none; - - .menu-pane { -+ --background-color: var(--app-menu-pane-background-color); - background: var(--background-color); -+ -+ --text-color: var(--app-menu-pane-color); -+ color: var(--text-color); -+ -+ --text-secondary-color: var(--app-menu-pane-secondary-color); -+ - pointer-events: all; - } -+ -+ .menu-item:hover { -+ &:not(.disabled) { -+ --text-color: var(--box-selected-active-text-color); -+ --text-secondary-color: var(--box-selected-active-text-color); -+ -+ color: var(--text-color); -+ background-color: var(--box-selected-active-background-color); -+ } -+ } - } - } -merged - result 100644 69f1e178d8523dc79986e345766ace7b3aa278c2 app/styles/ui/window/_toast-notification.scss - our 100644 965026fe769810b727cc768025c568ede86e918b app/styles/ui/window/_toast-notification.scss -@@ -14,8 +14,8 @@ - .toast-notification { - padding: var(--spacing) var(--spacing-double); - min-width: 100px; -- background: rgba($gray-900, 0.6); -- color: $gray-000; -+ background: var(--toast-notification-background-color); -+ color: var(--toast-notification-color); - text-align: center; - border-radius: 100px; - font-size: var(--font-size-md); -merged - result 100644 0e9a54a357e4abc1b90c957b3f2b5b9d770d63a9 app/styles/ui/window/_zoom-info.scss - our 100644 0c6db84cbb5f535dedef4192e2e914f5ab4ce20d app/styles/ui/window/_zoom-info.scss -@@ -14,8 +14,8 @@ - & > div { - padding: var(--spacing); - min-width: 100px; -- background: rgba($gray-900, 0.6); -- color: $gray-000; -+ background: var(--toast-notification-background-color); -+ color: var(--toast-notification-color); - text-align: center; - border-radius: 100px; - font-size: var(--font-size-md); -removed in remote - base 100755 a5d7b84a673458d14d9aab082183a1968c2c7492 app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/applypatch-msg.sample - our 100755 a5d7b84a673458d14d9aab082183a1968c2c7492 app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/applypatch-msg.sample -@@ -1,15 +0,0 @@ --#!/bin/sh --# --# An example hook script to check the commit log message taken by --# applypatch from an e-mail message. --# --# The hook should exit with non-zero status after issuing an --# appropriate message if it wants to stop the commit. The hook is --# allowed to edit the commit message file. --# --# To enable this hook, rename this file to "applypatch-msg". -- --. git-sh-setup --commitmsg="$(git rev-parse --git-path hooks/commit-msg)" --test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} --: -removed in remote - base 100755 b58d1184a9d43a39c0d95f32453efc78581877d6 app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/commit-msg.sample - our 100755 b58d1184a9d43a39c0d95f32453efc78581877d6 app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/commit-msg.sample -@@ -1,24 +0,0 @@ --#!/bin/sh --# --# An example hook script to check the commit log message. --# Called by "git commit" with one argument, the name of the file --# that has the commit message. The hook should exit with non-zero --# status after issuing an appropriate message if it wants to stop the --# commit. The hook is allowed to edit the commit message file. --# --# To enable this hook, rename this file to "commit-msg". -- --# Uncomment the below to add a Signed-off-by line to the message. --# Doing this in a hook is a bad idea in general, but the prepare-commit-msg --# hook is more suited to it. --# --# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') --# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" -- --# This example catches duplicate Signed-off-by lines. -- --test "" = "$(grep '^Signed-off-by: ' "$1" | -- sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { -- echo >&2 Duplicate Signed-off-by lines. -- exit 1 --} -removed in remote - base 100755 ec17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/post-update.sample - our 100755 ec17ec1939b7c3e86b7cb6c0c4de6b0818a7e75e app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/post-update.sample -@@ -1,8 +0,0 @@ --#!/bin/sh --# --# An example hook script to prepare a packed repository for use over --# dumb transports. --# --# To enable this hook, rename this file to "post-update". -- --exec git update-server-info -removed in remote - base 100755 4142082bcb939bbc17985a69ba748491ac6b62a5 app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/pre-applypatch.sample - our 100755 4142082bcb939bbc17985a69ba748491ac6b62a5 app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/pre-applypatch.sample -@@ -1,14 +0,0 @@ --#!/bin/sh --# --# An example hook script to verify what is about to be committed --# by applypatch from an e-mail message. --# --# The hook should exit with non-zero status after issuing an --# appropriate message if it wants to stop the commit. --# --# To enable this hook, rename this file to "pre-applypatch". -- --. git-sh-setup --precommit="$(git rev-parse --git-path hooks/pre-commit)" --test -x "$precommit" && exec "$precommit" ${1+"$@"} --: -removed in remote - base 100755 68d62d5446d963dc69006ad9a83907c6690f92c1 app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/pre-commit.sample - our 100755 68d62d5446d963dc69006ad9a83907c6690f92c1 app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/pre-commit.sample -@@ -1,49 +0,0 @@ --#!/bin/sh --# --# An example hook script to verify what is about to be committed. --# Called by "git commit" with no arguments. The hook should --# exit with non-zero status after issuing an appropriate message if --# it wants to stop the commit. --# --# To enable this hook, rename this file to "pre-commit". -- --if git rev-parse --verify HEAD >/dev/null 2>&1 --then -- against=HEAD --else -- # Initial commit: diff against an empty tree object -- against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 --fi -- --# If you want to allow non-ASCII filenames set this variable to true. --allownonascii=$(git config --bool hooks.allownonascii) -- --# Redirect output to stderr. --exec 1>&2 -- --# Cross platform projects tend to avoid non-ASCII filenames; prevent --# them from being added to the repository. We exploit the fact that the --# printable range starts at the space character and ends with tilde. --if [ "$allownonascii" != "true" ] && -- # Note that the use of brackets around a tr range is ok here, (it's -- # even required, for portability to Solaris 10's /usr/bin/tr), since -- # the square bracket bytes happen to fall in the designated range. -- test $(git diff --cached --name-only --diff-filter=A -z $against | -- LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 --then -- cat <<\EOF --Error: Attempt to add a non-ASCII file name. -- --This can cause problems if you want to work with people on other platforms. -- --To be portable it is advisable to rename the file. -- --If you know what you are doing you can disable this check using: -- -- git config hooks.allownonascii true --EOF -- exit 1 --fi -- --# If there are whitespace errors, print the offending file names and fail. --exec git diff-index --check --cached $against -- -removed in remote - base 100755 6187dbf4390fc6e28445dd3d988aefb9d1111988 app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/pre-push.sample - our 100755 6187dbf4390fc6e28445dd3d988aefb9d1111988 app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/pre-push.sample -@@ -1,53 +0,0 @@ --#!/bin/sh -- --# An example hook script to verify what is about to be pushed. Called by "git --# push" after it has checked the remote status, but before anything has been --# pushed. If this script exits with a non-zero status nothing will be pushed. --# --# This hook is called with the following parameters: --# --# $1 -- Name of the remote to which the push is being done --# $2 -- URL to which the push is being done --# --# If pushing without using a named remote those arguments will be equal. --# --# Information about the commits which are being pushed is supplied as lines to --# the standard input in the form: --# --# --# --# This sample shows how to prevent push of commits where the log message starts --# with "WIP" (work in progress). -- --remote="$1" --url="$2" -- --z40=0000000000000000000000000000000000000000 -- --while read local_ref local_sha remote_ref remote_sha --do -- if [ "$local_sha" = $z40 ] -- then -- # Handle delete -- : -- else -- if [ "$remote_sha" = $z40 ] -- then -- # New branch, examine all commits -- range="$local_sha" -- else -- # Update to existing branch, examine new commits -- range="$remote_sha..$local_sha" -- fi -- -- # Check for WIP commit -- commit=`git rev-list -n 1 --grep '^WIP' "$range"` -- if [ -n "$commit" ] -- then -- echo >&2 "Found WIP commit in $local_ref, not pushing" -- exit 1 -- fi -- fi --done -- --exit 0 -removed in remote - base 100755 6cbef5c370d8c3486ca85423dd70440c5e0a2aa2 app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/pre-rebase.sample - our 100755 6cbef5c370d8c3486ca85423dd70440c5e0a2aa2 app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/pre-rebase.sample -@@ -1,169 +0,0 @@ --#!/bin/sh --# --# Copyright (c) 2006, 2008 Junio C Hamano --# --# The "pre-rebase" hook is run just before "git rebase" starts doing --# its job, and can prevent the command from running by exiting with --# non-zero status. --# --# The hook is called with the following parameters: --# --# $1 -- the upstream the series was forked from. --# $2 -- the branch being rebased (or empty when rebasing the current branch). --# --# This sample shows how to prevent topic branches that are already --# merged to 'next' branch from getting rebased, because allowing it --# would result in rebasing already published history. -- --publish=next --basebranch="$1" --if test "$#" = 2 --then -- topic="refs/heads/$2" --else -- topic=`git symbolic-ref HEAD` || -- exit 0 ;# we do not interrupt rebasing detached HEAD --fi -- --case "$topic" in --refs/heads/??/*) -- ;; --*) -- exit 0 ;# we do not interrupt others. -- ;; --esac -- --# Now we are dealing with a topic branch being rebased --# on top of master. Is it OK to rebase it? -- --# Does the topic really exist? --git show-ref -q "$topic" || { -- echo >&2 "No such branch $topic" -- exit 1 --} -- --# Is topic fully merged to master? --not_in_master=`git rev-list --pretty=oneline ^master "$topic"` --if test -z "$not_in_master" --then -- echo >&2 "$topic is fully merged to master; better remove it." -- exit 1 ;# we could allow it, but there is no point. --fi -- --# Is topic ever merged to next? If so you should not be rebasing it. --only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` --only_next_2=`git rev-list ^master ${publish} | sort` --if test "$only_next_1" = "$only_next_2" --then -- not_in_topic=`git rev-list "^$topic" master` -- if test -z "$not_in_topic" -- then -- echo >&2 "$topic is already up to date with master" -- exit 1 ;# we could allow it, but there is no point. -- else -- exit 0 -- fi --else -- not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` -- /usr/bin/perl -e ' -- my $topic = $ARGV[0]; -- my $msg = "* $topic has commits already merged to public branch:\n"; -- my (%not_in_next) = map { -- /^([0-9a-f]+) /; -- ($1 => 1); -- } split(/\n/, $ARGV[1]); -- for my $elem (map { -- /^([0-9a-f]+) (.*)$/; -- [$1 => $2]; -- } split(/\n/, $ARGV[2])) { -- if (!exists $not_in_next{$elem->[0]}) { -- if ($msg) { -- print STDERR $msg; -- undef $msg; -- } -- print STDERR " $elem->[1]\n"; -- } -- } -- ' "$topic" "$not_in_next" "$not_in_master" -- exit 1 --fi -- --<<\DOC_END -- --This sample hook safeguards topic branches that have been --published from being rewound. -- --The workflow assumed here is: -- -- * Once a topic branch forks from "master", "master" is never -- merged into it again (either directly or indirectly). -- -- * Once a topic branch is fully cooked and merged into "master", -- it is deleted. If you need to build on top of it to correct -- earlier mistakes, a new topic branch is created by forking at -- the tip of the "master". This is not strictly necessary, but -- it makes it easier to keep your history simple. -- -- * Whenever you need to test or publish your changes to topic -- branches, merge them into "next" branch. -- --The script, being an example, hardcodes the publish branch name --to be "next", but it is trivial to make it configurable via --$GIT_DIR/config mechanism. -- --With this workflow, you would want to know: -- --(1) ... if a topic branch has ever been merged to "next". Young -- topic branches can have stupid mistakes you would rather -- clean up before publishing, and things that have not been -- merged into other branches can be easily rebased without -- affecting other people. But once it is published, you would -- not want to rewind it. -- --(2) ... if a topic branch has been fully merged to "master". -- Then you can delete it. More importantly, you should not -- build on top of it -- other people may already want to -- change things related to the topic as patches against your -- "master", so if you need further changes, it is better to -- fork the topic (perhaps with the same name) afresh from the -- tip of "master". -- --Let's look at this example: -- -- o---o---o---o---o---o---o---o---o---o "next" -- / / / / -- / a---a---b A / / -- / / / / -- / / c---c---c---c B / -- / / / \ / -- / / / b---b C \ / -- / / / / \ / -- ---o---o---o---o---o---o---o---o---o---o---o "master" -- -- --A, B and C are topic branches. -- -- * A has one fix since it was merged up to "next". -- -- * B has finished. It has been fully merged up to "master" and "next", -- and is ready to be deleted. -- -- * C has not merged to "next" at all. -- --We would want to allow C to be rebased, refuse A, and encourage --B to be deleted. -- --To compute (1): -- -- git rev-list ^master ^topic next -- git rev-list ^master next -- -- if these match, topic has not merged in next at all. -- --To compute (2): -- -- git rev-list master..topic -- -- if this is empty, it is fully merged to "master". -- --DOC_END -removed in remote - base 100755 a1fd29ec14823d8bc4a8d1a2cfe35451580f5118 app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/pre-receive.sample - our 100755 a1fd29ec14823d8bc4a8d1a2cfe35451580f5118 app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/pre-receive.sample -@@ -1,24 +0,0 @@ --#!/bin/sh --# --# An example hook script to make use of push options. --# The example simply echoes all push options that start with 'echoback=' --# and rejects all pushes when the "reject" push option is used. --# --# To enable this hook, rename this file to "pre-receive". -- --if test -n "$GIT_PUSH_OPTION_COUNT" --then -- i=0 -- while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" -- do -- eval "value=\$GIT_PUSH_OPTION_$i" -- case "$value" in -- echoback=*) -- echo "echo from the pre-receive-hook: ${value#*=}" >&2 -- ;; -- reject) -- exit 1 -- esac -- i=$((i + 1)) -- done --fi -removed in remote - base 100755 10fa14c5ab0134436e2ae435138bf921eb477c60 app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/prepare-commit-msg.sample - our 100755 10fa14c5ab0134436e2ae435138bf921eb477c60 app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/prepare-commit-msg.sample -@@ -1,42 +0,0 @@ --#!/bin/sh --# --# An example hook script to prepare the commit log message. --# Called by "git commit" with the name of the file that has the --# commit message, followed by the description of the commit --# message's source. The hook's purpose is to edit the commit --# message file. If the hook fails with a non-zero status, --# the commit is aborted. --# --# To enable this hook, rename this file to "prepare-commit-msg". -- --# This hook includes three examples. The first one removes the --# "# Please enter the commit message..." help message. --# --# The second includes the output of "git diff --name-status -r" --# into the message, just before the "git status" output. It is --# commented because it doesn't cope with --amend or with squashed --# commits. --# --# The third example adds a Signed-off-by line to the message, that can --# still be edited. This is rarely a good idea. -- --COMMIT_MSG_FILE=$1 --COMMIT_SOURCE=$2 --SHA1=$3 -- --/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" -- --# case "$COMMIT_SOURCE,$SHA1" in --# ,|template,) --# /usr/bin/perl -i.bak -pe ' --# print "\n" . `git diff --cached --name-status -r` --# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; --# *) ;; --# esac -- --# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') --# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" --# if test -z "$COMMIT_SOURCE" --# then --# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" --# fi -removed in remote - base 100755 80ba94135cc378364af9d3cb2450df48e51faf2c app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/update.sample - our 100755 80ba94135cc378364af9d3cb2450df48e51faf2c app/test/fixtures/submodule-basic-setup/_git/modules/foo/submodule/hooks/update.sample -@@ -1,128 +0,0 @@ --#!/bin/sh --# --# An example hook script to block unannotated tags from entering. --# Called by "git receive-pack" with arguments: refname sha1-old sha1-new --# --# To enable this hook, rename this file to "update". --# --# Config --# ------ --# hooks.allowunannotated --# This boolean sets whether unannotated tags will be allowed into the --# repository. By default they won't be. --# hooks.allowdeletetag --# This boolean sets whether deleting tags will be allowed in the --# repository. By default they won't be. --# hooks.allowmodifytag --# This boolean sets whether a tag may be modified after creation. By default --# it won't be. --# hooks.allowdeletebranch --# This boolean sets whether deleting branches will be allowed in the --# repository. By default they won't be. --# hooks.denycreatebranch --# This boolean sets whether remotely creating branches will be denied --# in the repository. By default this is allowed. --# -- --# --- Command line --refname="$1" --oldrev="$2" --newrev="$3" -- --# --- Safety check --if [ -z "$GIT_DIR" ]; then -- echo "Don't run this script from the command line." >&2 -- echo " (if you want, you could supply GIT_DIR then run" >&2 -- echo " $0 )" >&2 -- exit 1 --fi -- --if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then -- echo "usage: $0 " >&2 -- exit 1 --fi -- --# --- Config --allowunannotated=$(git config --bool hooks.allowunannotated) --allowdeletebranch=$(git config --bool hooks.allowdeletebranch) --denycreatebranch=$(git config --bool hooks.denycreatebranch) --allowdeletetag=$(git config --bool hooks.allowdeletetag) --allowmodifytag=$(git config --bool hooks.allowmodifytag) -- --# check for no description --projectdesc=$(sed -e '1q' "$GIT_DIR/description") --case "$projectdesc" in --"Unnamed repository"* | "") -- echo "*** Project description file hasn't been set" >&2 -- exit 1 -- ;; --esac -- --# --- Check types --# if $newrev is 0000...0000, it's a commit to delete a ref. --zero="0000000000000000000000000000000000000000" --if [ "$newrev" = "$zero" ]; then -- newrev_type=delete --else -- newrev_type=$(git cat-file -t $newrev) --fi -- --case "$refname","$newrev_type" in -- refs/tags/*,commit) -- # un-annotated tag -- short_refname=${refname##refs/tags/} -- if [ "$allowunannotated" != "true" ]; then -- echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 -- echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 -- exit 1 -- fi -- ;; -- refs/tags/*,delete) -- # delete tag -- if [ "$allowdeletetag" != "true" ]; then -- echo "*** Deleting a tag is not allowed in this repository" >&2 -- exit 1 -- fi -- ;; -- refs/tags/*,tag) -- # annotated tag -- if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 -- then -- echo "*** Tag '$refname' already exists." >&2 -- echo "*** Modifying a tag is not allowed in this repository." >&2 -- exit 1 -- fi -- ;; -- refs/heads/*,commit) -- # branch -- if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then -- echo "*** Creating a branch is not allowed in this repository" >&2 -- exit 1 -- fi -- ;; -- refs/heads/*,delete) -- # delete branch -- if [ "$allowdeletebranch" != "true" ]; then -- echo "*** Deleting a branch is not allowed in this repository" >&2 -- exit 1 -- fi -- ;; -- refs/remotes/*,commit) -- # tracking branch -- ;; -- refs/remotes/*,delete) -- # delete tracking branch -- if [ "$allowdeletebranch" != "true" ]; then -- echo "*** Deleting a tracking branch is not allowed in this repository" >&2 -- exit 1 -- fi -- ;; -- *) -- # Anything else (is there anything else?) -- echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 -- exit 1 -- ;; --esac -- --# --- Finished --exit 0 -merged - result 100644 c6c9857c1f579b979bb63020edfeee5cd8c1c3b2 app/test/helpers/repositories.ts - our 100644 684c5668ef4b431203378ee88185530b2bb7cf6f app/test/helpers/repositories.ts -@@ -23,7 +23,9 @@ - * - * @returns The path to the set up fixture repository. - */ --export function setupFixtureRepository(repositoryName: string): string { -+export async function setupFixtureRepository( -+ repositoryName: string -+): Promise { - const testRepoFixturePath = Path.join( - __dirname, - '..', -@@ -31,9 +33,9 @@ - repositoryName - ) - const testRepoPath = _temp.mkdirSync('desktop-git-test-') -- FSE.copySync(testRepoFixturePath, testRepoPath) -+ await FSE.copy(testRepoFixturePath, testRepoPath) - -- FSE.renameSync( -+ await FSE.rename( - Path.join(testRepoPath, '_git'), - Path.join(testRepoPath, '.git') - ) -@@ -49,11 +51,11 @@ - entry => Path.basename(entry.path) === '_git' - ) - -- submodules.forEach(entry => { -- const directory = Path.dirname(entry.path) -+ for (const submodule of submodules) { -+ const directory = Path.dirname(submodule.path) - const newPath = Path.join(directory, '.git') -- FSE.renameSync(entry.path, newPath) -- }) -+ await FSE.rename(submodule.path, newPath) -+ } - - return testRepoPath - } -@@ -84,19 +86,19 @@ - const repo = await setupEmptyRepository() - const filePath = Path.join(repo.path, 'foo') - -- FSE.writeFileSync(filePath, '') -+ await FSE.writeFile(filePath, '') - await GitProcess.exec(['add', 'foo'], repo.path) - await GitProcess.exec(['commit', '-m', 'Commit'], repo.path) - - await GitProcess.exec(['branch', 'other-branch'], repo.path) - -- FSE.writeFileSync(filePath, 'b1') -+ await FSE.writeFile(filePath, 'b1') - await GitProcess.exec(['add', 'foo'], repo.path) - await GitProcess.exec(['commit', '-m', 'Commit'], repo.path) - - await GitProcess.exec(['checkout', 'other-branch'], repo.path) - -- FSE.writeFileSync(filePath, 'b2') -+ await FSE.writeFile(filePath, 'b2') - await GitProcess.exec(['add', 'foo'], repo.path) - await GitProcess.exec(['commit', '-m', 'Commit'], repo.path) - -merged - result 100644 32e6cc0b6bac7d1adf6b538418ecc086354b1b67 app/test/unit/app-store-test.ts - our 100644 bd8253abfa8404e42377b4b26ffe52f11269f273 app/test/unit/app-store-test.ts -@@ -1,9 +1,7 @@ --/* eslint-disable no-sync */ -- --import { expect } from 'chai' -+import { expect, AssertionError } from 'chai' - - import * as Path from 'path' --import * as Fs from 'fs' -+import * as FSE from 'fs-extra' - import { GitProcess } from 'dugite' - - import { -@@ -30,7 +28,7 @@ - import { StatsStore } from '../../src/lib/stats' - - import { -- RepositorySection, -+ RepositorySectionTab, - SelectionType, - IRepositoryState, - } from '../../src/lib/app-state' -@@ -91,15 +89,15 @@ - describe('undo first commit', () => { - function getAppState(appStore: AppStore): IRepositoryState { - const selectedState = appStore.getState().selectedState -- if (!selectedState) { -- throw new chai.AssertionError('No selected state for AppStore') -+ if (selectedState == null) { -+ throw new AssertionError('No selected state for AppStore') - } - - switch (selectedState.type) { - case SelectionType.Repository: - return selectedState.state - default: -- throw new chai.AssertionError( -+ throw new AssertionError( - `Got selected state of type ${ - selectedState.type - } which is not supported.` -@@ -116,7 +114,7 @@ - const file = 'README.md' - const filePath = Path.join(repo.path, file) - -- Fs.writeFileSync(filePath, 'SOME WORDS GO HERE\n') -+ await FSE.writeFile(filePath, 'SOME WORDS GO HERE\n') - - await GitProcess.exec(['add', file], repo.path) - await GitProcess.exec(['commit', '-m', 'added file'], repo.path) -@@ -135,7 +133,7 @@ - await appStore._selectRepository(repository) - await appStore._changeRepositorySection( - repository, -- RepositorySection.Changes -+ RepositorySectionTab.Changes - ) - - let state = getAppState(appStore) -added in remote - their 100644 3b6e1598c0431836c3eb4416278702dcfb36fc7a app/test/unit/fuzzy-find-test.ts -@@ -0,0 +1,47 @@ -+import { expect } from 'chai' -+ -+import { match } from '../../src/lib/fuzzy-find' -+import { getText } from '../../src/ui/lib/filter-list' -+describe('fuzzy find', () => { -+ const items = [ -+ { -+ id: '300', -+ text: ['add fix for ...', 'opened 5 days ago by bob'], -+ }, -+ { -+ id: '500', -+ text: ['add support', '#4653 opened 3 days ago by damaneice '], -+ }, -+ { -+ id: '500', -+ text: ['add an awesome feature', '#7564 opened 10 days ago by ... '], -+ }, -+ ] -+ -+ it('should find matching item when searching by pull request number', () => { -+ const results = match('4653', items, getText) -+ -+ expect(results.length).to.equal(1) -+ expect(results[0].item['text'].join('')).to.include('4653') -+ }) -+ -+ it('should find matching item when searching by author', () => { -+ const results = match('damaneice', items, getText) -+ -+ expect(results.length).to.equal(1) -+ expect(results[0].item['text'].join('')).to.include('damaneice') -+ }) -+ -+ it('should find matching item when by title', () => { -+ const results = match('awesome feature', items, getText) -+ -+ expect(results.length).to.equal(1) -+ expect(results[0].item['text'].join('')).to.include('awesome feature') -+ }) -+ -+ it('should find nothing', () => { -+ const results = match('$%^', items, getText) -+ -+ expect(results.length).to.equal(0) -+ }) -+}) -merged - result 100644 e02161f0a2678543f55f2c71f1a61103faa56c1b app/test/unit/git-store-test.ts - our 100644 b69dfb902e2537440f7b72b9537c1de1aaf8b113 app/test/unit/git-store-test.ts -@@ -1,7 +1,5 @@ --/* eslint-disable no-sync */ -- - import { expect } from 'chai' --import * as Fs from 'fs' -+import * as FSE from 'fs-extra' - import * as Path from 'path' - import { GitProcess } from 'dugite' - -@@ -26,18 +24,18 @@ - const readmeFile = 'README.md' - const readmeFilePath = Path.join(repo.path, readmeFile) - -- Fs.writeFileSync(readmeFilePath, 'SOME WORDS GO HERE\n') -+ await FSE.writeFile(readmeFilePath, 'SOME WORDS GO HERE\n') - - const licenseFile = 'LICENSE.md' - const licenseFilePath = Path.join(repo.path, licenseFile) - -- Fs.writeFileSync(licenseFilePath, 'SOME WORDS GO HERE\n') -+ await FSE.writeFile(licenseFilePath, 'SOME WORDS GO HERE\n') - - // commit the readme file but leave the license - await GitProcess.exec(['add', readmeFile], repo.path) - await GitProcess.exec(['commit', '-m', 'added readme file'], repo.path) - -- Fs.writeFileSync(readmeFilePath, 'WRITING SOME NEW WORDS\n') -+ await FSE.writeFile(readmeFilePath, 'WRITING SOME NEW WORDS\n') - // setup requires knowing about the current tip - await gitStore.loadStatus() - -@@ -65,7 +63,7 @@ - const renamedFile = 'NEW-README.md' - const filePath = Path.join(repo.path, file) - -- Fs.writeFileSync(filePath, 'SOME WORDS GO HERE\n') -+ await FSE.writeFile(filePath, 'SOME WORDS GO HERE\n') - - // commit the file, and then rename it - await GitProcess.exec(['add', file], repo.path) -@@ -96,7 +94,7 @@ - const file = 'README.md' - const filePath = Path.join(repo.path, file) - -- Fs.writeFileSync(filePath, 'SOME WORDS GO HERE\n') -+ await FSE.writeFile(filePath, 'SOME WORDS GO HERE\n') - - await GitProcess.exec(['add', file], repo.path) - await GitProcess.exec(['commit', '-m', commitMessage], repo.path) -@@ -199,7 +197,7 @@ - const file = 'README.md' - const filePath = Path.join(repo.path, file) - -- Fs.writeFileSync(filePath, 'SOME WORDS GO HERE\n') -+ await FSE.writeFile(filePath, 'SOME WORDS GO HERE\n') - - let status = await getStatus(repo!) - let files = status.workingDirectory.files -merged - result 100644 b8af7e5f1bcd0c13b909dfa237c7d3378bcc683f app/test/unit/git/commit-test.ts - our 100644 b5ac688e52bb47f381388bb2ae97547c3766deb5 app/test/unit/git/commit-test.ts -@@ -1,6 +1,6 @@ --/* eslint-disable no-sync */ -- - import * as path from 'path' -+import * as FSE from 'fs-extra' -+ - import { expect } from 'chai' - - import { Repository } from '../../../src/models/repository' -@@ -31,8 +31,6 @@ - DiffType, - } from '../../../src/models/diff' - --import * as fs from 'fs-extra' -- - async function getTextDiff( - repo: Repository, - file: WorkingDirectoryFileChange -@@ -46,13 +44,16 @@ - let repository: Repository | null = null - - beforeEach(async () => { -- const testRepoPath = setupFixtureRepository('test-repo') -+ const testRepoPath = await setupFixtureRepository('test-repo') - repository = new Repository(testRepoPath, -1, null, false) - }) - - describe('createCommit normal', () => { - it('commits the given files', async () => { -- fs.writeFileSync(path.join(repository!.path, 'README.md'), 'Hi world\n') -+ await FSE.writeFile( -+ path.join(repository!.path, 'README.md'), -+ 'Hi world\n' -+ ) - - let status = await getStatus(repository!) - let files = status.workingDirectory.files -@@ -70,7 +71,10 @@ - }) - - it('commit does not strip commentary by default', async () => { -- fs.writeFileSync(path.join(repository!.path, 'README.md'), 'Hi world\n') -+ await FSE.writeFile( -+ path.join(repository!.path, 'README.md'), -+ 'Hi world\n' -+ ) - - const status = await getStatus(repository!) - const files = status.workingDirectory.files -@@ -91,8 +95,8 @@ - it('can commit for empty repository', async () => { - const repo = await setupEmptyRepository() - -- fs.writeFileSync(path.join(repo.path, 'foo'), 'foo\n') -- fs.writeFileSync(path.join(repo.path, 'bar'), 'bar\n') -+ await FSE.writeFile(path.join(repo.path, 'foo'), 'foo\n') -+ await FSE.writeFile(path.join(repo.path, 'bar'), 'bar\n') - - const status = await getStatus(repo) - const files = status.workingDirectory.files -@@ -124,7 +128,7 @@ - it('can commit renames', async () => { - const repo = await setupEmptyRepository() - -- fs.writeFileSync(path.join(repo.path, 'foo'), 'foo\n') -+ await FSE.writeFile(path.join(repo.path, 'foo'), 'foo\n') - - await GitProcess.exec(['add', 'foo'], repo.path) - await GitProcess.exec(['commit', '-m', 'Initial commit'], repo.path) -@@ -147,7 +151,7 @@ - - describe('createCommit partials', () => { - beforeEach(async () => { -- const testRepoPath = setupFixtureRepository('repo-with-changes') -+ const testRepoPath = await setupFixtureRepository('repo-with-changes') - repository = new Repository(testRepoPath, -1, null, false) - }) - -@@ -383,13 +387,13 @@ - it('can commit renames with modifications', async () => { - const repo = await setupEmptyRepository() - -- fs.writeFileSync(path.join(repo.path, 'foo'), 'foo\n') -+ await FSE.writeFile(path.join(repo.path, 'foo'), 'foo\n') - - await GitProcess.exec(['add', 'foo'], repo.path) - await GitProcess.exec(['commit', '-m', 'Initial commit'], repo.path) - await GitProcess.exec(['mv', 'foo', 'bar'], repo.path) - -- fs.writeFileSync(path.join(repo.path, 'bar'), 'bar\n') -+ await FSE.writeFile(path.join(repo.path, 'bar'), 'bar\n') - - const status = await getStatus(repo) - const files = status.workingDirectory.files -@@ -411,13 +415,13 @@ - it('can commit renames with partially selected modifications', async () => { - const repo = await setupEmptyRepository() - -- fs.writeFileSync(path.join(repo.path, 'foo'), 'line1\n') -+ await FSE.writeFile(path.join(repo.path, 'foo'), 'line1\n') - - await GitProcess.exec(['add', 'foo'], repo.path) - await GitProcess.exec(['commit', '-m', 'Initial commit'], repo.path) - await GitProcess.exec(['mv', 'foo', 'bar'], repo.path) - -- fs.writeFileSync(path.join(repo.path, 'bar'), 'line1\nline2\nline3\n') -+ await FSE.writeFile(path.join(repo.path, 'bar'), 'line1\nline2\nline3\n') - - const status = await getStatus(repo) - const files = status.workingDirectory.files -@@ -454,10 +458,12 @@ - const repo = await setupConflictedRepo() - const filePath = path.join(repo.path, 'foo') - -- const inMerge = fs.existsSync(path.join(repo.path, '.git', 'MERGE_HEAD')) -+ const inMerge = await FSE.pathExists( -+ path.join(repo.path, '.git', 'MERGE_HEAD') -+ ) - expect(inMerge).to.equal(true) - -- fs.writeFileSync(filePath, 'b1b2') -+ await FSE.writeFile(filePath, 'b1b2') - - const status = await getStatus(repo) - const files = status.workingDirectory.files -@@ -485,12 +491,12 @@ - const firstPath = path.join(repo.path, 'first') - const secondPath = path.join(repo.path, 'second') - -- fs.writeFileSync(firstPath, 'line1\n') -- fs.writeFileSync(secondPath, 'line2\n') -+ await FSE.writeFile(firstPath, 'line1\n') -+ await FSE.writeFile(secondPath, 'line2\n') - - await GitProcess.exec(['add', '.'], repo.path) - -- fs.unlinkSync(firstPath) -+ await FSE.unlink(firstPath) - - status = await getStatus(repo) - files = status.workingDirectory.files -@@ -519,14 +525,14 @@ - const repo = await setupEmptyRepository() - - const firstPath = path.join(repo.path, 'first') -- fs.writeFileSync(firstPath, 'line1\n') -+ await FSE.writeFile(firstPath, 'line1\n') - - await GitProcess.exec(['add', 'first'], repo.path) - await GitProcess.exec(['commit', '-am', 'commit first file'], repo.path) - await GitProcess.exec(['rm', '--cached', 'first'], repo.path) - - // if the text is now different, everything is fine -- fs.writeFileSync(firstPath, 'line2\n') -+ await FSE.writeFile(firstPath, 'line2\n') - - status = await getStatus(repo) - files = status.workingDirectory.files -merged - result 100644 d72e598b34da70f1894844dffc261776e7134a67 app/test/unit/git/config-test.ts - our 100644 15317f86c3ba7276aff4b60a3953977a2faeb366 app/test/unit/git/config-test.ts -@@ -1,5 +1,3 @@ --/* eslint-disable no-sync */ -- - import { expect } from 'chai' - - import { Repository } from '../../../src/models/repository' -@@ -15,8 +13,8 @@ - describe('git/config', () => { - let repository: Repository | null = null - -- beforeEach(() => { -- const testRepoPath = setupFixtureRepository('test-repo') -+ beforeEach(async () => { -+ const testRepoPath = await setupFixtureRepository('test-repo') - repository = new Repository(testRepoPath, -1, null, false) - }) - -merged - result 100644 9102d54e4ff407253f9f43fc45f7947c8e9bd28f app/test/unit/git/core-test.ts - our 100644 31f49752ce15852eb636a19c18f289d48fa9e745 app/test/unit/git/core-test.ts -@@ -1,5 +1,3 @@ --/* eslint-disable no-sync */ -- - import { expect } from 'chai' - import { GitError } from 'dugite' - -@@ -10,8 +8,8 @@ - describe('git/core', () => { - let repository: Repository | null = null - -- beforeEach(() => { -- const testRepoPath = setupFixtureRepository('test-repo') -+ beforeEach(async () => { -+ const testRepoPath = await setupFixtureRepository('test-repo') - repository = new Repository(testRepoPath, -1, null, false) - }) - -added in remote - their 100644 1ed66bd68f5c8720ca2034726118003654d19391 app/test/unit/git/description-test.ts -@@ -0,0 +1,35 @@ -+import { expect } from 'chai' -+import * as FSE from 'fs-extra' -+import * as Path from 'path' -+ -+import { getGitDescription } from '../../../src/lib/git' -+import { setupEmptyRepository } from '../../helpers/repositories' -+ -+describe('git/description', () => { -+ describe('getGitDescription', () => { -+ it('returns empty for an initialized repository', async () => { -+ const repo = await setupEmptyRepository() -+ const actual = await getGitDescription(repo.path) -+ expect(actual).equals('') -+ }) -+ -+ it('returns empty when path is missing', async () => { -+ const repo = await setupEmptyRepository() -+ const path = Path.join(repo.path, '.git', 'description') -+ await FSE.unlink(path) -+ -+ const actual = await getGitDescription(repo.path) -+ expect(actual).equals('') -+ }) -+ -+ it('reads the custom text', async () => { -+ const expected = 'this is a repository description' -+ const repo = await setupEmptyRepository() -+ const path = Path.join(repo.path, '.git', 'description') -+ await FSE.writeFile(path, expected) -+ -+ const actual = await getGitDescription(repo.path) -+ expect(actual).equals(expected) -+ }) -+ }) -+}) -merged - result 100644 70828b75f4fb7701c613f210cfcd5a077c1e6160 app/test/unit/git/diff-test.ts - our 100644 e51e778ec9c2cf88a9eeed5a4b7201e8ddbca64f app/test/unit/git/diff-test.ts -@@ -1,9 +1,7 @@ --/* eslint-disable no-sync */ -- - import { expect } from 'chai' - - import * as path from 'path' --import * as fs from 'fs-extra' -+import * as FSE from 'fs-extra' - - import { Repository } from '../../../src/models/repository' - import { -@@ -43,8 +41,8 @@ - describe('git/diff', () => { - let repository: Repository | null = null - -- beforeEach(() => { -- const testRepoPath = setupFixtureRepository('repo-with-image-changes') -+ beforeEach(async () => { -+ const testRepoPath = await setupFixtureRepository('repo-with-image-changes') - repository = new Repository(testRepoPath, -1, null, false) - }) - -@@ -135,7 +133,7 @@ - }) - - it('changes for text are not set', async () => { -- const testRepoPath = setupFixtureRepository('repo-with-changes') -+ const testRepoPath = await setupFixtureRepository('repo-with-changes') - repository = new Repository(testRepoPath, -1, null, false) - - const diffSelection = DiffSelection.fromInitialSelection( -@@ -153,8 +151,8 @@ - }) - - describe('getWorkingDirectoryDiff', () => { -- beforeEach(() => { -- const testRepoPath = setupFixtureRepository('repo-with-changes') -+ beforeEach(async () => { -+ const testRepoPath = await setupFixtureRepository('repo-with-changes') - repository = new Repository(testRepoPath, -1, null, false) - }) - -@@ -260,7 +258,7 @@ - it('is empty for a renamed file', async () => { - const repo = await setupEmptyRepository() - -- fs.writeFileSync(path.join(repo.path, 'foo'), 'foo\n') -+ await FSE.writeFile(path.join(repo.path, 'foo'), 'foo\n') - - await GitProcess.exec(['add', 'foo'], repo.path) - await GitProcess.exec(['commit', '-m', 'Initial commit'], repo.path) -@@ -283,13 +281,13 @@ - it('only shows modifications after move for a renamed and modified file', async () => { - const repo = await setupEmptyRepository() - -- fs.writeFileSync(path.join(repo.path, 'foo'), 'foo\n') -+ await FSE.writeFile(path.join(repo.path, 'foo'), 'foo\n') - - await GitProcess.exec(['add', 'foo'], repo.path) - await GitProcess.exec(['commit', '-m', 'Initial commit'], repo.path) - await GitProcess.exec(['mv', 'foo', 'bar'], repo.path) - -- fs.writeFileSync(path.join(repo.path, 'bar'), 'bar\n') -+ await FSE.writeFile(path.join(repo.path, 'bar'), 'bar\n') - - const status = await getStatus(repo) - const files = status.workingDirectory.files -@@ -309,11 +307,14 @@ - it('handles unborn repository with mixed state', async () => { - const repo = await setupEmptyRepository() - -- fs.writeFileSync(path.join(repo.path, 'foo'), 'WRITING THE FIRST LINE\n') -+ await FSE.writeFile( -+ path.join(repo.path, 'foo'), -+ 'WRITING THE FIRST LINE\n' -+ ) - - await GitProcess.exec(['add', 'foo'], repo.path) - -- fs.writeFileSync(path.join(repo.path, 'foo'), 'WRITING OVER THE TOP\n') -+ await FSE.writeFile(path.join(repo.path, 'foo'), 'WRITING OVER THE TOP\n') - - const status = await getStatus(repo) - const files = status.workingDirectory.files -@@ -337,7 +338,7 @@ - - let lineEnding = '\r\n' - -- fs.writeFileSync( -+ await FSE.writeFile( - filePath, - `WRITING MANY LINES ${lineEnding} USING THIS LINE ENDING ${lineEnding} TO SHOW THAT GIT${lineEnding} WILL INSERT IT WITHOUT CHANGING THING ${lineEnding} HA HA BUSINESS` - ) -@@ -351,7 +352,7 @@ - await GitProcess.exec(['config', 'core.autocrlf', 'true'], repo.path) - lineEnding = '\n\n' - -- fs.writeFileSync( -+ await FSE.writeFile( - filePath, - `WRITING MANY LINES ${lineEnding} USING THIS LINE ENDING ${lineEnding} TO SHOW THAT GIT${lineEnding} WILL INSERT IT WITHOUT CHANGING THING ${lineEnding} HA HA BUSINESS` - ) -@@ -375,7 +376,7 @@ - const filePath = path.join(repo.path, 'foo') - - const testString = 'here are some cool characters: • é 漢字' -- fs.writeFileSync(filePath, testString) -+ await FSE.writeFile(filePath, testString) - - const status = await getStatus(repo) - const files = status.workingDirectory.files -merged - result 100644 49b5c229ff03e3bb85d45773693b29bcf664cfa0 app/test/unit/git/for-each-ref-test.ts - our 100644 489ff8c45295f4effd89131fe26c32b9caeb4686 app/test/unit/git/for-each-ref-test.ts -@@ -10,8 +10,8 @@ - describe('git/for-each-ref', () => { - let repository: Repository | null = null - -- beforeEach(() => { -- const testRepoPath = setupFixtureRepository('repo-with-many-refs') -+ beforeEach(async () => { -+ const testRepoPath = await setupFixtureRepository('repo-with-many-refs') - repository = new Repository(testRepoPath, -1, null, false) - }) - -added in remote - their 100644 efa84e67645f24f1b4905d9815b78c84b1debcb5 app/test/unit/git/git-attributes-test.ts -@@ -0,0 +1,18 @@ -+import { expect } from 'chai' -+import * as FSE from 'fs-extra' -+import * as Path from 'path' -+ -+import { setupEmptyRepository } from '../../helpers/repositories' -+import { writeGitAttributes } from '../../../src/ui/add-repository/git-attributes' -+ -+describe('git/git-attributes', () => { -+ describe('writeGitAttributes', () => { -+ it('initializes a .gitattributes file', async () => { -+ const repo = await setupEmptyRepository() -+ await writeGitAttributes(repo.path) -+ const expectedPath = Path.join(repo.path, '.gitattributes') -+ const contents = await FSE.readFile(expectedPath, 'utf8') -+ expect(contents).to.contain('* text=auto') -+ }) -+ }) -+}) -merged - result 100644 4b5b3f160a0264cf66886c0aa339b1fad38181b1 app/test/unit/git/log-test.ts - our 100644 ad903fd317c8097f5cb62d13f559c282be3f0e55 app/test/unit/git/log-test.ts -@@ -1,5 +1,3 @@ --/* eslint-disable no-sync */ -- - import { expect } from 'chai' - - import { Repository } from '../../../src/models/repository' -@@ -11,8 +9,8 @@ - describe('git/log', () => { - let repository: Repository | null = null - -- beforeEach(() => { -- const testRepoPath = setupFixtureRepository('test-repo') -+ beforeEach(async () => { -+ const testRepoPath = await setupFixtureRepository('test-repo') - repository = new Repository(testRepoPath, -1, null, false) - }) - -@@ -48,7 +46,9 @@ - }) - - it('detects renames', async () => { -- const testRepoPath = setupFixtureRepository('rename-history-detection') -+ const testRepoPath = await setupFixtureRepository( -+ 'rename-history-detection' -+ ) - repository = new Repository(testRepoPath, -1, null, false) - - const first = await getChangedFiles(repository, '55bdecb') -@@ -65,7 +65,9 @@ - }) - - it('detect copies', async () => { -- const testRepoPath = setupFixtureRepository('copies-history-detection') -+ const testRepoPath = await setupFixtureRepository( -+ 'copies-history-detection' -+ ) - repository = new Repository(testRepoPath, -1, null, false) - - // ensure the test repository is configured to detect copies -merged - result 100644 26ef5a516cc51061106a84706a4b53aba7a4bae5 app/test/unit/git/reflog-test.ts - our 100644 753f89bdff58df67c59ada62fd5318e25de1f0c9 app/test/unit/git/reflog-test.ts -@@ -1,5 +1,3 @@ --/* eslint-disable no-sync */ -- - import { expect } from 'chai' - - import { Repository } from '../../../src/models/repository' -@@ -28,8 +26,8 @@ - describe('git/reflog', () => { - let repository: Repository | null = null - -- beforeEach(() => { -- const testRepoPath = setupFixtureRepository('test-repo') -+ beforeEach(async () => { -+ const testRepoPath = await setupFixtureRepository('test-repo') - repository = new Repository(testRepoPath, -1, null, false) - }) - -merged - result 100644 ec4c2f0abae62b3b2e24b3d1f8d4c026202866ae app/test/unit/git/remote-test.ts - our 100644 0c31a4654bc26c2af1888154faf1ed1c5b074f9e app/test/unit/git/remote-test.ts -@@ -1,5 +1,3 @@ --/* eslint-disable no-sync */ -- - import { expect } from 'chai' - - import { Repository } from '../../../src/models/repository' -@@ -17,7 +15,9 @@ - describe('git/remote', () => { - describe('getRemotes', () => { - it('should return both remotes', async () => { -- const testRepoPath = setupFixtureRepository('repo-with-multiple-remotes') -+ const testRepoPath = await setupFixtureRepository( -+ 'repo-with-multiple-remotes' -+ ) - const repository = new Repository(testRepoPath, -1, null, false) - - // NB: We don't check for exact URL equality because CircleCI's git config -@@ -36,7 +36,9 @@ - - describe('getDefaultRemote', () => { - it('returns origin when multiple remotes found', async () => { -- const testRepoPath = setupFixtureRepository('repo-with-multiple-remotes') -+ const testRepoPath = await setupFixtureRepository( -+ 'repo-with-multiple-remotes' -+ ) - const repository = new Repository(testRepoPath, -1, null, false) - - const result = await getDefaultRemote(repository) -@@ -45,7 +47,9 @@ - }) - - it('returns something when origin removed', async () => { -- const testRepoPath = setupFixtureRepository('repo-with-multiple-remotes') -+ const testRepoPath = await setupFixtureRepository( -+ 'repo-with-multiple-remotes' -+ ) - const repository = new Repository(testRepoPath, -1, null, false) - await removeRemote(repository, 'origin') - -merged - result 100644 ae434a7ebf90e34582704265a7bee208e3ee30e1 app/test/unit/git/reset-test.ts - our 100644 de0b8ecb1767d94f933eb81fdb46f8030e0ed0d1 app/test/unit/git/reset-test.ts -@@ -1,5 +1,3 @@ --/* eslint-disable no-sync */ -- - import * as path from 'path' - import { expect } from 'chai' - -@@ -9,13 +7,13 @@ - import { setupFixtureRepository } from '../../helpers/repositories' - import { GitProcess } from 'dugite' - --import * as fs from 'fs-extra' -+import * as FSE from 'fs-extra' - - describe('git/reset', () => { - let repository: Repository | null = null - -- beforeEach(() => { -- const testRepoPath = setupFixtureRepository('test-repo') -+ beforeEach(async () => { -+ const testRepoPath = await setupFixtureRepository('test-repo') - repository = new Repository(testRepoPath, -1, null, false) - }) - -@@ -25,7 +23,7 @@ - const fileName = 'README.md' - const filePath = path.join(repoPath, fileName) - -- fs.writeFileSync(filePath, 'Hi world\n') -+ await FSE.writeFile(filePath, 'Hi world\n') - - await reset(repository!, GitResetMode.Hard, 'HEAD') - -@@ -35,17 +33,17 @@ - }) - - describe('resetPaths', () => { -- it('resets discarded staged file', async () => { -+ it.skip('resets discarded staged file', async () => { - const repoPath = repository!.path - const fileName = 'README.md' - const filePath = path.join(repoPath, fileName) - - // modify the file -- fs.writeFileSync(filePath, 'Hi world\n') -+ await FSE.writeFile(filePath, 'Hi world\n') - - // stage the file, then delete it to mimic discarding - GitProcess.exec(['add', fileName], repoPath) -- fs.unlinkSync(filePath) -+ await FSE.unlink(filePath) - - await resetPaths(repository!, GitResetMode.Mixed, 'HEAD', [filePath]) - -merged - result 100644 9f59f8eafa96145f5a0182713ae312a61d5633c6 app/test/unit/git/rev-parse-test.ts - our 100644 2fe66109a93a488e1d52f361aa11b5fd03ab6c4d app/test/unit/git/rev-parse-test.ts -@@ -1,7 +1,5 @@ --/* eslint-disable no-sync */ -- - import * as path from 'path' --import * as Fs from 'fs' -+import * as FSE from 'fs-extra' - import * as os from 'os' - import { expect } from 'chai' - -@@ -16,8 +14,8 @@ - describe('git/rev-parse', () => { - let repository: Repository | null = null - -- beforeEach(() => { -- const testRepoPath = setupFixtureRepository('test-repo') -+ beforeEach(async () => { -+ const testRepoPath = await setupFixtureRepository('test-repo') - repository = new Repository(testRepoPath, -1, null, false) - }) - -@@ -39,10 +37,7 @@ - expect(result).to.equal(repository!.path) - - const subdirPath = path.join(repository!.path, 'subdir') -- -- await new Promise((resolve, reject) => { -- Fs.mkdir(subdirPath, e => (e ? reject(e) : resolve())) -- }) -+ await FSE.mkdir(subdirPath) - - const subDirResult = await getTopLevelWorkingDirectory(repository!.path) - expect(subDirResult).to.equal(repository!.path) -merged - result 100644 b70094de837ed6cb2305e65414cd7c4c3403edc0 app/test/unit/git/status-test.ts - our 100644 59e49a131e79925c8b8307125053a59d2970ba4e app/test/unit/git/status-test.ts -@@ -1,7 +1,7 @@ --/* eslint-disable no-sync */ -- - import * as path from 'path' - import { expect } from 'chai' -+import * as FSE from 'fs-extra' -+import { GitProcess } from 'dugite' - - import { Repository } from '../../../src/models/repository' - import { getStatus } from '../../../src/lib/git/status' -@@ -10,21 +10,21 @@ - setupEmptyRepository, - } from '../../helpers/repositories' - import { AppFileStatus } from '../../../src/models/status' --import { GitProcess } from 'dugite' -- --import * as fs from 'fs-extra' - - describe('git/status', () => { - let repository: Repository | null = null - -- beforeEach(() => { -- const testRepoPath = setupFixtureRepository('test-repo') -+ beforeEach(async () => { -+ const testRepoPath = await setupFixtureRepository('test-repo') - repository = new Repository(testRepoPath, -1, null, false) - }) - - describe('getStatus', () => { - it('parses changed files', async () => { -- fs.writeFileSync(path.join(repository!.path, 'README.md'), 'Hi world\n') -+ await FSE.writeFile( -+ path.join(repository!.path, 'README.md'), -+ 'Hi world\n' -+ ) - - const status = await getStatus(repository!) - const files = status.workingDirectory.files -@@ -44,7 +44,7 @@ - it('reflects renames', async () => { - const repo = await setupEmptyRepository() - -- fs.writeFileSync(path.join(repo.path, 'foo'), 'foo\n') -+ await FSE.writeFile(path.join(repo.path, 'foo'), 'foo\n') - - await GitProcess.exec(['add', 'foo'], repo.path) - await GitProcess.exec(['commit', '-m', 'Initial commit'], repo.path) -merged - result 100644 458f70ab3e9d3c2a72710726ed0ccf67f9644e7c app/test/unit/git/submodule-test.ts - our 100644 c03c4406fbdfec1ca3d327273d6fa3bf9fe4c17d app/test/unit/git/submodule-test.ts -@@ -12,7 +12,7 @@ - describe('git/submodule', () => { - describe('listSubmodules', () => { - it('returns the submodule entry', async () => { -- const testRepoPath = setupFixtureRepository('submodule-basic-setup') -+ const testRepoPath = await setupFixtureRepository('submodule-basic-setup') - const repository = new Repository(testRepoPath, -1, null, false) - const result = await listSubmodules(repository) - expect(result.length).to.equal(1) -@@ -22,7 +22,7 @@ - }) - - it('returns the expected tag', async () => { -- const testRepoPath = setupFixtureRepository('submodule-basic-setup') -+ const testRepoPath = await setupFixtureRepository('submodule-basic-setup') - const repository = new Repository(testRepoPath, -1, null, false) - - const submodulePath = path.join(testRepoPath, 'foo', 'submodule') -@@ -49,7 +49,7 @@ - - describe('resetSubmodulePaths', () => { - it('update submodule to original commit', async () => { -- const testRepoPath = setupFixtureRepository('submodule-basic-setup') -+ const testRepoPath = await setupFixtureRepository('submodule-basic-setup') - const repository = new Repository(testRepoPath, -1, null, false) - - const submodulePath = path.join(testRepoPath, 'foo', 'submodule') -added in remote - their 100644 b4f8bad4223c7ca09f796baa5b5bcc5da2d75cac app/test/unit/infer-comparison-branch-test.ts -@@ -0,0 +1,205 @@ -+import { expect } from 'chai' -+import { inferComparisonBranch } from '../../src/lib/stores/helpers/infer-comparison-branch' -+import { Branch, BranchType } from '../../src/models/branch' -+import { Commit } from '../../src/models/commit' -+import { CommitIdentity } from '../../src/models/commit-identity' -+import { GitHubRepository } from '../../src/models/github-repository' -+import { Owner } from '../../src/models/owner' -+import { PullRequest, PullRequestRef } from '../../src/models/pull-request' -+import { Repository } from '../../src/models/repository' -+import { IRemote } from '../../src/models/remote' -+import { ComparisonCache } from '../../src/lib/comparison-cache' -+ -+function createTestCommit(sha: string) { -+ return new Commit( -+ sha, -+ '', -+ '', -+ new CommitIdentity('tester', 'tester@test.com', new Date()), -+ new CommitIdentity('tester', 'tester@test.com', new Date()), -+ [], -+ [] -+ ) -+} -+ -+function createTestBranch( -+ name: string, -+ sha: string, -+ remote: string | null = null -+) { -+ return new Branch(name, remote, createTestCommit(sha), BranchType.Local) -+} -+ -+function createTestGhRepo( -+ name: string, -+ defaultBranch: string | null = null, -+ parent: GitHubRepository | null = null -+) { -+ return new GitHubRepository( -+ name, -+ new Owner('', '', null), -+ null, -+ false, -+ '', -+ `${ -+ defaultBranch !== null && defaultBranch.indexOf('/') !== -1 -+ ? defaultBranch.split('/')[1] -+ : defaultBranch -+ }`, -+ `${name.indexOf('/') !== -1 ? name.split('/')[1] : name}.git`, -+ parent -+ ) -+} -+ -+function createTestPrRef( -+ branch: Branch, -+ ghRepo: GitHubRepository | null = null -+) { -+ return new PullRequestRef(branch.name, branch.tip.sha, ghRepo) -+} -+ -+function createTestPr(head: PullRequestRef, base: PullRequestRef) { -+ return new PullRequest(-1, new Date(), null, '', 1, head, base, '') -+} -+ -+function createTestRepo(ghRepo: GitHubRepository | null = null) { -+ return new Repository('', -1, ghRepo, false) -+} -+ -+function mockGetRemotes(repo: Repository): Promise> { -+ return Promise.resolve([]) -+} -+ -+describe('inferComparisonBranch', () => { -+ const branches = [ -+ createTestBranch('master', '0', 'origin'), -+ createTestBranch('dev', '1', 'origin'), -+ createTestBranch('staging', '2', 'origin'), -+ createTestBranch('default', '3', 'origin'), -+ createTestBranch('head', '4', 'origin'), -+ createTestBranch('upstream/base', '5', 'upstream'), -+ createTestBranch('fork', '6', 'origin'), -+ ] -+ const comparisonCache = new ComparisonCache() -+ -+ beforeEach(() => { -+ comparisonCache.clear() -+ }) -+ -+ it('Returns the master branch when given unhosted repo', async () => { -+ const repo = createTestRepo() -+ const branch = await inferComparisonBranch( -+ repo, -+ branches, -+ null, -+ null, -+ mockGetRemotes, -+ comparisonCache -+ ) -+ -+ expect(branch).is.not.null -+ expect(branch!.tip.sha).to.equal('0') -+ }) -+ -+ it('Returns the default branch of a GitHub repository', async () => { -+ const ghRepo: GitHubRepository = createTestGhRepo('test', 'default') -+ const repo = createTestRepo(ghRepo) -+ -+ const branch = await inferComparisonBranch( -+ repo, -+ branches, -+ null, -+ null, -+ mockGetRemotes, -+ comparisonCache -+ ) -+ -+ expect(branch).is.not.null -+ expect(branch!.name).to.equal('default') -+ }) -+ -+ it('Returns the branch associated with the PR', async () => { -+ const ghRepo: GitHubRepository = createTestGhRepo('test', 'default') -+ const repo = createTestRepo(ghRepo) -+ const head = createTestPrRef(branches[4]) -+ const base = createTestPrRef(branches[5]) -+ const pr: PullRequest = createTestPr(head, base) -+ -+ const branch = await inferComparisonBranch( -+ repo, -+ branches, -+ pr, -+ null, -+ mockGetRemotes, -+ comparisonCache -+ ) -+ -+ expect(branch).is.not.null -+ expect(branch!.upstream).to.equal(branches[5].upstream) -+ }) -+ -+ it('Returns the default branch of the fork if it is ahead of the current branch', async () => { -+ const currentBranch = branches[3] -+ const defaultBranch = branches[6] -+ const parent = createTestGhRepo('parent', 'parent') -+ const fork = createTestGhRepo('fork', 'fork', parent) -+ const repo = createTestRepo(fork) -+ -+ comparisonCache.set(currentBranch.tip.sha, defaultBranch.tip.sha, { -+ ahead: 1, -+ behind: 0, -+ }) -+ -+ const branch = await inferComparisonBranch( -+ repo, -+ branches, -+ null, -+ currentBranch, -+ mockGetRemotes, -+ comparisonCache -+ ) -+ -+ expect(branch).is.not.null -+ expect(branch!.name).to.equal(defaultBranch.name) -+ }) -+ -+ it("Returns the default branch of the fork's parent branch if the fork is not ahead of the current branch", async () => { -+ const defaultBranchOfParent = branches[5] -+ const defaultBranchOfFork = branches[4] -+ const parent = createTestGhRepo( -+ 'parent', -+ defaultBranchOfParent.nameWithoutRemote -+ ) -+ const fork = createTestGhRepo('fork', defaultBranchOfFork.name, parent) -+ const repo = createTestRepo(fork) -+ const mockGetRemotes = (repo: Repository) => { -+ const remotes: ReadonlyArray = [ -+ { name: 'origin', url: fork.cloneURL! }, -+ { name: 'upstream', url: parent.cloneURL! }, -+ ] -+ -+ return Promise.resolve(remotes) -+ } -+ -+ comparisonCache.set( -+ defaultBranchOfParent.tip.sha, -+ defaultBranchOfFork.tip.sha, -+ { -+ ahead: 0, -+ behind: 0, -+ } -+ ) -+ -+ const branch = await inferComparisonBranch( -+ repo, -+ branches, -+ null, -+ defaultBranchOfParent, -+ mockGetRemotes, -+ comparisonCache -+ ) -+ -+ expect(branch).is.not.null -+ expect(branch!.upstream).to.equal(defaultBranchOfParent.upstream) -+ }) -+}) -added in remote - their 100644 dcebafa9c3051466b9d3347eb6ae9d827c796b0d app/test/unit/list-selection-test.ts -@@ -0,0 +1,52 @@ -+import { expect } from 'chai' -+ -+import { findNextSelectableRow } from '../../src/ui/lib/list/selection' -+ -+describe('list-selection', () => { -+ describe('findNextSelectableRow', () => { -+ const rowCount = 5 -+ -+ it('returns first row when selecting down outside list (filter text)', () => { -+ const selectedRow = findNextSelectableRow(rowCount, { -+ direction: 'down', -+ row: -1, -+ }) -+ expect(selectedRow).to.equal(0) -+ }) -+ -+ it('returns first selectable row when header is first', () => { -+ const selectedRow = findNextSelectableRow( -+ rowCount, -+ { -+ direction: 'down', -+ row: -1, -+ }, -+ row => { -+ if (row === 0) { -+ return false -+ } else { -+ return true -+ } -+ } -+ ) -+ expect(selectedRow).to.equal(1) -+ }) -+ -+ it('returns first row when selecting down from last row', () => { -+ const lastRow = rowCount - 1 -+ const selectedRow = findNextSelectableRow(rowCount, { -+ direction: 'down', -+ row: lastRow, -+ }) -+ expect(selectedRow).to.equal(0) -+ }) -+ -+ it('returns last row when selecting up from top row', () => { -+ const selectedRow = findNextSelectableRow(rowCount, { -+ direction: 'up', -+ row: 0, -+ }) -+ expect(selectedRow).to.equal(4) -+ }) -+ }) -+}) -merged - result 100644 c0b463a119f370007a15b53596eef661434e881a app/test/unit/patch-formatter-test.ts - our 100644 6a71395ab06843a86f54daca408878c6e8c603c6 app/test/unit/patch-formatter-test.ts -@@ -1,9 +1,7 @@ --/* eslint-disable no-sync */ -- - import { expect } from 'chai' - - import * as Path from 'path' --import * as FS from 'fs' -+import * as FSE from 'fs-extra' - - import { Repository } from '../../src/models/repository' - import { -@@ -36,8 +34,8 @@ - let repository: Repository | null = null - - describe('formatPatchesForModifiedFile', () => { -- beforeEach(() => { -- const testRepoPath = setupFixtureRepository('repo-with-changes') -+ beforeEach(async () => { -+ const testRepoPath = await setupFixtureRepository('repo-with-changes') - repository = new Repository(testRepoPath, -1, null, false) - }) - -@@ -161,7 +159,7 @@ - - it(`creates the right patch when an addition is selected but preceding deletions aren't`, async () => { - const modifiedFile = 'modified-file.md' -- FS.writeFileSync(Path.join(repository!.path, modifiedFile), 'line 1\n') -+ await FSE.writeFile(Path.join(repository!.path, modifiedFile), 'line 1\n') - - const unselectedFile = DiffSelection.fromInitialSelection( - DiffSelectionType.None -merged - result 100644 9cbf74cc7f09f42177a0ffa21b8dadf6a5cb408e app/test/unit/progress/clone-test.ts - our 100644 7c54590d069085e654f33a1d2d57765c2bf0cf0a app/test/unit/progress/clone-test.ts -@@ -36,21 +36,21 @@ - 'remote: Compressing objects: 45% (10/22)' - ) - expect(compressing.kind).to.equal('progress') -- expect(compressing.percent).to.be.closeTo(10 / 22 * 0.1, 0.01) -+ expect(compressing.percent).to.be.closeTo((10 / 22) * 0.1, 0.01) - - const receiving = parser.parse( - 'Receiving objects: 17% (4808/28282), 3.30 MiB | 1.29 MiB/s' - ) - expect(receiving.kind).to.equal('progress') -- expect(receiving.percent).to.be.closeTo(0.1 + 4808 / 28282 * 0.6, 0.01) -+ expect(receiving.percent).to.be.closeTo(0.1 + (4808 / 28282) * 0.6, 0.01) - - const resolving = parser.parse('Resolving deltas: 89% (18063/20263)') - expect(resolving.kind).to.equal('progress') -- expect(resolving.percent).to.be.closeTo(0.7 + 18063 / 20263 * 0.1, 0.01) -+ expect(resolving.percent).to.be.closeTo(0.7 + (18063 / 20263) * 0.1, 0.01) - - const checkingOut = parser.parse('Checking out files: 100% (579/579)') - expect(checkingOut.kind).to.equal('progress') -- expect(checkingOut.percent).to.be.closeTo(0.8 + 579 / 579 * 0.2, 0.01) -+ expect(checkingOut.percent).to.be.closeTo(0.8 + (579 / 579) * 0.2, 0.01) - }) - - it('ignores wrong order', () => { -added in remote - their 100644 1e72cf509cf524cdf0acea77b04f2bd6298fc33e app/test/unit/pull-request-status-test.ts -@@ -0,0 +1,91 @@ -+import { expect } from 'chai' -+ -+import { APIRefState } from '../../src/lib/api' -+import { getPRStatusSummary } from '../../src/ui/branches/pull-request-status' -+ -+const failure: APIRefState = 'failure' -+const pending: APIRefState = 'pending' -+const success: APIRefState = 'success' -+ -+describe('pull request status', () => { -+ it('uses the state when no statuses found', () => { -+ const prStatus = { -+ pullRequestNumber: 23, -+ state: success, -+ totalCount: 0, -+ sha: '', -+ statuses: [], -+ } -+ expect(getPRStatusSummary(prStatus)).to.equal('Commit status: success') -+ }) -+ -+ it('changes the failure message to something more friendly', () => { -+ const prStatus = { -+ pullRequestNumber: 23, -+ state: failure, -+ totalCount: 0, -+ sha: '', -+ statuses: [], -+ } -+ expect(getPRStatusSummary(prStatus)).to.equal('Commit status: failed') -+ }) -+ -+ it('reads the statuses when they are populated', () => { -+ const prStatus = { -+ pullRequestNumber: 23, -+ state: success, -+ totalCount: 2, -+ sha: '', -+ statuses: [ -+ { id: 1, state: success, description: 'first' }, -+ { id: 2, state: success, description: 'second' }, -+ ], -+ } -+ expect(getPRStatusSummary(prStatus)).to.equal('2/2 checks OK') -+ }) -+ -+ it('a successful status shows the description', () => { -+ const prStatus = { -+ pullRequestNumber: 23, -+ state: success, -+ totalCount: 2, -+ sha: '', -+ statuses: [ -+ { id: 1, state: success, description: 'The Travis CI build passed' }, -+ ], -+ } -+ expect(getPRStatusSummary(prStatus)).to.equal( -+ 'Success: The Travis CI build passed' -+ ) -+ }) -+ -+ it('an error status shows the description', () => { -+ const prStatus = { -+ pullRequestNumber: 23, -+ state: success, -+ totalCount: 2, -+ sha: '', -+ statuses: [ -+ { id: 1, state: failure, description: 'The Travis CI build failed' }, -+ ], -+ } -+ expect(getPRStatusSummary(prStatus)).to.equal( -+ 'Failure: The Travis CI build failed' -+ ) -+ }) -+ -+ it('only counts the successful statuses', () => { -+ const prStatus = { -+ pullRequestNumber: 23, -+ state: success, -+ totalCount: 3, -+ sha: '', -+ statuses: [ -+ { id: 1, state: success, description: 'first' }, -+ { id: 2, state: pending, description: 'second' }, -+ { id: 2, state: pending, description: 'third' }, -+ ], -+ } -+ expect(getPRStatusSummary(prStatus)).to.equal('1/3 checks OK') -+ }) -+}) -merged - result 100644 8c3c9ac4c1b7875569c8d7d44dec79ca7047423d app/test/unit/repositories-list-grouping-test.ts - our 100644 8c87f50afeab077a2eec435baab02e4db2417b4f app/test/unit/repositories-list-grouping-test.ts -@@ -1,7 +1,7 @@ - import { expect } from 'chai' - - import { groupRepositories } from '../../src/ui/repositories-list/group-repositories' --import { Repository } from '../../src/models/repository' -+import { Repository, ILocalRepositoryState } from '../../src/models/repository' - import { GitHubRepository } from '../../src/models/github-repository' - import { Owner } from '../../src/models/owner' - import { getDotComAPIEndpoint } from '../../src/lib/api' -@@ -28,8 +28,10 @@ - ), - ] - -+ const cache = new Map() -+ - it('groups repositories by GitHub/Enterprise/Other', () => { -- const grouped = groupRepositories(repositories) -+ const grouped = groupRepositories(repositories, cache) - expect(grouped.length).to.equal(3) - - expect(grouped[0].identifier).to.equal('github') -@@ -68,7 +70,10 @@ - ) - const repoZ = new Repository('z', 3, null, false) - -- const grouped = groupRepositories([repoC, repoB, repoZ, repoD, repoA]) -+ const grouped = groupRepositories( -+ [repoC, repoB, repoZ, repoD, repoA], -+ cache -+ ) - expect(grouped.length).to.equal(2) - - expect(grouped[0].identifier).to.equal('github') -@@ -119,20 +124,20 @@ - false - ) - -- const grouped = groupRepositories([repoA, repoB, repoC]) -+ const grouped = groupRepositories([repoA, repoB, repoC], cache) - expect(grouped.length).to.equal(1) - - expect(grouped[0].identifier).to.equal('github') - expect(grouped[0].items.length).to.equal(3) - - const items = grouped[0].items -- expect(items[0].text).to.equal('cool-repo') -+ expect(items[0].text[0]).to.equal('cool-repo') - expect(items[0].needsDisambiguation).to.equal(false) - -- expect(items[1].text).to.equal('repo') -+ expect(items[1].text[0]).to.equal('repo') - expect(items[1].needsDisambiguation).to.equal(true) - -- expect(items[2].text).to.equal('repo') -+ expect(items[2].text[0]).to.equal('repo') - expect(items[2].needsDisambiguation).to.equal(true) - }) - }) -merged - result 100644 2500924fc3357ff64eb65408ada24ec216b734ef app/test/unit/repository-settings-store-test.ts - our 100644 a0af361ddcda5e966fcae87cfe23274833ff3095 app/test/unit/repository-settings-store-test.ts -@@ -1,6 +1,4 @@ --/* eslint-disable no-sync */ -- --import * as FS from 'fs' -+import * as FSE from 'fs-extra' - import * as Path from 'path' - import { GitProcess } from 'dugite' - import { expect } from 'chai' -@@ -8,7 +6,6 @@ - import { RepositorySettingsStore } from '../../src/lib/stores' - import { setupEmptyRepository } from '../helpers/repositories' - import { getStatus } from '../../src/lib/git' --import { pathExists } from '../../src/lib/file-system' - - describe('RepositorySettingsStore', () => { - it('can create a gitignore file', async () => { -@@ -20,7 +17,7 @@ - await sut.saveGitIgnore('node_modules\n') - - // Make sure file exists on FS -- const exists = await pathExists(`${path}/.gitignore`) -+ const exists = await FSE.pathExists(`${path}/.gitignore`) - - expect(exists).is.true - }) -@@ -30,14 +27,14 @@ - const path = repo.path - - const ignoreFile = `${path}/.gitignore` -- FS.writeFileSync(ignoreFile, 'node_modules\n') -+ await FSE.writeFile(ignoreFile, 'node_modules\n') - - const sut = new RepositorySettingsStore(repo) - - // update gitignore file to be empty - await sut.saveGitIgnore('') - -- const exists = await pathExists(ignoreFile) -+ const exists = await FSE.pathExists(ignoreFile) - expect(exists).is.false - }) - -@@ -54,7 +51,7 @@ - // Create a txt file - const file = Path.join(repo.path, 'a.txt') - -- FS.writeFileSync(file, 'thrvbnmerkl;,iuw') -+ await FSE.writeFile(file, 'thrvbnmerkl;,iuw') - - // Check status of repo - const status = await getStatus(repo) -merged - result 100644 133e5af7e5501c236aeb4c8601f36046ad052609 app/test/unit/repository-test.ts - our 100644 1d0e7171ba217432250ae87d691596276db579e9 app/test/unit/repository-test.ts -@@ -9,5 +9,11 @@ - const repository = new Repository(repoPath, -1, null, false) - expect(repository.name).to.equal('path') - }) -+ -+ it('handles repository at root of the drive', async () => { -+ const repoPath = 'T:\\' -+ const repository = new Repository(repoPath, -1, null, false) -+ expect(repository.name).to.equal('T:\\') -+ }) - }) - }) -merged - result 100644 bbcf0ab0fd2e7a0f0528335e7a18a965fb1a464b app/test/unit/validated-repository-path-test.ts - our 100644 a8625f261275cbe39f142f52e51de14e1b1619fb app/test/unit/validated-repository-path-test.ts -@@ -7,7 +7,7 @@ - - describe('validatedRepositoryPath', () => { - it('returns the path to the repository', async () => { -- const testRepoPath = setupFixtureRepository('test-repo') -+ const testRepoPath = await setupFixtureRepository('test-repo') - const result = await validatedRepositoryPath(testRepoPath) - expect(result).to.equal(testRepoPath) - }) -removed in remote - base 100644 20da10ea8edc60b7201685b8ce2659593bc0dc0a app/webpack.common.js - our 100644 20da10ea8edc60b7201685b8ce2659593bc0dc0a app/webpack.common.js -@@ -1,205 +0,0 @@ --'use strict' -- --const path = require('path') --const Fs = require('fs') --const HtmlWebpackPlugin = require('html-webpack-plugin') --const CleanWebpackPlugin = require('clean-webpack-plugin') --const webpack = require('webpack') --const merge = require('webpack-merge') --const appInfo = require('./app-info') --const packageInfo = require('./package-info') --const distInfo = require('../script/dist-info') -- --const channel = distInfo.getReleaseChannel() -- --const externals = ['7zip'] --if (channel === 'development') { -- externals.push('devtron') --} -- --const outputDir = 'out' --const replacements = appInfo.getReplacements() -- --const commonConfig = { -- externals: externals, -- output: { -- filename: '[name].js', -- path: path.resolve(__dirname, '..', outputDir), -- libraryTarget: 'commonjs2', -- }, -- module: { -- rules: [ -- { -- test: /\.tsx?$/, -- include: path.resolve(__dirname, 'src'), -- use: [ -- { -- loader: 'awesome-typescript-loader', -- options: { -- useBabel: true, -- useCache: true, -- }, -- }, -- ], -- exclude: /node_modules/, -- }, -- { -- test: /\.node$/, -- use: [ -- { loader: 'node-native-loader', options: { name: '[name].[ext]' } }, -- ], -- }, -- ], -- }, -- plugins: [ -- new CleanWebpackPlugin([outputDir], { verbose: false }), -- // This saves us a bunch of bytes by pruning locales (which we don't use) -- // from moment. -- new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), -- new webpack.NoEmitOnErrorsPlugin(), -- ], -- resolve: { -- extensions: ['.js', '.ts', '.tsx'], -- modules: [path.resolve(__dirname, 'node_modules/')], -- }, -- node: { -- __dirname: false, -- __filename: false, -- }, --} -- --const mainConfig = merge({}, commonConfig, { -- entry: { main: path.resolve(__dirname, 'src/main-process/main') }, -- target: 'electron-main', -- plugins: [ -- new webpack.DefinePlugin( -- Object.assign({}, replacements, { -- __PROCESS_KIND__: JSON.stringify('main'), -- }) -- ), -- ], --}) -- --const rendererConfig = merge({}, commonConfig, { -- entry: { renderer: path.resolve(__dirname, 'src/ui/index') }, -- target: 'electron-renderer', -- module: { -- rules: [ -- { -- test: /\.(jpe?g|png|gif|ico)$/, -- use: ['file?name=[path][name].[ext]'], -- }, -- ], -- }, -- plugins: [ -- new HtmlWebpackPlugin({ -- template: path.join(__dirname, 'static', 'index.html'), -- chunks: ['renderer'], -- }), -- new webpack.DefinePlugin( -- Object.assign({}, replacements, { -- __PROCESS_KIND__: JSON.stringify('ui'), -- }) -- ), -- ], --}) -- --const askPassConfig = merge({}, commonConfig, { -- entry: { 'ask-pass': path.resolve(__dirname, 'src/ask-pass/main') }, -- target: 'node', -- plugins: [ -- new webpack.DefinePlugin( -- Object.assign({}, replacements, { -- __PROCESS_KIND__: JSON.stringify('askpass'), -- }) -- ), -- ], --}) -- --const crashConfig = merge({}, commonConfig, { -- entry: { crash: path.resolve(__dirname, 'src/crash/index') }, -- target: 'electron-renderer', -- plugins: [ -- new HtmlWebpackPlugin({ -- title: 'GitHub Desktop', -- filename: 'crash.html', -- chunks: ['crash'], -- }), -- new webpack.DefinePlugin( -- Object.assign({}, replacements, { -- __PROCESS_KIND__: JSON.stringify('crash'), -- }) -- ), -- ], --}) -- --const cliConfig = merge({}, commonConfig, { -- entry: { cli: path.resolve(__dirname, 'src/cli/main') }, -- target: 'node', -- plugins: [ -- new webpack.DefinePlugin( -- Object.assign({}, replacements, { -- __PROCESS_KIND__: JSON.stringify('cli'), -- }) -- ), -- ], --}) -- --const highlighterConfig = merge({}, commonConfig, { -- entry: { highlighter: path.resolve(__dirname, 'src/highlighter/index') }, -- output: { libraryTarget: 'var' }, -- target: 'webworker', -- plugins: [ -- new webpack.DefinePlugin( -- Object.assign({}, replacements, { -- __PROCESS_KIND__: JSON.stringify('highlighter'), -- }) -- ), -- ], -- resolve: { -- // We don't want to bundle all of CodeMirror in the highlighter. A web -- // worker doesn't have access to the DOM and most of CodeMirror's core -- // code is useless to us in that context. So instead we use this super -- // nifty subset of codemirror that defines the minimal context needed -- // to run a mode inside of node. Now, we're not running in node -- // but CodeMirror doesn't have to know about that. -- alias: { -- codemirror$: 'codemirror/addon/runmode/runmode.node.js', -- '../lib/codemirror$': '../addon/runmode/runmode.node.js', -- '../../lib/codemirror$': '../../addon/runmode/runmode.node.js', -- '../../addon/runmode/runmode$': '../../addon/runmode/runmode.node.js', -- }, -- }, --}) -- --highlighterConfig.module.rules = [ -- { -- test: /\.ts$/, -- include: path.resolve(__dirname, 'src/highlighter'), -- use: [ -- { -- loader: 'awesome-typescript-loader', -- options: { -- useBabel: true, -- useCache: true, -- configFileName: path.resolve( -- __dirname, -- 'src/highlighter/tsconfig.json' -- ), -- }, -- }, -- ], -- exclude: /node_modules/, -- }, --] -- --module.exports = { -- main: mainConfig, -- renderer: rendererConfig, -- askPass: askPassConfig, -- crash: crashConfig, -- cli: cliConfig, -- highlighter: highlighterConfig, -- replacements: replacements, -- externals: commonConfig.externals, --} -added in remote - their 100644 1022f36fa215969400d025fd13ce117793d98ddd app/webpack.common.ts -@@ -0,0 +1,219 @@ -+import * as path from 'path' -+import * as HtmlWebpackPlugin from 'html-webpack-plugin' -+import * as CleanWebpackPlugin from 'clean-webpack-plugin' -+import * as webpack from 'webpack' -+import * as merge from 'webpack-merge' -+import { getReleaseChannel } from '../script/dist-info' -+import { getReplacements } from './app-info' -+ -+const channel = getReleaseChannel() -+ -+export const externals = ['7zip'] -+if (channel === 'development') { -+ externals.push('devtron') -+} -+ -+const outputDir = 'out' -+export const replacements = getReplacements() -+ -+const commonConfig: webpack.Configuration = { -+ externals: externals, -+ output: { -+ filename: '[name].js', -+ path: path.resolve(__dirname, '..', outputDir), -+ libraryTarget: 'commonjs2', -+ }, -+ module: { -+ rules: [ -+ { -+ test: /\.tsx?$/, -+ include: path.resolve(__dirname, 'src'), -+ use: [ -+ { -+ loader: 'awesome-typescript-loader', -+ options: { -+ useBabel: true, -+ useCache: true, -+ }, -+ }, -+ ], -+ exclude: /node_modules/, -+ }, -+ { -+ test: /\.node$/, -+ loader: 'awesome-node-loader', -+ options: { -+ name: '[name].[ext]', -+ }, -+ }, -+ ], -+ }, -+ plugins: [ -+ new CleanWebpackPlugin([outputDir], { verbose: false }), -+ // This saves us a bunch of bytes by pruning locales (which we don't use) -+ // from moment. -+ new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), -+ new webpack.NoEmitOnErrorsPlugin(), -+ ], -+ resolve: { -+ extensions: ['.js', '.ts', '.tsx'], -+ modules: [path.resolve(__dirname, 'node_modules/')], -+ }, -+ node: { -+ __dirname: false, -+ __filename: false, -+ }, -+} -+ -+export const main = merge({}, commonConfig, { -+ entry: { main: path.resolve(__dirname, 'src/main-process/main') }, -+ target: 'electron-main', -+ plugins: [ -+ new webpack.DefinePlugin( -+ Object.assign({}, replacements, { -+ __PROCESS_KIND__: JSON.stringify('main'), -+ }) -+ ), -+ ], -+}) -+ -+export const renderer = merge({}, commonConfig, { -+ entry: { renderer: path.resolve(__dirname, 'src/ui/index') }, -+ target: 'electron-renderer', -+ module: { -+ rules: [ -+ { -+ test: /\.(jpe?g|png|gif|ico)$/, -+ use: ['file?name=[path][name].[ext]'], -+ }, -+ ], -+ }, -+ plugins: [ -+ new HtmlWebpackPlugin({ -+ template: path.join(__dirname, 'static', 'index.html'), -+ chunks: ['renderer'], -+ }), -+ new webpack.DefinePlugin( -+ Object.assign({}, replacements, { -+ __PROCESS_KIND__: JSON.stringify('ui'), -+ }) -+ ), -+ ], -+}) -+ -+export const askPass = merge({}, commonConfig, { -+ entry: { 'ask-pass': path.resolve(__dirname, 'src/ask-pass/main') }, -+ target: 'node', -+ plugins: [ -+ new webpack.DefinePlugin( -+ Object.assign({}, replacements, { -+ __PROCESS_KIND__: JSON.stringify('askpass'), -+ }) -+ ), -+ ], -+}) -+ -+export const crash = merge({}, commonConfig, { -+ entry: { crash: path.resolve(__dirname, 'src/crash/index') }, -+ target: 'electron-renderer', -+ plugins: [ -+ new HtmlWebpackPlugin({ -+ title: 'GitHub Desktop', -+ filename: 'crash.html', -+ chunks: ['crash'], -+ }), -+ new webpack.DefinePlugin( -+ Object.assign({}, replacements, { -+ __PROCESS_KIND__: JSON.stringify('crash'), -+ }) -+ ), -+ ], -+}) -+ -+export const cli = merge({}, commonConfig, { -+ entry: { cli: path.resolve(__dirname, 'src/cli/main') }, -+ target: 'node', -+ plugins: [ -+ new webpack.DefinePlugin( -+ Object.assign({}, replacements, { -+ __PROCESS_KIND__: JSON.stringify('cli'), -+ }) -+ ), -+ ], -+}) -+ -+export const highlighter = merge({}, commonConfig, { -+ entry: { highlighter: path.resolve(__dirname, 'src/highlighter/index') }, -+ output: { -+ libraryTarget: 'var', -+ chunkFilename: 'highlighter/[name].js', -+ }, -+ optimization: { -+ namedChunks: true, -+ splitChunks: { -+ cacheGroups: { -+ modes: { -+ enforce: true, -+ name: (mod, chunks) => { -+ const builtInMode = /node_modules\/codemirror\/mode\/(\w+)\//.exec( -+ mod.resource -+ ) -+ if (builtInMode) { -+ return `mode/${builtInMode[1]}` -+ } -+ const external = /node_modules\/codemirror-mode-(\w+)\//.exec( -+ mod.resource -+ ) -+ if (external) { -+ return `ext/${external[1]}` -+ } -+ return 'common' -+ }, -+ }, -+ }, -+ }, -+ }, -+ target: 'webworker', -+ plugins: [ -+ new webpack.DefinePlugin( -+ Object.assign({}, replacements, { -+ __PROCESS_KIND__: JSON.stringify('highlighter'), -+ }) -+ ), -+ ], -+ resolve: { -+ // We don't want to bundle all of CodeMirror in the highlighter. A web -+ // worker doesn't have access to the DOM and most of CodeMirror's core -+ // code is useless to us in that context. So instead we use this super -+ // nifty subset of codemirror that defines the minimal context needed -+ // to run a mode inside of node. Now, we're not running in node -+ // but CodeMirror doesn't have to know about that. -+ alias: { -+ codemirror$: 'codemirror/addon/runmode/runmode.node.js', -+ '../lib/codemirror$': '../addon/runmode/runmode.node.js', -+ '../../lib/codemirror$': '../../addon/runmode/runmode.node.js', -+ '../../addon/runmode/runmode$': '../../addon/runmode/runmode.node.js', -+ }, -+ }, -+}) -+ -+highlighter.module!.rules = [ -+ { -+ test: /\.ts$/, -+ include: path.resolve(__dirname, 'src/highlighter'), -+ use: [ -+ { -+ loader: 'awesome-typescript-loader', -+ options: { -+ useBabel: true, -+ useCache: true, -+ configFileName: path.resolve( -+ __dirname, -+ 'src/highlighter/tsconfig.json' -+ ), -+ }, -+ }, -+ ], -+ exclude: /node_modules/, -+ }, -+] -removed in remote - base 100644 aab57ac31250a9a96cd3297a5df761e08ec7c180 app/webpack.development.js - our 100644 aab57ac31250a9a96cd3297a5df761e08ec7c180 app/webpack.development.js -@@ -1,62 +0,0 @@ --'use strict' -- --const common = require('./webpack.common') -- --const webpack = require('webpack') --const merge = require('webpack-merge') -- --const config = { -- devtool: 'source-map', --} -- --const mainConfig = merge({}, common.main, config) --const askPassConfig = merge({}, common.askPass, config) --const cliConfig = merge({}, common.cli, config) --const highlighterConfig = merge({}, common.highlighter, config) -- --const rendererConfig = merge({}, common.renderer, config, { -- entry: { -- renderer: [ -- 'webpack-hot-middleware/client?path=http://localhost:3000/__webpack_hmr', -- common.renderer.entry.renderer, -- ], -- }, -- output: { -- publicPath: 'http://localhost:3000/build/', -- }, -- module: { -- rules: [ -- // This will cause the compiled CSS (and sourceMap) to be -- // embedded within the compiled javascript bundle and added -- // as a blob:// uri at runtime. -- { -- test: /\.(scss|css)$/, -- use: ['style-loader', 'css-loader?sourceMap', 'sass-loader?sourceMap'], -- }, -- ], -- }, -- plugins: [new webpack.HotModuleReplacementPlugin()], --}) -- --const crashConfig = merge({}, common.crash, config, { -- module: { -- rules: [ -- // This will cause the compiled CSS (and sourceMap) to be -- // embedded within the compiled javascript bundle and added -- // as a blob:// uri at runtime. -- { -- test: /\.(scss|css)$/, -- use: ['style-loader', 'css-loader?sourceMap', 'sass-loader?sourceMap'], -- }, -- ], -- }, --}) -- --module.exports = [ -- mainConfig, -- rendererConfig, -- askPassConfig, -- crashConfig, -- cliConfig, -- highlighterConfig, --] -added in remote - their 100644 85601e4b9f45f7a6177f1598e7e42f8f9f2563d8 app/webpack.development.ts -@@ -0,0 +1,77 @@ -+import * as common from './webpack.common' -+ -+import * as webpack from 'webpack' -+import * as merge from 'webpack-merge' -+ -+const config: webpack.Configuration = { -+ mode: 'development', -+ devtool: 'source-map', -+} -+ -+const mainConfig = merge({}, common.main, config) -+const askPassConfig = merge({}, common.askPass, config) -+const cliConfig = merge({}, common.cli, config) -+const highlighterConfig = merge({}, common.highlighter, config) -+ -+// TODO: -+// if we have a PORT environment variable set and running `yarn start` we also -+// need to update this script to use the same port when building because this -+// is currently hard-coded. -+ -+const webpackHotModuleReloadUrl = -+ 'webpack-hot-middleware/client?path=http://localhost:3000/__webpack_hmr' -+ -+const getRendererEntryPoint = () => { -+ const entry = common.renderer.entry as webpack.Entry -+ if (entry == null) { -+ throw new Error( -+ `Unable to resolve entry point. Check webpack.common.ts and try again` -+ ) -+ } -+ -+ return entry.renderer as string -+} -+ -+const rendererConfig = merge({}, common.renderer, config, { -+ entry: { -+ renderer: [webpackHotModuleReloadUrl, getRendererEntryPoint()], -+ }, -+ output: { -+ publicPath: 'http://localhost:3000/build/', -+ }, -+ module: { -+ rules: [ -+ // This will cause the compiled CSS (and sourceMap) to be -+ // embedded within the compiled javascript bundle and added -+ // as a blob:// uri at runtime. -+ { -+ test: /\.(scss|css)$/, -+ use: ['style-loader', 'css-loader?sourceMap', 'sass-loader?sourceMap'], -+ }, -+ ], -+ }, -+ plugins: [new webpack.HotModuleReplacementPlugin()], -+}) -+ -+const crashConfig = merge({}, common.crash, config, { -+ module: { -+ rules: [ -+ // This will cause the compiled CSS (and sourceMap) to be -+ // embedded within the compiled javascript bundle and added -+ // as a blob:// uri at runtime. -+ { -+ test: /\.(scss|css)$/, -+ use: ['style-loader', 'css-loader?sourceMap', 'sass-loader?sourceMap'], -+ }, -+ ], -+ }, -+}) -+ -+export = [ -+ mainConfig, -+ rendererConfig, -+ askPassConfig, -+ crashConfig, -+ cliConfig, -+ highlighterConfig, -+] -removed in remote - base 100644 1d053b4165d86beb66a65a0cc983e3c6433e6096 app/webpack.production.js - our 100644 1d053b4165d86beb66a65a0cc983e3c6433e6096 app/webpack.production.js -@@ -1,86 +0,0 @@ --'use strict' -- --const common = require('./webpack.common') -- --const webpack = require('webpack') --const merge = require('webpack-merge') --const ExtractTextPlugin = require('extract-text-webpack-plugin') --const BabelPlugin = require('babel-webpack-plugin') -- --const config = { -- devtool: 'source-map', -- plugins: [ -- new BabelPlugin({ -- test: /\.js$/, -- sourceMaps: true, -- compact: true, -- minified: true, -- comments: false, -- presets: [ -- [ -- 'minify', -- { -- evaluate: false, -- }, -- ], -- ], -- }), -- new webpack.optimize.ModuleConcatenationPlugin(), -- ], --} -- --const mainConfig = merge({}, common.main, config) --const askPassConfig = merge({}, common.askPass, config) --const cliConfig = merge({}, common.cli, config) --const highlighterConfig = merge({}, common.highlighter, config) -- --const rendererConfig = merge({}, common.renderer, config, { -- module: { -- rules: [ -- // This will cause the compiled CSS to be output to a -- // styles.css and a tag to be -- // appended to the index.html HEAD at compile time -- { -- test: /\.(scss|css)$/, -- use: ExtractTextPlugin.extract({ -- fallback: 'style-loader', -- use: ['css-loader', 'sass-loader'], -- }), -- }, -- ], -- }, -- plugins: [ -- // Necessary to be able to use ExtractTextPlugin as a loader. -- new ExtractTextPlugin('ui.css'), -- ], --}) -- --const crashConfig = merge({}, common.crash, config, { -- module: { -- rules: [ -- // This will cause the compiled CSS to be output to a -- // styles.css and a tag to be -- // appended to the index.html HEAD at compile time -- { -- test: /\.(scss|css)$/, -- use: ExtractTextPlugin.extract({ -- fallback: 'style-loader', -- use: ['css-loader', 'sass-loader'], -- }), -- }, -- ], -- }, -- plugins: [ -- // Necessary to be able to use ExtractTextPlugin as a loader. -- new ExtractTextPlugin('crash.css'), -- ], --}) -- --module.exports = [ -- mainConfig, -- rendererConfig, -- askPassConfig, -- crashConfig, -- cliConfig, -- highlighterConfig, --] -added in remote - their 100644 5ceca0028e592b33b03c18605f4eb67a3c69ecaf app/webpack.production.ts -@@ -0,0 +1,75 @@ -+import * as common from './webpack.common' -+ -+import * as webpack from 'webpack' -+import * as merge from 'webpack-merge' -+import * as MiniCssExtractPlugin from 'mini-css-extract-plugin' -+import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer' -+const MinifyPlugin = require('babel-minify-webpack-plugin') -+ -+const config: webpack.Configuration = { -+ mode: 'production', -+ devtool: 'source-map', -+ optimization: { -+ minimizer: [new MinifyPlugin()], -+ }, -+} -+ -+const mainConfig = merge({}, common.main, config) -+const askPassConfig = merge({}, common.askPass, config) -+const cliConfig = merge({}, common.cli, config) -+const highlighterConfig = merge({}, common.highlighter, config) -+ -+const rendererConfig = merge({}, common.renderer, config, { -+ module: { -+ rules: [ -+ // This will cause the compiled CSS to be output to a -+ // styles.css and a tag to be -+ // appended to the index.html HEAD at compile time -+ { -+ test: /\.(scss|css)$/, -+ use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'], -+ }, -+ ], -+ }, -+ plugins: [ -+ // Necessary to be able to use MiniCssExtractPlugin as a loader. -+ new MiniCssExtractPlugin({ filename: 'renderer.css' }), -+ new BundleAnalyzerPlugin({ -+ // this generates the static HTML file to view afterwards, rather -+ // than disrupting the user -+ analyzerMode: 'static', -+ openAnalyzer: false, -+ // we can't emit this directly to the dist directory because the -+ // build script immediately blows away dist after webpack is done -+ // compiling the source into bundles -+ reportFilename: 'renderer.report.html', -+ }), -+ ], -+}) -+ -+const crashConfig = merge({}, common.crash, config, { -+ module: { -+ rules: [ -+ // This will cause the compiled CSS to be output to a -+ // styles.css and a tag to be -+ // appended to the index.html HEAD at compile time -+ { -+ test: /\.(scss|css)$/, -+ use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'], -+ }, -+ ], -+ }, -+ plugins: [ -+ // Necessary to be able to use MiniCssExtractPlugin as a loader. -+ new MiniCssExtractPlugin({ filename: 'crash.css' }), -+ ], -+}) -+ -+export = [ -+ mainConfig, -+ rendererConfig, -+ askPassConfig, -+ crashConfig, -+ cliConfig, -+ highlighterConfig, -+] -merged - result 100644 1bfea3d3a8c831597a2bba1db9d15bdf1f470765 app/yarn.lock - our 100644 32c446515d5906010e9d52842742a9a913e42c16 app/yarn.lock -@@ -43,12 +43,6 @@ - dependencies: - execa "^0.4.0" - --argparse@^1.0.7: -- version "1.0.9" -- resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" -- dependencies: -- sprintf-js "~1.0.2" -- - asap@~2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" -@@ -94,22 +88,6 @@ - dependencies: - tweetnacl "^0.14.3" - --big.js@^3.1.3: -- version "3.2.0" -- resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" -- --boom@4.x.x: -- version "4.3.1" -- resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" -- dependencies: -- hoek "4.x.x" -- --boom@5.x.x: -- version "5.2.0" -- resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" -- dependencies: -- hoek "4.x.x" -- - brace-expansion@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" -@@ -212,12 +190,6 @@ - version "0.0.2" - resolved "https://registry.yarnpkg.com/cross-unzip/-/cross-unzip-0.0.2.tgz#5183bc47a09559befcf98cc4657964999359372f" - --cryptiles@3.x.x: -- version "3.1.2" -- resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" -- dependencies: -- boom "5.x.x" -- - cycle@1.0.x: - version "1.0.3" - resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" -@@ -266,14 +238,14 @@ - version "2.0.0" - resolved "https://registry.yarnpkg.com/dom-matches/-/dom-matches-2.0.0.tgz#d2728b416a87533980eb089b848d253cf23a758c" - --dugite@1.61.0: -- version "1.61.0" -- resolved "https://registry.yarnpkg.com/dugite/-/dugite-1.61.0.tgz#d5dad047af478c1312f8b791eb56d9935e6fc47d" -+dugite@^1.67.0: -+ version "1.67.0" -+ resolved "https://registry.yarnpkg.com/dugite/-/dugite-1.67.0.tgz#389f95051aa1fb2bc78dcee4294f913ae3438c47" - dependencies: - checksum "^0.1.1" - mkdirp "^0.5.1" - progress "^2.0.0" -- request "^2.83.0" -+ request "^2.86.0" - rimraf "^2.5.4" - tar "^4.0.2" - -@@ -324,10 +296,6 @@ - jsonfile "^2.2.3" - mkdirp "^0.5.1" - --emojis-list@^2.0.0: -- version "2.1.0" -- resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" -- - encoding@^0.1.11: - version "0.1.12" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" -@@ -338,10 +306,6 @@ - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - --esprima@^4.0.0: -- version "4.0.0" -- resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" -- - event-kit@^2.0.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/event-kit/-/event-kit-2.4.0.tgz#718aaf22df76670024ad66922483e1bba0544f33" -@@ -409,18 +373,13 @@ - combined-stream "^1.0.5" - mime-types "^2.1.12" - --front-matter@^2.1.2: -- version "2.2.0" -- resolved "https://registry.yarnpkg.com/front-matter/-/front-matter-2.2.0.tgz#35205f67522430b1213ef26149ecb068579fe38a" -- dependencies: -- js-yaml "^3.4.6" -- --fs-extra@^2.1.2: -- version "2.1.2" -- resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-2.1.2.tgz#046c70163cef9aad46b0e4a7fa467fb22d71de35" -+fs-extra@^6.0.0: -+ version "6.0.0" -+ resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.0.tgz#0f0afb290bb3deb87978da816fcd3c7797f3a817" - dependencies: - graceful-fs "^4.1.2" -- jsonfile "^2.1.0" -+ jsonfile "^4.0.0" -+ universalify "^0.1.0" - - fs-minipass@^1.2.3: - version "1.2.3" -@@ -472,23 +431,10 @@ - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" - --hawk@~6.0.2: -- version "6.0.2" -- resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" -- dependencies: -- boom "4.x.x" -- cryptiles "3.x.x" -- hoek "4.x.x" -- sntp "2.x.x" -- - highlight.js@^9.3.0: - version "9.12.0" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e" - --hoek@4.x.x: -- version "4.2.0" -- resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" -- - html-entities@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" -@@ -516,7 +462,7 @@ - once "^1.3.0" - wrappy "1" - --inherits@2: -+inherits@2, inherits@~2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - -@@ -547,13 +493,6 @@ - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - --js-yaml@^3.4.6: -- version "3.10.0" -- resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" -- dependencies: -- argparse "^1.0.7" -- esprima "^4.0.0" -- - jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" -@@ -570,16 +509,18 @@ - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - --json5@^0.5.0: -- version "0.5.1" -- resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" -- --jsonfile@^2.1.0, jsonfile@^2.2.3: -+jsonfile@^2.2.3: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - optionalDependencies: - graceful-fs "^4.1.6" - -+jsonfile@^4.0.0: -+ version "4.0.0" -+ resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" -+ optionalDependencies: -+ graceful-fs "^4.1.6" -+ - jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" -@@ -603,14 +544,6 @@ - dependencies: - nan "2.5.1" - --loader-utils@^1.0.2: -- version "1.1.0" -- resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" -- dependencies: -- big.js "^3.1.3" -- emojis-list "^2.0.0" -- json5 "^0.5.0" -- - loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.0, loose-envify@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" -@@ -777,6 +710,12 @@ - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - -+queue@^4.4.2: -+ version "4.4.2" -+ resolved "https://registry.yarnpkg.com/queue/-/queue-4.4.2.tgz#5a9733d9a8b8bd1b36e934bc9c55ab89b28e29c7" -+ dependencies: -+ inherits "~2.0.0" -+ - react-addons-shallow-compare@^15.6.2: - version "15.6.2" - resolved "https://registry.yarnpkg.com/react-addons-shallow-compare/-/react-addons-shallow-compare-15.6.2.tgz#198a00b91fc37623db64a28fd17b596ba362702f" -@@ -784,15 +723,19 @@ - fbjs "^0.8.4" - object-assign "^4.1.0" - --react-dom@^16.2.0: -- version "16.2.0" -- resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.2.0.tgz#69003178601c0ca19b709b33a83369fe6124c044" -+react-dom@^16.3.2: -+ version "16.3.2" -+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.3.2.tgz#cb90f107e09536d683d84ed5d4888e9640e0e4df" - dependencies: - fbjs "^0.8.16" - loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.0" - -+react-lifecycles-compat@^3.0.4: -+ version "3.0.4" -+ resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" -+ - react-transition-group@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-1.2.1.tgz#e11f72b257f921b213229a774df46612346c7ca6" -@@ -803,19 +746,20 @@ - prop-types "^15.5.6" - warning "^3.0.0" - --react-virtualized@^9.18.5: -- version "9.18.5" -- resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.18.5.tgz#42dd390ebaa7ea809bfcaf775d39872641679b89" -+react-virtualized@^9.20.0: -+ version "9.20.0" -+ resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.20.0.tgz#b024992cc857c1a1b2884a019ac52ed686cd690b" - dependencies: - babel-runtime "^6.26.0" - classnames "^2.2.3" - dom-helpers "^2.4.0 || ^3.0.0" - loose-envify "^1.3.0" - prop-types "^15.6.0" -+ react-lifecycles-compat "^3.0.4" - --react@^16.2.0: -- version "16.2.0" -- resolved "https://registry.yarnpkg.com/react/-/react-16.2.0.tgz#a31bd2dab89bff65d42134fa187f24d054c273ba" -+react@^16.3.2: -+ version "16.3.2" -+ resolved "https://registry.yarnpkg.com/react/-/react-16.3.2.tgz#fdc8420398533a1e58872f59091b272ce2f91ea9" - dependencies: - fbjs "^0.8.16" - loose-envify "^1.1.0" -@@ -832,9 +776,9 @@ - dependencies: - nan "^2.8.0" - --request@^2.83.0: -- version "2.83.0" -- resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" -+request@^2.86.0: -+ version "2.87.0" -+ resolved "https://registry.yarnpkg.com/request/-/request-2.87.0.tgz#32f00235cd08d482b4d0d68db93a829c0ed5756e" - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.6.0" -@@ -844,7 +788,6 @@ - forever-agent "~0.6.1" - form-data "~2.3.1" - har-validator "~5.0.3" -- hawk "~6.0.2" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" -@@ -854,7 +797,6 @@ - performance-now "^2.1.0" - qs "~6.5.1" - safe-buffer "^5.1.1" -- stringstream "~0.0.5" - tough-cookie "~2.3.3" - tunnel-agent "^0.6.0" - uuid "^3.1.0" -@@ -887,12 +829,6 @@ - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - --sntp@2.x.x: -- version "2.1.0" -- resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" -- dependencies: -- hoek "4.x.x" -- - source-map-support@^0.4.15: - version "0.4.18" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" -@@ -903,10 +839,6 @@ - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - --sprintf-js@~1.0.2: -- version "1.0.3" -- resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" -- - sshpk@^1.7.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" -@@ -925,10 +857,6 @@ - version "0.0.10" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" - --stringstream@~0.0.5: -- version "0.0.5" -- resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" -- - strip-ansi@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" -@@ -945,12 +873,6 @@ - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - --style-loader@^0.13.2: -- version "0.13.2" -- resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.13.2.tgz#74533384cf698c7104c7951150b49717adc2f3bb" -- dependencies: -- loader-utils "^1.0.2" -- - supports-color@^4.0.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" -@@ -999,6 +921,10 @@ - version "0.7.14" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.14.tgz#110d53fa4c3f326c121292bbeac904d2e03387ca" - -+universalify@^0.1.0: -+ version "0.1.1" -+ resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" -+ - untildify@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.2.tgz#7f1f302055b3fea0f3e81dc78eb36766cb65e3f1" -merged - result 100644 5185c7d6e7e86cafdb3aec94115c1120c9e776a2 appveyor.yml - our 100644 e9a9426356bf8465dbdc277c0ee9a2fb876e5e67 appveyor.yml -@@ -4,7 +4,7 @@ - - x64 - - environment: -- nodejs_version: "8.9.0" -+ nodejs_version: "8.11" - - cache: - - .eslintcache -merged - result 100644 6e0feab6683b3ff164dfee68d69eb6fdd5478b53 changelog.json - our 100644 061dd96a1d5f2e461c954e4a3e42398dfd8fc837 changelog.json -@@ -1,5 +1,194 @@ - { - "releases": { -+ "1.2.7-test1": [ -+ "Sanity check deployment for refactored scripts" -+ ], -+ "1.2.7-beta0": [ -+ "[Fixed] Visual indicator for upcoming feature should not be shown - #5026" -+ ], -+ "1.2.6": [ -+ "[Fixed] Visual indicator for upcoming feature should not be shown - #5026" -+ ], -+ "1.2.6-beta0": [ -+ "[Fixed] Feature flag for upcoming feature not applied correctly - #5024" -+ ], -+ "1.2.5": [ -+ "[Fixed] Feature flag for upcoming feature not applied correctly - #5024" -+ ], -+ "1.2.4": [ -+ "[New] Dark Theme preview - #4849", -+ "[Added] Syntax highlighting for Cake files - #4935. Thanks @say25!", -+ "[Added] WebStorm support for macOS - #4841. Thanks @mrsimonfletcher!", -+ "[Fixed] Compare tab appends older commits when scrolling to bottom of list - #4964", -+ "[Fixed] Remove temporary directory after Git LFS operation completes - #4414", -+ "[Fixed] Unable to compare when two branches exist - #4947 #4730", -+ "[Fixed] Unhandled errors when refreshing pull requests fails - #4844 #4866", -+ "[Improved] Remove context menu needs to hint if a dialog will be shown - #4975", -+ "[Improved] Upgrade embedded Git LFS - #4602 #4745", -+ "[Improved] Update banner message clarifies that only Desktop needs to be restarted - #4891. Thanks @KennethSweezy!", -+ "[Improved] Discard Changes context menu entry should contain ellipses when user needs to confirm - #4846. Thanks @yongdamsh!", -+ "[Improved] Initializing syntax highlighting components - #4764", -+ "[Improved] Only show overflow shadow when description overflows - #4898", -+ "[Improved] Changes tab displays number of changed files instead of dot - #4772. Thanks @yongdamsh!" -+ ], -+ "1.2.4-beta5": [ -+ -+ ], -+ "1.2.4-beta4": [ -+ "[Fixed] Compare tab appends older commits when scrolling to bottom of list - #4964", -+ "[Fixed] Remove temporary directory after Git LFS operation completes - #4414", -+ "[Improved] Remove context menu needs to hint if a dialog will be shown - #4975", -+ "[Improved] Upgrade embedded Git LFS - #4602 #4745" -+ ], -+ "1.2.4-test1": [ -+ "Confirming latest Git LFS version addresses reported issues" -+ ], -+ "1.2.4-beta3": [ -+ "[Added] WebStorm support for macOS - #4841. Thanks @mrsimonfletcher!", -+ "[Improved] Update banner message clarifies that only Desktop needs to be restarted - #4891. Thanks @KennethSweezy!" -+ ], -+ "1.2.4-beta2": [ -+ ], -+ "1.2.4-beta1": [ -+ "[New] Dark Theme preview - #4849", -+ "[Added] Syntax highlighting for Cake files - #4935. Thanks @say25!", -+ "[Fixed] Unable to compare when two branches exist - #4947 #4730", -+ "[Fixed] Unhandled errors when refreshing pull requests fails - #4844 #4866", -+ "[Improved] Discard Changes context menu entry should contain ellipses when user needs to confirm - #4846. Thanks @yongdamsh!", -+ "[Improved] Initializing syntax highlighting components - #4764", -+ "[Improved] Only show overflow shadow when description overflows - #4898", -+ "[Improved] Changes tab displays number of changed files instead of dot - #4772. Thanks @yongdamsh!" -+ ], -+ "1.2.3": [ -+ "[Fixed] No autocomplete when searching for co-authors - #4847", -+ "[Fixed] Error when checking out a PR from a fork - #4842" -+ ], -+ "1.2.3-beta1": [ -+ "[Fixed] No autocomplete when searching for co-authors - #4847", -+ "[Fixed] Error when checking out a PR from a fork - #4842" -+ ], -+ "1.2.3-test1": [ -+ "Confirming switch from uglify-es to babel-minify addresses minification issue - #4871" -+ ], -+ "1.2.2": [ -+ "[Fixed] Make cURL/schannel default to using the Windows certificate store - #4817", -+ "[Fixed] Restore text selection highlighting in diffs - #4818" -+ ], -+ "1.2.2-beta1": [ -+ "[Fixed] Make cURL/schannel default to using the Windows certificate store - #4817", -+ "[Fixed] Text selection highlighting in diffs is back - #4818" -+ ], -+ "1.2.1": [ -+ "[Added] Brackets support for macOS - #4608. Thanks @3raxton!", -+ "[Added] Pull request number and author are included in fuzzy-find filtering - #4653. Thanks @damaneice!", -+ "[Fixed] Decreased the max line length limit - #3740. Thanks @sagaragarwal94!", -+ "[Fixed] Updated embedded Git to 2.17.1 to address upstream security issue - #4791", -+ "[Improved] Display the difference in file size of an image in the diff view - #4380. Thanks @ggajos!" -+ ], -+ "1.2.1-test1": [ -+ "Upgraded embedded Git to 2.17.0" -+ ], -+ "1.2.1-beta1": [ -+ "[Added] Brackets support for macOS - #4608. Thanks @3raxton!", -+ "[Added] Pull request number and author are included in fuzzy-find filtering - #4653. Thanks @damaneice!", -+ "[Fixed] Decreased the max line length limit - #3740. Thanks @sagaragarwal94!", -+ "[Fixed] Updated embedded Git to 2.17.1 to address upstream security issue - #4791", -+ "[Improved] Display the difference in file size of an image in the diff view - #4380. Thanks @ggajos!" -+ ], -+ "1.2.1-beta0": [ -+ -+ ], -+ "1.1.2-test6": [ -+ "Testing the Webpack v4 output from the project" -+ ], -+ "1.2.0": [ -+ "[New] History now has ability to compare to another branch and merge outstanding commits", -+ "[New] Support for selecting more than one file in the changes list - #1712. Thanks @icosamuel!", -+ "[New] Render bitmap images in diffs - #4367. Thanks @MagicMarvMan!", -+ "[Added] Add PowerShell Core support for Windows and macOS - #3791. Thanks @saschanaz!", -+ "[Added] Add MacVim support for macOS - #4532. Thanks @johnelliott!", -+ "[Added] Syntax highlighting for JavaServer Pages (JSP) - #4470. Thanks @damaneice!", -+ "[Added] Syntax highlighting for Haxe files - #4445. Thanks @Gama11!", -+ "[Added] Syntax highlighting for R files - #4455. Thanks @say25!", -+ "[Fixed] 'Open in Shell' on Linux ensures Git is on PATH - #4619. Thanks @ziggy42!", -+ "[Fixed] Pressing 'Enter' on filtered Pull Request does not checkout - #4673", -+ "[Fixed] Alert icon shrinks in rename dialog when branch name is long - #4566", -+ "[Fixed] 'Open in Desktop' performs fetch to ensure branch exists before checkout - #3006", -+ "[Fixed] 'Open in Default Program' on Windows changes the window title - #4446", -+ "[Fixed] Skip fast-forwarding when there are many eligible local branches - #4392", -+ "[Fixed] Image diffs not working for files with upper-case file extension - #4466", -+ "[Fixed] Syntax highlighting not working for files with upper-case file extension - #4462. Thanks @say25!", -+ "[Fixed] Error when creating Git LFS progress causes clone to fail - #4307. Thanks @MagicMarvMan!", -+ "[Fixed] 'Open File in External Editor' always opens a new instance - #4381", -+ "[Fixed] 'Select All' shortcut now works for changes list - #3821", -+ "[Improved] Automatically add valid repository when using command line interface - #4513. Thanks @ggajos!", -+ "[Improved] Always fast-forward the default branch - #4506", -+ "[Improved] Warn when trying to rename a published branch - #4035. Thanks @agisilaos!", -+ "[Improved] Added context menu for files in commit history - #2845. Thanks @crea7or", -+ "[Improved] Discarding all changes always prompts for confirmation - #4459", -+ "[Improved] Getting list of changed files is now more efficient when dealing with thousands of files - #4443", -+ "[Improved] Checking out a Pull Request may skip unnecessary fetch - #4068. Thanks @agisilaos!", -+ "[Improved] Commit summary now has a hint to indicate why committing is disabled - #4429.", -+ "[Improved] Pull request status text now matches format on GitHub - #3521", -+ "[Improved] Add escape hatch to disable hardware acceleration when launching - #3921" -+ ], -+ "1.1.2-beta7": [ -+ ], -+ "1.1.2-beta6": [ -+ "[Added] Add MacVim support for macOS - #4532. Thanks @johnelliott!", -+ "[Fixed] Open in Shell on Linux ensures Git is available on the user's PATH - #4619. Thanks @ziggy42!", -+ "[Fixed] Keyboard focus issues when navigating Pull Request list - #4673", -+ "[Improved] Automatically add valid repository when using command line interface - #4513. Thanks @ggajos!" -+ ], -+ "1.1.2-test5": [ -+ "Actually upgrading fs-extra to v6 in the app" -+ ], -+ "1.1.2-test4": [ -+ "Upgrading fs-extra to v6" -+ ], -+ "1.1.2-beta5": [ -+ "[Added] Syntax highlighting for JavaServer Pages (JSP) - #4470. Thanks @damaneice!", -+ "[Fixed] Prevent icon from shrinking in rename dialog - #4566" -+ ], -+ "1.1.2-beta4": [ -+ "[New] New Compare tab allowing visualization of the relationship between branches", -+ "[New] Support for selecting more than one file in the changes list - #1712. Thanks @icosamuel!", -+ "[Fixed] 'Select All' shortcut now works for changes list - #3821", -+ "[Improved] Always fast-forward the default branch - #4506", -+ "[Improved] Warn when trying to rename a published branch - #4035. Thanks @agisilaos!", -+ "[Improved] Added context menu for files in commit history - #2845. Thanks @crea7or", -+ "[Improved] Discarding all changes always prompts for confirmation - #4459" -+ ], -+ "1.1.2-beta3": [ -+ "[Added] Syntax highlighting for Haxe files - #4445. Thanks @Gama11!", -+ "[Added] Syntax highlighting for R files - #4455. Thanks @say25!", -+ "[Fixed] Fetch to ensure \"Open in Desktop\" has a branch to checkout - #3006", -+ "[Fixed] Handle the click event when opening a binary file - #4446", -+ "[Fixed] Skip fast-forwarding when there are a lot of eligible local branches - #4392", -+ "[Fixed] Image diffs not working for files with upper-case file extension - #4466", -+ "[Fixed] Syntax highlighting not working for files with upper-case file extension - #4462. Thanks @say25!", -+ "[Improved] Getting list of changed files is now more efficient when dealing with thousands of files - #4443", -+ "[Improved] Checking out a Pull Request may skip unnecessary fetch - #4068. Thanks @agisilaos!", -+ "[Improved] Commit summary now has a hint to indicate why committing is disabled - #4429." -+ ], -+ "1.1.2-test3": [ -+ "[New] Comparison Branch demo build" -+ ], -+ "1.1.2-test2": [ -+ "Refactoring the diff internals to potentially land some SVG improvements" -+ ], -+ "1.1.2-test1": [ -+ "Refactoring the diff internals to potentially land some SVG improvements" -+ ], -+ "1.1.2-beta2": [ -+ "[New] Render bitmap images in diffs - #4367. Thanks @MagicMarvMan!", -+ "[New] Add PowerShell Core support for Windows and macOS - #3791. Thanks @saschanaz!", -+ "[Fixed] Error when creating Git LFS progress causes clone to fail - #4307. Thanks @MagicMarvMan!", -+ "[Fixed] 'Open File in External Editor' does not use existing window - #4381", -+ "[Fixed] Always ask for confirmation when discarding all changes - #4423", -+ "[Improved] Pull request status text now matches format on GitHub - #3521", -+ "[Improved] Add escape hatch to disable hardware acceleration when launching - #3921" -+ ], - "1.1.2-beta1": [ - - ], -merged - result 100644 19865d13f3ab50d13c233da23115035bf423212e circle.yml - our 100644 6dc532103b44f2896468ac6d61f4b4db4d2394f7 circle.yml -@@ -20,12 +20,12 @@ - - brew update - # uninstall Node 6 which is shipped by default on Circle - - brew uninstall node -- # install latest Node LTS (8.9.3 as of writing) -+ # install latest Node LTS (8.11.* as of writing) - - brew install node@8 --force - # everything is terrible, but we must march on - - brew link --overwrite node@8 --force - # workaround for yarn installation issue -- - curl -o- -L https://yarnpkg.com/install.sh | TERM=xterm bash -+ - curl -o- -L https://yarnpkg.com/install.sh | TERM=xterm bash -s -- --version 1.5.1 - - override: - - yarn install --force -merged - result 100644 85f2237dba6b5f8296b3fe7c9214125fb1ab8291 docs/README.md - our 100644 1b5837911492e094338cbe0808ba278c35d4ed08 docs/README.md -@@ -28,7 +28,7 @@ - releases - - **[Issue Triage](process/issue-triage.md)** - how we address issues reported - by users -- - **[Review Process](process/reviews.md)** - how we review contributions -+ - **[Pull Request Triage](process/pull-request-triage.md)** - how contributions are reviewed - - **[Releasing Updates](process/releasing-updates.md)** - how we deploy things - - ## Technical -merged - result 100644 e6d7547da4874c319f72d7264d11e060f2270d41 docs/contributing/setup.md - our 100644 5b9cda4685280976fbfceb7265cab922d7b508b3 docs/contributing/setup.md -@@ -6,13 +6,13 @@ - - ### macOS - -- - [Node.js v8.9.0](https://nodejs.org/dist/v8.9.0/) -+ - [Node.js v8.11.2](https://nodejs.org/dist/v8.11.2/) - - [Python 2.7](https://www.python.org/downloads/mac-osx/) - - Xcode and Xcode Command Line Tools (Xcode -> Preferences -> Downloads) - - ### Windows - -- - [Node.js v8.9.0](https://nodejs.org/dist/v8.9.0/) -+ - [Node.js v8.11.2](https://nodejs.org/dist/v8.11.2/) - - *Make sure you allow the Node.js installer to add node to the PATH.* - - [Python 2.7](https://www.python.org/downloads/windows/) - - *Let Python install into the default suggested path (`c:\Python27`), otherwise you'll have -@@ -32,7 +32,7 @@ - - ### Fedora 26 - --First, add the NodeJS package repository. -+First, add the NodeJS package repository for 8.x. - - ```shellsession - $ curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash - -@@ -67,7 +67,7 @@ - $ sudo apt install curl - ``` - --Then add the NodeJS package repository: -+Then add the NodeJS package repository for 8.x: - - ```shellsession - $ curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - -@@ -95,35 +95,45 @@ - on setup there. - * Instead of running `yarn` to get all required dependencies on your machine, you will - instead need to run `script/install-arm64-deps.sh`. -+* Before building with `yarn build:dev` or `yarn build:prod`, you will need to -+set the environment variable `TARGET_ARCH` to `arm64` eg: -+```shellsession -+export TARGET_ARCH=arm64 -+``` - --## Verification -+## Install Yarn - --With these things installed, open a shell and install `yarn` (you might need --to `sudo` here depending on how Node was installed): -+After doing this setup, you also need to install `yarn` as Desktop uses -+this for managing packages instead of NPM. **Do not install `yarn` through -+NPM**. Refer to the [install instructions](https://yarnpkg.com/en/docs/install) -+for your OS. - --```shellsession --$ npm install -g yarn@1.3.2 --``` -+This is important because `yarn` uses lock files to pin dependencies. If you -+find yourself changing packages, this will prevent mismatches in versions -+between machines. -+ -+If you're not familiar with `yarn`, please read [this document](./working-with-packages.md) -+to help familiarize yourself with how to do the common package tasks that are -+relevant to Desktop. - --This is important because yarn uses lock files to pin dependencies. If you find --yourself changing packages, this will prevent mismatches in versions between machines. -+## Verification - --Then validate you have these commands available and that the versions look similar: -+Then verify you have these commands available in your shell and that the found -+versions look similar to the below output: - - ```shellsession - $ node -v --v7.8.0 -+v8.11.2 - - $ yarn -v --1.2.0 -+1.5.1 - - $ python --version - Python 2.7.13 - ``` - --There are also [additional resources](tooling.md) to --configure your favorite editor to work nicely with the GitHub Desktop --repository. -+There are also [additional resources](tooling.md) to configure your favorite -+editor to work nicely with the GitHub Desktop repository. - - ## Building Desktop - -@@ -133,7 +143,7 @@ - * Run `yarn` to get all required dependencies on your machine. - * Run `yarn build:dev` to create a development build of the app. - * Run `yarn start` to launch the application. Changes will be compiled in the -- background. The app can then be reloaded to see the changes (Ctrl/Command+R). -+ background. The app can then be reloaded to see the changes (Ctrl/Command+Alt+R). - - **Optional Tip**: On macOS and Linux, you can use `screen` to avoid filling your terminal with logging output: - -@@ -156,25 +166,15 @@ - ## Running tests - - - `yarn test` - Runs all unit and integration tests --- `yarn test:unit` - Runs all unit tests -+- `yarn test:unit` - Runs all unit tests (add `--debug` to open Chrome Dev Tools while running tests) - - `yarn test:integration` - Runs all integration tests - --**Pro Tip:** If you're only interested in the results of a single test and don't --wish to run the entire test suite to see it you can pass along a search string --in order to only run the tests that match that string. -- --```shellsession --$ yarn test:unit -- --grep CloneProgressParser --``` -- --This example will run all test names containing `CloneProgressParser`. -- - ## Debugging - - Electron ships with Chrome Dev Tools to assist with debugging, profiling and - other measurement tools. - --1. Run the command `npm start` to launch the app -+1. Run the command `yarn start` to launch the app - 2. Under the **View** menu, select **Toggle Developer Tools** - - When running the app in development mode, -@@ -193,7 +193,7 @@ - - You're almost there! Here's a couple of things we recommend you read next: - -- - [Help Wanted](../../.github/CONTRIBUTING.md#help-wanted) - we've marked some tasks in -- the backlog that are ideal for external contributors -- - [Code Reviews](../process/reviews.md) - some notes on how the team does -- code reviews -+ - [Help Wanted](../../.github/CONTRIBUTING.md#help-wanted) - we've marked some -+ tasks in the backlog that are ideal for external contributors -+ - [Notes for Contributors](../process/notes-for-contributors.md) - some notes -+ for new contributors getting started -merged - result 100644 68616f214de0f1dfb283dee8a0d503eabf3374f2 docs/contributing/styleguide.md - our 100644 3dd9587dfcc10f13be634b635aa26bee01b894ea docs/contributing/styleguide.md -@@ -41,7 +41,7 @@ - - The [`Dispatcher`](https://github.com/desktop/desktop/blob/master/app/src/lib/dispatcher/dispatcher.ts) - is the entry point for most interactions with the application which update state, --and for most usages this work is then delegated to the [`AppStore`](https://github.com/desktop/desktop/blob/master/app/src/lib/dispatcher/app-store.ts). -+and for most usages this work is then delegated to the [`AppStore`](https://github.com/desktop/desktop/blob/master/app/src/lib/stores/app-store.ts). - Due to this coupling, we need to discourage callers directly manipulating - specific methods in the `AppStore` unless there's a compelling reason. - -merged - result 100644 265fc7e708fdeb51902542f01f6dc5ab7fcf1272 docs/known-issues.md - our 100644 6260d6cfcc30bb19e986dc534dd64471b05506a3 docs/known-issues.md -@@ -14,7 +14,7 @@ - - ### My issue is not listed here? - --Please check the [open](https://github.com/desktop/desktop/labels/bug) and [closed](https://github.com/desktop/desktop/issues?q=is%3Aclosed+label%3Abug) bugs in the issue tracker for the details of your bug. If you can't find it, or if you're not sure, open a [new issue](https://github.com/desktop/desktop/issues/new). -+Please check the [open](https://github.com/desktop/desktop/labels/bug) and [closed](https://github.com/desktop/desktop/issues?q=is%3Aclosed+label%3Abug) bugs in the issue tracker for the details of your bug. If you can't find it, or if you're not sure, open a [new issue](https://github.com/desktop/desktop/issues/new?template=bug_report.md). - - ## macOS - -@@ -118,3 +118,9 @@ - Enabling Mandatory ASLR affects the MSYS2 core library, which is relied upon by Git for Windows to emulate process forking. - - **Not supported:** this is an upstream limitation of MSYS2, and it is recommend that you either disable Mandatory ASLR or whitelist all executables under `\usr\bin` which depend on MSYS2. -+ -+### I get a black screen when launching Desktop -+ -+Electron enables hardware accelerated graphics by default, but some graphics cards have issues with hardware acceleration which means the application will launch successfully but it will be a black screen. -+ -+**Workaround:** if you set the `GITHUB_DESKTOP_DISABLE_HARDWARE_ACCELERATION` environment variable to any value and launch Desktop again it will disable hardware acceleration on launch, so the application is usable. -\ No newline at end of file -added in remote - their 100644 1fd166574ae526e79f25a6163285059d9f837946 docs/process/notes-for-contributors.md -@@ -0,0 +1,37 @@ -+## Notes for Contributors -+ -+### Work-in-Progress -+ -+We recommend open pull requests early - ideally as soon as you have something to -+show. This is especially helpful for large pieces of work, as continuous -+integration tests are run earlier on, and regressions can be caught before -+humans get involved. -+ -+Until the code is ready for review, you can prefix the PR title with [WIP] to -+indicate that it's under development. -+ -+### Use Task Lists -+ -+If you are working through a list of tasks as part of a pull request, listing -+those tasks and indicating when they have been completed helps reviewers to -+understand quickly what's changed. -+ -+### Keep The Commit History Tidy -+ -+We're not that fussy about the history, but to make reviewing easier here's -+some general tips: -+ -+ - make small, meaningful and logical commits - these make the review process easier -+ - [write good commit messages](https://chris.beams.io/posts/git-commit/) - -+ these help the reviewer to understand the changes -+ - keep up to date with `master` - not only does this address potential merge -+ conflicts, it ensures you're integrating with the latest code -+ -+When merging, we prefer you merge `master` into your branch, but for small -+PRs a rebase is fine. -+ -+### These Things Take Time -+ -+Our team is distributed around the world, and often we like to get their -+feedback for specific areas of the codebase. And even with minor changes, we often like to let -+them sit for a while and give everyone a chance to provide their input. -added in remote - their 100644 4c2d1f5be688335f169fe3e3b466e96883b2913f docs/process/pull-request-triage.md -@@ -0,0 +1,100 @@ -+# Pull Request Triage -+ -+This document outlines how the Desktop team handles pull requests, to ensure -+a consistent process for contributions from the core team and the community. -+ -+## The Review Process -+ -+1. **Contributor** opens pull request. -+1. When it's ready for review, add a comment to the pull request. -+1. A member of the reviewer team will give it a quick look over and -+ add the `ready-for-review` label. -+1. A **reviewer** with bandwidth will appear. -+1. **Reviewer** assigns the PR to themselves. -+1. **Reviewer** leaves line comments with suggestions or questions. -+1. When the **reviewer** is done they comment on the PR with an emoji, meme, -+ pokémon, or words to that effect. -+1. The **contributor** responds to feedback, makes changes, etc. -+1. When the **contributor** is ready for the **reviewer** to re-review, they -+ comment on the PR with an emoji, meme, pokémon or words to that effect. -+1. Goto 6 until both parties are happy with the PR. -+1. The **reviewer** hits the big green merge button and deletes the branch (if -+ applicable). -+ -+Merged contributions are first published to the beta channel (we aim to publish -+new versions weekly if contributions are availlable) before then being -+published to the production channel (we aim to publish new versions on a monthly -+cadence). -+ -+### When The Review Is Done -+ -+We're using GitHub's review tools to co-ordinate feedback, and we like to be -+methodical with our reviews, so you'll probably end up with one of two results: -+ -+ - **Approved**: nothing else to do; the contribution is great! :gem: -+ - **Request Changes**: there are things to address; reviewer provides details :memo: -+ -+Reviews can take a few iterations, especially for large contributions. Don't -+be disheartened if you feel it takes time - we just want to ensure each -+contribution is high-quality and that any outstanding questions are resolved, -+captured or documented for posterity. -+ -+### Assignees -+ -+The reviewers team uses the **Assignee** field to indicate who "owns" the review -+process for a contribution. While others can add their reviews to a pull request - -+and large features will likely have multiple reviewers - it's up to the assignee -+to take charge of the process and see it through to the end. -+ -+If a reviewer is feeling overloaded, or if a review has stalled, the reviewer may -+remove themselves from a pull request. This helps others know where they can help -+out to share the load. -+ -+### Everyone Reviews -+ -+While everyone has their own domain expertise around the codebase, we encourage -+people to share the load of reviews and reviewing areas of the codebase that -+aren't as familiar. This spreads knowledge across the team -+ -+### 24 Hours Cooling Off -+ -+After being approved, most contributions will remain in this state for at least -+24 hours before merging. The review team does this to ensure everyone on the team, -+who are normally spread around the world, has a chance to provide feedback about -+the changes. -+ -+### No Self-Merges -+ -+We encourage a strong review culture, and contributors should not merge their -+own PRs unless there are exceptional reasons. -+ -+Examples of exceptional situations: -+ -+- [#2733](https://github.com/desktop/desktop/pull/2733) was pinning a dependency -+ that affected our continuous integration tests by installing the incorrect -+ version -+ -+- [#4319](https://github.com/desktop/desktop/pull/4319) was a minor packaging -+ change introduced unexpectedly on `master` but would affect everyone when they -+ updated their local repositories. -+ -+These should be called out by the merging person with a `#jolo` - "Josh Only -+Lives Once" - to acknowledge to everyone that they're bypassing the review -+process, and the reasons for doing that. -+ -+### Stale Pull Requests -+ -+A reviewer will return to an **open and reviewed** pull request if, after 14 -+days: -+ -+ - no response has been received from the contributor, or -+ - no new commits have been made to the pull request -+ -+This is done to ensure we keep the number of reviews under control. -+ -+The reviewer should ask if the contributor is still interested in working on -+this, and indicate that they are welcome to open a fresh pull request later if -+they lack the time currently to continue on. -+ -+If it's agreed to put this contribution on hold, or if no feedback is -+received after 3 days, the pull request will be closed. -merged - result 100644 268eeb03374d21788fd404ce2b1398f8fafd53a2 docs/process/releasing-updates.md - our 100644 bf564284a648d40cfd836cff85fe41a788edd31a docs/process/releasing-updates.md -@@ -135,7 +135,7 @@ - - We're using `.release` with a bang so that we don't have to wait for any current CI on the branch to finish. This might feel a little wrong, but it's OK since making the release itself will also run CI. - --If you're releasing a `production` update, release a `beta` update for the next version too, so that beta users are on the latest release. -+If you're releasing a `production` update, release a `beta` update for the next version too, so that beta users are on the latest release. For example, if the version just released to production is `1.2.0` then the beta release should be `1.2.1-beta0` to indicate there are no new changes on top of what's currently on `production`. - - ### 4. Check for Completed Release - -removed in remote - base 100644 bac857303b48b6efb4fd0ddf4c8b07d6d3b64477 docs/process/reviews.md - our 100644 bac857303b48b6efb4fd0ddf4c8b07d6d3b64477 docs/process/reviews.md -@@ -1,93 +0,0 @@ --# The Review Process -- --This is the typical flow: -- --1. **Contributor** opens pull request. --1. When it's ready for review, they comment on it saying so. --1. A member of the maintainer team will give it a quick look over and -- add the `ready-for-review` label. --1. Suddenly a wild **reviewer** appears! --1. **Reviewer** assigns the PR to themselves. --1. **Reviewer** leaves line comments with suggestions or questions. --1. When the **reviewer** is done they comment on the PR with an emoji, meme, -- pokémon, or words to that effect. --1. The **contributor** responds to feedback, makes changes, etc. --1. When the **contributor** is ready for the **reviewer** to re-review, they -- comment on the PR with an emoji, meme, pokémon or words to that effect. --1. Goto 6 until both parties are happy with the PR. --1. The **reviewer** hits the big green merge button and deletes the branch (if -- applicable). -- --The rest of this document goes into more details around this flow. -- --## Notes for Contributors -- --### Work-in-Progress -- --We recommend open pull requests early - ideally as soon as you have something to --show. This is especially helpful for large pieces of work, as continuous --integration tests are run earlier on, and regressions can be caught before --humans get involved. -- --Until the code is ready for review, you can prefix the PR title with [WIP] to --indicate that it's under development. -- --### Use Task Lists -- --If you are working through a list of tasks as part of a pull request, listing --those tasks and indicating when they have been completed helps reviewers to --understand quickly what's changed. -- --### Keep The Commit History Tidy -- --We're not that fussy about the history, but to make reviewing easier here's --some general tips: -- -- - make small, meaningful and logical commits - these make the review process easier -- - [write good commit messages](https://chris.beams.io/posts/git-commit/) - -- these help the reviewer to understand the changes -- - keep up to date with `master` - not only does this address potential merge -- conflicts, it ensures you're integrating with the latest code -- --When merging, we prefer you merge `master` into your branch, but for small --PRs a rebase is fine. -- --### At Least One Assignee -- --While many people can be involved with a review, there's generally one person --who eventually approves the pull request and merges. They'll be assigned to the --pull request early on, so we can easily verify every active pull request has a --reviewer. -- --### When The Review Is Done -- --We're using GitHub's review tools to co-ordinate feedback, and we like to be --methodical with our reviews, so you'll probably end up with one of two results: -- -- - **Approved**: nothing else to do; the reviewer merges -- - **Request Changes**: there are things to address; reviewer provides details -- --Reviews can take a few iterations, especially for large contributions. Don't --be disheartened if you feel it takes time - we just want to ensure each --contribution is high-quality and that any outstanding questions are resolved, --captured or documented for posterity. -- --### These Things Take Time -- --Our team is distributed around the world, and often we like to get their --feedback for specific areas. And even with minor changes, we often like to let --them sit for a while and give everyone a chance to provide their input. -- --## Other Rules -- --## No Self-Merges -- --Even for minor changes, we discourage people from merging their own pull --requests. -- --## Everyone Reviews -- --While everyone has their own domain expertise around the codebase, we encourage --people to share the load of reviews and reviewing areas of the codebase that --aren't as familiar. This spreads knowledge across the team -- -merged - result 100644 8e82f6aa314a7abf83144610e658942287d27eb4 docs/process/testing.md - our 100644 28e3af154f93357a29a5f0e0321ef13332ca957b docs/process/testing.md -@@ -215,6 +215,8 @@ - - [ ] `Cancel` button closes modal - - [ ] Protected branches cannot be deleted - - [ ] Update from Default Branch (cannot be master; Mac: `⇧⌘U`; Windows: `Ctrl+Shift+U`) -+ - [ ] Compare to Branch (Mac: `⇧⌘B`; Windows: `Ctrl+Shift+B`) -+ - [ ] Takes you to the history tab with the input selected so you can directly choose a branch - - [ ] Merge into Current Branch (Mac: `⇧⌘M`; Windows: `Ctrl+Shift+M`) - - [ ] Use can filter existing branches - - [ ] User can select branch, other than current -@@ -272,8 +274,8 @@ - - [ ] Panes can be resized horizontally, and contents resize to take the full width - - [ ] Quitting Desktop and relaunching remembers sizes - --### Compare tab -- - [ ] Compare (was History) tab shows commits on your current branch by default -+### History tab -+ - [ ] History tab shows commits on your current branch by default - - [ ] All commits listed in chronological order, with avatar, date and name; list is scrollable with arrow keys enabled - - [ ] Right clicking any commit shows options: Revert, Copy SHA, View on GitHub - - [ ] Hover shows file name in tooltip -@@ -285,6 +287,20 @@ - - [ ] After successful merge, tab counts update and merge button is disabled - - [ ] Merge conflict results in dialog shown directing user to commit view - -+### Relationship between branches -+ - [ ] Clicking in field with placeholder text `Select Branch to Compare…` shows a list of all branches and their number of commits ahead and behind the currently checked out branch -+ - [ ] Pressing `esc` key clears the current filter -+ - [ ] Filtering for branch name that doesn't exist shows "Sorry, I can't find that branch" -+ - [ ] Selecting a branch from the list populates the tab with that branch comparison data -+ - [ ] Behind tab is shown by default -+ - [ ] See number of commits behind in tab header -+ - [ ] If more than 0 commits behind, a list of commits are shown in reverse chronological order -+ - [ ] See button to merge into current branch (button disabled if 0 commits behind) -+ - [ ] Clicking the merge button shows merge conflicts if any, or successfully merges the commit(s) -+ - [ ] After merging, the comparison branch is 0 commits behind -+ - [ ] Ahead tab is on the right-hand side -+ - [ ] If more than 0 commits ahead, a list of commits are shown in reverse chronological order -+ - ### Diffs tab - - [ ] All commits have avatar, selectable SHA, # of files changed, commit message, commit description (optional) - - [ ] Long commit descriptions can be toggled with expand/collapse icon -@@ -310,7 +326,8 @@ - - [ ] `Push` with number of commits badge is decremented or reverts to `Fetch origin` - - [ ] `Undo` button disabled if user is pushing commit - - [ ] User can publish a new repo with no commits (aka unborn repo/branch) -- - [ ] User can make new branch the default branch, by making the intial commit on the new branch. -+ - [ ] User can make new branch the default branch, by making the intial commit on the new branch. -+ - [ ] User can select individual files to commit at a time - - ### Co-authoring - - [ ] clicking co-author icon toggles co-author field; or right-click within commit area -@@ -373,7 +390,7 @@ - ### Github.com - - [ ] If Desktop linked to .com (/settings/applications), the Desktop icon should show on File Revisions tab for all Pull Requests. - - [ ] Clicking the "computer icon" opens from a Pull Request page opens the branch on Desktop -- - [ ] `Open is Desktop` button under a repo's `Clone and Download` button should open repo in Desktop -+ - [ ] `Open in Desktop` button under a repo's `Clone and Download` button should open repo in Desktop - - [ ] If private email is enabled (http://github.com/settings/emails), user is blocked from pushing to all associated repositories on Desktop? - - [ ] If user updates name in Settings, change should reflect in Preferences - -@@ -393,17 +410,9 @@ - ### Security - - [ ] `Untrusted server` warning surfaced if GitHub cannot verify the identity of `api.github.com`; user can `Cancel` or `Continue` - -+ - ### TBD placeholder (WIP) --- Merge tool for conflicted files --- Conflicted files vs changed files --- Relationship between branches -- - Commit/Compare tabs now occupy left pane -- - Compare tab shows branch dropdown -- - Choose a branch from the list (same order as branch list? current branch present?) or user filter; `ESC` clears filter -- - Once branch selected, quantity of commits behind surfaced; matches commits shown -- - `Merge X commits` button is activated -- - Merge conflict count surfaced below button if relevant -- - Clicking `Merge` button merges all shown commits -- - Commit history present, chronological order, descending --- Show Git LFS (Cloning, Committing, Checking out, Reverting, Switching branches) --- Report Git LFS (Cloning, Pushing, Pulling, Switching branches, Reverting) -+ - Merge tool for conflicted files -+ - Conflicted files vs changed files -+ - Show Git LFS (Cloning, Committing, Checking out, Reverting, Switching branches) -+ - Report Git LFS (Cloning, Pushing, Pulling, Switching branches, Reverting) -added in remote - their 100644 10459559490b110ff84127440cbbc8070a71f320 docs/technical/discard-changes.md -@@ -0,0 +1,41 @@ -+# Discard Changes -+ -+The `Discard Changes` feature allows users to clean up uncommitted changes from -+a repository, and has evolved over time to support different workflows. -+ -+## Implementation -+ -+As the implementation details of this may change over time, this section will -+instead describe the high-level flow of the implementation. -+ -+You can view a reference of this function [here](https://github.com/desktop/desktop/blob/2b111155914cb44824b39ee197deed23bb825a1a/app/src/lib/stores/git-store.ts#L1066). -+ -+The `Discard Changes` flow is composed of multiple steps. -+ -+### Moving Files to Trash -+ -+Electron provides the [`shell.moveItemToTrash(fullPath)`](https://electronjs.org/docs/api/shell#shellmoveitemtotrashfullpath) -+API to manage moving files into the OS-specific trash. -+ -+Desktop uses this API to move _all new or modified files_ out from the -+repository as a way to preserve changes, in case the user wishes to recover -+them later. Files moved to the Trash are moved over as-is, so ensure you have -+the ability to view hidden files if you wish to recover files that are prefixed -+with `.`. -+ -+### Reset Paths -+ -+The next step is identifying any files that have been listed for discard that -+are also staged in the index. While Desktop doesn't stage files itself, a user -+might be using other tools alongside Desktop, so this is a sanity check before -+proceeding to the next stage. -+ -+**Git CLI equivalent**: `git reset HEAD -- [path]` -+ -+### Checkout Paths -+ -+The last step is to replace the modified files in the working directory with -+whatever is currently in the index - this ensures that Desktop only replaces -+files that the user has chosen to discard. -+ -+**Git CLI equivalent**: `git checkout-index -f -u -- [path]` -merged - result 100644 29e7d36057950d884bd046bbe958c6329d2bf877 docs/technical/editor-integration.md - our 100644 7eae1dc4e64282e2f51e3012da408314bb28d269 docs/technical/editor-integration.md -@@ -1,7 +1,7 @@ - # "Open External Editor" integration - - GitHub Desktop supports the user choosing an external program to open their --local repositories, and this is available from the top-level **Repository** menu -+local repositories, and this is available from the top-level **Repository** menu - or when right-clicking on a repository in the sidebar. - - ### My favourite editor XYZ isn't supported! -@@ -205,12 +205,17 @@ - These editors are currently supported: - - - [Atom](https://atom.io/) -+ - [MacVim](https://macvim-dev.github.io/macvim/) - - [Visual Studio Code](https://code.visualstudio.com/) - both stable and Insiders channel - - [Sublime Text](https://www.sublimetext.com/) - - [BBEdit](http://www.barebones.com/products/bbedit/) - - [PhpStorm](https://www.jetbrains.com/phpstorm/) - - [RubyMine](https://www.jetbrains.com/rubymine/) - - [TextMate](https://macromates.com) -+ - [Brackets](http://brackets.io/) -+ - To use Brackets the Command Line shortcut must be installed. -+ - This can be done by opening Brackets, choosing File > Install Command Line Shortcut -+ - [WebStorm](https://www.jetbrains.com/webstorm/) - - These are defined in an enum at the top of the file: - -@@ -218,6 +223,7 @@ - - export enum ExternalEditor { - Atom = 'Atom', -+ MacVim = 'MacVim', - VisualStudioCode = 'Visual Studio Code', - VisualStudioCodeInsiders = 'Visual Studio Code (Insiders)', - SublimeText = 'Sublime Text', -@@ -225,6 +231,8 @@ - PhpStorm = 'PhpStorm', - RubyMine = 'RubyMine', - TextMate = 'TextMate', -+ Brackets = 'Brackets', -+ WebStorm = 'WebStorm', - } - ``` - -merged - result 100644 7d8f4be31c11ad21552dbebfde4c9e7fe02c50c9 docs/technical/feature-flagging.md - our 100644 3528b827f8657b3ef30659605b96356d36362ced docs/technical/feature-flagging.md -@@ -50,10 +50,10 @@ - ## How to test - - **Opting-in for preview features** --1. Set the `GITHUB_DESKTOP_PREVIEW_FEATURES` environment variable to any value -+1. Set the `GITHUB_DESKTOP_PREVIEW_FEATURES` environment variable to `1` - 1. Restart GitHub Desktop - --Don't have that environment variable? -+Don't have that environment variable? - No worries, simply create it. (here's a [handy guide](https://www.schrodinger.com/kb/1842) for doing that on most major OSs). - - **Opting-out for preview features** -merged - result 100644 348333d12c84aba9cf5ec7404d91e9a8c2816d07 docs/technical/placeholders.md - our 100644 3264bc826adeac79be5573e87f2765c1dd8a4f60 docs/technical/placeholders.md -@@ -29,7 +29,7 @@ - - ### Replacements - --The replacements defined for Desktop are found in [`app/app-info.js`](https://github.com/desktop/desktop/blob/master/app/app-info.js) -+The replacements defined for Desktop are found in [`app/app-info.ts`](https://github.com/desktop/desktop/blob/master/app/app-info.ts) - as a hash of key-value pairs. - - ```ts -merged - result 100644 ec1f940bd847054000a5e38f06e6b665799e8c10 docs/technical/shell-integration.md - our 100644 9ddeb7ae5be00a841b49590b1966b84660000a77 docs/technical/shell-integration.md -@@ -25,6 +25,7 @@ - - - Command Prompt (cmd) - - PowerShell -+ - [PowerShell Core](https://github.com/powershell/powershell/) - - [Hyper](https://hyper.sh/) - - Git Bash (from [Git for Windows](https://git-for-windows.github.io/)) - -@@ -34,6 +35,7 @@ - export enum Shell { - Cmd = 'Command Prompt', - PowerShell = 'PowerShell', -+ PowerShellCore = 'PowerShell Core', - Hyper = 'Hyper', - GitBash = 'Git Bash', - } -@@ -117,13 +119,14 @@ - - ## macOS - --The source for the macOS shell integration is found in [`app/src/lib/shells/darwin.ts`](https://github.com/desktop/desktop/blob/master/app/src/lib/shell/darwin.ts). -+The source for the macOS shell integration is found in [`app/src/lib/shells/darwin.ts`](https://github.com/desktop/desktop/blob/master/app/src/lib/shells/darwin.ts). - - These shells are currently supported: - - - Terminal - - [Hyper](https://hyper.sh/) - - [iTerm2](https://www.iterm2.com/) -+ - [PowerShell Core](https://github.com/powershell/powershell/) - - These are defined in an enum at the top of the file: - -@@ -132,6 +135,7 @@ - Terminal = 'Terminal', - Hyper = 'Hyper', - iTerm2 = 'iTerm2', -+ PowerShellCore = 'PowerShell Core', - } - ``` - -@@ -159,10 +163,16 @@ - export async function getAvailableShells(): Promise< - ReadonlyArray> - > { -- const [terminalPath, hyperPath, iTermPath] = await Promise.all([ -+ const [ -+ terminalPath, -+ hyperPath, -+ iTermPath, -+ powerShellCorePath, -+ ] = await Promise.all([ - getShellPath(Shell.Terminal), - getShellPath(Shell.Hyper), - getShellPath(Shell.iTerm2), -+ getShellPath(Shell.PowerShellCore), - ]) - - // other code -@@ -194,7 +204,7 @@ - - ## Linux - --The source for the Linux shell integration is found in [`app/src/lib/shells/linux.ts`](https://github.com/desktop/desktop/blob/master/app/src/lib/shell/linux.ts). -+The source for the Linux shell integration is found in [`app/src/lib/shells/linux.ts`](https://github.com/desktop/desktop/blob/master/app/src/lib/shells/linux.ts). - - These shells are currently supported: - -@@ -238,7 +248,13 @@ - export async function getAvailableShells(): Promise< - ReadonlyArray> - > { -- const [gnomeTerminalPath, tilixPath] = await Promise.all([ -+ const [ -+ gnomeTerminalPath, -+ tilixPath, -+ urxvtPath, -+ konsolePath, -+ xtermPath, -+ ] = await Promise.all([ - getShellPath(Shell.Gnome), - getShellPath(Shell.Tilix), - getShellPath(Shell.Urxvt), -merged - result 100644 51b1541b7f0f67eef996aa5e53e8cc204767184f docs/technical/syntax-highlighting.md - our 100644 35f4bc1d7dc42db2bcfe7ba638f3b5eaa4a7ec1f docs/technical/syntax-highlighting.md -@@ -8,7 +8,7 @@ - - We currently support syntax highlighting for the following languages. - --JavaScript, JSON, TypeScript, Coffeescript, HTML, CSS, SCSS, LESS, VUE, Markdown, Yaml, XML, Objective-C, Scala, C#, Java, C, C++, Kotlin, Ocaml, F#, sh/bash, Swift, SQL, CYPHER, Go, Perl, PHP, Python, Ruby, Clojure, Rust, Elixir -+JavaScript, JSON, TypeScript, Coffeescript, HTML, CSS, SCSS, LESS, VUE, Markdown, Yaml, XML, Objective-C, Scala, C#, Java, C, C++, Kotlin, Ocaml, F#, sh/bash, Swift, SQL, CYPHER, Go, Perl, PHP, Python, Ruby, Clojure, Rust, Elixir, Haxe, R, JavaServer Pages, PowerShell - - This list was never meant to be exhaustive, we expect to add more languages going forward but this seemed like a good first step. - -merged - result 100644 24218535cd0fa338ea3b7a8a32e7b458b6811b44 eslint-rules/insecure-random.js - our 100644 710ff6f58b2b9abf091c4353b1264456baeb1fb3 eslint-rules/insecure-random.js -@@ -1,5 +1,6 @@ --// strings from https://github.com/Microsoft/tslint-microsoft-contrib/blob/b720cd9/src/insecureRandomRule.ts -+'use strict' - -+// strings from https://github.com/Microsoft/tslint-microsoft-contrib/blob/b720cd9/src/insecureRandomRule.ts - const MATH_FAIL_STRING = - 'Math.random produces insecure random numbers. ' + - 'Use crypto.randomBytes() or window.crypto.getRandomValues() instead' -changed in both - base 100644 dc892d10739ef87c70391aedcfdc3241753eebbb package.json - our 100644 a230a49de70c920a24d34b1af9952a17b72e7a1c package.json - their 100644 461f60af798d32097510dcd519c5cdd4b860771e package.json -@@ -5,11 +5,12 @@ - }, - "description": "GitHub Desktop build dependencies", - "scripts": { -- "cli": "ts-node --require ./app/test/globals.ts --require ./app/src/cli/dev-commands-global.js app/src/cli/main.ts", -- "test:integration": "cross-env TEST_ENV=1 ELECTRON_NO_ATTACH_CONSOLE=1 xvfb-maybe mocha -t 30000 --require ts-node/register app/test/integration/*.ts", -- "test:unit": "cross-env GIT_AUTHOR_NAME=\"Joe Bloggs\" GIT_AUTHOR_EMAIL=\"joe.bloggs@somewhere.com\" GIT_COMMITTER_NAME=\"Joe Bloggs\" GIT_COMMITTER_EMAIL=\"joe.bloggs@somewhere.com\" TEST_ENV=1 ELECTRON_NO_ATTACH_CONSOLE=1 xvfb-maybe electron-mocha -t 10000 --renderer --require ts-node/register --require ./app/test/globals.ts app/test/unit/*.{ts,tsx} app/test/unit/**/*.{ts,tsx}", -+ "cli": "ts-node --require ./app/test/globals.ts --require ./app/src/cli/dev-commands-global.ts app/src/cli/main.ts", -+ "test:integration": "cross-env TEST_ENV=1 ELECTRON_NO_ATTACH_CONSOLE=1 xvfb-maybe --auto-servernum -- mocha -t 30000 --require ts-node/register app/test/integration/*.ts", -+ "test:unit": "ts-node script/unit-tests.ts", - "test:script": "mocha -t 10000 --require ts-node/register script/changelog/test/*.ts", - "test": "yarn test:unit && yarn test:script && yarn test:integration", -+<<<<<<< .our - "test:setup": "ts-node script/test-setup.ts", - "test:review": "ts-node script/test-review.ts", - "postinstall": "yarn install-app && yarn install-changelog && yarn update-submodules && yarn compile:tslint", -@@ -23,20 +24,31 @@ - "compile:prod": "cross-env NODE_ENV=production parallel-webpack --config app/webpack.production.js", - "build:dev": "yarn compile:dev && cross-env NODE_ENV=development ts-node script/build.ts", - "build:prod": "yarn compile:prod && cross-env NODE_ENV=production ts-node script/build.ts", -+======= -+ "test:setup": "ts-node -P script/tsconfig.json script/test-setup.ts", -+ "test:review": "ts-node -P script/tsconfig.json script/test-review.ts", -+ "postinstall": "cd app && yarn install --force && cd .. && git submodule update --recursive --init && yarn compile:tslint && yarn compile:script", -+ "start": "cross-env NODE_ENV=development ts-node -P script/tsconfig.json script/start.ts", -+ "start:prod": "cross-env NODE_ENV=production ts-node -P script/tsconfig.json script/start.ts", -+ "compile:dev": "cross-env NODE_ENV=development parallel-webpack --config app/webpack.development.ts", -+ "compile:prod": "cross-env NODE_ENV=production parallel-webpack --config app/webpack.production.ts", -+ "build:dev": "yarn compile:dev && cross-env NODE_ENV=development ts-node -P script/tsconfig.json script/build.ts", -+ "build:prod": "yarn compile:prod && cross-env NODE_ENV=production ts-node -P script/tsconfig.json script/build.ts", -+>>>>>>> .their - "package": "ts-node -P script/tsconfig.json script/package.ts", -- "generate-octicons": "ts-node script/generate-octicons.ts", -+ "generate-octicons": "ts-node -P script/tsconfig.json script/generate-octicons.ts", - "clean:tslint": "rimraf tslint-rules/*.js", -- "compile:tslint": "tsc -p tslint-rules", -- "compile:script": "tsc -p script", -+ "compile:tslint": "tsc -P tslint-rules", -+ "compile:script": "tsc -P script/tsconfig.json", - "lint": "yarn lint:src && yarn lint:prettier", - "lint:fix": "yarn lint:src:fix && yarn lint:prettier --fix", - "lint:prettier": "ts-node script/prettier.ts", - "lint:src": "yarn tslint && yarn eslint-check && yarn eslint", - "lint:src:fix": "yarn tslint --fix && yarn eslint --fix", -- "tslint": "tslint ./{script,tslint-rules}/*.ts ./app/{src,typings,test}/**/*.{ts,tsx}", -- "eslint": "ts-node script/eslint.ts", -+ "tslint": "tslint -p .", -+ "eslint": "ts-node -P script/tsconfig.json script/eslint.ts", - "eslint-check": "eslint --print-config .eslintrc.* | eslint-config-prettier-check", -- "publish": "node script/publish", -+ "publish": "ts-node -P script/tsconfig.json script/publish.ts", - "clean-slate": "rimraf out node_modules app/node_modules && yarn", - "rebuild-hard:dev": "yarn clean-slate && yarn build:dev", - "rebuild-hard:prod": "yarn clean-slate && yarn build:prod", -@@ -51,61 +63,63 @@ - }, - "license": "MIT", - "engines": { -- "node": ">= 7", -- "yarn": ">= 1.2.0" -+ "node": ">= 8.10", -+ "yarn": ">= 1.5.0" - }, - "dependencies": { - "ajv": "^6.4.0", -- "awesome-typescript-loader": "^3.4.0", -+ "awesome-node-loader": "^1.1.0", -+ "awesome-typescript-loader": "^5.0.0", - "aws-sdk": "^2.23.0", -- "babel-core": "^6.24.1", -- "babel-minify": "^0.2.0", -- "babel-webpack-plugin": "^0.1.1", -+ "babel-core": "^6.26.3", -+ "babel-minify-webpack-plugin": "^0.3.1", -+ "babel-plugin-syntax-dynamic-import": "^6.18.0", - "chai": "^4.1.1", - "chai-as-promised": "^7.1.1", - "chai-datetime": "^1.4.1", - "chalk": "^2.2.0", -- "clean-webpack-plugin": "^0.1.16", -+ "clean-webpack-plugin": "^0.1.19", - "cross-env": "^5.0.5", -- "css-loader": "^0.28.5", -+ "css-loader": "^0.28.11", - "eslint": "^4.19.1", - "eslint-config-prettier": "^2.9.0", - "eslint-plugin-babel": "^4.1.2", - "eslint-plugin-json": "^1.2.0", - "eslint-plugin-prettier": "^2.6.0", - "eslint-plugin-react": "^7.7.0", -- "eslint-plugin-typescript": "^0.10.0", -+ "eslint-plugin-typescript": "^0.12.0", - "express": "^4.15.0", -- "extract-text-webpack-plugin": "^3.0.0", -- "fs-extra": "^2.1.2", -- "html-webpack-plugin": "^2.30.1", -+ "front-matter": "^2.3.0", -+ "fs-extra": "^6.0.0", -+ "html-webpack-plugin": "^3.2.0", - "json-pretty": "^0.0.1", - "klaw-sync": "^3.0.0", - "legal-eagle": "0.15.0", -+ "mini-css-extract-plugin": "^0.4.0", - "mocha": "^5.0.4", -- "node-native-loader": "^1.1.1", - "node-sass": "^4.7.2", - "octicons": "^7.0.1", -- "parallel-webpack": "^2.1.0", -- "prettier": "1.11.1", -+ "parallel-webpack": "^2.3.0", -+ "prettier": "1.13.0", - "request": "^2.72.0", - "rimraf": "^2.5.2", -- "sass-loader": "^6.0.6", -+ "sass-loader": "^7.0.1", - "semver": "^5.5.0", - "spectron": "^3.8.0", -- "style-loader": "^0.19.1", -+ "style-loader": "^0.21.0", - "to-camel-case": "^1.0.0", - "ts-node": "^5.0.1", - "tslint": "^5.9.1", - "tslint-config-prettier": "^1.10.0", - "tslint-microsoft-contrib": "^5.0.3", - "tslint-react": "^3.5.1", -- "typescript": "^2.8.1", -- "typescript-eslint-parser": "^14.0.0", -- "webpack": "^3.10.0", -- "webpack-dev-middleware": "^2.0.3", -- "webpack-hot-middleware": "^2.21.0", -- "webpack-merge": "^4.1.0", -+ "typescript": "^2.9.1", -+ "typescript-eslint-parser": "^16.0.0", -+ "webpack": "^4.8.3", -+ "webpack-bundle-analyzer": "^2.13.0", -+ "webpack-dev-middleware": "^3.1.3", -+ "webpack-hot-middleware": "^2.22.2", -+ "webpack-merge": "^4.1.2", - "xml2js": "^0.4.16", - "xvfb-maybe": "^0.2.1" - }, -@@ -114,21 +128,28 @@ - "@types/chai": "^4.1.2", - "@types/chai-datetime": "^0.0.31", - "@types/classnames": "^2.2.2", -+ "@types/clean-webpack-plugin": "^0.1.2", - "@types/codemirror": "0.0.55", - "@types/electron-packager": "^10.1.0", - "@types/electron-winstaller": "^2.6.0", - "@types/event-kit": "^1.2.28", -+ "@types/express": "^4.11.0", -+ "@types/extract-text-webpack-plugin": "^3.0.3", - "@types/file-url": "^2.0.0", -- "@types/fs-extra": "2.1.0", -+ "@types/fs-extra": "^5.0.2", - "@types/fuzzaldrin-plus": "^0.0.1", -+ "@types/html-webpack-plugin": "^2.30.3", - "@types/keytar": "^4.0.0", -+ "@types/legal-eagle": "^0.15.0", -+ "@types/mini-css-extract-plugin": "^0.2.0", - "@types/mocha": "^2.2.48", - "@types/mri": "^1.1.0", -- "@types/node": "^7.0.18", -- "@types/react": "^16.0.40", -- "@types/react-dom": "^16.0.4", -+ "@types/node": "^8.10.4", -+ "@types/react": "^16.3.16", -+ "@types/react-dom": "^16.0.5", - "@types/react-transition-group": "1.1.1", - "@types/react-virtualized": "^9.7.12", -+ "@types/request": "^2.0.9", - "@types/semver": "^5.5.0", - "@types/strip-ansi": "^3.0.0", - "@types/temp": "^0.8.29", -@@ -137,9 +158,14 @@ - "@types/ua-parser-js": "^0.7.30", - "@types/untildify": "^3.0.0", - "@types/uuid": "^3.4.0", -+ "@types/webpack": "^4.4.0", -+ "@types/webpack-bundle-analyzer": "^2.9.2", -+ "@types/webpack-dev-middleware": "^2.0.1", -+ "@types/webpack-hot-middleware": "^2.16.3", -+ "@types/webpack-merge": "^4.1.3", - "@types/winston": "^2.2.0", - "@types/xml2js": "^0.4.0", -- "electron": "1.8.3", -+ "electron": "1.8.7", - "electron-builder": "20.2.0", - "electron-mocha": "^6.0.1", - "electron-packager": "^11.0.0", -merged - result 100644 793329336d0e4e7086d8a4856cc3e404b6d33528 script/.eslintrc.yml - our 100644 cb8912301f224a449793498cd95802cb6161ee31 script/.eslintrc.yml -@@ -1,4 +1,3 @@ - rules: - unicorn/no-process-exit: off - import/no-commonjs: off -- no-sync: off -merged - result 100755 a76c37cc7ddbf18efa4c1cbbd3e5aba7f4ce6678 script/build.ts - our 100755 c1e7dfd7e04705645c003fc4d315617e68abc846 script/build.ts -@@ -1,4 +1,3 @@ --/* tslint:disable:no-sync-functions */ - /* eslint-disable no-sync */ - /// - -@@ -7,7 +6,34 @@ - import * as fs from 'fs-extra' - import * as packager from 'electron-packager' - --const legalEagle: LegalEagle = require('legal-eagle') -+import { licenseOverrides } from './license-overrides' -+ -+import { externals } from '../app/webpack.common' -+ -+import * as legalEagle from 'legal-eagle' -+ -+interface IFrontMatterResult { -+ readonly attributes: T -+ readonly body: string -+} -+ -+interface IChooseALicense { -+ readonly title: string -+ readonly nickname?: string -+ readonly featured?: boolean -+ readonly hidden?: boolean -+} -+ -+export interface ILicense { -+ readonly name: string -+ readonly featured: boolean -+ readonly body: string -+ readonly hidden: boolean -+} -+ -+const frontMatter: ( -+ path: string -+) => IFrontMatterResult = require('front-matter') - - import { - getBundleID, -@@ -37,6 +63,11 @@ - console.log('Copying static resources…') - copyStaticResources() - -+console.log('Parsing license metadata…') -+generateLicenseMetadata(outRoot) -+ -+moveAnalysisFiles() -+ - const isFork = process.env.CIRCLE_PR_USERNAME - if (process.platform === 'darwin' && process.env.CIRCLECI && !isFork) { - console.log('Setting up keychain…') -@@ -95,10 +126,24 @@ - ) - } - -+ const toPackageArch = (targetArch: string | undefined): packager.arch => { -+ if (targetArch === undefined) { -+ return 'x64' -+ } -+ -+ if (targetArch === 'arm64' || targetArch === 'x64') { -+ return targetArch -+ } -+ -+ throw new Error( -+ `Building Desktop for architecture '${targetArch}' is not supported` -+ ) -+ } -+ - const options: packager.Options & IPackageAdditionalOptions = { - name: getExecutableName(), - platform: toPackagePlatform(process.platform), -- arch: process.env.TARGET_ARCH || 'x64', -+ arch: toPackageArch(process.env.TARGET_ARCH), - asar: false, // TODO: Probably wanna enable this down the road. - out: getDistRoot(), - icon: path.join(projectRoot, 'app', 'static', 'logos', 'icon-logo'), -@@ -175,7 +220,23 @@ - if (fs.existsSync(platformSpecific)) { - fs.copySync(platformSpecific, destination) - } -- fs.copySync(common, destination, { clobber: false }) -+ fs.copySync(common, destination, { overwrite: false }) -+} -+ -+function moveAnalysisFiles() { -+ const rendererReport = 'renderer.report.html' -+ const analysisSource = path.join(outRoot, rendererReport) -+ if (fs.existsSync(analysisSource)) { -+ const distRoot = getDistRoot() -+ const destination = path.join(distRoot, rendererReport) -+ fs.mkdirpSync(distRoot) -+ // there's no moveSync API here, so let's do it the old fashioned way -+ // -+ // unlinkSync below ensures that the analysis file isn't bundled into -+ // the app by accident -+ fs.copySync(analysisSource, destination, { overwrite: true }) -+ fs.unlinkSync(analysisSource) -+ } - } - - function copyDependencies() { -@@ -186,9 +247,6 @@ - 'package.json' - )) - -- // eslint-disable-next-line import/no-dynamic-require -- const commonConfig = require(path.resolve(__dirname, '../app/webpack.common')) -- const externals = commonConfig.externals - const oldDependencies = originalPackage.dependencies - const newDependencies: PackageLookup = {} - -@@ -296,7 +354,6 @@ - function updateLicenseDump(callback: (err: Error | null) => void) { - const appRoot = path.join(projectRoot, 'app') - const outPath = path.join(outRoot, 'static', 'licenses.json') -- const licenseOverrides: LicenseLookup = require('./license-overrides') - - legalEagle( - { path: appRoot, overrides: licenseOverrides, omitPermissive: true }, -@@ -353,3 +410,54 @@ - } - ) - } -+ -+function generateLicenseMetadata(outRoot: string) { -+ const chooseALicense = path.join(outRoot, 'static', 'choosealicense.com') -+ const licensesDir = path.join(chooseALicense, '_licenses') -+ -+ const files = fs.readdirSync(licensesDir) -+ -+ const licenses = new Array() -+ for (const file of files) { -+ const fullPath = path.join(licensesDir, file) -+ const contents = fs.readFileSync(fullPath, 'utf8') -+ const result = frontMatter(contents) -+ const license: ILicense = { -+ name: result.attributes.nickname || result.attributes.title, -+ featured: result.attributes.featured || false, -+ hidden: -+ result.attributes.hidden === undefined || result.attributes.hidden, -+ body: result.body.trim(), -+ } -+ -+ if (!license.hidden) { -+ licenses.push(license) -+ } -+ } -+ -+ const licensePayload = path.join(outRoot, 'static', 'available-licenses.json') -+ const text = JSON.stringify(licenses) -+ fs.writeFileSync(licensePayload, text, 'utf8') -+ -+ // embed the license alongside the generated license payload -+ const chooseALicenseLicense = path.join(chooseALicense, 'LICENSE.md') -+ const licenseDestination = path.join( -+ outRoot, -+ 'static', -+ 'LICENSE.choosealicense.md' -+ ) -+ -+ const licenseText = fs.readFileSync(chooseALicenseLicense, 'utf8') -+ const licenseWithHeader = `GitHub Desktop uses licensing information provided by choosealicense.com. -+ -+The bundle in available-licenses.json has been generated from a source list provided at https://github.com/github/choosealicense.com, which is made available under the below license: -+ -+------------ -+ -+${licenseText}` -+ -+ fs.writeFileSync(licenseDestination, licenseWithHeader, 'utf8') -+ -+ // sweep up the choosealicense directory as the important bits have been bundled in the app -+ fs.removeSync(chooseALicense) -+} -changed in both - base 100644 b0a88cf77391d915e28566a1695cbf31c2ab7bbb script/changelog/parser.ts - our 100644 ff08e0ef253ffb980b0ed57114f9fefea05d7fc1 script/changelog/parser.ts - their 100644 aad3c838c2d7931127adbc843bdd83ccda5968a1 script/changelog/parser.ts -@@ -116,6 +116,7 @@ - const root = Path.dirname(Path.dirname(__dirname)) - const changelogPath = Path.join(root, 'changelog.json') - -+ // eslint-disable-next-line no-sync - const buffer = Fs.readFileSync(changelogPath) - const changelogText = buffer.toString() - -removed in remote - base 100644 ad4855567fb5e193b74292af394786561793577f script/debug - our 100644 ad4855567fb5e193b74292af394786561793577f script/debug -@@ -1,29 +0,0 @@ --#!/usr/bin/env node -- --'use strict' -- --const express = require('express') --const webpack = require('webpack') --const config = require('../app/webpack.development') --const server = express() --const compiler = webpack(config) --const port = process.env.PORT || 3000 -- --server.use( -- require('webpack-dev-middleware')(compiler, { -- publicPath: config.output.publicPath, -- noInfo: true, -- }) --) -- --server.use(require('webpack-hot-middleware')(compiler)) -- --server.listen(port, 'localhost', err => { -- if (err) { -- console.log(err) -- process.exit(1) -- return -- } -- -- console.log(`Server running at http://localhost:${port}`) --}) -removed in remote - base 100644 761dea8563e41854304fb72b473ef14d0ead525f script/dist-info.d.ts - our 100644 761dea8563e41854304fb72b473ef14d0ead525f script/dist-info.d.ts -@@ -1,20 +0,0 @@ --export function getDistRoot(): string --export function getDistPath(): string --export function getOSXZipName(): string --export function getOSXZipPath(): string --export function getWindowsInstallerName(): string --export function getWindowsInstallerPath(): string --export function getWindowsStandaloneName(): string --export function getWindowsStandalonePath(): string --export function getWindowsFullNugetPackageName(): string --export function getWindowsFullNugetPackagePath(): string --export function getWindowsIdentifierName(): string --export function getBundleSizes(): { rendererSize: number; mainSize: number } --export function getReleaseChannel(): string | null --export function getReleaseSHA(): string | null --export function getUpdatesURL(): string --export function getWindowsDeltaNugetPackageName(): string --export function getWindowsDeltaNugetPackagePath(): string --export function shouldMakeDelta(): boolean --export function getReleaseBranchName(): string --export function getExecutableName(): string -removed in remote - base 100644 b516179431c4275fa3a02610faa699fab1241710 script/dist-info.js - our 100644 b516179431c4275fa3a02610faa699fab1241710 script/dist-info.js -@@ -1,163 +0,0 @@ --'use strict' -- --const path = require('path') --const fs = require('fs') --const os = require('os') -- --const packageInfo = require('../app/package-info') --const productName = packageInfo.getProductName() --const version = packageInfo.getVersion() -- --const projectRoot = path.join(__dirname, '..') -- --function getDistRoot() { -- return path.join(projectRoot, 'dist') --} -- --function getDistPath() { -- return path.join( -- getDistRoot(), -- `${getExecutableName()}-${process.platform}-${os.arch()}` -- ) --} -- --function getExecutableName() { -- const suffix = process.env.NODE_ENV === 'development' ? '-dev' : '' -- -- if (process.platform === 'win32') { -- return `${getWindowsIdentifierName()}${suffix}` -- } else if (process.platform === 'linux') { -- return 'desktop' -- } else { -- return productName -- } --} -- --function getOSXZipName() { -- return `${productName}.zip` --} -- --function getOSXZipPath() { -- return path.join(getDistPath(), '..', getOSXZipName()) --} -- --function getWindowsInstallerName() { -- const productName = getExecutableName() -- return `${productName}Setup.msi` --} -- --function getWindowsInstallerPath() { -- return path.join(getDistPath(), '..', 'installer', getWindowsInstallerName()) --} -- --function getWindowsStandaloneName() { -- const productName = getExecutableName() -- return `${productName}Setup.exe` --} -- --function getWindowsStandalonePath() { -- return path.join(getDistPath(), '..', 'installer', getWindowsStandaloneName()) --} -- --function getWindowsFullNugetPackageName() { -- return `${getWindowsIdentifierName()}-${version}-full.nupkg` --} -- --function getWindowsFullNugetPackagePath() { -- return path.join( -- getDistPath(), -- '..', -- 'installer', -- getWindowsFullNugetPackageName() -- ) --} -- --function getWindowsDeltaNugetPackageName() { -- return `${getWindowsIdentifierName()}-${version}-delta.nupkg` --} -- --function getWindowsDeltaNugetPackagePath() { -- return path.join( -- getDistPath(), -- '..', -- 'installer', -- getWindowsDeltaNugetPackageName() -- ) --} -- --function getWindowsIdentifierName() { -- return 'GitHubDesktop' --} -- --function getBundleSizes() { -- const rendererStats = fs.statSync( -- path.join(projectRoot, 'out', 'renderer.js') -- ) -- const mainStats = fs.statSync(path.join(projectRoot, 'out', 'main.js')) -- return { rendererSize: rendererStats.size, mainSize: mainStats.size } --} -- --function getReleaseBranchName() { -- let branchName -- if (process.platform === 'darwin') { -- branchName = process.env.CIRCLE_BRANCH -- } else if (process.platform === 'win32') { -- branchName = process.env.APPVEYOR_REPO_BRANCH -- } -- -- return branchName || '' --} -- --function getReleaseChannel() { -- // Branch name format: __release-CHANNEL-DEPLOY_ID -- const pieces = getReleaseBranchName().split('-') -- if (pieces.length < 3 || pieces[0] !== '__release') { -- return process.env.NODE_ENV || 'development' -- } -- -- return pieces[1] --} -- --function getReleaseSHA() { -- // Branch name format: __release-CHANNEL-DEPLOY_ID -- const pieces = getReleaseBranchName().split('-') -- if (pieces.length < 3 || pieces[0] !== '__release') { -- return null -- } -- -- return pieces[2] --} -- --function getUpdatesURL() { -- return `https://central.github.com/api/deployments/desktop/desktop/latest?version=${version}&env=${getReleaseChannel()}` --} -- --function shouldMakeDelta() { -- // Only production and beta channels include deltas. Test releases aren't -- // necessarily sequential so deltas wouldn't make sense. -- const channelsWithDeltas = ['production', 'beta'] -- return channelsWithDeltas.indexOf(getReleaseChannel()) > -1 --} -- --module.exports = { -- getDistRoot, -- getDistPath, -- getOSXZipName, -- getOSXZipPath, -- getWindowsInstallerName, -- getWindowsInstallerPath, -- getWindowsStandaloneName, -- getWindowsStandalonePath, -- getWindowsFullNugetPackageName, -- getWindowsFullNugetPackagePath, -- getWindowsIdentifierName, -- getBundleSizes, -- getReleaseChannel, -- getReleaseSHA, -- getUpdatesURL, -- getWindowsDeltaNugetPackageName, -- getWindowsDeltaNugetPackagePath, -- shouldMakeDelta, -- getReleaseBranchName, -- getExecutableName, --} -added in remote - their 100644 8661aa1a9becdd6f0f77dc9101c6eb665295544d script/dist-info.ts -@@ -0,0 +1,137 @@ -+import * as Path from 'path' -+import * as Fs from 'fs' -+ -+import { getProductName, getVersion } from '../app/package-info' -+ -+const productName = getProductName() -+const version = getVersion() -+ -+const projectRoot = Path.join(__dirname, '..') -+ -+export function getDistRoot() { -+ return Path.join(projectRoot, 'dist') -+} -+ -+export function getDistPath() { -+ return Path.join( -+ getDistRoot(), -+ `${getExecutableName()}-${process.platform}-x64` -+ ) -+} -+ -+export function getExecutableName() { -+ const suffix = process.env.NODE_ENV === 'development' ? '-dev' : '' -+ -+ if (process.platform === 'win32') { -+ return `${getWindowsIdentifierName()}${suffix}` -+ } else if (process.platform === 'linux') { -+ return 'desktop' -+ } else { -+ return productName -+ } -+} -+ -+export function getOSXZipName() { -+ return `${productName}.zip` -+} -+ -+export function getOSXZipPath() { -+ return Path.join(getDistPath(), '..', getOSXZipName()) -+} -+ -+export function getWindowsInstallerName() { -+ const productName = getExecutableName() -+ return `${productName}Setup.msi` -+} -+ -+export function getWindowsInstallerPath() { -+ return Path.join(getDistPath(), '..', 'installer', getWindowsInstallerName()) -+} -+ -+export function getWindowsStandaloneName() { -+ const productName = getExecutableName() -+ return `${productName}Setup.exe` -+} -+ -+export function getWindowsStandalonePath() { -+ return Path.join(getDistPath(), '..', 'installer', getWindowsStandaloneName()) -+} -+ -+export function getWindowsFullNugetPackageName() { -+ return `${getWindowsIdentifierName()}-${version}-full.nupkg` -+} -+ -+export function getWindowsFullNugetPackagePath() { -+ return Path.join( -+ getDistPath(), -+ '..', -+ 'installer', -+ getWindowsFullNugetPackageName() -+ ) -+} -+ -+export function getWindowsDeltaNugetPackageName() { -+ return `${getWindowsIdentifierName()}-${version}-delta.nupkg` -+} -+ -+export function getWindowsDeltaNugetPackagePath() { -+ return Path.join( -+ getDistPath(), -+ '..', -+ 'installer', -+ getWindowsDeltaNugetPackageName() -+ ) -+} -+ -+export function getWindowsIdentifierName() { -+ return 'GitHubDesktop' -+} -+ -+export function getBundleSizes() { -+ // eslint-disable-next-line no-sync -+ const rendererStats = Fs.statSync( -+ Path.join(projectRoot, 'out', 'renderer.js') -+ ) -+ // eslint-disable-next-line no-sync -+ const mainStats = Fs.statSync(Path.join(projectRoot, 'out', 'main.js')) -+ return { rendererSize: rendererStats.size, mainSize: mainStats.size } -+} -+ -+export function getReleaseBranchName(): string { -+ return ( -+ process.env.CIRCLE_BRANCH || // macOS -+ process.env.APPVEYOR_REPO_BRANCH || // Windows -+ '' -+ ) -+} -+ -+export function getReleaseChannel() { -+ // Branch name format: __release-CHANNEL-DEPLOY_ID -+ const pieces = getReleaseBranchName().split('-') -+ if (pieces.length < 3 || pieces[0] !== '__release') { -+ return process.env.NODE_ENV || 'development' -+ } -+ -+ return pieces[1] -+} -+ -+export function getReleaseSHA() { -+ // Branch name format: __release-CHANNEL-DEPLOY_ID -+ const pieces = getReleaseBranchName().split('-') -+ if (pieces.length < 3 || pieces[0] !== '__release') { -+ return null -+ } -+ -+ return pieces[2] -+} -+ -+export function getUpdatesURL() { -+ return `https://central.github.com/api/deployments/desktop/desktop/latest?version=${version}&env=${getReleaseChannel()}` -+} -+ -+export function shouldMakeDelta() { -+ // Only production and beta channels include deltas. Test releases aren't -+ // necessarily sequential so deltas wouldn't make sense. -+ const channelsWithDeltas = ['production', 'beta'] -+ return channelsWithDeltas.indexOf(getReleaseChannel()) > -1 -+} -merged - result 100644 c71f2850346b76957d6eb4312308b15714d08361 script/eslint.ts - our 100644 953deb6d112573e32a78fd54bc428c723508a788 script/eslint.ts -@@ -16,7 +16,7 @@ - const report = eslint.executeOnFiles([ - './{script,eslint-rules}/**/*.{j,t}s?(x)', - './tslint-rules/**/*.ts', -- './app/*.js', -+ './app/*.ts', - './app/{src,typings,test}/**/*.{j,t}s?(x)', - './changelog.json', - ]) -merged - result 100644 bb3b7645eac13fe68f14a1e2b6b95e522d234648 script/globals.d.ts - our 100644 d9ee18180f09bbb636b084a49eac223aa170eb71 script/globals.d.ts -@@ -6,63 +6,6 @@ - devDependencies: PackageLookup - } - --// type declarations for legal-eagle --type LicenseLookup = { -- [key: string]: LicenseEntry --} -- --type LegalEagleOptions = { -- path: string -- overrides: LicenseLookup -- omitPermissive?: boolean --} -- --type LicenseEntry = { -- license: string -- source: string -- repository: string -- sourceText: string --} -- --type LegalEagle = ( -- options: LegalEagleOptions, -- callback: (error: Error | null, summary: LicenseLookup) => void --) => void -- --// type declarations for electron-installer-redhat --type RedhatOptions = { -- src: string -- dest: string -- arch: string --} -- --type ElectronInstallerRedhat = ( -- options: RedhatOptions, -- callback: (error: Error | null) => void --) => void -- --// type declarations for electron-installer-debian --type DebianOptions = { -- src: string -- dest: string -- arch: string --} -- --type ElectronInstallerDebian = ( -- options: DebianOptions, -- callback: (error: Error | null) => void --) => void -- --// type declarations for electron-installer-appimage --type AppImageOptions = { -- dir: string -- targetArch: string --} -- --type ElectronInstallerAppImage = { -- default: (options: AppImageOptions) => Promise --} -- - declare namespace NodeJS { - // eslint-disable-next-line typescript/interface-name-prefix - interface Process extends EventEmitter { -removed in remote - base 100644 92a4128288d1d86d9eca15d695a8cb8d846bcb58 script/license-overrides.js - our 100644 92a4128288d1d86d9eca15d695a8cb8d846bcb58 script/license-overrides.js -@@ -1,45 +0,0 @@ --module.exports = { -- 'cycle@1.0.3': { -- repository: 'git+ssh://git@github.com/dscape/cycle', -- license: 'Public Domain', -- source: -- 'cycle.js header comment at https://github.com/dscape/cycle/blob/ab67ce90e8fa2efdb8f21074661366ec56f6a724/cycle.js', -- sourceText: -- 'Public Domain.\n\nNO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.', -- }, -- -- 'json-schema@0.2.3': { -- repository: 'git+ssh://git@github.com/kriszyp/json-schema', -- license: 'BSD', -- source: -- 'README.md at https://github.com/kriszyp/json-schema/tree/24c4ed1b2359ab457a00e90606a777c2962ecd3b', -- sourceText: -- 'Code is licensed under the AFL or BSD 3-Clause license as part of the Persevere project which is administered under the Dojo foundation, and all contributions require a Dojo CLA.', -- }, -- -- 'wicg-focus-ring@1.0.1': { -- repository: 'git+https://github.com/WICG/focus-ring', -- license: 'MIT', -- source: -- 'https://github.com/WICG/focus-ring/blob/4df78f379e4c7dbaa1a5e4ff25cf1b56700b24ee/LICENSE.md', -- sourceText: `This work is being provided by the copyright holders under the following license. -- --License -- --By obtaining and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions. -- --Permission to copy, modify, and distribute this work, with or without modification, for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the work or portions thereof, including modifications: -- --* The full text of this NOTICE in a location viewable to users of the redistributed or derivative work. --* Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, the W3C Software and Document Short Notice should be included. --* Notice of any changes or modifications, through a copyright statement on the new code or document such as "This software or document includes material copied from or derived from [title and URI of the W3C document]. Copyright © [YEAR] W3C® (MIT, ERCIM, Keio, Beihang)." -- --Disclaimers -- --THIS WORK IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENT WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. -- --COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENT. -- --The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the work without specific, written prior permission. Title to copyright in this work will at all times remain with copyright holders.`, -- }, --} -added in remote - their 100644 03fdf69fd8b91f2bd0d89f4f124473a4f2affff5 script/license-overrides.ts -@@ -0,0 +1,47 @@ -+import { LicenseLookup } from 'legal-eagle' -+ -+export const licenseOverrides: LicenseLookup = { -+ 'cycle@1.0.3': { -+ repository: 'git+ssh://git@github.com/dscape/cycle', -+ license: 'Public Domain', -+ source: -+ 'cycle.js header comment at https://github.com/dscape/cycle/blob/ab67ce90e8fa2efdb8f21074661366ec56f6a724/cycle.js', -+ sourceText: -+ 'Public Domain.\n\nNO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.', -+ }, -+ -+ 'json-schema@0.2.3': { -+ repository: 'git+ssh://git@github.com/kriszyp/json-schema', -+ license: 'BSD', -+ source: -+ 'README.md at https://github.com/kriszyp/json-schema/tree/24c4ed1b2359ab457a00e90606a777c2962ecd3b', -+ sourceText: -+ 'Code is licensed under the AFL or BSD 3-Clause license as part of the Persevere project which is administered under the Dojo foundation, and all contributions require a Dojo CLA.', -+ }, -+ -+ 'wicg-focus-ring@1.0.1': { -+ repository: 'git+https://github.com/WICG/focus-ring', -+ license: 'MIT', -+ source: -+ 'https://github.com/WICG/focus-ring/blob/4df78f379e4c7dbaa1a5e4ff25cf1b56700b24ee/LICENSE.md', -+ sourceText: `This work is being provided by the copyright holders under the following license. -+ -+License -+ -+By obtaining and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions. -+ -+Permission to copy, modify, and distribute this work, with or without modification, for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the work or portions thereof, including modifications: -+ -+* The full text of this NOTICE in a location viewable to users of the redistributed or derivative work. -+* Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, the W3C Software and Document Short Notice should be included. -+* Notice of any changes or modifications, through a copyright statement on the new code or document such as "This software or document includes material copied from or derived from [title and URI of the W3C document]. Copyright © [YEAR] W3C® (MIT, ERCIM, Keio, Beihang)." -+ -+Disclaimers -+ -+THIS WORK IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENT WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. -+ -+COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENT. -+ -+The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the work without specific, written prior permission. Title to copyright in this work will at all times remain with copyright holders.`, -+ }, -+} -merged - result 100644 4f340bd02953a3f1dbcadde80836e441a1d4c69c script/prettier.ts - our 100644 146c1fcc48a0541fe8d79bf5245d94c06b3b832e script/prettier.ts -@@ -11,7 +11,12 @@ - const prettier = process.platform === 'win32' ? 'prettier.cmd' : 'prettier' - const prettierPath = Path.join(root, 'node_modules', '.bin', prettier) - --const args = ['**/*.scss', '--list-different'] -+const args = [ -+ '**/*.scss', -+ 'app/**/*.{ts,tsx}', -+ 'script/**/*.ts', -+ '--list-different', -+] - - if (shouldFix) { - args.push('--write') -removed in remote - base 100644 68800a13155c68afc965da100c263aad461916a8 script/publish - our 100644 68800a13155c68afc965da100c263aad461916a8 script/publish -@@ -1,200 +0,0 @@ --#!/usr/bin/env node -- --'use strict' -- --const TEST_PUBLISH = false --const PUBLISH_CHANNELS = ['production', 'test', 'beta'] --const distInfo = require('./dist-info') --const gitInfo = require('../app/git-info') --const packageInfo = require('../app/package-info') -- --if (PUBLISH_CHANNELS.indexOf(distInfo.getReleaseChannel()) < 0) { -- console.log('Not a publishable build. Skipping publish.') -- process.exit(0) --} -- --const releaseSHA = distInfo.getReleaseSHA() --if (!releaseSHA) { -- console.log(`No release SHA found for build. Skipping publish.`) -- process.exit(0) --} -- --const currentTipSHA = gitInfo.getSHA() --if ( -- !currentTipSHA || -- !currentTipSHA.toUpperCase().startsWith(releaseSHA.toUpperCase()) --) { -- console.log( -- `Current tip '${currentTipSHA}' does not match release SHA '${releaseSHA}'. Skipping publish.` -- ) -- process.exit(0) --} -- --const fs = require('fs') --const cp = require('child_process') --const AWS = require('aws-sdk') --const crypto = require('crypto') --const request = require('request') -- --console.log('Packaging…') --cp.execSync('yarn package') -- --let sha = '' --if (process.platform === 'darwin') { -- sha = process.env.CIRCLE_SHA1 --} else if (process.platform === 'win32') { -- sha = process.env.APPVEYOR_REPO_COMMIT --} -- --sha = sha.substr(0, 8) -- --console.log('Uploading…') -- --let uploadPromise = null --if (process.platform === 'darwin') { -- uploadPromise = uploadOSXAssets() --} else if (process.platform === 'win32') { -- uploadPromise = uploadWindowsAssets() --} else { -- console.error(`I dunno how to publish a release for ${process.platform} :(`) -- process.exit(1) --} -- --uploadPromise -- .then(artifacts => { -- const names = artifacts.map(function(item, index) { -- return item.name -- }) -- console.log(`Uploaded artifacts: ${names}`) -- return updateDeploy(artifacts) -- }) -- .catch(e => { -- console.error(`Publishing failed: ${e}`) -- process.exit(1) -- }) -- --function uploadOSXAssets() { -- const uploads = [upload(distInfo.getOSXZipName(), distInfo.getOSXZipPath())] -- return Promise.all(uploads) --} -- --function uploadWindowsAssets() { -- const uploads = [ -- upload( -- distInfo.getWindowsInstallerName(), -- distInfo.getWindowsInstallerPath() -- ), -- upload( -- distInfo.getWindowsStandaloneName(), -- distInfo.getWindowsStandalonePath() -- ), -- upload( -- distInfo.getWindowsFullNugetPackageName(), -- distInfo.getWindowsFullNugetPackagePath() -- ), -- ] -- -- if (distInfo.shouldMakeDelta()) { -- uploads.push( -- upload( -- distInfo.getWindowsDeltaNugetPackageName(), -- distInfo.getWindowsDeltaNugetPackagePath() -- ) -- ) -- } -- -- return Promise.all(uploads) --} -- --function upload(assetName, assetPath) { -- const s3Info = { -- accessKeyId: process.env.S3_KEY, -- secretAccessKey: process.env.S3_SECRET, -- } -- const s3 = new AWS.S3(s3Info) -- -- const bucket = process.env.S3_BUCKET -- const key = `releases/${packageInfo.getVersion()}-${sha}/${assetName.replace( -- / /g, -- '' -- )}` -- const url = `https://s3.amazonaws.com/${bucket}/${key}` -- -- const uploadParams = { -- Bucket: bucket, -- ACL: 'public-read', -- Key: key, -- Body: fs.createReadStream(assetPath), -- } -- -- return new Promise((resolve, reject) => { -- s3.upload(uploadParams, (error, data) => { -- if (error) { -- reject(error) -- } else { -- const stats = fs.statSync(assetPath) -- const hash = crypto.createHash('sha1') -- const input = fs.createReadStream(assetPath) -- -- hash.on('finish', () => { -- const sha = hash.read().toString('hex') -- resolve({ name: assetName, url, size: stats['size'], sha }) -- }) -- -- input.pipe(hash) -- } -- }) -- }) --} -- --function createSignature(body) { -- const hmac = crypto.createHmac('sha1', process.env.DEPLOYMENT_SECRET) -- hmac.update(JSON.stringify(body)) -- return `sha1=${hmac.digest('hex')}` --} -- --function updateDeploy(artifacts) { -- const { rendererSize, mainSize } = distInfo.getBundleSizes() -- const body = { -- context: process.platform, -- branch_name: distInfo.getReleaseBranchName(), -- artifacts, -- stats: { -- platform: process.platform, -- rendererBundleSize: rendererSize, -- mainBundleSize: mainSize, -- }, -- } -- const signature = createSignature(body) -- const options = { -- method: 'POST', -- url: 'https://central.github.com/api/deploy_built', -- headers: { -- 'X-Hub-Signature': signature, -- }, -- json: true, -- body, -- } -- -- return new Promise((resolve, reject) => { -- request(options, (error, response, body) => { -- if (error) { -- reject(error) -- return -- } -- -- if (response.statusCode !== 200) { -- reject( -- new Error( -- `Received a non-200 response (${response.statusCode}): ${JSON.stringify( -- body -- )}` -- ) -- ) -- return -- } -- -- resolve() -- }) -- }) --} -added in remote - their 100644 4d6fbd455197c1eaf2b4279aa43467b07e669937 script/publish.ts -@@ -0,0 +1,222 @@ -+const PUBLISH_CHANNELS = ['production', 'test', 'beta'] -+import * as distInfo from './dist-info' -+import * as gitInfo from '../app/git-info' -+import * as packageInfo from '../app/package-info' -+ -+if (PUBLISH_CHANNELS.indexOf(distInfo.getReleaseChannel()) < 0) { -+ console.log('Not a publishable build. Skipping publish.') -+ process.exit(0) -+} -+ -+const releaseSHA = distInfo.getReleaseSHA() -+if (releaseSHA == null) { -+ console.log(`No release SHA found for build. Skipping publish.`) -+ process.exit(0) -+} -+ -+const currentTipSHA = gitInfo.getSHA() -+if (!currentTipSHA.toUpperCase().startsWith(releaseSHA!.toUpperCase())) { -+ console.log( -+ `Current tip '${currentTipSHA}' does not match release SHA '${releaseSHA}'. Skipping publish.` -+ ) -+ process.exit(0) -+} -+ -+import * as Fs from 'fs' -+import { execSync } from 'child_process' -+import * as AWS from 'aws-sdk' -+import * as Crypto from 'crypto' -+import * as request from 'request' -+ -+console.log('Packaging…') -+execSync('yarn package') -+ -+function getSha() { -+ if (process.platform === 'darwin' && process.env.CIRCLE_SHA1 != null) { -+ return process.env.CIRCLE_SHA1 -+ } else if ( -+ process.platform === 'win32' && -+ process.env.APPVEYOR_REPO_COMMIT != null -+ ) { -+ return process.env.APPVEYOR_REPO_COMMIT -+ } -+ -+ throw new Error( -+ `Unable to get the SHA for the current platform. Check the vendor docs for the desired environment variables.` -+ ) -+} -+ -+const sha = getSha().substr(0, 8) -+ -+function getSecret() { -+ if (process.env.DEPLOYMENT_SECRET != null) { -+ return process.env.DEPLOYMENT_SECRET -+ } -+ -+ throw new Error( -+ `Unable to get deployment seret environment variable. Deployment aborting...` -+ ) -+} -+ -+console.log('Uploading…') -+ -+let uploadPromise = null -+if (process.platform === 'darwin') { -+ uploadPromise = uploadOSXAssets() -+} else if (process.platform === 'win32') { -+ uploadPromise = uploadWindowsAssets() -+} else { -+ console.error(`I dunno how to publish a release for ${process.platform} :(`) -+ process.exit(1) -+} -+ -+uploadPromise! -+ .then(artifacts => { -+ const names = artifacts.map(function(item, index) { -+ return item.name -+ }) -+ console.log(`Uploaded artifacts: ${names}`) -+ return updateDeploy(artifacts, getSecret()) -+ }) -+ .catch(e => { -+ console.error(`Publishing failed: ${e}`) -+ process.exit(1) -+ }) -+ -+function uploadOSXAssets() { -+ const uploads = [upload(distInfo.getOSXZipName(), distInfo.getOSXZipPath())] -+ return Promise.all(uploads) -+} -+ -+function uploadWindowsAssets() { -+ const uploads = [ -+ upload( -+ distInfo.getWindowsInstallerName(), -+ distInfo.getWindowsInstallerPath() -+ ), -+ upload( -+ distInfo.getWindowsStandaloneName(), -+ distInfo.getWindowsStandalonePath() -+ ), -+ upload( -+ distInfo.getWindowsFullNugetPackageName(), -+ distInfo.getWindowsFullNugetPackagePath() -+ ), -+ ] -+ -+ if (distInfo.shouldMakeDelta()) { -+ uploads.push( -+ upload( -+ distInfo.getWindowsDeltaNugetPackageName(), -+ distInfo.getWindowsDeltaNugetPackagePath() -+ ) -+ ) -+ } -+ -+ return Promise.all(uploads) -+} -+ -+interface IUploadResult { -+ name: string -+ url: string -+ size: number -+ sha: string -+} -+ -+function upload(assetName: string, assetPath: string) { -+ const s3Info = { -+ accessKeyId: process.env.S3_KEY, -+ secretAccessKey: process.env.S3_SECRET, -+ } -+ const s3 = new AWS.S3(s3Info) -+ -+ const bucket = process.env.S3_BUCKET || '' -+ const key = `releases/${packageInfo.getVersion()}-${sha}/${assetName.replace( -+ / /g, -+ '' -+ )}` -+ const url = `https://s3.amazonaws.com/${bucket}/${key}` -+ -+ const uploadParams = { -+ Bucket: bucket, -+ ACL: 'public-read', -+ Key: key, -+ Body: Fs.createReadStream(assetPath), -+ } -+ -+ return new Promise((resolve, reject) => { -+ s3.upload( -+ uploadParams, -+ (error: Error, data: AWS.S3.ManagedUpload.SendData) => { -+ if (error != null) { -+ reject(error) -+ } else { -+ // eslint-disable-next-line no-sync -+ const stats = Fs.statSync(assetPath) -+ const hash = Crypto.createHash('sha1') -+ hash.setEncoding('hex') -+ const input = Fs.createReadStream(assetPath) -+ -+ hash.on('finish', () => { -+ const sha = hash.read() as string -+ resolve({ name: assetName, url, size: stats['size'], sha }) -+ }) -+ -+ input.pipe(hash) -+ } -+ } -+ ) -+ }) -+} -+ -+function createSignature(body: any, secret: string) { -+ const hmac = Crypto.createHmac('sha1', secret) -+ hmac.update(JSON.stringify(body)) -+ return `sha1=${hmac.digest('hex')}` -+} -+ -+function updateDeploy(artifacts: ReadonlyArray, secret: string) { -+ const { rendererSize, mainSize } = distInfo.getBundleSizes() -+ const body = { -+ context: process.platform, -+ branch_name: distInfo.getReleaseBranchName(), -+ artifacts, -+ stats: { -+ platform: process.platform, -+ rendererBundleSize: rendererSize, -+ mainBundleSize: mainSize, -+ }, -+ } -+ const signature = createSignature(body, secret) -+ const options = { -+ method: 'POST', -+ url: 'https://central.github.com/api/deploy_built', -+ headers: { -+ 'X-Hub-Signature': signature, -+ }, -+ json: true, -+ body, -+ } -+ -+ return new Promise((resolve, reject) => { -+ request(options, (error, response, body) => { -+ if (error) { -+ reject(error) -+ return -+ } -+ -+ if (response.statusCode !== 200) { -+ reject( -+ new Error( -+ `Received a non-200 response (${ -+ response.statusCode -+ }): ${JSON.stringify(body)}` -+ ) -+ ) -+ return -+ } -+ -+ resolve() -+ }) -+ }) -+} -merged - result 100644 903faa6e50dc2fafc46924b0438baa3b9e6f634b script/review-logs.ts - our 100644 68ca321f41b2e29ff3393e3d9a6abd62c560c699 script/review-logs.ts -@@ -8,7 +8,13 @@ - - function getUserDataPath() { - if (process.platform === 'win32') { -- return path.join(process.env.APPDATA, getExecutableName()) -+ if (process.env.APPDATA) { -+ return path.join(process.env.APPDATA, getExecutableName()) -+ } else { -+ throw new Error( -+ `Unable to find the application data directory on Windows :(` -+ ) -+ } - } else if (process.platform === 'darwin') { - const home = os.homedir() - return path.join(home, 'Library', 'Application Support', getProductName()) -removed in remote - base 100644 77bf79b8ff282fb277c0f780772d8f30eca82e7d script/run.js - our 100644 77bf79b8ff282fb277c0f780772d8f30eca82e7d script/run.js -@@ -1,46 +0,0 @@ --'use strict' -- --const path = require('path') --const cp = require('child_process') --const fs = require('fs') --const distInfo = require('./dist-info') -- --const distPath = distInfo.getDistPath() --const productName = distInfo.getExecutableName() -- --let binaryPath = '' --if (process.platform === 'darwin') { -- binaryPath = path.join( -- distPath, -- `${productName}.app`, -- 'Contents', -- 'MacOS', -- `${productName}` -- ) --} else if (process.platform === 'win32') { -- binaryPath = path.join(distPath, `${productName}.exe`) --} else if (process.platform === 'linux') { -- binaryPath = path.join(distPath, productName) --} else { -- console.error(`I dunno how to run on ${process.platform} ${process.arch} :(`) -- process.exit(1) --} -- --module.exports = function(spawnOptions) { -- try { -- const stats = fs.statSync(binaryPath) -- if (!stats.isFile()) { -- return null -- } -- } catch (e) { -- return null -- } -- -- const opts = Object.assign({}, spawnOptions) -- -- opts.env = Object.assign(opts.env || {}, process.env, { -- NODE_ENV: 'development', -- }) -- -- return cp.spawn(binaryPath, [], opts) --} -added in remote - their 100644 6551aefb22d8539c0c733a0a3dbd436b4e88fa51 script/run.ts -@@ -0,0 +1,45 @@ -+import { join } from 'path' -+import { spawn, SpawnOptions } from 'child_process' -+import * as Fs from 'fs' -+import { getDistPath, getExecutableName } from './dist-info' -+ -+const distPath = getDistPath() -+const productName = getExecutableName() -+ -+let binaryPath = '' -+if (process.platform === 'darwin') { -+ binaryPath = join( -+ distPath, -+ `${productName}.app`, -+ 'Contents', -+ 'MacOS', -+ `${productName}` -+ ) -+} else if (process.platform === 'win32') { -+ binaryPath = join(distPath, `${productName}.exe`) -+} else if (process.platform === 'linux') { -+ binaryPath = join(distPath, productName) -+} else { -+ console.error(`I dunno how to run on ${process.platform} ${process.arch} :(`) -+ process.exit(1) -+} -+ -+export function run(spawnOptions: SpawnOptions) { -+ try { -+ // eslint-disable-next-line no-sync -+ const stats = Fs.statSync(binaryPath) -+ if (!stats.isFile()) { -+ return null -+ } -+ } catch (e) { -+ return null -+ } -+ -+ const opts = Object.assign({}, spawnOptions) -+ -+ opts.env = Object.assign(opts.env || {}, process.env, { -+ NODE_ENV: 'development', -+ }) -+ -+ return spawn(binaryPath, [], opts) -+} -removed in remote - base 100644 e2fdac76cfc9f9f60ad2e6163a08a7da7cc6a336 script/start - our 100644 e2fdac76cfc9f9f60ad2e6163a08a7da7cc6a336 script/start -@@ -1,53 +0,0 @@ --#!/usr/bin/env node -- --'use strict' -- --const run = require('./run') --const express = require('express') --const webpack = require('webpack') --const configs = require('../app/webpack.development') -- --function startApp() { -- const runningApp = run({ stdio: 'inherit' }) -- if (!runningApp) { -- console.error( -- "Couldn't launch the app. You probably need to build it first. Run `yarn build:dev`." -- ) -- process.exit(1) -- } -- -- runningApp.on('close', () => { -- process.exit(0) -- }) --} -- --if (process.env.NODE_ENV === 'production') { -- startApp() -- return --} -- --const [mainConfig, rendererConfig, askPassConfig] = configs -- --const server = express() --const compiler = webpack(rendererConfig) --const port = process.env.PORT || 3000 -- --server.use( -- require('webpack-dev-middleware')(compiler, { -- publicPath: rendererConfig.output.publicPath, -- noInfo: true, -- }) --) -- --server.use(require('webpack-hot-middleware')(compiler)) -- --server.listen(port, 'localhost', err => { -- if (err) { -- console.log(err) -- process.exit(1) -- return -- } -- -- console.log(`Server running at http://localhost:${port}`) -- startApp() --}) -added in remote - their 100644 96fdc173cf1566aef93aff0b05bdbe08daa597ef script/start.ts -@@ -0,0 +1,72 @@ -+import * as express from 'express' -+import * as webpack from 'webpack' -+import * as devMiddleware from 'webpack-dev-middleware' -+import * as hotMiddleware from 'webpack-hot-middleware' -+ -+import { forceUnwrap as u } from '../app/src/lib/fatal-error' -+ -+import configs = require('../app/webpack.development') -+ -+import { run } from './run' -+ -+function getPortOrDefault() { -+ const port = process.env.PORT -+ if (port != null) { -+ const result = parseInt(port) -+ if (isNaN(result)) { -+ throw new Error(`Unable to parse '${port}' into valid number`) -+ } -+ return result -+ } -+ -+ return 3000 -+} -+ -+function startApp() { -+ const runningApp = run({ stdio: 'inherit' }) -+ if (runningApp == null) { -+ console.error( -+ "Couldn't launch the app. You probably need to build it first. Run `yarn build:dev`." -+ ) -+ process.exit(1) -+ return -+ } -+ -+ runningApp.on('close', () => { -+ process.exit(0) -+ }) -+} -+ -+if (process.env.NODE_ENV === 'production') { -+ startApp() -+} else { -+ const rendererConfig = configs[1] -+ -+ const server = express() -+ const compiler = webpack(rendererConfig) -+ const port = getPortOrDefault() -+ -+ const message = 'Could not find public path from configuration' -+ server.use( -+ devMiddleware(compiler, { -+ publicPath: u( -+ message, -+ u(message, u(message, rendererConfig).output).publicPath -+ ), -+ logLevel: 'error', -+ }) -+ ) -+ -+ server.use(hotMiddleware(compiler)) -+ -+ server.listen(port, 'localhost', (err: Error | null) => { -+ if (err) { -+ console.log(err) -+ process.exit(1) -+ return -+ } -+ -+ console.log(`Server running at http://localhost:${port}`) -+ startApp() -+ }) -+} -merged - result 100644 5542fdd0d59adecb94be7f9b26f60659a899a77f script/tsconfig.json - our 100644 14dd9e3066f9076b88a5096328332f218696513d script/tsconfig.json -@@ -3,14 +3,12 @@ - "module": "commonjs", - "moduleResolution": "node", - "target": "es6", -- "noImplicitAny": true, - "noImplicitReturns": true, -- "noImplicitThis": true, - "noFallthroughCasesInSwitch": true, - "noUnusedLocals": true, -- "strictNullChecks": true, - "sourceMap": false, -- "noEmit": true -+ "noEmit": true, -+ "strict": true, - }, - "compileOnSave": false - } -added in remote - their 100644 67afebf6479af930fa36dc6216880f9810e08abe script/unit-tests.ts -@@ -0,0 +1,98 @@ -+#!/usr/bin/env ts-node -+ -+import * as Path from 'path' -+import { spawnSync, SpawnSyncOptions } from 'child_process' -+ -+const environmentVariables = { -+ // setting commit information so that tests don't need to rely on global config -+ GIT_AUTHOR_NAME: 'Joe Bloggs', -+ GIT_AUTHOR_EMAIL: 'joe.bloggs@somewhere.com', -+ GIT_COMMITTER_NAME: 'Joe Bloggs', -+ GIT_COMMITTER_EMAIL: 'joe.bloggs@somewhere.com', -+ // signalling to dugite to use the bundled Git environment -+ TEST_ENV: '1', -+ // ensuring Electron doesn't attach to the current console session (Windows only) -+ ELECTRON_NO_ATTACH_CONSOLE: '1', -+} -+ -+const env = { ...process.env, ...environmentVariables } -+ -+// ensure commands are executed from the root of the repository -+const repositoryRoot = Path.dirname(__dirname) -+ -+const options: SpawnSyncOptions = { -+ cwd: repositoryRoot, -+ env, -+ // ensure stdout/stderr is propagated to the parent process so the test results -+ // are displayed to the user -+ stdio: 'inherit', -+} -+ -+const electronMocha = -+ process.platform === 'win32' ? 'electron-mocha.cmd' : 'electron-mocha' -+ -+const electronMochaPath = Path.join( -+ repositoryRoot, -+ 'node_modules', -+ '.bin', -+ electronMocha -+) -+ -+const electronMochaArgs = [ -+ // timeout for 10s -+ '-t', -+ '10000', -+ // ensure tests are run within a renderer process -+ '--renderer', -+ '--require', -+ 'ts-node/register', -+ '--require', -+ './app/test/globals.ts', -+ 'app/test/unit/*.{ts,tsx}', -+ 'app/test/unit/**/*.{ts,tsx}', -+] -+ -+const shouldDebug = process.argv.indexOf('--debug') > -1 -+ -+if (shouldDebug) { -+ electronMochaArgs.push('--debug') -+} -+ -+let exitCode = -1 -+ -+if (process.platform === 'linux') { -+ // xvfb-maybe wraps xvfb-run to ensure Electron tests are run within the -+ // context where the DISPLAY environment variable is set. It only runs on -+ // Linux and is designed for CI scenarios, but this is making the whole -+ // thing more explicit than the previous inline usage in package.json -+ const xvfbMaybe = Path.join( -+ repositoryRoot, -+ 'node_modules', -+ '.bin', -+ 'xvfb-maybe' -+ ) -+ -+ const args = [ -+ // on Travis there may be a problem with the default display being -+ // unavailable - this ensures we use a free server number -+ '--auto-servernum', -+ '--', -+ // and then we pass through the test runner commands -+ electronMochaPath, -+ ...electronMochaArgs, -+ ] -+ -+ console.log(`spawing xvfb-maybe with args: ${args.join(' ')}`) -+ -+ const { status } = spawnSync(xvfbMaybe, args, options) -+ exitCode = status -+} else { -+ console.log( -+ `spawing electron-mocha with args: ${electronMochaArgs.join(' ')}` -+ ) -+ -+ const { status } = spawnSync(electronMochaPath, electronMochaArgs, options) -+ exitCode = status -+} -+ -+process.exitCode = exitCode -merged - result 100644 d9481a63e89bd672307df8f1048caa69ee6276a9 script/validate-changelog.ts - our 100644 99d3cf95c36c9a4c5fa58f5c5e2138fb7c281dec script/validate-changelog.ts -@@ -36,6 +36,7 @@ - const repositoryRoot = Path.dirname(__dirname) - const changelogPath = Path.join(repositoryRoot, 'changelog.json') - -+// eslint-disable-next-line no-sync - const changelog = Fs.readFileSync(changelogPath, 'utf8') - - let changelogObj = null -merged - result 100644 3162be12e327f202d1aab8c198ad93c33ff738c9 tsconfig.json - our 100644 277ed46c185a8c539e2c44a06c4c539a248d2577 tsconfig.json -@@ -9,9 +9,14 @@ - "sourceMap": true, - "jsx": "react", - "strict": true, -+ "noEmit": true, - "outDir": "./out" - }, -- "include": ["app/**/*.ts", "app/**/*.tsx", "app/**/*.d.tsx"], -+ "include": [ -+ "app/**/*.ts", -+ "app/**/*.tsx", -+ "app/**/*.d.tsx" -+ ], - "exclude": [ - "node_modules", - "app/node_modules", -added in remote - their 100644 cea9476153ecf2e440e28d7b84dc334a433fd12d vsts.yml -@@ -0,0 +1,62 @@ -+phases: -+- phase: Windows -+ queue: Hosted VS2017 -+ steps: -+ - task: NodeTool@0 -+ inputs: -+ versionSpec: "8.11.1" -+ - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 -+ inputs: -+ versionSpec: "1.5.1" -+ - script: | -+ yarn install --force -+ name: Install -+ - script: | -+ yarn lint && yarn build:prod -+ name: Build -+ - script: | -+ yarn test:setup && yarn test -+ name: Test -+ -+- phase: Linux -+ queue: Hosted Linux Preview -+ steps: -+ - script: | -+ apt-get update -+ apt-get install -y --no-install-recommends libsecret-1-dev xvfb fakeroot dpkg rpm xz-utils xorriso zsync libxss1 libgconf2-4 -+ - task: NodeTool@0 -+ inputs: -+ versionSpec: "8.11.1" -+ - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 -+ inputs: -+ versionSpec: "1.5.1" -+ - script: | -+ yarn install --force -+ name: Install -+ - script: | -+ yarn lint && yarn build:prod -+ name: Build -+ - script: | -+ export DISPLAY=':99.0' -+ Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & -+ yarn test:setup && yarn test -+ name: Test -+ -+- phase: macOS -+ queue: Hosted macOS Preview -+ steps: -+ - task: NodeTool@0 -+ inputs: -+ versionSpec: "8.11.1" -+ - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 -+ inputs: -+ versionSpec: "1.5.1" -+ - script: | -+ yarn install --force -+ name: Install -+ - script: | -+ yarn lint && yarn build:prod -+ name: Build -+ - script: | -+ yarn test:setup && yarn test -+ name: Test -merged - result 100644 518ebd962c3152899bf04a5ae668a826085179c5 yarn.lock - our 100644 b62b02a9d580648aaf19776890ce70c967670310 yarn.lock -@@ -22,6 +22,13 @@ - "7zip-bin-mac" "~1.0.1" - "7zip-bin-win" "~2.2.0" - -+"@types/body-parser@*": -+ version "1.16.8" -+ resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.16.8.tgz#687ec34140624a3bec2b1a8ea9268478ae8f3be3" -+ dependencies: -+ "@types/express" "*" -+ "@types/node" "*" -+ - "@types/byline@^4.2.31": - version "4.2.31" - resolved "https://registry.yarnpkg.com/@types/byline/-/byline-4.2.31.tgz#0e61fcb9c03e047d21c4496554c7116297ab60cd" -@@ -46,10 +53,26 @@ - version "2.2.3" - resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.3.tgz#3f0ff6873da793870e20a260cada55982f38a9e5" - -+"@types/clean-css@*": -+ version "3.4.30" -+ resolved "https://registry.yarnpkg.com/@types/clean-css/-/clean-css-3.4.30.tgz#0052c136f5248002428e3638b37de4a39818641d" -+ -+"@types/clean-webpack-plugin@^0.1.2": -+ version "0.1.2" -+ resolved "https://registry.yarnpkg.com/@types/clean-webpack-plugin/-/clean-webpack-plugin-0.1.2.tgz#f3c9d97dd397a9db86ba6b9b245ca0eedf88f3b2" -+ dependencies: -+ "@types/webpack" "*" -+ - "@types/codemirror@0.0.55": - version "0.0.55" - resolved "https://registry.yarnpkg.com/@types/codemirror/-/codemirror-0.0.55.tgz#f4292b7a5f33b2aab509501c3db7e45d19a7c057" - -+"@types/connect@*": -+ version "3.4.31" -+ resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.31.tgz#1f92d6b117ecc05076c49ecd024f7976e528bad9" -+ dependencies: -+ "@types/node" "*" -+ - "@types/electron-packager@^10.1.0": - version "10.1.0" - resolved "https://registry.yarnpkg.com/@types/electron-packager/-/electron-packager-10.1.0.tgz#8d61ef76a2676936c59d14392a9c0c1853405953" -@@ -64,13 +87,39 @@ - version "1.2.32" - resolved "https://registry.yarnpkg.com/@types/event-kit/-/event-kit-1.2.32.tgz#068cbdc69e8c969afae8c9f6e3a51ea4b1b5522e" - -+"@types/express-serve-static-core@*": -+ version "4.11.0" -+ resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.11.0.tgz#aaaf472777191c3e56ec7aa160034c6b55ebdd59" -+ dependencies: -+ "@types/node" "*" -+ -+"@types/express@*", "@types/express@^4.11.0": -+ version "4.11.0" -+ resolved "https://registry.yarnpkg.com/@types/express/-/express-4.11.0.tgz#234d65280af917cb290634b7a8d6bcac24aecbad" -+ dependencies: -+ "@types/body-parser" "*" -+ "@types/express-serve-static-core" "*" -+ "@types/serve-static" "*" -+ -+"@types/extract-text-webpack-plugin@^3.0.3": -+ version "3.0.3" -+ resolved "https://registry.yarnpkg.com/@types/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.3.tgz#b4ef831c7ea7bc0585ccabc61e8b0d6cd69fccc3" -+ dependencies: -+ "@types/webpack" "*" -+ - "@types/file-url@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/file-url/-/file-url-2.0.0.tgz#23d00a219b5064d903d4baa0cf7558692ea0eeb6" - --"@types/fs-extra@2.1.0": -- version "2.1.0" -- resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-2.1.0.tgz#8b350239c0455d92b8d3c626edac193860ff395f" -+"@types/form-data@*": -+ version "2.2.1" -+ resolved "https://registry.yarnpkg.com/@types/form-data/-/form-data-2.2.1.tgz#ee2b3b8eaa11c0938289953606b745b738c54b1e" -+ dependencies: -+ "@types/node" "*" -+ -+"@types/fs-extra@^5.0.2": -+ version "5.0.2" -+ resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-5.0.2.tgz#235a7e2b56452cc0a6a4809b53e1d1eaffff9c96" - dependencies: - "@types/node" "*" - -@@ -78,10 +127,49 @@ - version "0.0.1" - resolved "https://registry.yarnpkg.com/@types/fuzzaldrin-plus/-/fuzzaldrin-plus-0.0.1.tgz#bfe5e25bc5b4066848171baf7a8aaf30e267d30a" - -+"@types/html-minifier@*": -+ version "1.1.30" -+ resolved "https://registry.yarnpkg.com/@types/html-minifier/-/html-minifier-1.1.30.tgz#3b3817c27df23922f7b5aa87eff45b3ab934aec9" -+ dependencies: -+ "@types/clean-css" "*" -+ "@types/relateurl" "*" -+ "@types/uglify-js" "*" -+ -+"@types/html-webpack-plugin@^2.30.3": -+ version "2.30.3" -+ resolved "https://registry.yarnpkg.com/@types/html-webpack-plugin/-/html-webpack-plugin-2.30.3.tgz#848baba8e35010c6ef6d36b04174820b9d884583" -+ dependencies: -+ "@types/html-minifier" "*" -+ "@types/webpack" "*" -+ - "@types/keytar@^4.0.0": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/keytar/-/keytar-4.0.1.tgz#e2cf6405dc33861424e59b67516c66d2cf7bc21b" - -+"@types/legal-eagle@^0.15.0": -+ version "0.15.0" -+ resolved "https://registry.yarnpkg.com/@types/legal-eagle/-/legal-eagle-0.15.0.tgz#3a3cf08edca425ffaf9518304c4f1efddea36e42" -+ -+"@types/loglevel@*": -+ version "1.5.3" -+ resolved "https://registry.yarnpkg.com/@types/loglevel/-/loglevel-1.5.3.tgz#adfce55383edc5998a2170ad581b3e23d6adb5b8" -+ -+"@types/memory-fs@*": -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/@types/memory-fs/-/memory-fs-0.3.0.tgz#847596a94f9a9688a2e342f4017fcc0050e8e2da" -+ dependencies: -+ "@types/node" "*" -+ -+"@types/mime@*": -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.0.tgz#5a7306e367c539b9f6543499de8dd519fac37a8b" -+ -+"@types/mini-css-extract-plugin@^0.2.0": -+ version "0.2.0" -+ resolved "https://registry.yarnpkg.com/@types/mini-css-extract-plugin/-/mini-css-extract-plugin-0.2.0.tgz#afb037dbbd76f6c13803927c2751d194188b5d47" -+ dependencies: -+ "@types/webpack" "*" -+ - "@types/mocha@^2.2.48": - version "2.2.48" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.48.tgz#3523b126a0b049482e1c3c11877460f76622ffab" -@@ -94,21 +182,21 @@ - version "8.0.47" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.47.tgz#968e596f91acd59069054558a00708c445ca30c2" - --"@types/node@^7.0.18": -- version "7.0.46" -- resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.46.tgz#c3dedd25558c676b3d6303e51799abb9c3f8f314" -- - "@types/node@^8.0.24": -- version "8.5.10" -- resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.10.tgz#49bd3637125dea5f55d7d1e8f51efd6cb835e1f7" -+ version "8.10.1" -+ resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.1.tgz#aac98b810c50568054486f2bb8c486d824713be8" -+ -+"@types/node@^8.10.4": -+ version "8.10.4" -+ resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.4.tgz#d3ca40ee884c853e2b786ee73096726ec59a5b31" - - "@types/prop-types@*": - version "15.5.2" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.5.2.tgz#3c6b8dceb2906cc87fe4358e809f9d20c8d59be1" - --"@types/react-dom@^16.0.4": -- version "16.0.4" -- resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.0.4.tgz#2e8fd45f5443780ed49bf2cdd9809e6091177a7d" -+"@types/react-dom@^16.0.5": -+ version "16.0.6" -+ resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.0.6.tgz#f1a65a4e7be8ed5d123f8b3b9eacc913e35a1a3c" - dependencies: - "@types/node" "*" - "@types/react" "*" -@@ -120,24 +208,52 @@ - "@types/react" "*" - - "@types/react-virtualized@^9.7.12": -- version "9.7.12" -- resolved "https://registry.yarnpkg.com/@types/react-virtualized/-/react-virtualized-9.7.12.tgz#3dc212c0f94c9e9eab2fe7cb5a23db18ba2d1ee1" -+ version "9.7.14" -+ resolved "https://registry.yarnpkg.com/@types/react-virtualized/-/react-virtualized-9.7.14.tgz#4ce4b1f4a8d242edf317c7f798852788150a0040" - dependencies: - "@types/prop-types" "*" - "@types/react" "*" - --"@types/react@*", "@types/react@^16.0.40": -- version "16.0.40" -- resolved "https://registry.yarnpkg.com/@types/react/-/react-16.0.40.tgz#caabc2296886f40b67f6fc80f0f3464476461df9" -+"@types/react@*", "@types/react@^16.3.16": -+ version "16.3.16" -+ resolved "https://registry.yarnpkg.com/@types/react/-/react-16.3.16.tgz#78fc44a90b45701f50c8a7008f733680ba51fc86" -+ dependencies: -+ csstype "^2.2.0" -+ -+"@types/relateurl@*": -+ version "0.2.28" -+ resolved "https://registry.yarnpkg.com/@types/relateurl/-/relateurl-0.2.28.tgz#6bda7db8653fa62643f5ee69e9f69c11a392e3a6" -+ -+"@types/request@^2.0.9": -+ version "2.0.9" -+ resolved "https://registry.yarnpkg.com/@types/request/-/request-2.0.9.tgz#125b8a60d8a439e8d87e6d1335c61cccdc18343a" -+ dependencies: -+ "@types/form-data" "*" -+ "@types/node" "*" - - "@types/semver@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45" - -+"@types/serve-static@*": -+ version "1.13.1" -+ resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.1.tgz#1d2801fa635d274cd97d4ec07e26b21b44127492" -+ dependencies: -+ "@types/express-serve-static-core" "*" -+ "@types/mime" "*" -+ -+"@types/source-map@*": -+ version "0.5.1" -+ resolved "https://registry.yarnpkg.com/@types/source-map/-/source-map-0.5.1.tgz#7e74db5d06ab373a712356eebfaea2fad0ea2367" -+ - "@types/strip-ansi@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/strip-ansi/-/strip-ansi-3.0.0.tgz#9b63d453a6b54aa849182207711a08be8eea48ae" - -+"@types/tapable@*": -+ version "1.0.2" -+ resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.2.tgz#e13182e1b69871a422d7863e11a4a6f5b814a4bd" -+ - "@types/temp@^0.8.29": - version "0.8.31" - resolved "https://registry.yarnpkg.com/@types/temp/-/temp-0.8.31.tgz#8518b6fb4c7d7cf106c78e5d88d3cff88d508f97" -@@ -156,6 +272,12 @@ - version "0.7.32" - resolved "https://registry.yarnpkg.com/@types/ua-parser-js/-/ua-parser-js-0.7.32.tgz#8827d451d6702307248073b5d98aa9293d02b5e5" - -+"@types/uglify-js@*": -+ version "2.6.29" -+ resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-2.6.29.tgz#521347f69e20201d218f5991ae66e10878afcf1a" -+ dependencies: -+ "@types/source-map" "*" -+ - "@types/untildify@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/untildify/-/untildify-3.0.0.tgz#cd3e6624e46ccf292d3823fb48fa90dda0deaec0" -@@ -166,6 +288,43 @@ - dependencies: - "@types/node" "*" - -+"@types/webpack-bundle-analyzer@^2.9.2": -+ version "2.9.2" -+ resolved "https://registry.yarnpkg.com/@types/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.9.2.tgz#a3f9f4dd8bc3025550001a1704cfd31125773f40" -+ dependencies: -+ "@types/webpack" "*" -+ -+"@types/webpack-dev-middleware@^2.0.1": -+ version "2.0.1" -+ resolved "https://registry.yarnpkg.com/@types/webpack-dev-middleware/-/webpack-dev-middleware-2.0.1.tgz#516d953602d9e8ac72ca1196969969d580d4b0a6" -+ dependencies: -+ "@types/connect" "*" -+ "@types/loglevel" "*" -+ "@types/memory-fs" "*" -+ "@types/webpack" "*" -+ -+"@types/webpack-hot-middleware@^2.16.3": -+ version "2.16.3" -+ resolved "https://registry.yarnpkg.com/@types/webpack-hot-middleware/-/webpack-hot-middleware-2.16.3.tgz#c262ab826afae16030c15049e3c997849f9c8461" -+ dependencies: -+ "@types/connect" "*" -+ "@types/webpack" "*" -+ -+"@types/webpack-merge@^4.1.3": -+ version "4.1.3" -+ resolved "https://registry.yarnpkg.com/@types/webpack-merge/-/webpack-merge-4.1.3.tgz#e6af0f2a0f20a86ac83d7da84a2e454063121ad4" -+ dependencies: -+ "@types/webpack" "*" -+ -+"@types/webpack@*", "@types/webpack@^4.4.0": -+ version "4.4.0" -+ resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.4.0.tgz#c0551b772be241d786c0548812dd75a932f8efb4" -+ dependencies: -+ "@types/node" "*" -+ "@types/tapable" "*" -+ "@types/uglify-js" "*" -+ source-map "^0.6.0" -+ - "@types/winston@^2.2.0": - version "2.3.7" - resolved "https://registry.yarnpkg.com/@types/winston/-/winston-2.3.7.tgz#2ea18b2dc772d459b6af0f587447704df31afec2" -@@ -178,6 +337,122 @@ - dependencies: - "@types/node" "*" - -+"@webassemblyjs/ast@1.4.3": -+ version "1.4.3" -+ resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.4.3.tgz#3b3f6fced944d8660273347533e6d4d315b5934a" -+ dependencies: -+ "@webassemblyjs/helper-wasm-bytecode" "1.4.3" -+ "@webassemblyjs/wast-parser" "1.4.3" -+ debug "^3.1.0" -+ webassemblyjs "1.4.3" -+ -+"@webassemblyjs/floating-point-hex-parser@1.4.3": -+ version "1.4.3" -+ resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.4.3.tgz#f5aee4c376a717c74264d7bacada981e7e44faad" -+ -+"@webassemblyjs/helper-buffer@1.4.3": -+ version "1.4.3" -+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.4.3.tgz#0434b55958519bf503697d3824857b1dea80b729" -+ dependencies: -+ debug "^3.1.0" -+ -+"@webassemblyjs/helper-code-frame@1.4.3": -+ version "1.4.3" -+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.4.3.tgz#f1349ca3e01a8e29ee2098c770773ef97af43641" -+ dependencies: -+ "@webassemblyjs/wast-printer" "1.4.3" -+ -+"@webassemblyjs/helper-fsm@1.4.3": -+ version "1.4.3" -+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.4.3.tgz#65a921db48fb43e868f17b27497870bdcae22b79" -+ -+"@webassemblyjs/helper-wasm-bytecode@1.4.3": -+ version "1.4.3" -+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.4.3.tgz#0e5b4b5418e33f8a26e940b7809862828c3721a5" -+ -+"@webassemblyjs/helper-wasm-section@1.4.3": -+ version "1.4.3" -+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.4.3.tgz#9ceedd53a3f152c3412e072887ade668d0b1acbf" -+ dependencies: -+ "@webassemblyjs/ast" "1.4.3" -+ "@webassemblyjs/helper-buffer" "1.4.3" -+ "@webassemblyjs/helper-wasm-bytecode" "1.4.3" -+ "@webassemblyjs/wasm-gen" "1.4.3" -+ debug "^3.1.0" -+ -+"@webassemblyjs/leb128@1.4.3": -+ version "1.4.3" -+ resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.4.3.tgz#5a5e5949dbb5adfe3ae95664d0439927ac557fb8" -+ dependencies: -+ leb "^0.3.0" -+ -+"@webassemblyjs/validation@1.4.3": -+ version "1.4.3" -+ resolved "https://registry.yarnpkg.com/@webassemblyjs/validation/-/validation-1.4.3.tgz#9e66c9b3079d7bbcf2070c1bf52a54af2a09aac9" -+ dependencies: -+ "@webassemblyjs/ast" "1.4.3" -+ -+"@webassemblyjs/wasm-edit@1.4.3": -+ version "1.4.3" -+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.4.3.tgz#87febd565e0ffb5ae25f6495bb3958d17aa0a779" -+ dependencies: -+ "@webassemblyjs/ast" "1.4.3" -+ "@webassemblyjs/helper-buffer" "1.4.3" -+ "@webassemblyjs/helper-wasm-bytecode" "1.4.3" -+ "@webassemblyjs/helper-wasm-section" "1.4.3" -+ "@webassemblyjs/wasm-gen" "1.4.3" -+ "@webassemblyjs/wasm-opt" "1.4.3" -+ "@webassemblyjs/wasm-parser" "1.4.3" -+ "@webassemblyjs/wast-printer" "1.4.3" -+ debug "^3.1.0" -+ -+"@webassemblyjs/wasm-gen@1.4.3": -+ version "1.4.3" -+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.4.3.tgz#8553164d0154a6be8f74d653d7ab355f73240aa4" -+ dependencies: -+ "@webassemblyjs/ast" "1.4.3" -+ "@webassemblyjs/helper-wasm-bytecode" "1.4.3" -+ "@webassemblyjs/leb128" "1.4.3" -+ -+"@webassemblyjs/wasm-opt@1.4.3": -+ version "1.4.3" -+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.4.3.tgz#26c7a23bfb136aa405b1d3410e63408ec60894b8" -+ dependencies: -+ "@webassemblyjs/ast" "1.4.3" -+ "@webassemblyjs/helper-buffer" "1.4.3" -+ "@webassemblyjs/wasm-gen" "1.4.3" -+ "@webassemblyjs/wasm-parser" "1.4.3" -+ debug "^3.1.0" -+ -+"@webassemblyjs/wasm-parser@1.4.3": -+ version "1.4.3" -+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.4.3.tgz#7ddd3e408f8542647ed612019cfb780830993698" -+ dependencies: -+ "@webassemblyjs/ast" "1.4.3" -+ "@webassemblyjs/helper-wasm-bytecode" "1.4.3" -+ "@webassemblyjs/leb128" "1.4.3" -+ "@webassemblyjs/wasm-parser" "1.4.3" -+ webassemblyjs "1.4.3" -+ -+"@webassemblyjs/wast-parser@1.4.3": -+ version "1.4.3" -+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.4.3.tgz#3250402e2c5ed53dbe2233c9de1fe1f9f0d51745" -+ dependencies: -+ "@webassemblyjs/ast" "1.4.3" -+ "@webassemblyjs/floating-point-hex-parser" "1.4.3" -+ "@webassemblyjs/helper-code-frame" "1.4.3" -+ "@webassemblyjs/helper-fsm" "1.4.3" -+ long "^3.2.0" -+ webassemblyjs "1.4.3" -+ -+"@webassemblyjs/wast-printer@1.4.3": -+ version "1.4.3" -+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.4.3.tgz#3d59aa8d0252d6814a3ef4e6d2a34c9ded3904e0" -+ dependencies: -+ "@webassemblyjs/ast" "1.4.3" -+ "@webassemblyjs/wast-parser" "1.4.3" -+ long "^3.2.0" -+ - abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" -@@ -189,11 +464,18 @@ - mime-types "~2.1.16" - negotiator "0.6.1" - --acorn-dynamic-import@^2.0.0: -- version "2.0.2" -- resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4" -+accepts@~1.3.5: -+ version "1.3.5" -+ resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" -+ dependencies: -+ mime-types "~2.1.18" -+ negotiator "0.6.1" -+ -+acorn-dynamic-import@^3.0.0: -+ version "3.0.0" -+ resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" - dependencies: -- acorn "^4.0.3" -+ acorn "^5.0.0" - - acorn-jsx@^3.0.0: - version "3.0.1" -@@ -205,23 +487,15 @@ - version "3.3.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" - --acorn@^4.0.3: -- version "4.0.13" -- resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" -- - acorn@^5.0.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7" - --acorn@^5.5.0: -+acorn@^5.3.0, acorn@^5.5.0: - version "5.5.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" - --ajv-keywords@^1.1.1: -- version "1.5.1" -- resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" -- --ajv-keywords@^2.0.0, ajv-keywords@^2.1.0: -+ajv-keywords@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" - -@@ -229,14 +503,14 @@ - version "3.1.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.1.0.tgz#ac2b27939c543e95d2c06e7f7f5c27be4aa543be" - --ajv@^4.7.0, ajv@^4.9.1, ajv@^4.9.2: -+ajv@^4.9.1, ajv@^4.9.2: - version "4.11.8" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" - dependencies: - co "^4.6.0" - json-stable-stringify "^1.0.1" - --ajv@^5.0.0, ajv@^5.1.0, ajv@^5.1.5, ajv@^5.2.3: -+ajv@^5.1.0, ajv@^5.2.3: - version "5.3.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.3.0.tgz#4414ff74a50879c208ee5fdc826e32c303549eda" - dependencies: -@@ -254,6 +528,15 @@ - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" - -+ajv@^6.1.0: -+ version "6.5.0" -+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.0.tgz#4c8affdf80887d8f132c9c52ab8a2dc4d0b7b24c" -+ dependencies: -+ fast-deep-equal "^2.0.1" -+ fast-json-stable-stringify "^2.0.0" -+ json-schema-traverse "^0.3.0" -+ uri-js "^4.2.1" -+ - ajv@^6.1.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.2.0.tgz#afac295bbaa0152449e522742e4547c1ae9328d2" -@@ -271,14 +554,6 @@ - json-schema-traverse "^0.3.0" - uri-js "^3.0.2" - --align-text@^0.1.1, align-text@^0.1.3: -- version "0.1.4" -- resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" -- dependencies: -- kind-of "^3.0.2" -- longest "^1.0.1" -- repeat-string "^1.5.2" -- - alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" -@@ -323,29 +598,59 @@ - dependencies: - color-convert "^1.9.0" - -+ansi-styles@^3.2.1: -+ version "3.2.1" -+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" -+ dependencies: -+ color-convert "^1.9.0" -+ - any-promise@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" - --anymatch@^1.3.0: -- version "1.3.2" -- resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" -+anymatch@^2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - dependencies: -- micromatch "^2.1.5" -- normalize-path "^2.0.0" -+ micromatch "^3.1.4" -+ normalize-path "^2.1.1" - - app-builder-bin-linux@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/app-builder-bin-linux/-/app-builder-bin-linux-1.5.0.tgz#c22df1ab9ee7fb0270ec27a3c8a6993966ea4220" - -+app-builder-bin-linux@1.6.0: -+ version "1.6.0" -+ resolved "https://registry.yarnpkg.com/app-builder-bin-linux/-/app-builder-bin-linux-1.6.0.tgz#d7731d7988b8a740e74d591cbd565f168a266111" -+ -+app-builder-bin-linux@1.8.4: -+ version "1.8.4" -+ resolved "https://registry.yarnpkg.com/app-builder-bin-linux/-/app-builder-bin-linux-1.8.4.tgz#9fa4f4f6af21f147cdedc69279940134c77d297f" -+ - app-builder-bin-mac@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/app-builder-bin-mac/-/app-builder-bin-mac-1.5.0.tgz#40821128a1f20e0559f1fca71a59ecab81bb59b5" - -+app-builder-bin-mac@1.6.0: -+ version "1.6.0" -+ resolved "https://registry.yarnpkg.com/app-builder-bin-mac/-/app-builder-bin-mac-1.6.0.tgz#c976da70796d67aeb7134a57899636f2581d1c67" -+ -+app-builder-bin-mac@1.8.4: -+ version "1.8.4" -+ resolved "https://registry.yarnpkg.com/app-builder-bin-mac/-/app-builder-bin-mac-1.8.4.tgz#abd35353167b037a15353fe44c84b0b17045d12f" -+ - app-builder-bin-win@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/app-builder-bin-win/-/app-builder-bin-win-1.5.0.tgz#0a12437d825ac89fc2357e8be0ba855f54c083e9" - -+app-builder-bin-win@1.6.0: -+ version "1.6.0" -+ resolved "https://registry.yarnpkg.com/app-builder-bin-win/-/app-builder-bin-win-1.6.0.tgz#528ef96430d519c270b4de260bea0ddc70df1733" -+ -+app-builder-bin-win@1.8.4: -+ version "1.8.4" -+ resolved "https://registry.yarnpkg.com/app-builder-bin-win/-/app-builder-bin-win-1.8.4.tgz#ba5f7a7d8ae48d32c400691b3c45f6f746c27748" -+ - app-builder-bin@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-1.5.0.tgz#dc768af9704876959c68af5456ef31f67a4663fe" -@@ -354,7 +659,23 @@ - app-builder-bin-mac "1.5.0" - app-builder-bin-win "1.5.0" - --aproba@^1.0.3: -+app-builder-bin@1.6.0: -+ version "1.6.0" -+ resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-1.6.0.tgz#c0e88a488d4c23c2e7fe0bbfb70c1d61165be206" -+ optionalDependencies: -+ app-builder-bin-linux "1.6.0" -+ app-builder-bin-mac "1.6.0" -+ app-builder-bin-win "1.6.0" -+ -+app-builder-bin@1.8.4: -+ version "1.8.4" -+ resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-1.8.4.tgz#ca8fd02209c2e0681de97fdb4c559d93381cc812" -+ optionalDependencies: -+ app-builder-bin-linux "1.8.4" -+ app-builder-bin-mac "1.8.4" -+ app-builder-bin-win "1.8.4" -+ -+aproba@^1.0.3, aproba@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - -@@ -396,17 +717,11 @@ - dependencies: - sprintf-js "~1.0.2" - --arr-diff@^2.0.0: -- version "2.0.0" -- resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" -- dependencies: -- arr-flatten "^1.0.1" -- - arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - --arr-flatten@^1.0.1, arr-flatten@^1.1.0: -+arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - -@@ -439,10 +754,6 @@ - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - --array-unique@^0.2.1: -- version "0.2.1" -- resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" -- - array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" -@@ -510,6 +821,10 @@ - version "1.0.2" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" - -+assign-symbols@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" -+ - async-each@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" -@@ -522,7 +837,11 @@ - version "0.1.3" - resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" - --async@^2.0.0, async@^2.1.2, async@^2.1.5, async@^2.4.1: -+async-limiter@~1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" -+ -+async@^2.0.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d" - dependencies: -@@ -555,18 +874,23 @@ - postcss "^5.2.16" - postcss-value-parser "^3.2.3" - --awesome-typescript-loader@^3.4.0: -- version "3.4.0" -- resolved "https://registry.yarnpkg.com/awesome-typescript-loader/-/awesome-typescript-loader-3.4.0.tgz#aed2c83af614d617d11e3ec368ac3befb55d002f" -+awesome-node-loader@^1.1.0: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/awesome-node-loader/-/awesome-node-loader-1.1.0.tgz#95cf054ec2fa233c38f29ce18cc59b0ef0c002db" - dependencies: -- colors "^1.1.2" -- enhanced-resolve "3.3.0" - loader-utils "^1.1.0" -- lodash "^4.17.4" -- micromatch "^3.0.3" -+ -+awesome-typescript-loader@^5.0.0: -+ version "5.0.0" -+ resolved "https://registry.yarnpkg.com/awesome-typescript-loader/-/awesome-typescript-loader-5.0.0.tgz#130c304ae52a60933f15d93f7629003b483fa8b1" -+ dependencies: -+ chalk "^2.3.1" -+ enhanced-resolve "^4.0.0" -+ loader-utils "^1.1.0" -+ lodash "^4.17.5" -+ micromatch "^3.1.9" - mkdirp "^0.5.1" -- object-assign "^4.1.1" -- source-map-support "^0.4.15" -+ source-map-support "^0.5.3" - - aws-sdk@^2.23.0: - version "2.142.0" -@@ -595,7 +919,7 @@ - version "1.6.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" - --babel-code-frame@^6.11.0, babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: -+babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" - dependencies: -@@ -603,7 +927,7 @@ - esutils "^2.0.2" - js-tokens "^3.0.2" - --babel-core@^6.22.1, babel-core@^6.24.1, babel-core@^6.26.0: -+babel-core@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" - dependencies: -@@ -627,6 +951,30 @@ - slash "^1.0.0" - source-map "^0.5.6" - -+babel-core@^6.26.3: -+ version "6.26.3" -+ resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" -+ dependencies: -+ babel-code-frame "^6.26.0" -+ babel-generator "^6.26.0" -+ babel-helpers "^6.24.1" -+ babel-messages "^6.23.0" -+ babel-register "^6.26.0" -+ babel-runtime "^6.26.0" -+ babel-template "^6.26.0" -+ babel-traverse "^6.26.0" -+ babel-types "^6.26.0" -+ babylon "^6.18.0" -+ convert-source-map "^1.5.1" -+ debug "^2.6.9" -+ json5 "^0.5.1" -+ lodash "^4.17.4" -+ minimatch "^3.0.4" -+ path-is-absolute "^1.0.1" -+ private "^0.1.8" -+ slash "^1.0.0" -+ source-map "^0.5.7" -+ - babel-generator@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" -@@ -640,33 +988,33 @@ - source-map "^0.5.6" - trim-right "^1.0.1" - --babel-helper-evaluate-path@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.2.0.tgz#0bb2eb01996c0cef53c5e8405e999fe4a0244c08" -+babel-helper-evaluate-path@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.3.0.tgz#2439545e0b6eae5b7f49b790acbebd6b9a73df20" - --babel-helper-flip-expressions@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.2.0.tgz#160d2090a3d9f9c64a750905321a0bc218f884ec" -+babel-helper-flip-expressions@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.3.0.tgz#f5b6394bd5219b43cf8f7b201535ed540c6e7fa2" - - babel-helper-is-nodes-equiv@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz#34e9b300b1479ddd98ec77ea0bbe9342dfe39684" - --babel-helper-is-void-0@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-helper-is-void-0/-/babel-helper-is-void-0-0.2.0.tgz#6ed0ada8a9b1c5b6e88af6b47c1b3b5c080860eb" -+babel-helper-is-void-0@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-helper-is-void-0/-/babel-helper-is-void-0-0.3.0.tgz#95570d20bd27b2206f68083ae9980ee7003d8fe7" - --babel-helper-mark-eval-scopes@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.2.0.tgz#7648aaf2ec92aae9b09a20ad91e8df5e1fcc94b2" -+babel-helper-mark-eval-scopes@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.3.0.tgz#b4731314fdd7a89091271a5213b4e12d236e29e8" - --babel-helper-remove-or-void@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.2.0.tgz#8e46ad5b30560d57d7510b3fd93f332ee7c67386" -+babel-helper-remove-or-void@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.3.0.tgz#f43c86147c8fcc395a9528cbb31e7ff49d7e16e3" - --babel-helper-to-multiple-sequence-expressions@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.2.0.tgz#d1a419634c6cb301f27858c659167cfee0a9d318" -+babel-helper-to-multiple-sequence-expressions@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.3.0.tgz#8da2275ccc26995566118f7213abfd9af7214427" - - babel-helpers@^6.24.1: - version "6.24.1" -@@ -681,156 +1029,157 @@ - dependencies: - babel-runtime "^6.22.0" - --babel-minify@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-minify/-/babel-minify-0.2.0.tgz#36d381fee4002d7949dd5d796e74800336057d67" -+babel-minify-webpack-plugin@^0.3.1: -+ version "0.3.1" -+ resolved "https://registry.yarnpkg.com/babel-minify-webpack-plugin/-/babel-minify-webpack-plugin-0.3.1.tgz#292aa240af190e2dcadf4f684d6d84d179b6d5a4" - dependencies: -- babel-core "^6.24.1" -- babel-preset-minify "^0.2.0" -- fs-readdir-recursive "^1.0.0" -- mkdirp "^0.5.1" -- util.promisify "^1.0.0" -- yargs-parser "^5.0.0" -+ babel-core "^6.26.0" -+ babel-preset-minify "^0.3.0" -+ webpack-sources "^1.0.1" - --babel-plugin-minify-builtins@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.2.0.tgz#317f824b0907210b6348671bb040ca072e2e0c82" -+babel-plugin-minify-builtins@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.3.0.tgz#4740117a6a784063aaf8f092989cf9e4bd484860" - dependencies: -- babel-helper-evaluate-path "^0.2.0" -+ babel-helper-evaluate-path "^0.3.0" - --babel-plugin-minify-constant-folding@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.2.0.tgz#8c70b528b2eb7c13e94d95c8789077d4cdbc3970" -+babel-plugin-minify-constant-folding@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.3.0.tgz#687e40336bd4ddd921e0e197f0006235ac184bb9" - dependencies: -- babel-helper-evaluate-path "^0.2.0" -+ babel-helper-evaluate-path "^0.3.0" - --babel-plugin-minify-dead-code-elimination@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.2.0.tgz#e8025ee10a1e5e4f202633a6928ce892c33747e3" -+babel-plugin-minify-dead-code-elimination@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.3.0.tgz#a323f686c404b824186ba5583cf7996cac81719e" - dependencies: -- babel-helper-evaluate-path "^0.2.0" -- babel-helper-mark-eval-scopes "^0.2.0" -- babel-helper-remove-or-void "^0.2.0" -+ babel-helper-evaluate-path "^0.3.0" -+ babel-helper-mark-eval-scopes "^0.3.0" -+ babel-helper-remove-or-void "^0.3.0" - lodash.some "^4.6.0" - --babel-plugin-minify-flip-comparisons@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.2.0.tgz#0c9c8e93155c8f09dedad8118b634c259f709ef5" -+babel-plugin-minify-flip-comparisons@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.3.0.tgz#6627893a409c9f30ef7f2c89e0c6eea7ee97ddc4" - dependencies: -- babel-helper-is-void-0 "^0.2.0" -+ babel-helper-is-void-0 "^0.3.0" - --babel-plugin-minify-guarded-expressions@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.2.0.tgz#8a8c950040fce3e258a12e6eb21eab94ad7235ab" -+babel-plugin-minify-guarded-expressions@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.3.0.tgz#2552d96189ef45d9a463f1a6b5e4fa110703ac8d" - dependencies: -- babel-helper-flip-expressions "^0.2.0" -+ babel-helper-flip-expressions "^0.3.0" - --babel-plugin-minify-infinity@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.2.0.tgz#30960c615ddbc657c045bb00a1d8eb4af257cf03" -+babel-plugin-minify-infinity@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.3.0.tgz#c5ec0edd433517cf31b3af17077c202beb48bbe7" - --babel-plugin-minify-mangle-names@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.2.0.tgz#719892297ff0106a6ec1a4b0fc062f1f8b6a8529" -+babel-plugin-minify-mangle-names@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.3.0.tgz#f28561bad0dd2f0380816816bb946e219b3b6135" - dependencies: -- babel-helper-mark-eval-scopes "^0.2.0" -+ babel-helper-mark-eval-scopes "^0.3.0" - --babel-plugin-minify-numeric-literals@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.2.0.tgz#5746e851700167a380c05e93f289a7070459a0d1" -+babel-plugin-minify-numeric-literals@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.3.0.tgz#b57734a612e8a592005407323c321119f27d4b40" - --babel-plugin-minify-replace@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.2.0.tgz#3c1f06bc4e6d3e301eacb763edc1be611efc39b0" -+babel-plugin-minify-replace@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.3.0.tgz#980125bbf7cbb5a637439de9d0b1b030a4693893" - --babel-plugin-minify-simplify@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.2.0.tgz#21ceec4857100c5476d7cef121f351156e5c9bc0" -+babel-plugin-minify-simplify@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.3.0.tgz#14574cc74d21c81d3060fafa041010028189f11b" - dependencies: -- babel-helper-flip-expressions "^0.2.0" -+ babel-helper-flip-expressions "^0.3.0" - babel-helper-is-nodes-equiv "^0.0.1" -- babel-helper-to-multiple-sequence-expressions "^0.2.0" -+ babel-helper-to-multiple-sequence-expressions "^0.3.0" - --babel-plugin-minify-type-constructors@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.2.0.tgz#7f3b6458be0863cfd59e9985bed6d134aa7a2e17" -+babel-plugin-minify-type-constructors@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.3.0.tgz#7f5a86ef322c4746364e3c591b8514eeafea6ad4" - dependencies: -- babel-helper-is-void-0 "^0.2.0" -+ babel-helper-is-void-0 "^0.3.0" - --babel-plugin-transform-inline-consecutive-adds@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.2.0.tgz#15dae78921057f4004f8eafd79e15ddc5f12f426" -+babel-plugin-syntax-dynamic-import@^6.18.0: -+ version "6.18.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" - --babel-plugin-transform-member-expression-literals@^6.8.5: -- version "6.8.5" -- resolved "https://registry.yarnpkg.com/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.8.5.tgz#e06ae305cf48d819822e93a70d79269f04d89eec" -+babel-plugin-transform-inline-consecutive-adds@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.3.0.tgz#f07d93689c0002ed2b2b62969bdd99f734e03f57" -+ -+babel-plugin-transform-member-expression-literals@^6.9.0: -+ version "6.9.4" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.9.4.tgz#37039c9a0c3313a39495faac2ff3a6b5b9d038bf" - --babel-plugin-transform-merge-sibling-variables@^6.8.6: -- version "6.8.6" -- resolved "https://registry.yarnpkg.com/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.8.6.tgz#6d21efa5ee4981f71657fae716f9594bb2622aef" -+babel-plugin-transform-merge-sibling-variables@^6.9.0: -+ version "6.9.4" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.9.4.tgz#85b422fc3377b449c9d1cde44087203532401dae" - --babel-plugin-transform-minify-booleans@^6.8.3: -- version "6.8.3" -- resolved "https://registry.yarnpkg.com/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.8.3.tgz#5906ed776d3718250519abf1bace44b0b613ddf9" -+babel-plugin-transform-minify-booleans@^6.9.0: -+ version "6.9.4" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.9.4.tgz#acbb3e56a3555dd23928e4b582d285162dd2b198" - --babel-plugin-transform-property-literals@^6.8.5: -- version "6.8.5" -- resolved "https://registry.yarnpkg.com/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.8.5.tgz#67ed5930b34805443452c8b9690c7ebe1e206c40" -+babel-plugin-transform-property-literals@^6.9.0: -+ version "6.9.4" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.9.4.tgz#98c1d21e255736573f93ece54459f6ce24985d39" - dependencies: - esutils "^2.0.2" - --babel-plugin-transform-regexp-constructors@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.2.0.tgz#6aa5dd0acc515db4be929bbcec4ed4c946c534a3" -+babel-plugin-transform-regexp-constructors@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.3.0.tgz#9bb2c8dd082271a5cb1b3a441a7c52e8fd07e0f5" - --babel-plugin-transform-remove-console@^6.8.5: -- version "6.8.5" -- resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.8.5.tgz#fde9d2d3d725530b0fadd8d31078402410386810" -+babel-plugin-transform-remove-console@^6.9.0: -+ version "6.9.4" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.9.4.tgz#b980360c067384e24b357a588d807d3c83527780" - --babel-plugin-transform-remove-debugger@^6.8.5: -- version "6.8.5" -- resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.8.5.tgz#809584d412bf918f071fdf41e1fdb15ea89cdcd5" -+babel-plugin-transform-remove-debugger@^6.9.0: -+ version "6.9.4" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.9.4.tgz#42b727631c97978e1eb2d199a7aec84a18339ef2" - --babel-plugin-transform-remove-undefined@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.2.0.tgz#94f052062054c707e8d094acefe79416b63452b1" -+babel-plugin-transform-remove-undefined@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.3.0.tgz#03f5f0071867781e9beabbc7b77bf8095fd3f3ec" - dependencies: -- babel-helper-evaluate-path "^0.2.0" -+ babel-helper-evaluate-path "^0.3.0" - --babel-plugin-transform-simplify-comparison-operators@^6.8.5: -- version "6.8.5" -- resolved "https://registry.yarnpkg.com/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.8.5.tgz#a838786baf40cc33a93b95ae09e05591227e43bf" -+babel-plugin-transform-simplify-comparison-operators@^6.9.0: -+ version "6.9.4" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.9.4.tgz#f62afe096cab0e1f68a2d753fdf283888471ceb9" - --babel-plugin-transform-undefined-to-void@^6.8.3: -- version "6.8.3" -- resolved "https://registry.yarnpkg.com/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.8.3.tgz#fc52707f6ee1ddc71bb91b0d314fbefdeef9beb4" -+babel-plugin-transform-undefined-to-void@^6.9.0: -+ version "6.9.4" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.9.4.tgz#be241ca81404030678b748717322b89d0c8fe280" - --babel-preset-minify@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/babel-preset-minify/-/babel-preset-minify-0.2.0.tgz#006566552d9b83834472273f306c0131062a0acc" -- dependencies: -- babel-plugin-minify-builtins "^0.2.0" -- babel-plugin-minify-constant-folding "^0.2.0" -- babel-plugin-minify-dead-code-elimination "^0.2.0" -- babel-plugin-minify-flip-comparisons "^0.2.0" -- babel-plugin-minify-guarded-expressions "^0.2.0" -- babel-plugin-minify-infinity "^0.2.0" -- babel-plugin-minify-mangle-names "^0.2.0" -- babel-plugin-minify-numeric-literals "^0.2.0" -- babel-plugin-minify-replace "^0.2.0" -- babel-plugin-minify-simplify "^0.2.0" -- babel-plugin-minify-type-constructors "^0.2.0" -- babel-plugin-transform-inline-consecutive-adds "^0.2.0" -- babel-plugin-transform-member-expression-literals "^6.8.5" -- babel-plugin-transform-merge-sibling-variables "^6.8.6" -- babel-plugin-transform-minify-booleans "^6.8.3" -- babel-plugin-transform-property-literals "^6.8.5" -- babel-plugin-transform-regexp-constructors "^0.2.0" -- babel-plugin-transform-remove-console "^6.8.5" -- babel-plugin-transform-remove-debugger "^6.8.5" -- babel-plugin-transform-remove-undefined "^0.2.0" -- babel-plugin-transform-simplify-comparison-operators "^6.8.5" -- babel-plugin-transform-undefined-to-void "^6.8.3" -+babel-preset-minify@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/babel-preset-minify/-/babel-preset-minify-0.3.0.tgz#7db64afa75f16f6e06c0aa5f25195f6f36784d77" -+ dependencies: -+ babel-plugin-minify-builtins "^0.3.0" -+ babel-plugin-minify-constant-folding "^0.3.0" -+ babel-plugin-minify-dead-code-elimination "^0.3.0" -+ babel-plugin-minify-flip-comparisons "^0.3.0" -+ babel-plugin-minify-guarded-expressions "^0.3.0" -+ babel-plugin-minify-infinity "^0.3.0" -+ babel-plugin-minify-mangle-names "^0.3.0" -+ babel-plugin-minify-numeric-literals "^0.3.0" -+ babel-plugin-minify-replace "^0.3.0" -+ babel-plugin-minify-simplify "^0.3.0" -+ babel-plugin-minify-type-constructors "^0.3.0" -+ babel-plugin-transform-inline-consecutive-adds "^0.3.0" -+ babel-plugin-transform-member-expression-literals "^6.9.0" -+ babel-plugin-transform-merge-sibling-variables "^6.9.0" -+ babel-plugin-transform-minify-booleans "^6.9.0" -+ babel-plugin-transform-property-literals "^6.9.0" -+ babel-plugin-transform-regexp-constructors "^0.3.0" -+ babel-plugin-transform-remove-console "^6.9.0" -+ babel-plugin-transform-remove-debugger "^6.9.0" -+ babel-plugin-transform-remove-undefined "^0.3.0" -+ babel-plugin-transform-simplify-comparison-operators "^6.9.0" -+ babel-plugin-transform-undefined-to-void "^6.9.0" - lodash.isplainobject "^4.0.6" - - babel-register@^6.26.0: -@@ -892,15 +1241,6 @@ - lodash "^4.17.4" - to-fast-properties "^1.0.3" - --babel-webpack-plugin@^0.1.1: -- version "0.1.1" -- resolved "https://registry.yarnpkg.com/babel-webpack-plugin/-/babel-webpack-plugin-0.1.1.tgz#ab9f3c427d1574456caa33024f1bdb7b2848460c" -- dependencies: -- babel-core "^6.22.1" -- source-map "^0.5.6" -- webpack "^2.2.0" -- webpack-sources "^0.1.4" -- - babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" -@@ -939,6 +1279,14 @@ - dependencies: - tweetnacl "^0.14.3" - -+bfj-node4@^5.2.0: -+ version "5.3.1" -+ resolved "https://registry.yarnpkg.com/bfj-node4/-/bfj-node4-5.3.1.tgz#e23d8b27057f1d0214fc561142ad9db998f26830" -+ dependencies: -+ bluebird "^3.5.1" -+ check-types "^7.3.0" -+ tryer "^1.0.0" -+ - big.js@^3.1.3: - version "3.2.0" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" -@@ -972,7 +1320,7 @@ - dependencies: - bluebird "^3.5.1" - --bluebird@^3.0.6, bluebird@^3.1.1, bluebird@^3.3.4, bluebird@^3.4.7, bluebird@^3.5.0, bluebird@^3.5.1: -+bluebird@^3.0.6, bluebird@^3.1.1, bluebird@^3.3.4, bluebird@^3.5.0, bluebird@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" - -@@ -1036,14 +1384,6 @@ - balanced-match "^1.0.0" - concat-map "0.0.1" - --braces@^1.8.2: -- version "1.8.5" -- resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" -- dependencies: -- expand-range "^1.8.1" -- preserve "^0.2.0" -- repeat-element "^1.1.2" -- - braces@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.0.tgz#a46941cb5fb492156b3d6a656e06c35364e3e66e" -@@ -1060,6 +1400,21 @@ - split-string "^3.0.2" - to-regex "^3.0.1" - -+braces@^2.3.1: -+ version "2.3.2" -+ resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" -+ dependencies: -+ arr-flatten "^1.1.0" -+ array-unique "^0.3.2" -+ extend-shallow "^2.0.1" -+ fill-range "^4.0.0" -+ isobject "^3.0.1" -+ repeat-element "^1.1.2" -+ snapdragon "^0.8.1" -+ snapdragon-node "^2.0.1" -+ split-string "^3.0.2" -+ to-regex "^3.0.1" -+ - brorand@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" -@@ -1131,6 +1486,10 @@ - version "0.2.13" - resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" - -+buffer-from@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.0.0.tgz#4cb8832d23612589b0406e9e2956c17f06fdf531" -+ - buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" -@@ -1147,7 +1506,7 @@ - version "0.1.1" - resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" - --builder-util-runtime@4.0.5, builder-util-runtime@^4.0.5: -+builder-util-runtime@4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-4.0.5.tgz#5340cf9886b9283ea6e5b20dc09b5e3e461aef62" - dependencies: -@@ -1156,7 +1515,16 @@ - fs-extra-p "^4.5.0" - sax "^1.2.4" - --builder-util@5.6.0, builder-util@^5.6.0: -+builder-util-runtime@^4.0.5, builder-util-runtime@^4.2.0: -+ version "4.2.0" -+ resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-4.2.0.tgz#c56aa18d34390143da031c418c9d3a055fbd3522" -+ dependencies: -+ bluebird-lst "^1.0.5" -+ debug "^3.1.0" -+ fs-extra-p "^4.5.2" -+ sax "^1.2.4" -+ -+builder-util@5.6.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-5.6.0.tgz#c37c5207cd818531bda819ac836b6d51dfbccd4a" - dependencies: -@@ -1175,6 +1543,44 @@ - stat-mode "^0.2.2" - temp-file "^3.1.1" - -+builder-util@5.6.1: -+ version "5.6.1" -+ resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-5.6.1.tgz#ab90845cb8949ea4ac81da0ce87b8ec3424cdbf9" -+ dependencies: -+ "7zip-bin" "~3.1.0" -+ app-builder-bin "1.6.0" -+ bluebird-lst "^1.0.5" -+ builder-util-runtime "^4.0.5" -+ chalk "^2.3.2" -+ debug "^3.1.0" -+ fs-extra-p "^4.5.2" -+ is-ci "^1.1.0" -+ js-yaml "^3.10.0" -+ lazy-val "^1.0.3" -+ semver "^5.5.0" -+ source-map-support "^0.5.3" -+ stat-mode "^0.2.2" -+ temp-file "^3.1.1" -+ -+builder-util@^5.6.0: -+ version "5.7.5" -+ resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-5.7.5.tgz#58f8d2b7a35445c5fb45bff50b39bbed554c9863" -+ dependencies: -+ "7zip-bin" "~3.1.0" -+ app-builder-bin "1.8.4" -+ bluebird-lst "^1.0.5" -+ builder-util-runtime "^4.2.0" -+ chalk "^2.3.2" -+ debug "^3.1.0" -+ fs-extra-p "^4.5.2" -+ is-ci "^1.1.0" -+ js-yaml "^3.11.0" -+ lazy-val "^1.0.3" -+ semver "^5.5.0" -+ source-map-support "^0.5.4" -+ stat-mode "^0.2.2" -+ temp-file "^3.1.1" -+ - builtin-modules@^1.0.0, builtin-modules@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" -@@ -1187,6 +1593,24 @@ - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - -+cacache@^10.0.4: -+ version "10.0.4" -+ resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460" -+ dependencies: -+ bluebird "^3.5.1" -+ chownr "^1.0.1" -+ glob "^7.1.2" -+ graceful-fs "^4.1.11" -+ lru-cache "^4.1.1" -+ mississippi "^2.0.0" -+ mkdirp "^0.5.1" -+ move-concurrently "^1.0.1" -+ promise-inflight "^1.0.1" -+ rimraf "^2.6.2" -+ ssri "^5.2.4" -+ unique-filename "^1.1.0" -+ y18n "^4.0.0" -+ - cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" -@@ -1225,10 +1649,6 @@ - camelcase "^2.0.0" - map-obj "^1.0.0" - --camelcase@^1.0.2: -- version "1.2.1" -- resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" -- - camelcase@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" -@@ -1266,13 +1686,6 @@ - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - --center-align@^0.1.1: -- version "0.1.3" -- resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" -- dependencies: -- align-text "^0.1.3" -- lazy-cache "^1.0.3" -- - chai-as-promised@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" -@@ -1320,24 +1733,55 @@ - escape-string-regexp "^1.0.5" - supports-color "^4.0.0" - -+chalk@^2.3.1: -+ version "2.4.1" -+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" -+ dependencies: -+ ansi-styles "^3.2.1" -+ escape-string-regexp "^1.0.5" -+ supports-color "^5.3.0" -+ -+chalk@^2.3.2: -+ version "2.3.2" -+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65" -+ dependencies: -+ ansi-styles "^3.2.1" -+ escape-string-regexp "^1.0.5" -+ supports-color "^5.3.0" -+ - check-error@^1.0.1, check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - --chokidar@^1.7.0: -- version "1.7.0" -- resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" -+check-types@^7.3.0: -+ version "7.3.0" -+ resolved "https://registry.yarnpkg.com/check-types/-/check-types-7.3.0.tgz#468f571a4435c24248f5fd0cb0e8d87c3c341e7d" -+ -+chokidar@^2.0.2: -+ version "2.0.3" -+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.3.tgz#dcbd4f6cbb2a55b4799ba8a840ac527e5f4b1176" - dependencies: -- anymatch "^1.3.0" -+ anymatch "^2.0.0" - async-each "^1.0.0" -- glob-parent "^2.0.0" -+ braces "^2.3.0" -+ glob-parent "^3.1.0" - inherits "^2.0.1" - is-binary-path "^1.0.0" -- is-glob "^2.0.0" -+ is-glob "^4.0.0" -+ normalize-path "^2.1.1" - path-is-absolute "^1.0.0" - readdirp "^2.0.0" -+ upath "^1.0.0" - optionalDependencies: -- fsevents "^1.0.0" -+ fsevents "^1.1.2" -+ -+chownr@^1.0.1: -+ version "1.0.1" -+ resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" -+ -+chrome-trace-event@^0.1.1: -+ version "0.1.3" -+ resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-0.1.3.tgz#d395af2d31c87b90a716c831fe326f69768ec084" - - chromium-pickle-js@^0.1.0: - version "0.1.0" -@@ -1384,9 +1828,9 @@ - dependencies: - source-map "0.5.x" - --clean-webpack-plugin@^0.1.16: -- version "0.1.17" -- resolved "https://registry.yarnpkg.com/clean-webpack-plugin/-/clean-webpack-plugin-0.1.17.tgz#71c57242e6d47204d46f809413176e7bed28ec49" -+clean-webpack-plugin@^0.1.19: -+ version "0.1.19" -+ resolved "https://registry.yarnpkg.com/clean-webpack-plugin/-/clean-webpack-plugin-0.1.19.tgz#ceda8bb96b00fe168e9b080272960d20fdcadd6d" - dependencies: - rimraf "^2.6.1" - -@@ -1411,14 +1855,6 @@ - exit "0.1.2" - glob "^7.1.1" - --cliui@^2.1.0: -- version "2.1.0" -- resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" -- dependencies: -- center-align "^0.1.1" -- right-align "^0.1.1" -- wordwrap "0.0.2" -- - cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" -@@ -1435,14 +1871,14 @@ - strip-ansi "^4.0.0" - wrap-ansi "^2.0.0" - --clone-deep@^0.3.0: -- version "0.3.0" -- resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-0.3.0.tgz#348c61ae9cdbe0edfe053d91ff4cc521d790ede8" -+clone-deep@^2.0.1: -+ version "2.0.2" -+ resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-2.0.2.tgz#00db3a1e173656730d1188c3d6aced6d7ea97713" - dependencies: - for-own "^1.0.0" -- is-plain-object "^2.0.1" -- kind-of "^3.2.2" -- shallow-clone "^0.1.2" -+ is-plain-object "^2.0.4" -+ kind-of "^6.0.0" -+ shallow-clone "^1.0.0" - - clone@^1.0.2: - version "1.0.2" -@@ -1505,7 +1941,7 @@ - css-color-names "0.0.4" - has "^1.0.1" - --colors@^1.1.2, colors@~1.1.2: -+colors@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" - -@@ -1519,10 +1955,18 @@ - version "2.11.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" - --commander@^2.12.1, commander@^2.14.1: -+commander@^2.12.1, commander@^2.13.0, commander@^2.14.1: - version "2.15.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" - -+commander@~2.13.0: -+ version "2.13.0" -+ resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" -+ -+commondir@^1.0.1: -+ version "1.0.1" -+ resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" -+ - compare-version@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/compare-version/-/compare-version-0.1.2.tgz#0162ec2d9351f5ddd59a9202cba935366a725080" -@@ -1552,6 +1996,15 @@ - readable-stream "^2.2.2" - typedarray "^0.0.6" - -+concat-stream@^1.5.0: -+ version "1.6.2" -+ resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" -+ dependencies: -+ buffer-from "^1.0.0" -+ inherits "^2.0.3" -+ readable-stream "^2.2.2" -+ typedarray "^0.0.6" -+ - configstore@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.1.tgz#094ee662ab83fad9917678de114faaea8fcdca90" -@@ -1589,6 +2042,10 @@ - version "1.5.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" - -+convert-source-map@^1.5.1: -+ version "1.5.1" -+ resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" -+ - cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" -@@ -1597,6 +2054,17 @@ - version "0.3.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" - -+copy-concurrently@^1.0.0: -+ version "1.0.5" -+ resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" -+ dependencies: -+ aproba "^1.1.1" -+ fs-write-stream-atomic "^1.0.8" -+ iferr "^0.1.5" -+ mkdirp "^0.5.1" -+ rimraf "^2.5.4" -+ run-queue "^1.0.0" -+ - copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" -@@ -1718,22 +2186,22 @@ - version "0.0.4" - resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" - --css-loader@^0.28.5: -- version "0.28.7" -- resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.7.tgz#5f2ee989dd32edd907717f953317656160999c1b" -+css-loader@^0.28.11: -+ version "0.28.11" -+ resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.11.tgz#c3f9864a700be2711bb5a2462b2389b1a392dab7" - dependencies: -- babel-code-frame "^6.11.0" -+ babel-code-frame "^6.26.0" - css-selector-tokenizer "^0.7.0" -- cssnano ">=2.6.1 <4" -+ cssnano "^3.10.0" - icss-utils "^2.1.0" - loader-utils "^1.0.2" - lodash.camelcase "^4.3.0" -- object-assign "^4.0.1" -+ object-assign "^4.1.1" - postcss "^5.0.6" -- postcss-modules-extract-imports "^1.0.0" -- postcss-modules-local-by-default "^1.0.1" -- postcss-modules-scope "^1.0.0" -- postcss-modules-values "^1.1.0" -+ postcss-modules-extract-imports "^1.2.0" -+ postcss-modules-local-by-default "^1.2.0" -+ postcss-modules-scope "^1.1.0" -+ postcss-modules-values "^1.3.0" - postcss-value-parser "^3.3.0" - source-list-map "^2.0.0" - -@@ -1781,7 +2249,7 @@ - version "0.1.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" - --"cssnano@>=2.6.1 <4": -+cssnano@^3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-3.10.0.tgz#4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38" - dependencies: -@@ -1825,6 +2293,10 @@ - clap "^1.0.9" - source-map "^0.5.3" - -+csstype@^2.2.0: -+ version "2.3.0" -+ resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.3.0.tgz#062e141c78345cf814da0e0b716ad777931b08af" -+ - cuint@^0.2.1: - version "0.2.2" - resolved "https://registry.yarnpkg.com/cuint/-/cuint-0.2.2.tgz#408086d409550c2631155619e9fa7bcadc3b991b" -@@ -1835,11 +2307,9 @@ - dependencies: - array-find-index "^1.0.1" - --d@1: -- version "1.0.0" -- resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" -- dependencies: -- es5-ext "^0.10.9" -+cyclist@~0.2.2: -+ version "0.2.2" -+ resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" - - dashdash@^1.12.0: - version "1.14.1" -@@ -1851,7 +2321,7 @@ - version "0.1.4" - resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" - --debug@2.6.9, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8: -+debug@2.6.9, debug@^2.1.2, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - dependencies: -@@ -1867,7 +2337,7 @@ - version "1.0.1" - resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" - --decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: -+decamelize@^1.1.1, decamelize@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - -@@ -1924,6 +2394,13 @@ - dependencies: - is-descriptor "^1.0.0" - -+define-property@^2.0.2: -+ version "2.0.2" -+ resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" -+ dependencies: -+ is-descriptor "^1.0.2" -+ isobject "^3.0.1" -+ - defined@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" -@@ -1952,6 +2429,10 @@ - version "1.1.1" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" - -+depd@~1.1.2: -+ version "1.1.2" -+ resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" -+ - des.js@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" -@@ -1969,6 +2450,10 @@ - dependencies: - repeating "^2.0.0" - -+detect-libc@^1.0.2: -+ version "1.0.3" -+ resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" -+ - dev-null@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/dev-null/-/dev-null-0.1.1.tgz#5a205ce3c2b2ef77b6238d6ba179eb74c6a0e818" -@@ -2009,7 +2494,13 @@ - parse-color "^1.0.0" - sanitize-filename "^1.6.1" - --doctrine@^2.0.2, doctrine@^2.1.0: -+doctrine@^2.0.2: -+ version "2.0.2" -+ resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.2.tgz#68f96ce8efc56cc42651f1faadb4f175273b0075" -+ dependencies: -+ esutils "^2.0.2" -+ -+doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - dependencies: -@@ -2083,6 +2574,19 @@ - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - -+duplexer@^0.1.1: -+ version "0.1.1" -+ resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" -+ -+duplexify@^3.4.2, duplexify@^3.5.3: -+ version "3.5.4" -+ resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.4.tgz#4bb46c1796eabebeec4ca9a2e66b808cb7a3d8b4" -+ dependencies: -+ end-of-stream "^1.0.0" -+ inherits "^2.0.1" -+ readable-stream "^2.0.0" -+ stream-shift "^1.0.0" -+ - easy-stack@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/easy-stack/-/easy-stack-1.0.0.tgz#12c91b3085a37f0baa336e9486eac4bf94e3e788" -@@ -2101,7 +2605,7 @@ - version "2.5.7" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.7.tgz#cc872c168880ae3c7189762fd5ffc00896c9518a" - --electron-builder-lib@20.2.0, electron-builder-lib@~20.2.0: -+electron-builder-lib@20.2.0: - version "20.2.0" - resolved "https://registry.yarnpkg.com/electron-builder-lib/-/electron-builder-lib-20.2.0.tgz#e8dba288cf26858803eb1800da870d7312837bfa" - dependencies: -@@ -2130,6 +2634,35 @@ - semver "^5.5.0" - temp-file "^3.1.1" - -+electron-builder-lib@~20.2.0: -+ version "20.2.1" -+ resolved "https://registry.yarnpkg.com/electron-builder-lib/-/electron-builder-lib-20.2.1.tgz#ff8dc6ac7f6f3c676fc370ddafb2aba464a17672" -+ dependencies: -+ "7zip-bin" "~3.1.0" -+ app-builder-bin "1.6.0" -+ async-exit-hook "^2.0.1" -+ bluebird-lst "^1.0.5" -+ builder-util "5.6.1" -+ builder-util-runtime "4.0.5" -+ chromium-pickle-js "^0.2.0" -+ debug "^3.1.0" -+ ejs "^2.5.7" -+ electron-osx-sign "0.4.8" -+ electron-publish "20.2.0" -+ fs-extra-p "^4.5.2" -+ hosted-git-info "^2.5.0" -+ is-ci "^1.1.0" -+ isbinaryfile "^3.0.2" -+ js-yaml "^3.10.0" -+ lazy-val "^1.0.3" -+ minimatch "^3.0.4" -+ normalize-package-data "^2.4.0" -+ plist "^2.1.0" -+ read-config-file "3.0.0" -+ sanitize-filename "^1.6.1" -+ semver "^5.5.0" -+ temp-file "^3.1.1" -+ - electron-builder@20.2.0: - version "20.2.0" - resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-20.2.0.tgz#aaeaa439cb96c9a3d7ffda25b28130327c982982" -@@ -2231,8 +2764,8 @@ - plist "^2.1.0" - - electron-packager@^11.0.0: -- version "11.0.0" -- resolved "https://registry.yarnpkg.com/electron-packager/-/electron-packager-11.0.0.tgz#3150e0efb831b41df40b28186d9baa64bbb2cc52" -+ version "11.2.0" -+ resolved "https://registry.yarnpkg.com/electron-packager/-/electron-packager-11.2.0.tgz#facc17d2b92c10da1bfa1d7c5f58f13774571839" - dependencies: - asar "^0.14.0" - debug "^3.0.0" -@@ -2247,11 +2780,11 @@ - pify "^3.0.0" - plist "^2.0.0" - pruner "^0.0.7" -- rcedit "^0.9.0" -+ rcedit "^1.0.0" - resolve "^1.1.6" - sanitize-filename "^1.6.0" - semver "^5.3.0" -- yargs-parser "^8.0.0" -+ yargs-parser "^9.0.2" - - electron-publish@20.2.0: - version "20.2.0" -@@ -2286,9 +2819,9 @@ - lodash.template "^4.2.2" - temp "^0.8.3" - --electron@1.8.3: -- version "1.8.3" -- resolved "https://registry.yarnpkg.com/electron/-/electron-1.8.3.tgz#001416ea3a25ce594e317cb5531bc41eadd22f7f" -+electron@1.8.7: -+ version "1.8.7" -+ resolved "https://registry.yarnpkg.com/electron/-/electron-1.8.7.tgz#373c1dc4589d7ab4acd49aff8db4a1c0a6c3bcc1" - dependencies: - "@types/node" "^8.0.24" - electron-download "^3.0.1" -@@ -2314,6 +2847,10 @@ - version "1.0.1" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" - -+encodeurl@~1.0.2: -+ version "1.0.2" -+ resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" -+ - encoding@^0.1.11: - version "0.1.12" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" -@@ -2326,23 +2863,19 @@ - dependencies: - once "^1.4.0" - --enhanced-resolve@3.3.0: -- version "3.3.0" -- resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.3.0.tgz#950964ecc7f0332a42321b673b38dc8ff15535b3" -+end-of-stream@^1.1.0: -+ version "1.4.1" -+ resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" - dependencies: -- graceful-fs "^4.1.2" -- memory-fs "^0.4.0" -- object-assign "^4.0.1" -- tapable "^0.2.5" -+ once "^1.4.0" - --enhanced-resolve@^3.3.0, enhanced-resolve@^3.4.0: -- version "3.4.1" -- resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e" -+enhanced-resolve@^4.0.0: -+ version "4.0.0" -+ resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.0.0.tgz#e34a6eaa790f62fccd71d93959f56b2b432db10a" - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.4.0" -- object-assign "^4.0.1" -- tapable "^0.2.7" -+ tapable "^1.0.0" - - entities@1.0: - version "1.0.0" -@@ -2362,6 +2895,12 @@ - dependencies: - prr "~0.0.0" - -+errno@~0.1.7: -+ version "0.1.7" -+ resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" -+ dependencies: -+ prr "~1.0.1" -+ - error-ex@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" -@@ -2386,62 +2925,10 @@ - is-date-object "^1.0.1" - is-symbol "^1.0.1" - --es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14: -- version "0.10.35" -- resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.35.tgz#18ee858ce6a3c45c7d79e91c15fcca9ec568494f" -- dependencies: -- es6-iterator "~2.0.1" -- es6-symbol "~3.1.1" -- --es6-iterator@^2.0.1, es6-iterator@~2.0.1: -- version "2.0.3" -- resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" -- dependencies: -- d "1" -- es5-ext "^0.10.35" -- es6-symbol "^3.1.1" -- --es6-map@^0.1.3: -- version "0.1.5" -- resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" -- dependencies: -- d "1" -- es5-ext "~0.10.14" -- es6-iterator "~2.0.1" -- es6-set "~0.1.5" -- es6-symbol "~3.1.1" -- event-emitter "~0.3.5" -- - es6-promise@^4.0.5: - version "4.1.1" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.1.1.tgz#8811e90915d9a0dba36274f0b242dbda78f9c92a" - --es6-set@~0.1.5: -- version "0.1.5" -- resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" -- dependencies: -- d "1" -- es5-ext "~0.10.14" -- es6-iterator "~2.0.1" -- es6-symbol "3.1.1" -- event-emitter "~0.3.5" -- --es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1: -- version "3.1.1" -- resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" -- dependencies: -- d "1" -- es5-ext "~0.10.14" -- --es6-weak-map@^2.0.1: -- version "2.0.2" -- resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" -- dependencies: -- d "1" -- es5-ext "^0.10.14" -- es6-iterator "^2.0.1" -- es6-symbol "^3.1.1" -- - escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" -@@ -2450,15 +2937,6 @@ - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - --escope@^3.6.0: -- version "3.6.0" -- resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" -- dependencies: -- es6-map "^0.1.3" -- es6-weak-map "^2.0.1" -- esrecurse "^4.1.0" -- estraverse "^4.1.1" -- - eslint-config-prettier@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-2.9.0.tgz#5ecd65174d486c22dff389fe036febf502d468a3" -@@ -2491,9 +2969,9 @@ - jsx-ast-utils "^2.0.1" - prop-types "^15.6.0" - --eslint-plugin-typescript@^0.10.0: -- version "0.10.0" -- resolved "https://registry.yarnpkg.com/eslint-plugin-typescript/-/eslint-plugin-typescript-0.10.0.tgz#009a8fcaf0ec7bf68f6fb71576df0d84ebd0b114" -+eslint-plugin-typescript@^0.12.0: -+ version "0.12.0" -+ resolved "https://registry.yarnpkg.com/eslint-plugin-typescript/-/eslint-plugin-typescript-0.12.0.tgz#e23d58cb27fe28e89fc641a1f20e8d862cb99aef" - dependencies: - requireindex "~1.1.0" - -@@ -2591,13 +3069,6 @@ - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - --event-emitter@~0.3.5: -- version "0.3.5" -- resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" -- dependencies: -- d "1" -- es5-ext "~0.10.14" -- - event-pubsub@4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/event-pubsub/-/event-pubsub-4.3.0.tgz#f68d816bc29f1ec02c539dc58c8dd40ce72cb36e" -@@ -2629,12 +3100,6 @@ - version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - --expand-brackets@^0.1.4: -- version "0.1.5" -- resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" -- dependencies: -- is-posix-bracket "^0.1.0" -- - expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" -@@ -2647,17 +3112,46 @@ - snapdragon "^0.8.1" - to-regex "^3.0.1" - --expand-range@^1.8.1: -- version "1.8.2" -- resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" -+express@^4.15.0: -+ version "4.16.2" -+ resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c" - dependencies: -- fill-range "^2.1.0" -+ accepts "~1.3.4" -+ array-flatten "1.1.1" -+ body-parser "1.18.2" -+ content-disposition "0.5.2" -+ content-type "~1.0.4" -+ cookie "0.3.1" -+ cookie-signature "1.0.6" -+ debug "2.6.9" -+ depd "~1.1.1" -+ encodeurl "~1.0.1" -+ escape-html "~1.0.3" -+ etag "~1.8.1" -+ finalhandler "1.1.0" -+ fresh "0.5.2" -+ merge-descriptors "1.0.1" -+ methods "~1.1.2" -+ on-finished "~2.3.0" -+ parseurl "~1.3.2" -+ path-to-regexp "0.1.7" -+ proxy-addr "~2.0.2" -+ qs "6.5.1" -+ range-parser "~1.2.0" -+ safe-buffer "5.1.1" -+ send "0.16.1" -+ serve-static "1.13.1" -+ setprototypeof "1.1.0" -+ statuses "~1.3.1" -+ type-is "~1.6.15" -+ utils-merge "1.0.1" -+ vary "~1.1.2" - --express@^4.15.0: -- version "4.16.2" -- resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c" -+express@^4.16.2: -+ version "4.16.3" -+ resolved "https://registry.yarnpkg.com/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53" - dependencies: -- accepts "~1.3.4" -+ accepts "~1.3.5" - array-flatten "1.1.1" - body-parser "1.18.2" - content-disposition "0.5.2" -@@ -2665,26 +3159,26 @@ - cookie "0.3.1" - cookie-signature "1.0.6" - debug "2.6.9" -- depd "~1.1.1" -- encodeurl "~1.0.1" -+ depd "~1.1.2" -+ encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" -- finalhandler "1.1.0" -+ finalhandler "1.1.1" - fresh "0.5.2" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.2" - path-to-regexp "0.1.7" -- proxy-addr "~2.0.2" -+ proxy-addr "~2.0.3" - qs "6.5.1" - range-parser "~1.2.0" - safe-buffer "5.1.1" -- send "0.16.1" -- serve-static "1.13.1" -+ send "0.16.2" -+ serve-static "1.13.2" - setprototypeof "1.1.0" -- statuses "~1.3.1" -- type-is "~1.6.15" -+ statuses "~1.4.0" -+ type-is "~1.6.16" - utils-merge "1.0.1" - vary "~1.1.2" - -@@ -2694,6 +3188,13 @@ - dependencies: - is-extendable "^0.1.0" - -+extend-shallow@^3.0.2: -+ version "3.0.2" -+ resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" -+ dependencies: -+ assign-symbols "^1.0.0" -+ is-extendable "^1.0.1" -+ - extend@~3.0.0, extend@~3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" -@@ -2706,15 +3207,9 @@ - jschardet "^1.4.2" - tmp "^0.0.33" - --extglob@^0.3.1: -- version "0.3.2" -- resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" -- dependencies: -- is-extglob "^1.0.0" -- --extglob@^2.0.2: -- version "2.0.2" -- resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.2.tgz#3290f46208db1b2e8eb8be0c94ed9e6ad80edbe2" -+extglob@^2.0.4: -+ version "2.0.4" -+ resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" -@@ -2725,15 +3220,6 @@ - snapdragon "^0.8.1" - to-regex "^3.0.1" - --extract-text-webpack-plugin@^3.0.0: -- version "3.0.2" -- resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz#5f043eaa02f9750a9258b78c0a6e0dc1408fb2f7" -- dependencies: -- async "^2.4.1" -- loader-utils "^1.1.0" -- schema-utils "^0.3.0" -- webpack-sources "^1.0.1" -- - extract-zip@^1.0.3, extract-zip@^1.6.5: - version "1.6.6" - resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.6.tgz#1290ede8d20d0872b429fd3f351ca128ec5ef85c" -@@ -2751,6 +3237,10 @@ - version "1.0.0" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" - -+fast-deep-equal@^2.0.1: -+ version "2.0.1" -+ resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" -+ - fast-diff@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.1.2.tgz#4b62c42b8e03de3f848460b639079920695d0154" -@@ -2798,19 +3288,9 @@ - flat-cache "^1.2.1" - object-assign "^4.0.1" - --filename-regex@^2.0.0: -- version "2.0.1" -- resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" -- --fill-range@^2.1.0: -- version "2.2.3" -- resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" -- dependencies: -- is-number "^2.1.0" -- isobject "^2.0.0" -- randomatic "^1.1.3" -- repeat-element "^1.1.2" -- repeat-string "^1.5.2" -+filesize@^3.5.11: -+ version "3.6.1" -+ resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" - - fill-range@^4.0.0: - version "4.0.0" -@@ -2833,6 +3313,26 @@ - statuses "~1.3.1" - unpipe "~1.0.0" - -+finalhandler@1.1.1: -+ version "1.1.1" -+ resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" -+ dependencies: -+ debug "2.6.9" -+ encodeurl "~1.0.2" -+ escape-html "~1.0.3" -+ on-finished "~2.3.0" -+ parseurl "~1.3.2" -+ statuses "~1.4.0" -+ unpipe "~1.0.0" -+ -+find-cache-dir@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" -+ dependencies: -+ commondir "^1.0.1" -+ make-dir "^1.0.0" -+ pkg-dir "^2.0.0" -+ - find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" -@@ -2859,6 +3359,13 @@ - version "1.0.2" - resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" - -+flush-write-stream@^1.0.0: -+ version "1.0.3" -+ resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" -+ dependencies: -+ inherits "^2.0.1" -+ readable-stream "^2.0.4" -+ - for-in@^0.1.3: - version "0.1.8" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1" -@@ -2867,12 +3374,6 @@ - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - --for-own@^0.1.4: -- version "0.1.5" -- resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" -- dependencies: -- for-in "^1.0.1" -- - for-own@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" -@@ -2917,6 +3418,19 @@ - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - -+from2@^2.1.0: -+ version "2.3.0" -+ resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" -+ dependencies: -+ inherits "^2.0.1" -+ readable-stream "^2.0.0" -+ -+front-matter@^2.3.0: -+ version "2.3.0" -+ resolved "https://registry.yarnpkg.com/front-matter/-/front-matter-2.3.0.tgz#7203af896ce357ee04e2aa45169ea91ed7f67504" -+ dependencies: -+ js-yaml "^3.10.0" -+ - fs-extra-p@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/fs-extra-p/-/fs-extra-p-4.5.0.tgz#b79f3f3fcc0b5e57b7e7caeb06159f958ef15fe8" -@@ -2951,7 +3465,7 @@ - path-is-absolute "^1.0.0" - rimraf "^2.2.8" - --fs-extra@^2.0.0, fs-extra@^2.1.2: -+fs-extra@^2.0.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-2.1.2.tgz#046c70163cef9aad46b0e4a7fa467fb22d71de35" - dependencies: -@@ -2982,30 +3496,41 @@ - jsonfile "^4.0.0" - universalify "^0.1.0" - --fs-readdir-recursive@^1.0.0: -- version "1.0.0" -- resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.0.0.tgz#8cd1745c8b4f8a29c8caec392476921ba195f560" -+fs-extra@^6.0.0: -+ version "6.0.0" -+ resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.0.tgz#0f0afb290bb3deb87978da816fcd3c7797f3a817" -+ dependencies: -+ graceful-fs "^4.1.2" -+ jsonfile "^4.0.0" -+ universalify "^0.1.0" -+ -+fs-minipass@^1.2.5: -+ version "1.2.5" -+ resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" -+ dependencies: -+ minipass "^2.2.1" -+ -+fs-write-stream-atomic@^1.0.8: -+ version "1.0.10" -+ resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" -+ dependencies: -+ graceful-fs "^4.1.2" -+ iferr "^0.1.5" -+ imurmurhash "^0.1.4" -+ readable-stream "1 || 2" - - fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - --fsevents@^1.0.0: -- version "1.1.2" -- resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.2.tgz#3282b713fb3ad80ede0e9fcf4611b5aa6fc033f4" -- dependencies: -- nan "^2.3.0" -- node-pre-gyp "^0.6.36" -- --fstream-ignore@^1.0.5: -- version "1.0.5" -- resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" -+fsevents@^1.1.2: -+ version "1.2.3" -+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.3.tgz#08292982e7059f6674c93d8b829c1e8604979ac0" - dependencies: -- fstream "^1.0.0" -- inherits "2" -- minimatch "^3.0.0" -+ nan "^2.9.2" -+ node-pre-gyp "^0.9.0" - --fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: -+fstream@^1.0.0, fstream@^1.0.2: - version "1.0.11" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" - dependencies: -@@ -3098,18 +3623,12 @@ - version "1.0.2" - resolved "https://registry.yarnpkg.com/github-url-from-username-repo/-/github-url-from-username-repo-1.0.2.tgz#7dd79330d2abe69c10c2cef79714c97215791dfa" - --glob-base@^0.3.0: -- version "0.3.0" -- resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" -- dependencies: -- glob-parent "^2.0.0" -- is-glob "^2.0.0" -- --glob-parent@^2.0.0: -- version "2.0.0" -- resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" -+glob-parent@^3.1.0: -+ version "3.1.0" -+ resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - dependencies: -- is-glob "^2.0.0" -+ is-glob "^3.1.0" -+ path-dirname "^1.0.0" - - glob@7.1.2, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1: - version "7.1.2" -@@ -3205,6 +3724,13 @@ - version "1.10.3" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f" - -+gzip-size@^4.1.0: -+ version "4.1.0" -+ resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-4.1.0.tgz#8ae096257eabe7d69c45be2b67c448124ffb517c" -+ dependencies: -+ duplexer "^0.1.1" -+ pify "^3.0.0" -+ - har-schema@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" -@@ -3250,6 +3776,10 @@ - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" - -+has-flag@^3.0.0: -+ version "3.0.0" -+ resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" -+ - has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" -@@ -3307,7 +3837,7 @@ - inherits "^2.0.3" - minimalistic-assert "^1.0.0" - --hawk@3.1.3, hawk@~3.1.3: -+hawk@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" - dependencies: -@@ -3381,16 +3911,17 @@ - relateurl "0.2.x" - uglify-js "3.1.x" - --html-webpack-plugin@^2.30.1: -- version "2.30.1" -- resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-2.30.1.tgz#7f9c421b7ea91ec460f56527d78df484ee7537d5" -+html-webpack-plugin@^3.2.0: -+ version "3.2.0" -+ resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz#b01abbd723acaaa7b37b6af4492ebda03d9dd37b" - dependencies: -- bluebird "^3.4.7" - html-minifier "^3.2.3" - loader-utils "^0.2.16" - lodash "^4.17.3" - pretty-error "^2.0.2" -+ tapable "^1.0.0" - toposort "^1.0.0" -+ util.promisify "1.0.0" - - htmlparser2@3.8.x: - version "3.8.3" -@@ -3444,6 +3975,12 @@ - version "0.4.19" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" - -+iconv-lite@^0.4.4: -+ version "0.4.21" -+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.21.tgz#c47f8733d02171189ebc4a400f3218d348094798" -+ dependencies: -+ safer-buffer "^2.1.0" -+ - icss-replace-symbols@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" -@@ -3458,6 +3995,16 @@ - version "1.1.8" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" - -+iferr@^0.1.5: -+ version "0.1.5" -+ resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" -+ -+ignore-walk@^3.0.1: -+ version "3.0.1" -+ resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" -+ dependencies: -+ minimatch "^3.0.4" -+ - ignore@^3.3.3: - version "3.3.7" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" -@@ -3544,7 +4091,7 @@ - strip-ansi "^3.0.0" - through "^2.3.6" - --interpret@^1.0.0, interpret@^1.0.1: -+interpret@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.4.tgz#820cdd588b868ffb191a809506d6c9c8f212b1b0" - -@@ -3562,6 +4109,10 @@ - version "1.5.2" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.5.2.tgz#d4b505bde9946987ccf0fc58d9010ff9607e3fa0" - -+ipaddr.js@1.6.0: -+ version "1.6.0" -+ resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.6.0.tgz#e3fa357b773da619f26e95f049d055c72796f86b" -+ - is-absolute-url@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" -@@ -3572,6 +4123,12 @@ - dependencies: - kind-of "^3.0.2" - -+is-accessor-descriptor@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" -+ dependencies: -+ kind-of "^6.0.0" -+ - is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" -@@ -3582,7 +4139,7 @@ - dependencies: - binary-extensions "^1.0.0" - --is-buffer@^1.0.2, is-buffer@^1.1.5: -+is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - -@@ -3608,6 +4165,12 @@ - dependencies: - kind-of "^3.0.2" - -+is-data-descriptor@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" -+ dependencies: -+ kind-of "^6.0.0" -+ - is-date-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" -@@ -3628,27 +4191,31 @@ - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - --is-dotfile@^1.0.0: -- version "1.0.3" -- resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" -+is-descriptor@^1.0.2: -+ version "1.0.2" -+ resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" -+ dependencies: -+ is-accessor-descriptor "^1.0.0" -+ is-data-descriptor "^1.0.0" -+ kind-of "^6.0.2" - - is-electron-renderer@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-electron-renderer/-/is-electron-renderer-2.0.1.tgz#a469d056f975697c58c98c6023eb0aa79af895a2" - --is-equal-shallow@^0.1.3: -- version "0.1.3" -- resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" -- dependencies: -- is-primitive "^2.0.0" -- - is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - --is-extglob@^1.0.0: -- version "1.0.0" -- resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" -+is-extendable@^1.0.1: -+ version "1.0.1" -+ resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" -+ dependencies: -+ is-plain-object "^2.0.4" -+ -+is-extglob@^2.1.0, is-extglob@^2.1.1: -+ version "2.1.1" -+ resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - - is-finite@^1.0.0: - version "1.0.2" -@@ -3666,11 +4233,17 @@ - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - --is-glob@^2.0.0, is-glob@^2.0.1: -- version "2.0.1" -- resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" -+is-glob@^3.1.0: -+ version "3.1.0" -+ resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - dependencies: -- is-extglob "^1.0.0" -+ is-extglob "^2.1.0" -+ -+is-glob@^4.0.0: -+ version "4.0.0" -+ resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" -+ dependencies: -+ is-extglob "^2.1.1" - - is-installed-globally@^0.1.0: - version "0.1.0" -@@ -3692,27 +4265,25 @@ - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" - --is-number@^2.1.0: -- version "2.1.0" -- resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" -- dependencies: -- kind-of "^3.0.2" -- - is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - dependencies: - kind-of "^3.0.2" - -+is-number@^4.0.0: -+ version "4.0.0" -+ resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" -+ - is-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - --is-odd@^1.0.0: -- version "1.0.0" -- resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-1.0.0.tgz#3b8a932eb028b3775c39bb09e91767accdb69088" -+is-odd@^2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24" - dependencies: -- is-number "^3.0.0" -+ is-number "^4.0.0" - - is-path-cwd@^1.0.0: - version "1.0.0" -@@ -3734,20 +4305,12 @@ - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - --is-plain-object@^2.0.1, is-plain-object@^2.0.3: -+is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - dependencies: - isobject "^3.0.1" - --is-posix-bracket@^0.1.0: -- version "0.1.1" -- resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" -- --is-primitive@^2.0.0: -- version "2.0.0" -- resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" -- - is-promise@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" -@@ -3806,6 +4369,10 @@ - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.1.tgz#310db70f742d259a16a369202b51af84233310d9" - -+is-windows@^1.0.2: -+ version "1.0.2" -+ resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" -+ - isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" -@@ -3880,7 +4447,7 @@ - argparse "^1.0.7" - esprima "^4.0.0" - --js-yaml@^3.7.0: -+js-yaml@^3.11.0, js-yaml@^3.7.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" - dependencies: -@@ -3923,10 +4490,6 @@ - shelljs "0.3.x" - strip-json-comments "1.0.x" - --json-loader@^0.5.4: -- version "0.5.7" -- resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" -- - json-parse-helpfulerror@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz#13f14ce02eed4e981297b64eb9e3b932e2dd13dc" -@@ -3998,13 +4561,7 @@ - dependencies: - array-includes "^3.0.3" - --kind-of@^2.0.1: -- version "2.0.1" -- resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-2.0.1.tgz#018ec7a4ce7e3a86cb9141be519d24c8faa981b5" -- dependencies: -- is-buffer "^1.0.2" -- --kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0, kind-of@^3.2.2: -+kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - dependencies: -@@ -4016,7 +4573,7 @@ - dependencies: - is-buffer "^1.1.5" - --kind-of@^5.0.0, kind-of@^5.0.2: -+kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - -@@ -4024,6 +4581,10 @@ - version "6.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.0.tgz#3606e9e2fa960e7ddaa8898c03804e47e5d66644" - -+kind-of@^6.0.2: -+ version "6.0.2" -+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" -+ - klaw-sync@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-3.0.2.tgz#bf3a5ca463af5aec007201dbe8be7088ef29d067" -@@ -4042,14 +4603,6 @@ - dependencies: - package-json "^4.0.0" - --lazy-cache@^0.2.3: -- version "0.2.7" -- resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-0.2.7.tgz#7feddf2dcb6edb77d11ef1d117ab5ffdf0ab1b65" -- --lazy-cache@^1.0.3: -- version "1.0.4" -- resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" -- - lazy-cache@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264" -@@ -4072,6 +4625,10 @@ - dependencies: - invert-kv "^1.0.0" - -+leb@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/leb/-/leb-0.3.0.tgz#32bee9fad168328d6aea8522d833f4180eed1da3" -+ - legal-eagle@0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/legal-eagle/-/legal-eagle-0.15.0.tgz#826b47475c948543b803a82baa2907a350449e04" -@@ -4118,7 +4675,7 @@ - json5 "^0.5.0" - object-assign "^4.0.1" - --loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.0.3, loader-utils@^1.1.0: -+loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" - dependencies: -@@ -4210,6 +4767,10 @@ - version "4.17.4" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" - -+lodash@^4.17.5: -+ version "4.17.10" -+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" -+ - log-symbols@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.1.0.tgz#f35fa60e278832b538dc4dddcbb478a45d3e3be6" -@@ -4220,9 +4781,9 @@ - version "1.0.1" - resolved "https://registry.yarnpkg.com/loglevelnext/-/loglevelnext-1.0.1.tgz#8b17b5a43395338a96c67911a962c44af466d1c8" - --longest@^1.0.1: -- version "1.0.1" -- resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" -+long@^3.2.0: -+ version "3.2.0" -+ resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" - - loose-envify@^1.0.0, loose-envify@^1.3.1: - version "1.3.1" -@@ -4252,6 +4813,13 @@ - pseudomap "^1.0.2" - yallist "^2.1.2" - -+lru-cache@^4.1.1: -+ version "4.1.2" -+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.2.tgz#45234b2e6e2f2b33da125624c4664929a0224c3f" -+ dependencies: -+ pseudomap "^1.0.2" -+ yallist "^2.1.2" -+ - macaddress@^0.2.8: - version "0.2.8" - resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12" -@@ -4331,41 +4899,23 @@ - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - --micromatch@^2.1.5: -- version "2.3.11" -- resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" -- dependencies: -- arr-diff "^2.0.0" -- array-unique "^0.2.1" -- braces "^1.8.2" -- expand-brackets "^0.1.4" -- extglob "^0.3.1" -- filename-regex "^2.0.0" -- is-extglob "^1.0.0" -- is-glob "^2.0.1" -- kind-of "^3.0.2" -- normalize-path "^2.0.1" -- object.omit "^2.0.0" -- parse-glob "^3.0.4" -- regex-cache "^0.4.2" -- --micromatch@^3.0.3: -- version "3.1.4" -- resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.4.tgz#bb812e741a41f982c854e42b421a7eac458796f4" -+micromatch@^3.1.4, micromatch@^3.1.8, micromatch@^3.1.9: -+ version "3.1.10" -+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" -- braces "^2.3.0" -- define-property "^1.0.0" -- extend-shallow "^2.0.1" -- extglob "^2.0.2" -+ braces "^2.3.1" -+ define-property "^2.0.2" -+ extend-shallow "^3.0.2" -+ extglob "^2.0.4" - fragment-cache "^0.2.1" -- kind-of "^6.0.0" -- nanomatch "^1.2.5" -+ kind-of "^6.0.2" -+ nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" -- to-regex "^3.0.1" -+ to-regex "^3.0.2" - - miller-rabin@^4.0.0: - version "4.0.1" -@@ -4378,12 +4928,22 @@ - version "1.30.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" - -+mime-db@~1.33.0: -+ version "1.33.0" -+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" -+ - mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.16, mime-types@~2.1.17, mime-types@~2.1.7: - version "2.1.17" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" - dependencies: - mime-db "~1.30.0" - -+mime-types@~2.1.18: -+ version "2.1.18" -+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" -+ dependencies: -+ mime-db "~1.33.0" -+ - mime@1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" -@@ -4393,13 +4953,20 @@ - resolved "https://registry.yarnpkg.com/mime/-/mime-2.1.0.tgz#1022a5ada445aa30686e4059abaea83d0b4e8f9c" - - mime@^2.2.0: -- version "2.2.0" -- resolved "https://registry.yarnpkg.com/mime/-/mime-2.2.0.tgz#161e541965551d3b549fa1114391e3a3d55b923b" -+ version "2.2.2" -+ resolved "https://registry.yarnpkg.com/mime/-/mime-2.2.2.tgz#6b4c109d88031d7b5c23635f5b923da336d79121" - - mimic-fn@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" - -+mini-css-extract-plugin@^0.4.0: -+ version "0.4.0" -+ resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.4.0.tgz#ff3bf08bee96e618e177c16ca6131bfecef707f9" -+ dependencies: -+ loader-utils "^1.1.0" -+ webpack-sources "^1.1.0" -+ - minimalistic-assert@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3" -@@ -4426,6 +4993,34 @@ - version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - -+minipass@^2.2.1, minipass@^2.2.4: -+ version "2.2.4" -+ resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.2.4.tgz#03c824d84551ec38a8d1bb5bc350a5a30a354a40" -+ dependencies: -+ safe-buffer "^5.1.1" -+ yallist "^3.0.0" -+ -+minizlib@^1.1.0: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" -+ dependencies: -+ minipass "^2.2.1" -+ -+mississippi@^2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-2.0.0.tgz#3442a508fafc28500486feea99409676e4ee5a6f" -+ dependencies: -+ concat-stream "^1.5.0" -+ duplexify "^3.4.2" -+ end-of-stream "^1.1.0" -+ flush-write-stream "^1.0.0" -+ from2 "^2.1.0" -+ parallel-transform "^1.1.0" -+ pump "^2.0.1" -+ pumpify "^1.3.3" -+ stream-each "^1.1.0" -+ through2 "^2.0.0" -+ - mixin-deep@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.2.0.tgz#d02b8c6f8b6d4b8f5982d3fd009c4919851c3fe2" -@@ -4465,8 +5060,8 @@ - request "^2.79.0" - - mocha@^5.0.1, mocha@^5.0.4: -- version "5.0.4" -- resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.0.4.tgz#6b7aa328472da1088e69d47e75925fd3a3bb63c6" -+ version "5.0.5" -+ resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.0.5.tgz#e228e3386b9387a4710007a641f127b00be44b52" - dependencies: - browser-stdout "1.3.1" - commander "2.11.0" -@@ -4479,6 +5074,17 @@ - mkdirp "0.5.1" - supports-color "4.4.0" - -+move-concurrently@^1.0.1: -+ version "1.0.1" -+ resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" -+ dependencies: -+ aproba "^1.1.1" -+ copy-concurrently "^1.0.0" -+ fs-write-stream-atomic "^1.0.8" -+ mkdirp "^0.5.1" -+ rimraf "^2.5.4" -+ run-queue "^1.0.3" -+ - ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" -@@ -4495,21 +5101,26 @@ - object-assign "^4.0.1" - thenify-all "^1.0.0" - --nan@^2.3.0, nan@^2.3.2: -+nan@^2.3.2: - version "2.7.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.7.0.tgz#d95bf721ec877e08db276ed3fc6eb78f9083ad46" - --nanomatch@^1.2.5: -- version "1.2.5" -- resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.5.tgz#5c9ab02475c76676275731b0bf0a7395c624a9c4" -+nan@^2.9.2: -+ version "2.10.0" -+ resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" -+ -+nanomatch@^1.2.9: -+ version "1.2.9" -+ resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.9.tgz#879f7150cb2dab7a471259066c104eee6e0fa7c2" - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" -- define-property "^1.0.0" -- extend-shallow "^2.0.1" -+ define-property "^2.0.2" -+ extend-shallow "^3.0.2" - fragment-cache "^0.2.1" -- is-odd "^1.0.0" -- kind-of "^5.0.2" -+ is-odd "^2.0.0" -+ is-windows "^1.0.2" -+ kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" -@@ -4529,10 +5140,22 @@ - dependencies: - xml-char-classes "^1.0.0" - -+needle@^2.2.0: -+ version "2.2.1" -+ resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.1.tgz#b5e325bd3aae8c2678902fa296f729455d1d3a7d" -+ dependencies: -+ debug "^2.1.2" -+ iconv-lite "^0.4.4" -+ sax "^1.2.4" -+ - negotiator@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" - -+neo-async@^2.5.0: -+ version "2.5.1" -+ resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.1.tgz#acb909e327b1e87ec9ef15f41b8a269512ad41ee" -+ - no-case@^2.2.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" -@@ -4600,26 +5223,20 @@ - util "^0.10.3" - vm-browserify "0.0.4" - --node-native-loader@^1.1.1: -- version "1.1.1" -- resolved "https://registry.yarnpkg.com/node-native-loader/-/node-native-loader-1.1.1.tgz#ff1c2072f795947b3dde1da2f5412451ef564337" -- dependencies: -- loader-utils "^1.0.3" -- --node-pre-gyp@^0.6.36: -- version "0.6.38" -- resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.38.tgz#e92a20f83416415bb4086f6d1fb78b3da73d113d" -+node-pre-gyp@^0.9.0: -+ version "0.9.1" -+ resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.9.1.tgz#f11c07516dd92f87199dbc7e1838eab7cd56c9e0" - dependencies: -- hawk "3.1.3" -+ detect-libc "^1.0.2" - mkdirp "^0.5.1" -+ needle "^2.2.0" - nopt "^4.0.1" -+ npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.1.7" -- request "2.81.0" - rimraf "^2.6.1" - semver "^5.3.0" -- tar "^2.2.1" -- tar-pack "^3.4.0" -+ tar "^4" - - node-sass@^4.7.2: - version "4.7.2" -@@ -4688,7 +5305,7 @@ - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - --normalize-path@^2.0.0, normalize-path@^2.0.1: -+normalize-path@^2.0.0, normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - dependencies: -@@ -4707,10 +5324,21 @@ - query-string "^4.1.0" - sort-keys "^1.0.0" - -+npm-bundled@^1.0.1: -+ version "1.0.3" -+ resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.3.tgz#7e71703d973af3370a9591bafe3a63aca0be2308" -+ - npm-install-package@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/npm-install-package/-/npm-install-package-2.1.0.tgz#d7efe3cfcd7ab00614b896ea53119dc9ab259125" - -+npm-packlist@^1.1.6: -+ version "1.1.10" -+ resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.10.tgz#1039db9e985727e464df066f4cf0ab6ef85c398a" -+ dependencies: -+ ignore-walk "^3.0.1" -+ npm-bundled "^1.0.1" -+ - npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" -@@ -4789,13 +5417,6 @@ - define-properties "^1.1.2" - es-abstract "^1.5.1" - --object.omit@^2.0.0: -- version "2.0.1" -- resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" -- dependencies: -- for-own "^0.1.4" -- is-extendable "^0.1.1" -- - object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" -@@ -4814,7 +5435,7 @@ - dependencies: - ee-first "1.1.1" - --once@^1.3.0, once@^1.3.3, once@^1.4.0: -+once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - dependencies: -@@ -4826,6 +5447,10 @@ - dependencies: - mimic-fn "^1.0.0" - -+opener@^1.4.3: -+ version "1.4.3" -+ resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8" -+ - optimist@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" -@@ -4904,9 +5529,17 @@ - version "0.2.9" - resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" - --parallel-webpack@^2.1.0: -- version "2.2.0" -- resolved "https://registry.yarnpkg.com/parallel-webpack/-/parallel-webpack-2.2.0.tgz#7171440b684444610ba890d32439a33666ab46cb" -+parallel-transform@^1.1.0: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" -+ dependencies: -+ cyclist "~0.2.2" -+ inherits "^2.0.3" -+ readable-stream "^2.1.5" -+ -+parallel-webpack@^2.3.0: -+ version "2.3.0" -+ resolved "https://registry.yarnpkg.com/parallel-webpack/-/parallel-webpack-2.3.0.tgz#a614625e25647cea9655918cb80cf829fa674ff8" - dependencies: - ajv "^4.9.2" - bluebird "^3.0.6" -@@ -4949,15 +5582,6 @@ - dependencies: - color-convert "~0.5.0" - --parse-glob@^3.0.4: -- version "3.0.4" -- resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" -- dependencies: -- glob-base "^0.3.0" -- is-dotfile "^1.0.0" -- is-extglob "^1.0.0" -- is-glob "^2.0.0" -- - parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" -@@ -4976,6 +5600,10 @@ - version "0.0.0" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" - -+path-dirname@^1.0.0: -+ version "1.0.2" -+ resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" -+ - path-exists@^2.0.0, path-exists@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" -@@ -5064,6 +5692,12 @@ - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - -+pkg-dir@^2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" -+ dependencies: -+ find-up "^2.1.0" -+ - plist@^2.0.0, plist@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/plist/-/plist-2.1.0.tgz#57ccdb7a0821df21831217a3cad54e3e146a1025" -@@ -5206,27 +5840,27 @@ - postcss "^5.0.14" - postcss-selector-parser "^2.0.0" - --postcss-modules-extract-imports@^1.0.0: -+postcss-modules-extract-imports@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.0.tgz#66140ecece38ef06bf0d3e355d69bf59d141ea85" - dependencies: - postcss "^6.0.1" - --postcss-modules-local-by-default@^1.0.1: -+postcss-modules-local-by-default@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069" - dependencies: - css-selector-tokenizer "^0.7.0" - postcss "^6.0.1" - --postcss-modules-scope@^1.0.0: -+postcss-modules-scope@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90" - dependencies: - css-selector-tokenizer "^0.7.0" - postcss "^6.0.1" - --postcss-modules-values@^1.1.0: -+postcss-modules-values@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20" - dependencies: -@@ -5338,13 +5972,9 @@ - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - --preserve@^0.2.0: -- version "0.2.0" -- resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" -- --prettier@1.11.1: -- version "1.11.1" -- resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.11.1.tgz#61e43fc4cd44e68f2b0dfc2c38cd4bb0fccdcc75" -+prettier@1.13.0: -+ version "1.13.0" -+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.13.0.tgz#054de8d5fb1a4405c845d16183f58a2c301f6f16" - - pretty-bytes@^1.0.2: - version "1.0.4" -@@ -5360,7 +5990,7 @@ - renderkid "^2.0.1" - utila "~0.4" - --private@^0.1.7: -+private@^0.1.7, private@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - -@@ -5368,6 +5998,10 @@ - version "1.0.7" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" - -+process-nextick-args@~2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" -+ - process@^0.11.0: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" -@@ -5383,6 +6017,10 @@ - version "2.0.0" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" - -+promise-inflight@^1.0.1: -+ version "1.0.1" -+ resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" -+ - promise@^7.1.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" -@@ -5410,10 +6048,21 @@ - forwarded "~0.1.2" - ipaddr.js "1.5.2" - -+proxy-addr@~2.0.3: -+ version "2.0.3" -+ resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.3.tgz#355f262505a621646b3130a728eb647e22055341" -+ dependencies: -+ forwarded "~0.1.2" -+ ipaddr.js "1.6.0" -+ - prr@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" - -+prr@~1.0.1: -+ version "1.0.1" -+ resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" -+ - pruner@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/pruner/-/pruner-0.0.7.tgz#345fbcb3e80701163a1d7adf56bac229a5a1e4c1" -@@ -5434,6 +6083,21 @@ - parse-asn1 "^5.0.0" - randombytes "^2.0.1" - -+pump@^2.0.0, pump@^2.0.1: -+ version "2.0.1" -+ resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" -+ dependencies: -+ end-of-stream "^1.1.0" -+ once "^1.3.1" -+ -+pumpify@^1.3.3: -+ version "1.4.0" -+ resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.4.0.tgz#80b7c5df7e24153d03f0e7ac8a05a5d068bd07fb" -+ dependencies: -+ duplexify "^3.5.3" -+ inherits "^2.0.3" -+ pump "^2.0.0" -+ - punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" -@@ -5477,13 +6141,6 @@ - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - --randomatic@^1.1.3: -- version "1.1.7" -- resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" -- dependencies: -- is-number "^3.0.0" -- kind-of "^4.0.0" -- - randombytes@^2.0.0, randombytes@^2.0.1: - version "2.0.5" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.5.tgz#dc009a246b8d09a177b4b7a0ae77bc570f4b1b79" -@@ -5512,9 +6169,9 @@ - minimist "^1.2.0" - strip-json-comments "~2.0.1" - --rcedit@^0.9.0: -- version "0.9.0" -- resolved "https://registry.yarnpkg.com/rcedit/-/rcedit-0.9.0.tgz#3910df57345399e2b0325f4a519007f89e55ef1c" -+rcedit@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/rcedit/-/rcedit-1.0.0.tgz#43309ecbc8814f3582fca6b751748cfad66a16a2" - - read-config-file@3.0.0: - version "3.0.0" -@@ -5583,6 +6240,18 @@ - normalize-package-data "^2.3.2" - path-type "^2.0.0" - -+"readable-stream@1 || 2", readable-stream@^2.0.4, readable-stream@^2.1.5: -+ version "2.3.6" -+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" -+ dependencies: -+ core-util-is "~1.0.0" -+ inherits "~2.0.3" -+ isarray "~1.0.0" -+ process-nextick-args "~2.0.0" -+ safe-buffer "~5.1.1" -+ string_decoder "~1.1.1" -+ util-deprecate "~1.0.1" -+ - readable-stream@1.0: - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" -@@ -5610,7 +6279,7 @@ - isarray "0.0.1" - string_decoder "~0.10.x" - --readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2, readable-stream@^2.2.6: -+readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.2.6: - version "2.3.3" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" - dependencies: -@@ -5673,21 +6342,22 @@ - version "0.11.0" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1" - --regex-cache@^0.4.2: -- version "0.4.4" -- resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" -- dependencies: -- is-equal-shallow "^0.1.3" -- - regex-not@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.0.tgz#42f83e39771622df826b02af176525d6a5f157f9" - dependencies: - extend-shallow "^2.0.1" - -+regex-not@^1.0.2: -+ version "1.0.2" -+ resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" -+ dependencies: -+ extend-shallow "^3.0.2" -+ safe-regex "^1.1.0" -+ - regexpp@^1.0.1: -- version "1.0.1" -- resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.0.1.tgz#d857c3a741dce075c2848dcb019a0a975b190d43" -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" - - regexpu-core@^1.0.0: - version "1.0.0" -@@ -5742,7 +6412,7 @@ - version "1.1.2" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" - --repeat-string@^1.5.2, repeat-string@^1.6.1: -+repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - -@@ -5779,18 +6449,18 @@ - tunnel-agent "^0.6.0" - uuid "^3.1.0" - --request@2.81.0, request@~2.81.0: -- version "2.81.0" -- resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" -+request@~2.79.0: -+ version "2.79.0" -+ resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" - dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" -- caseless "~0.12.0" -+ caseless "~0.11.0" - combined-stream "~1.0.5" - extend "~3.0.0" - forever-agent "~0.6.1" - form-data "~2.1.1" -- har-validator "~4.2.1" -+ har-validator "~2.0.6" - hawk "~3.1.3" - http-signature "~1.1.0" - is-typedarray "~1.0.0" -@@ -5798,26 +6468,24 @@ - json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - oauth-sign "~0.8.1" -- performance-now "^0.2.0" -- qs "~6.4.0" -- safe-buffer "^5.0.1" -+ qs "~6.3.0" - stringstream "~0.0.4" - tough-cookie "~2.3.0" -- tunnel-agent "^0.6.0" -+ tunnel-agent "~0.4.1" - uuid "^3.0.0" - --request@~2.79.0: -- version "2.79.0" -- resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" -+request@~2.81.0: -+ version "2.81.0" -+ resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" - dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" -- caseless "~0.11.0" -+ caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.0" - forever-agent "~0.6.1" - form-data "~2.1.1" -- har-validator "~2.0.6" -+ har-validator "~4.2.1" - hawk "~3.1.3" - http-signature "~1.1.0" - is-typedarray "~1.0.0" -@@ -5825,10 +6493,12 @@ - json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - oauth-sign "~0.8.1" -- qs "~6.3.0" -+ performance-now "^0.2.0" -+ qs "~6.4.0" -+ safe-buffer "^5.0.1" - stringstream "~0.0.4" - tough-cookie "~2.3.0" -- tunnel-agent "~0.4.1" -+ tunnel-agent "^0.6.0" - uuid "^3.0.0" - - require-directory@^2.1.1: -@@ -5871,17 +6541,15 @@ - onetime "^2.0.0" - signal-exit "^3.0.2" - -+ret@~0.1.10: -+ version "0.1.15" -+ resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" -+ - rgb2hex@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/rgb2hex/-/rgb2hex-0.1.0.tgz#ccd55f860ae0c5c4ea37504b958e442d8d12325b" - --right-align@^0.1.1: -- version "0.1.3" -- resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" -- dependencies: -- align-text "^0.1.1" -- --rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.2, rimraf@^2.6.1: -+rimraf@2, rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - dependencies: -@@ -5904,6 +6572,12 @@ - dependencies: - is-promise "^2.1.0" - -+run-queue@^1.0.0, run-queue@^1.0.3: -+ version "1.0.3" -+ resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" -+ dependencies: -+ aproba "^1.1.1" -+ - rx-lite-aggregates@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" -@@ -5922,10 +6596,24 @@ - version "5.1.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" - -+safe-buffer@^5.1.2: -+ version "5.1.2" -+ resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" -+ - safe-buffer@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" - -+safe-regex@^1.1.0: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" -+ dependencies: -+ ret "~0.1.10" -+ -+safer-buffer@^2.1.0: -+ version "2.1.2" -+ resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" -+ - sanitize-filename@^1.6.0, sanitize-filename@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.1.tgz#612da1c96473fa02dccda92dcd5b4ab164a6772a" -@@ -5941,14 +6629,14 @@ - scss-tokenizer "^0.2.3" - yargs "^7.0.0" - --sass-loader@^6.0.6: -- version "6.0.6" -- resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-6.0.6.tgz#e9d5e6c1f155faa32a4b26d7a9b7107c225e40f9" -+sass-loader@^7.0.1: -+ version "7.0.1" -+ resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-7.0.1.tgz#fd937259ccba3a9cfe0d5f8a98746d48adfcc261" - dependencies: -- async "^2.1.5" -- clone-deep "^0.3.0" -+ clone-deep "^2.0.1" - loader-utils "^1.0.1" - lodash.tail "^4.1.1" -+ neo-async "^2.5.0" - pify "^3.0.0" - - sax@1.2.1: -@@ -5959,11 +6647,12 @@ - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - --schema-utils@^0.3.0: -- version "0.3.0" -- resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf" -+schema-utils@^0.4.4, schema-utils@^0.4.5: -+ version "0.4.5" -+ resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.5.tgz#21836f0608aac17b78f9e3e24daff14a5ca13a3e" - dependencies: -- ajv "^5.0.0" -+ ajv "^6.1.0" -+ ajv-keywords "^3.1.0" - - scss-tokenizer@^0.2.3: - version "0.2.3" -@@ -6012,6 +6701,28 @@ - range-parser "~1.2.0" - statuses "~1.3.1" - -+send@0.16.2: -+ version "0.16.2" -+ resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" -+ dependencies: -+ debug "2.6.9" -+ depd "~1.1.2" -+ destroy "~1.0.4" -+ encodeurl "~1.0.2" -+ escape-html "~1.0.3" -+ etag "~1.8.1" -+ fresh "0.5.2" -+ http-errors "~1.6.2" -+ mime "1.4.1" -+ ms "2.0.0" -+ on-finished "~2.3.0" -+ range-parser "~1.2.0" -+ statuses "~1.4.0" -+ -+serialize-javascript@^1.4.0: -+ version "1.5.0" -+ resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.5.0.tgz#1aa336162c88a890ddad5384baebc93a655161fe" -+ - serve-static@1.13.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719" -@@ -6021,6 +6732,15 @@ - parseurl "~1.3.2" - send "0.16.1" - -+serve-static@1.13.2: -+ version "1.13.2" -+ resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" -+ dependencies: -+ encodeurl "~1.0.2" -+ escape-html "~1.0.3" -+ parseurl "~1.3.2" -+ send "0.16.2" -+ - set-blocking@^2.0.0, set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" -@@ -6072,13 +6792,12 @@ - inherits "^2.0.1" - safe-buffer "^5.0.1" - --shallow-clone@^0.1.2: -- version "0.1.2" -- resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-0.1.2.tgz#5909e874ba77106d73ac414cfec1ffca87d97060" -+shallow-clone@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-1.0.0.tgz#4480cd06e882ef68b2ad88a3ea54832e2c48b571" - dependencies: - is-extendable "^0.1.1" -- kind-of "^2.0.1" -- lazy-cache "^0.2.3" -+ kind-of "^5.0.0" - mixin-object "^2.0.1" - - shebang-command@^1.2.0: -@@ -6168,10 +6887,6 @@ - version "2.0.0" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" - --source-list-map@~0.1.7: -- version "0.1.8" -- resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106" -- - source-map-resolve@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.3.1.tgz#610f6122a445b8dd51535a2a71b783dfc1248761" -@@ -6197,9 +6912,9 @@ - dependencies: - source-map "^0.5.6" - --source-map-support@^0.5.3: -- version "0.5.3" -- resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.3.tgz#2b3d5fff298cfa4d1afd7d4352d569e9a0158e76" -+source-map-support@^0.5.3, source-map-support@^0.5.4: -+ version "0.5.4" -+ resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.4.tgz#54456efa89caa9270af7cd624cc2f123e51fbae8" - dependencies: - source-map "^0.6.0" - -@@ -6211,7 +6926,7 @@ - version "0.3.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.3.0.tgz#7ecaf13b57bcd09da8a40c5d269db33799d4aaf9" - --source-map@0.5.x, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3: -+source-map@0.5.x, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.3: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - -@@ -6289,6 +7004,12 @@ - jsbn "~0.1.0" - tweetnacl "~0.14.0" - -+ssri@^5.2.4: -+ version "5.3.0" -+ resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.3.0.tgz#ba3872c9c6d33a0704a7d71ff045e5ec48999d06" -+ dependencies: -+ safe-buffer "^5.1.1" -+ - stat-mode@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/stat-mode/-/stat-mode-0.2.2.tgz#e6c80b623123d7d80cf132ce538f346289072502" -@@ -6300,7 +7021,7 @@ - define-property "^0.2.5" - object-copy "^0.1.0" - --"statuses@>= 1.3.1 < 2": -+"statuses@>= 1.3.1 < 2", statuses@~1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" - -@@ -6321,6 +7042,13 @@ - inherits "~2.0.1" - readable-stream "^2.0.2" - -+stream-each@^1.1.0: -+ version "1.2.2" -+ resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd" -+ dependencies: -+ end-of-stream "^1.1.0" -+ stream-shift "^1.0.0" -+ - stream-http@^2.3.1: - version "2.7.2" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.2.tgz#40a050ec8dc3b53b33d9909415c02c0bf1abfbad" -@@ -6331,6 +7059,10 @@ - to-arraybuffer "^1.0.0" - xtend "^4.0.0" - -+stream-shift@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" -+ - strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" -@@ -6360,6 +7092,12 @@ - dependencies: - safe-buffer "~5.1.0" - -+string_decoder@~1.1.1: -+ version "1.1.1" -+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" -+ dependencies: -+ safe-buffer "~5.1.0" -+ - stringstream@~0.0.4, stringstream@~0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" -@@ -6404,12 +7142,12 @@ - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - --style-loader@^0.19.1: -- version "0.19.1" -- resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.19.1.tgz#591ffc80bcefe268b77c5d9ebc0505d772619f85" -+style-loader@^0.21.0: -+ version "0.21.0" -+ resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.21.0.tgz#68c52e5eb2afc9ca92b6274be277ee59aea3a852" - dependencies: -- loader-utils "^1.0.2" -- schema-utils "^0.3.0" -+ loader-utils "^1.1.0" -+ schema-utils "^0.4.5" - - sumchecker@^1.2.0: - version "1.3.1" -@@ -6434,18 +7172,24 @@ - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - --supports-color@^3.1.0, supports-color@^3.1.2, supports-color@^3.2.3, supports-color@~3.2.3: -+supports-color@^3.1.2, supports-color@^3.2.3, supports-color@~3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - dependencies: - has-flag "^1.0.0" - --supports-color@^4.0.0, supports-color@^4.2.1, supports-color@^4.4.0: -+supports-color@^4.0.0, supports-color@^4.4.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" - dependencies: - has-flag "^2.0.0" - -+supports-color@^5.3.0: -+ version "5.4.0" -+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" -+ dependencies: -+ has-flag "^3.0.0" -+ - svgo@^0.7.0: - version "0.7.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5" -@@ -6469,22 +7213,9 @@ - slice-ansi "1.0.0" - string-width "^2.1.1" - --tapable@^0.2.5, tapable@^0.2.7, tapable@~0.2.5: -- version "0.2.8" -- resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22" -- --tar-pack@^3.4.0: -- version "3.4.1" -- resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f" -- dependencies: -- debug "^2.2.0" -- fstream "^1.0.10" -- fstream-ignore "^1.0.5" -- once "^1.3.3" -- readable-stream "^2.1.4" -- rimraf "^2.5.1" -- tar "^2.2.1" -- uid-number "^0.0.6" -+tapable@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.0.0.tgz#cbb639d9002eed9c6b5975eb20598d7936f1f9f2" - - tar-stream@^1.5.0: - version "1.5.4" -@@ -6495,7 +7226,7 @@ - readable-stream "^2.0.0" - xtend "^4.0.0" - --tar@^2.0.0, tar@^2.2.1: -+tar@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" - dependencies: -@@ -6503,6 +7234,18 @@ - fstream "^1.0.2" - inherits "2" - -+tar@^4: -+ version "4.4.2" -+ resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.2.tgz#60685211ba46b38847b1ae7ee1a24d744a2cd462" -+ dependencies: -+ chownr "^1.0.1" -+ fs-minipass "^1.2.5" -+ minipass "^2.2.4" -+ minizlib "^1.1.0" -+ mkdirp "^0.5.0" -+ safe-buffer "^5.1.2" -+ yallist "^3.0.2" -+ - temp-file@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/temp-file/-/temp-file-3.1.1.tgz#8823649aa4e8a6e419eb71b601a2e4d472b0f24f" -@@ -6545,6 +7288,13 @@ - version "0.0.2" - resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-0.0.2.tgz#cfedf88e60c00dd9697b61fdd2a8343a9b680eaf" - -+through2@^2.0.0: -+ version "2.0.3" -+ resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" -+ dependencies: -+ readable-stream "^2.1.5" -+ xtend "~4.0.1" -+ - through2@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/through2/-/through2-0.2.3.tgz#eb3284da4ea311b6cc8ace3653748a52abf25a3f" -@@ -6617,6 +7367,15 @@ - extend-shallow "^2.0.1" - regex-not "^1.0.0" - -+to-regex@^3.0.2: -+ version "3.0.2" -+ resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" -+ dependencies: -+ define-property "^2.0.2" -+ extend-shallow "^3.0.2" -+ regex-not "^1.0.2" -+ safe-regex "^1.1.0" -+ - to-space-case@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/to-space-case/-/to-space-case-1.0.0.tgz#b052daafb1b2b29dc770cea0163e5ec0ebc9fc17" -@@ -6663,6 +7422,10 @@ - dependencies: - utf8-byte-length "^1.0.1" - -+tryer@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.0.tgz#027b69fa823225e551cace3ef03b11f6ab37c1d7" -+ - tryit@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" -@@ -6728,8 +7491,8 @@ - tslib "^1.7.1" - - tsutils@^2.13.1: -- version "2.22.2" -- resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.22.2.tgz#0b9f3d87aa3eb95bd32d26ce2b88aa329a657951" -+ version "2.25.1" -+ resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.25.1.tgz#24a46342ab8b174a3fbde632e60dcd11b64982f9" - dependencies: - tslib "^1.8.1" - -@@ -6768,25 +7531,39 @@ - media-typer "0.3.0" - mime-types "~2.1.15" - -+type-is@~1.6.16: -+ version "1.6.16" -+ resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" -+ dependencies: -+ media-typer "0.3.0" -+ mime-types "~2.1.18" -+ - typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - --typescript-eslint-parser@^14.0.0: -- version "14.0.0" -- resolved "https://registry.yarnpkg.com/typescript-eslint-parser/-/typescript-eslint-parser-14.0.0.tgz#c90a8f541c1d96e5c55e2807c61d154e788520f9" -+typescript-eslint-parser@^16.0.0: -+ version "16.0.0" -+ resolved "https://registry.yarnpkg.com/typescript-eslint-parser/-/typescript-eslint-parser-16.0.0.tgz#14a9ab75932b15af919602faef553c6f0487f352" - dependencies: - lodash.unescape "4.0.1" - semver "5.5.0" - --typescript@^2.8.1: -- version "2.8.1" -- resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.8.1.tgz#6160e4f8f195d5ba81d4876f9c0cc1fbc0820624" -+typescript@^2.9.1: -+ version "2.9.1" -+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.1.tgz#fdb19d2c67a15d11995fd15640e373e09ab09961" - - ua-parser-js@^0.7.9: - version "0.7.17" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" - -+uglify-es@^3.3.4: -+ version "3.3.9" -+ resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" -+ dependencies: -+ commander "~2.13.0" -+ source-map "~0.6.1" -+ - uglify-js@3.1.x: - version "3.1.6" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.1.6.tgz#918832602036e95d2318e11f27ee8461a8592c5d" -@@ -6794,30 +7571,18 @@ - commander "~2.11.0" - source-map "~0.6.1" - --uglify-js@^2.8.27, uglify-js@^2.8.29: -- version "2.8.29" -- resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" -- dependencies: -- source-map "~0.5.1" -- yargs "~3.10.0" -- optionalDependencies: -- uglify-to-browserify "~1.0.0" -- --uglify-to-browserify@~1.0.0: -- version "1.0.2" -- resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" -- --uglifyjs-webpack-plugin@^0.4.6: -- version "0.4.6" -- resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz#b951f4abb6bd617e66f63eb891498e391763e309" -+uglifyjs-webpack-plugin@^1.2.4: -+ version "1.2.5" -+ resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.5.tgz#2ef8387c8f1a903ec5e44fa36f9f3cbdcea67641" - dependencies: -- source-map "^0.5.6" -- uglify-js "^2.8.29" -- webpack-sources "^1.0.1" -- --uid-number@^0.0.6: -- version "0.0.6" -- resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" -+ cacache "^10.0.4" -+ find-cache-dir "^1.0.0" -+ schema-utils "^0.4.5" -+ serialize-javascript "^1.4.0" -+ source-map "^0.6.1" -+ uglify-es "^3.3.4" -+ webpack-sources "^1.1.0" -+ worker-farm "^1.5.2" - - underscore@~1.6.0: - version "1.6.0" -@@ -6846,6 +7611,18 @@ - version "2.0.0" - resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" - -+unique-filename@^1.1.0: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3" -+ dependencies: -+ unique-slug "^2.0.0" -+ -+unique-slug@^2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.0.tgz#db6676e7c7cc0629878ff196097c78855ae9f4ab" -+ dependencies: -+ imurmurhash "^0.1.4" -+ - unique-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" -@@ -6871,6 +7648,10 @@ - version "2.0.1" - resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" - -+upath@^1.0.0: -+ version "1.0.5" -+ resolved "https://registry.yarnpkg.com/upath/-/upath-1.0.5.tgz#02cab9ecebe95bbec6d5fc2566325725ab6d1a73" -+ - update-notifier@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.3.0.tgz#4e8827a6bb915140ab093559d7014e3ebb837451" -@@ -6895,13 +7676,19 @@ - dependencies: - punycode "^2.1.0" - -+uri-js@^4.2.1: -+ version "4.2.1" -+ resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.1.tgz#4595a80a51f356164e22970df64c7abd6ade9850" -+ dependencies: -+ punycode "^2.1.0" -+ - urix@^0.1.0, urix@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - --url-join@^2.0.2: -- version "2.0.2" -- resolved "https://registry.yarnpkg.com/url-join/-/url-join-2.0.2.tgz#c072756967ad24b8b59e5741551caac78f50b8b7" -+url-join@^4.0.0: -+ version "4.0.0" -+ resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.0.tgz#4d3340e807d3773bda9991f8305acdcc2a665d2a" - - url-parse-lax@^1.0.0: - version "1.0.0" -@@ -6943,7 +7730,7 @@ - version "1.0.3" - resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f" - --util.promisify@^1.0.0: -+util.promisify@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" - dependencies: -@@ -7009,18 +7796,28 @@ - version "0.0.11" - resolved "https://registry.yarnpkg.com/walkdir/-/walkdir-0.0.11.tgz#a16d025eb931bd03b52f308caed0f40fcebe9532" - --watchpack@^1.3.1, watchpack@^1.4.0: -- version "1.4.0" -- resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.4.0.tgz#4a1472bcbb952bd0a9bb4036801f954dfb39faac" -+watchpack@^1.5.0: -+ version "1.6.0" -+ resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" - dependencies: -- async "^2.1.2" -- chokidar "^1.7.0" -+ chokidar "^2.0.2" - graceful-fs "^4.1.2" -+ neo-async "^2.5.0" - - wdio-dot-reporter@~0.0.8: - version "0.0.9" - resolved "https://registry.yarnpkg.com/wdio-dot-reporter/-/wdio-dot-reporter-0.0.9.tgz#929b2adafd49d6b0534fda068e87319b47e38fe5" - -+webassemblyjs@1.4.3: -+ version "1.4.3" -+ resolved "https://registry.yarnpkg.com/webassemblyjs/-/webassemblyjs-1.4.3.tgz#0591893efb8fbde74498251cbe4b2d83df9239cb" -+ dependencies: -+ "@webassemblyjs/ast" "1.4.3" -+ "@webassemblyjs/validation" "1.4.3" -+ "@webassemblyjs/wasm-parser" "1.4.3" -+ "@webassemblyjs/wast-parser" "1.4.3" -+ long "^3.2.0" -+ - webdriverio@^4.8.0: - version "4.8.0" - resolved "https://registry.yarnpkg.com/webdriverio/-/webdriverio-4.8.0.tgz#d52929b749080f89967f6e1614051cbc8172d132" -@@ -7048,21 +7845,38 @@ - wdio-dot-reporter "~0.0.8" - wgxpath "~1.0.0" - --webpack-dev-middleware@^2.0.3: -- version "2.0.3" -- resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-2.0.3.tgz#44e15480ec58d275417ac4d93a0126c7b72450bd" -+webpack-bundle-analyzer@^2.13.0: -+ version "2.13.0" -+ resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.13.0.tgz#8d7db44c3d4844bc911890998e1110514cf12264" -+ dependencies: -+ acorn "^5.3.0" -+ bfj-node4 "^5.2.0" -+ chalk "^2.3.0" -+ commander "^2.13.0" -+ ejs "^2.5.7" -+ express "^4.16.2" -+ filesize "^3.5.11" -+ gzip-size "^4.1.0" -+ lodash "^4.17.4" -+ mkdirp "^0.5.1" -+ opener "^1.4.3" -+ ws "^4.0.0" -+ -+webpack-dev-middleware@^3.1.3: -+ version "3.1.3" -+ resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.1.3.tgz#8b32aa43da9ae79368c1bf1183f2b6cf5e1f39ed" - dependencies: - loud-rejection "^1.6.0" - memory-fs "~0.4.1" - mime "^2.1.0" - path-is-absolute "^1.0.0" - range-parser "^1.0.3" -- url-join "^2.0.2" -+ url-join "^4.0.0" - webpack-log "^1.0.1" - --webpack-hot-middleware@^2.21.0: -- version "2.21.0" -- resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.21.0.tgz#7b3c113a7a4b301c91e0749573c7aab28b414b52" -+webpack-hot-middleware@^2.22.2: -+ version "2.22.2" -+ resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.22.2.tgz#623b77ce591fcd4e1fb99f18167781443e50afac" - dependencies: - ansi-html "0.0.7" - html-entities "^1.2.0" -@@ -7078,18 +7892,11 @@ - loglevelnext "^1.0.1" - uuid "^3.1.0" - --webpack-merge@^4.1.0: -- version "4.1.1" -- resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.1.1.tgz#f1197a0a973e69c6fbeeb6d658219aa8c0c13555" -- dependencies: -- lodash "^4.17.4" -- --webpack-sources@^0.1.4: -- version "0.1.5" -- resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.1.5.tgz#aa1f3abf0f0d74db7111c40e500b84f966640750" -+webpack-merge@^4.1.2: -+ version "4.1.2" -+ resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.1.2.tgz#5d372dddd3e1e5f8874f5bf5a8e929db09feb216" - dependencies: -- source-list-map "~0.1.7" -- source-map "~0.5.3" -+ lodash "^4.17.5" - - webpack-sources@^1.0.1: - version "1.0.1" -@@ -7098,58 +7905,39 @@ - source-list-map "^2.0.0" - source-map "~0.5.3" - --webpack@^2.2.0: -- version "2.7.0" -- resolved "https://registry.yarnpkg.com/webpack/-/webpack-2.7.0.tgz#b2a1226804373ffd3d03ea9c6bd525067034f6b1" -+webpack-sources@^1.1.0: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" - dependencies: -- acorn "^5.0.0" -- acorn-dynamic-import "^2.0.0" -- ajv "^4.7.0" -- ajv-keywords "^1.1.1" -- async "^2.1.2" -- enhanced-resolve "^3.3.0" -- interpret "^1.0.0" -- json-loader "^0.5.4" -- json5 "^0.5.1" -- loader-runner "^2.3.0" -- loader-utils "^0.2.16" -- memory-fs "~0.4.1" -- mkdirp "~0.5.0" -- node-libs-browser "^2.0.0" -- source-map "^0.5.3" -- supports-color "^3.1.0" -- tapable "~0.2.5" -- uglify-js "^2.8.27" -- watchpack "^1.3.1" -- webpack-sources "^1.0.1" -- yargs "^6.0.0" -+ source-list-map "^2.0.0" -+ source-map "~0.6.1" - --webpack@^3.10.0: -- version "3.10.0" -- resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.10.0.tgz#5291b875078cf2abf42bdd23afe3f8f96c17d725" -+webpack@^4.8.3: -+ version "4.8.3" -+ resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.8.3.tgz#957c8e80000f9e5cc03d775e78b472d8954f4eeb" - dependencies: -+ "@webassemblyjs/ast" "1.4.3" -+ "@webassemblyjs/wasm-edit" "1.4.3" -+ "@webassemblyjs/wasm-parser" "1.4.3" - acorn "^5.0.0" -- acorn-dynamic-import "^2.0.0" -- ajv "^5.1.5" -- ajv-keywords "^2.0.0" -- async "^2.1.2" -- enhanced-resolve "^3.4.0" -- escope "^3.6.0" -- interpret "^1.0.0" -- json-loader "^0.5.4" -- json5 "^0.5.1" -+ acorn-dynamic-import "^3.0.0" -+ ajv "^6.1.0" -+ ajv-keywords "^3.1.0" -+ chrome-trace-event "^0.1.1" -+ enhanced-resolve "^4.0.0" -+ eslint-scope "^3.7.1" - loader-runner "^2.3.0" - loader-utils "^1.1.0" - memory-fs "~0.4.1" -+ micromatch "^3.1.8" - mkdirp "~0.5.0" -+ neo-async "^2.5.0" - node-libs-browser "^2.0.0" -- source-map "^0.5.3" -- supports-color "^4.2.1" -- tapable "^0.2.7" -- uglifyjs-webpack-plugin "^0.4.6" -- watchpack "^1.4.0" -+ schema-utils "^0.4.4" -+ tapable "^1.0.0" -+ uglifyjs-webpack-plugin "^1.2.4" -+ watchpack "^1.5.0" - webpack-sources "^1.0.1" -- yargs "^8.0.2" - - wgxpath@~1.0.0: - version "1.0.0" -@@ -7189,14 +7977,6 @@ - dependencies: - string-width "^1.0.1" - --window-size@0.1.0: -- version "0.1.0" -- resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" -- --wordwrap@0.0.2: -- version "0.0.2" -- resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" -- - wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" -@@ -7212,6 +7992,12 @@ - errno "^0.1.4" - xtend "^4.0.1" - -+worker-farm@^1.5.2: -+ version "1.6.0" -+ resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0" -+ dependencies: -+ errno "~0.1.7" -+ - wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" -@@ -7237,6 +8023,13 @@ - dependencies: - mkdirp "^0.5.1" - -+ws@^4.0.0: -+ version "4.1.0" -+ resolved "https://registry.yarnpkg.com/ws/-/ws-4.1.0.tgz#a979b5d7d4da68bf54efe0408967c324869a7289" -+ dependencies: -+ async-limiter "~1.0.0" -+ safe-buffer "~5.1.0" -+ - xdg-basedir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" -@@ -7277,7 +8070,7 @@ - version "0.1.27" - resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" - --xtend@^4.0.0, xtend@^4.0.1: -+xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - -@@ -7298,15 +8091,17 @@ - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - -+y18n@^4.0.0: -+ version "4.0.0" -+ resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" -+ - yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - --yargs-parser@^4.2.0: -- version "4.2.1" -- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" -- dependencies: -- camelcase "^3.0.0" -+yallist@^3.0.0, yallist@^3.0.2: -+ version "3.0.2" -+ resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" - - yargs-parser@^5.0.0: - version "5.0.0" -@@ -7314,18 +8109,6 @@ - dependencies: - camelcase "^3.0.0" - --yargs-parser@^7.0.0: -- version "7.0.0" -- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" -- dependencies: -- camelcase "^4.1.0" -- --yargs-parser@^8.0.0: -- version "8.0.0" -- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.0.0.tgz#21d476330e5a82279a4b881345bf066102e219c6" -- dependencies: -- camelcase "^4.1.0" -- - yargs-parser@^9.0.2: - version "9.0.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" -@@ -7349,24 +8132,6 @@ - y18n "^3.2.1" - yargs-parser "^9.0.2" - --yargs@^6.0.0: -- version "6.6.0" -- resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" -- dependencies: -- camelcase "^3.0.0" -- cliui "^3.2.0" -- decamelize "^1.1.1" -- get-caller-file "^1.0.1" -- os-locale "^1.4.0" -- read-pkg-up "^1.0.1" -- require-directory "^2.1.1" -- require-main-filename "^1.0.1" -- set-blocking "^2.0.0" -- string-width "^1.0.2" -- which-module "^1.0.0" -- y18n "^3.2.1" -- yargs-parser "^4.2.0" -- - yargs@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" -@@ -7385,33 +8150,6 @@ - y18n "^3.2.1" - yargs-parser "^5.0.0" - --yargs@^8.0.2: -- version "8.0.2" -- resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" -- dependencies: -- camelcase "^4.1.0" -- cliui "^3.2.0" -- decamelize "^1.1.1" -- get-caller-file "^1.0.1" -- os-locale "^2.0.0" -- read-pkg-up "^2.0.0" -- require-directory "^2.1.1" -- require-main-filename "^1.0.1" -- set-blocking "^2.0.0" -- string-width "^2.0.0" -- which-module "^2.0.0" -- y18n "^3.2.1" -- yargs-parser "^7.0.0" -- --yargs@~3.10.0: -- version "3.10.0" -- resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" -- dependencies: -- camelcase "^1.0.2" -- cliui "^2.1.0" -- decamelize "^1.0.0" -- window-size "0.1.0" -- - yauzl@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005" diff --git a/app/test/fixtures/merge-parser/desktop/failed-merge-stale-branch-into-master.txt b/app/test/fixtures/merge-parser/desktop/failed-merge-stale-branch-into-master.txt deleted file mode 100644 index 4143e782258..00000000000 --- a/app/test/fixtures/merge-parser/desktop/failed-merge-stale-branch-into-master.txt +++ /dev/null @@ -1,434 +0,0 @@ -added in remote - their 100644 a309d474e0ebfbd83ab04a460c27dd2b8906c4e8 .eslintignore -@@ -0,0 +1,3 @@ -+node_modules -+app/node_modules/ -+script/changelog/node_modules -\ No newline at end of file -merged - result 100644 22724fb6c88b57702fe40d191883a455f70b01a1 .prettierignore - our 100644 d247d9a68070ec5848c5feb83bddbfab02adbb6c .prettierignore -@@ -1,16 +1,17 @@ --out/ -+app/static/common -+app/test/fixtures - dist/ -+gemoji - node_modules/ -+out/ -+ - npm-debug.log - yarn-error.log --app/node_modules/ -+ - .DS_Store - .awcache - .idea/ - .eslintcache - --app/static/common --app/test/fixtures --gemoji - *.json - *.md -changed in both - base 100644 dc892d10739ef87c70391aedcfdc3241753eebbb package.json - our 100644 461f60af798d32097510dcd519c5cdd4b860771e package.json - their 100644 a230a49de70c920a24d34b1af9952a17b72e7a1c package.json -@@ -10,6 +10,7 @@ - "test:unit": "ts-node script/unit-tests.ts", - "test:script": "mocha -t 10000 --require ts-node/register script/changelog/test/*.ts", - "test": "yarn test:unit && yarn test:script && yarn test:integration", -+<<<<<<< .our - "test:setup": "ts-node -P script/tsconfig.json script/test-setup.ts", - "test:review": "ts-node -P script/tsconfig.json script/test-review.ts", - "postinstall": "cd app && yarn install --force && cd .. && git submodule update --recursive --init && yarn compile:tslint && yarn compile:script", -@@ -19,6 +20,21 @@ - "compile:prod": "cross-env NODE_ENV=production parallel-webpack --config app/webpack.production.ts", - "build:dev": "yarn compile:dev && cross-env NODE_ENV=development ts-node -P script/tsconfig.json script/build.ts", - "build:prod": "yarn compile:prod && cross-env NODE_ENV=production ts-node -P script/tsconfig.json script/build.ts", -+======= -+ "test:setup": "ts-node script/test-setup.ts", -+ "test:review": "ts-node script/test-review.ts", -+ "postinstall": "yarn install-app && yarn install-changelog && yarn update-submodules && yarn compile:tslint", -+ "install-app": "cd app && yarn install --force && cd ..", -+ "install-changelog": "cd script/changelog && yarn install && cd ../..", -+ "update-submodules": "git submodule update --recursive --init", -+ "start": "cross-env NODE_ENV=development node script/start", -+ "start:prod": "cross-env NODE_ENV=production node script/start", -+ "debug": "cross-env NODE_ENV=development node script/debug", -+ "compile:dev": "cross-env NODE_ENV=development parallel-webpack --config app/webpack.development.js", -+ "compile:prod": "cross-env NODE_ENV=production parallel-webpack --config app/webpack.production.js", -+ "build:dev": "yarn compile:dev && cross-env NODE_ENV=development ts-node script/build.ts", -+ "build:prod": "yarn compile:prod && cross-env NODE_ENV=production ts-node script/build.ts", -+>>>>>>> .their - "package": "ts-node -P script/tsconfig.json script/package.ts", - "generate-octicons": "ts-node -P script/tsconfig.json script/generate-octicons.ts", - "clean:tslint": "rimraf tslint-rules/*.js", -merged - result 100644 f723edfaa45b088c09cc8feef59b701e163fe639 script/changelog/api.ts - our 100644 9cd75d75226643dd9d12c9e42de23c33fdd44a8b script/changelog/api.ts -@@ -1,60 +1,129 @@ --import * as HTTPS from 'https' -+const octokit = require('@octokit/rest')({ -+ timeout: 0, -+ requestMedia: 'application/vnd.github.v3+json', -+ headers: { -+ 'User-Agent': 'what-the-changelog', -+ }, -+}) - --export interface IAPIPR { -+export interface IDesktopPullRequest { - readonly title: string - readonly body: string -+ readonly collaborators: ReadonlySet -+ readonly commits: ReadonlyArray - } - --type GraphQLResponse = { -- readonly data: { -- readonly repository: { -- readonly pullRequest: IAPIPR -- } -- } -+interface IAPIUser { -+ readonly login: string - } - --export function fetchPR(id: number): Promise { -- return new Promise((resolve, reject) => { -- const options: HTTPS.RequestOptions = { -- host: 'api.github.com', -- protocol: 'https:', -- path: '/graphql', -- method: 'POST', -- headers: { -- Authorization: `bearer ${process.env.GITHUB_ACCESS_TOKEN}`, -- 'User-Agent': 'what-the-changelog', -- }, -- } -+interface IAPIPullRequest { -+ readonly title: string -+ readonly body: string -+ readonly user: IAPIUser -+} -+ -+interface IAPICommit { -+ readonly sha: string -+ readonly author?: IAPIUser -+ readonly committer?: IAPIUser -+} - -- const request = HTTPS.request(options, response => { -- let received = '' -- response.on('data', chunk => { -- received += chunk -- }) -- -- response.on('end', () => { -- try { -- const json: GraphQLResponse = JSON.parse(received) -- const pr = json.data.repository.pullRequest -- resolve(pr) -- } catch (e) { -- resolve(null) -- } -- }) -+interface IAPITeam { -+ readonly name: string -+ readonly id: number -+} -+ -+interface IAPITeamMember { -+ readonly login: string -+} -+ -+// this account is assigned by GitHub as the committer for merged pull requests -+// and should be excluded from being considered an external contributor -+const webflowAccount = ['web-flow'] -+ -+export function initialize(token: string) { -+ octokit.authenticate({ -+ type: 'token', -+ token, -+ }) -+} -+ -+export async function getCoreTeamMembers(): Promise> { -+ try { -+ let response = await octokit.orgs.getTeams({ -+ org: 'desktop', -+ per_page: 100, - }) -+ const teams: ReadonlyArray = response.data -+ const coreTeam = teams.find(t => t.name === 'Core') || null - -- const graphql = ` --{ -- repository(owner: "desktop", name: "desktop") { -- pullRequest(number: ${id}) { -- title -- body -+ if (coreTeam == null) { -+ console.error('Unable to find core team on API') -+ return new Set() - } -+ -+ const id = coreTeam.id -+ -+ response = await octokit.orgs.getTeamMembers({ -+ id, -+ role: 'all', -+ per_page: 100, -+ }) -+ const members: ReadonlyArray = response.data -+ -+ return new Set(members.map(m => m.login).concat(webflowAccount)) -+ } catch (err) { -+ console.error('API lookup failed for getCoreTeamMembers', err) -+ return new Set() - } - } --` -- request.write(JSON.stringify({ query: graphql })) - -- request.end() -- }) -+export async function fetchPR(id: number): Promise { -+ try { -+ const pullRequestResponse = await octokit.pullRequests.get({ -+ owner: 'desktop', -+ repo: 'desktop', -+ number: id, -+ }) -+ const { title, body } = pullRequestResponse.data as IAPIPullRequest -+ -+ let commitsResponse = await octokit.pullRequests.getCommits({ -+ owner: 'desktop', -+ repo: 'desktop', -+ number: id, -+ per_page: 100, -+ }) -+ -+ let data: Array = commitsResponse.data -+ while (octokit.hasNextPage(commitsResponse)) { -+ commitsResponse = await octokit.getNextPage(commitsResponse) -+ data = data.concat(commitsResponse.data) -+ } -+ -+ const collaborators = new Set() -+ const commits = new Array() -+ -+ for (const commit of data) { -+ const { sha, author, committer } = commit -+ -+ commits.push(sha) -+ if (author != null && !collaborators.has(author.login)) { -+ collaborators.add(author.login) -+ } -+ if (committer != null && !collaborators.has(committer.login)) { -+ collaborators.add(committer.login) -+ } -+ } -+ -+ return { -+ title: title, -+ body: body, -+ collaborators, -+ commits, -+ } -+ } catch (err) { -+ console.error('API lookup failed for fetchPR', err) -+ return null -+ } - } -added in remote - their 100644 2b223d9eca4c82f03969d8ca5d9d8a80a270a041 script/changelog/package.json -@@ -0,0 +1,24 @@ -+{ -+ "name": "changelog", -+ "repository": { -+ "type": "git", -+ "url": "https://github.com/desktop/desktop.git" -+ }, -+ "description": "GitHub Desktop changelog dependencies", -+ "author": { -+ "name": "GitHub, Inc.", -+ "email": "opensource+desktop@github.com", -+ "url": "https://desktop.github.com/" -+ }, -+ "license": "MIT", -+ "engines": { -+ "node": ">= 7", -+ "yarn": ">= 1.2.0" -+ }, -+ "dependencies": { -+ "@octokit/rest": "^14.0.8", -+ "listify": "^1.0.0" -+ }, -+ "devDependencies": { -+ } -+} -changed in both - base 100644 b0a88cf77391d915e28566a1695cbf31c2ab7bbb script/changelog/parser.ts - our 100644 aad3c838c2d7931127adbc843bdd83ccda5968a1 script/changelog/parser.ts - their 100644 ff08e0ef253ffb980b0ed57114f9fefea05d7fc1 script/changelog/parser.ts -@@ -2,10 +2,11 @@ - import * as Fs from 'fs' - import { gt as greaterThan } from 'semver' - --import { fetchPR, IAPIPR } from './api' -+import { fetchPR, IDesktopPullRequest } from './api' -+ -+const listify: (values: Array) => string = require('listify') - - const PlaceholderChangeType = '???' --const OfficialOwner = 'desktop' - - interface IParsedCommit { - readonly prID: number -@@ -53,7 +54,11 @@ - return issueRef - } - --function getChangelogEntry(commit: IParsedCommit, pr: IAPIPR): string { -+function getChangelogEntry( -+ commit: IParsedCommit, -+ pr: IDesktopPullRequest, -+ externalContributors: ReadonlySet -+): string { - let type = PlaceholderChangeType - const description = capitalized(pr.title) - -@@ -66,15 +71,19 @@ - } - - let attribution = '' -- if (commit.owner !== OfficialOwner) { -- attribution = `. Thanks @${commit.owner}!` -+ -+ if (externalContributors.size > 0) { -+ const mentions = [...externalContributors].map(c => `@${c}`) -+ const combinedMentions = listify(mentions) -+ attribution = `. Thanks ${combinedMentions}!` - } - - return `[${type}] ${description} -${issueRef}${attribution}` - } - - export async function convertToChangelogFormat( -- lines: ReadonlyArray -+ lines: ReadonlyArray, -+ coreMembers: ReadonlySet - ): Promise> { - const entries = [] - for (const line of lines) { -@@ -85,7 +94,13 @@ - throw new Error(`Unable to get PR from API: ${commit.prID}`) - } - -- const entry = getChangelogEntry(commit, pr) -+ const collaborators = pr.collaborators -+ -+ const externalContributors = new Set( -+ [...collaborators].filter(c => !coreMembers.has(c)) -+ ) -+ -+ const entry = getChangelogEntry(commit, pr, externalContributors) - entries.push(entry) - } catch (e) { - console.warn('Unable to parse line, using the full message.', e) -merged - result 100644 8259a4c42f949aa6b07249546bddad9e5a341816 script/changelog/run.ts - our 100644 d324476ff6f0b766693c2b4c2aa8656852a3a4f8 script/changelog/run.ts -@@ -1,4 +1,5 @@ - import { spawn } from './spawn' -+import { getCoreTeamMembers } from './api' - import { getLogLines } from './git' - import { convertToChangelogFormat } from './parser' - import { sort as semverSort } from 'semver' -@@ -47,7 +48,8 @@ - ) - } - -+ const coreMembers = await getCoreTeamMembers() - const lines = await getLogLines(previousVersion) -- const changelogEntries = await convertToChangelogFormat(lines) -+ const changelogEntries = await convertToChangelogFormat(lines, coreMembers) - console.log(jsonStringify(changelogEntries)) - } -added in remote - their 100644 05d54aba4df2a44bee37177eebc9e559e391e602 script/changelog/yarn.lock -@@ -0,0 +1,48 @@ -+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -+# yarn lockfile v1 -+ -+ -+"@octokit/rest@^14.0.8": -+ version "14.0.9" -+ resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-14.0.9.tgz#d5e0a00dcb78901dd7b2ef852acfc0aea7c479ef" -+ dependencies: -+ before-after-hook "^1.1.0" -+ debug "^3.1.0" -+ is-array-buffer "^1.0.0" -+ is-stream "^1.1.0" -+ lodash "^4.17.4" -+ url-template "^2.0.8" -+ -+before-after-hook@^1.1.0: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-1.1.0.tgz#83165e15a59460d13702cb8febd6a1807896db5a" -+ -+debug@^3.1.0: -+ version "3.1.0" -+ resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" -+ dependencies: -+ ms "2.0.0" -+ -+is-array-buffer@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-1.0.0.tgz#f32497a0509d109423f472003f98bab6a8ea34cb" -+ -+is-stream@^1.1.0: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" -+ -+listify@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/listify/-/listify-1.0.0.tgz#03ca7ba2d150d4267773f74e57558d1053d2bee3" -+ -+lodash@^4.17.4: -+ version "4.17.5" -+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" -+ -+ms@2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" -+ -+url-template@^2.0.8: -+ version "2.0.8" -+ resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21" -merged - result 100644 bcb2b3c76a15cdcae1cdb7f5d26d02e9e8ce9935 script/draft-release/run.ts - our 100644 c017ace71061eb0f6db7f42290cb63cca40ab5cb script/draft-release/run.ts -@@ -6,6 +6,7 @@ - convertToChangelogFormat, - getChangelogEntriesSince, - } from '../changelog/parser' -+import { getCoreTeamMembers, initialize } from '../changelog/api' - - import { Channel } from './channel' - import { getNextVersionNumber } from './version' -@@ -88,7 +89,10 @@ - if (noChangesFound) { - printInstructions(nextVersion, []) - } else { -- const changelogEntries = await convertToChangelogFormat(lines) -+ initialize(process.env.GITHUB_ACCESS_TOKEN) -+ -+ const coreMembers = await getCoreTeamMembers() -+ const changelogEntries = await convertToChangelogFormat(lines, coreMembers) - - console.log("Here's what you should do next:\n") - diff --git a/app/test/fixtures/merge-parser/desktop/merge-add-some-context-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-add-some-context-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index ab1459196a2..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-add-some-context-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,58 +0,0 @@ -changed in both - base 100644 461a0bdb996fedc0a40861c61e387fe0d5fad667 app/src/lib/stores/helpers/background-fetcher.ts - our 100644 edadf1aea655fa18f9e3264b999dbc4583fed66b app/src/lib/stores/helpers/background-fetcher.ts - their 100644 8b61968bcc378722d08b01acc741c193dba0c614 app/src/lib/stores/helpers/background-fetcher.ts -@@ -1,4 +1,4 @@ --import { Repository } from '../../../models/repository' -+import { Repository, formatRepositoryName } from '../../../models/repository' - import { Account } from '../../../models/account' - import { GitHubRepository } from '../../../models/github-repository' - import { API } from '../../api' -@@ -96,11 +96,20 @@ - try { - await this.fetch(this.repository) - } catch (e) { -+<<<<<<< .our - const ghRepo = this.repository.gitHubRepository - const repoName = - ghRepo !== null ? ghRepo.fullName : this.repository.name - - log.error(`Error performing periodic fetch for '${repoName}'`, e) -+======= -+ log.error( -+ `Error performing periodic fetch for repository '${formatRepositoryName( -+ this.repository -+ )}'`, -+ e -+ ) -+>>>>>>> .their - } - } - -changed in both - base 100644 6a4b61f9fe2be4768d09c5ba220b92bac6e36e4a app/src/models/repository.ts - our 100644 4eb1a58be5e5e17b1a8714be9248b2d332f526e4 app/src/models/repository.ts - their 100644 782c50e60421f5fcfe22fecc91fa84fc7be86a02 app/src/models/repository.ts -@@ -69,6 +69,7 @@ - } - - /** -+<<<<<<< .our - * Returns the owner/name alias if associated with a GitHub repository, - * otherwise the folder name that contains the repository - */ -@@ -76,4 +77,14 @@ - const { gitHubRepository } = repository - - return gitHubRepository !== null ? gitHubRepository.fullName : repository.name -+======= -+ * Generate a distinct name for the repository. -+ */ -+export function formatRepositoryName(repository: Repository) { -+ if (repository.gitHubRepository !== null) { -+ return repository.gitHubRepository.fullName -+ } -+ -+ return repository.name -+>>>>>>> .their - } diff --git a/app/test/fixtures/merge-parser/desktop/merge-ahead-behind-toggle-spike-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-ahead-behind-toggle-spike-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 65ad49d752b..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-ahead-behind-toggle-spike-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,838 +0,0 @@ -changed in both - base 100644 127d134f2254d76c375b7185af1f42369b62fed0 app/src/lib/app-state.ts - our 100644 b30f0fe080d909b81d2fb683ceb8deb365fb0191 app/src/lib/app-state.ts - their 100644 f6cb64e0cf4b2fbb859658db3fd65faceb895bde app/src/lib/app-state.ts -@@ -342,7 +342,12 @@ - } - - export interface IRepositoryState { -+<<<<<<< .our - readonly commitSelection: ICommitSelection -+======= -+ readonly historyState: IHistoryState -+ readonly compareState: ICompareState -+>>>>>>> .their - readonly changesState: IChangesState - readonly compareState: ICompareState - readonly selectedSection: RepositorySectionTab -@@ -564,6 +569,36 @@ - export interface ICommitSelection { - /** The commit currently selected in the app */ - readonly sha: string | null -+<<<<<<< .our -+======= -+ readonly file: CommittedFileChange | null -+} -+ -+export enum CompareMode { -+ Default = 'Default', -+ Ahead = 'Ahead', -+ Behind = 'Behind', -+} -+ -+export interface ICompareState { -+ readonly selection: IHistorySelection -+ -+ readonly commits: ReadonlyArray -+ -+ readonly mode: CompareMode -+ -+ readonly branch: Branch | null -+ -+ readonly behindCount: number -+ readonly aheadCount: number -+} -+ -+export interface IHistoryState { -+ readonly selection: IHistorySelection -+ -+ /** The ordered SHAs. */ -+ readonly history: ReadonlyArray -+>>>>>>> .their - - /** The list of files associated with the current commit */ - readonly changedFiles: ReadonlyArray -changed in both - base 100644 9c822d8df65d53f5fbdb6939e203a7ba2e11a58c app/src/lib/dispatcher/dispatcher.ts - our 100644 5e56c00e713342e76f5ccba040062e322e8c90cb app/src/lib/dispatcher/dispatcher.ts - their 100644 2da1dbbe3c8a2fb7a2a1a916112c7f50d1f9c6cb app/src/lib/dispatcher/dispatcher.ts -@@ -17,8 +17,12 @@ - Foldout, - FoldoutType, - ImageDiffType, -+<<<<<<< .our - CompareAction, - ICompareFormUpdate, -+======= -+ CompareMode, -+>>>>>>> .their - } from '../app-state' - import { AppStore } from '../stores/app-store' - import { CloningRepository } from '../../models/cloning-repository' -@@ -120,6 +124,22 @@ - return this.appStore._updateRepositoryMissing(repository, missing) - } - -+<<<<<<< .our -+======= -+ public loadCompareState( -+ repository: Repository, -+ branch: Branch | null, -+ mode: CompareMode -+ ): Promise { -+ return this.appStore._loadCompareState(repository, branch, mode) -+ } -+ -+ /** Load the history for the repository. */ -+ public loadHistory(repository: Repository): Promise { -+ return this.appStore._loadHistory(repository) -+ } -+ -+>>>>>>> .their - /** Load the next batch of history for the repository. */ - public loadNextCommitBatch(repository: Repository): Promise { - return this.appStore._loadNextCommitBatch(repository) -changed in both - base 100644 9a3faa08e8e9cdae8d49ff0ac05118135bf2e291 app/src/lib/feature-flag.ts - our 100644 716a3c2396b0db5e84ec87d6529001e633b08700 app/src/lib/feature-flag.ts - their 100644 1469cbbf931b1ccdde675c010a03df5aa08988eb app/src/lib/feature-flag.ts -@@ -27,6 +27,18 @@ - return enableDevelopmentFeatures() || __RELEASE_CHANNEL__ === 'beta' - } - -+<<<<<<< .our -+======= -+/** Should PR integration be enabled? */ -+export function enablePRIntegration(): boolean { -+ return enableBetaFeatures() -+} -+ -+export function enableCompareTab(): boolean { -+ return enableDevelopmentFeatures() -+} -+ -+>>>>>>> .their - /** Should merge tool integration be enabled? */ - export function enableMergeTool(): boolean { - return enableDevelopmentFeatures() -changed in both - base 100644 ce2b9ab3f38d37bcf3a74d6bb159ef3ab0257083 app/src/lib/git/rev-list.ts - our 100644 3f1e4abe01f964c4aa4b46ec41185ef132ec2c8a app/src/lib/git/rev-list.ts - their 100644 054b714aa201316976da4403c833ee28a800d077 app/src/lib/git/rev-list.ts -@@ -1,7 +1,12 @@ - import { GitError } from 'dugite' - import { git } from './core' - import { Repository } from '../../models/repository' -+<<<<<<< .our - import { Branch, BranchType, IAheadBehind } from '../../models/branch' -+======= -+import { Branch, BranchType } from '../../models/branch' -+import { Commit } from '../../models/commit' -+>>>>>>> .their - - /** - * Convert two refs into the Git range syntax representing the set of commits -@@ -33,6 +38,12 @@ - return `${from}...${to}` - } - -+export interface ICompareResult { -+ readonly ahead: number -+ readonly behind: number -+ readonly commits: ReadonlyArray -+} -+ - /** Calculate the number of commits the range is ahead and behind. */ - export async function getAheadBehind( - repository: Repository, -changed in both - base 100644 c07fbbd73ffd330aebdb9910fb2712d21e331c5a app/src/lib/stores/app-store.ts - our 100644 1a4e387e4d192d34abfd0621b4b5ebe8cc34d8d1 app/src/lib/stores/app-store.ts - their 100644 be19b43b27a9237958322956866f3ac26e0a5f42 app/src/lib/stores/app-store.ts -@@ -16,6 +16,7 @@ - Progress, - ImageDiffType, - IRevertProgress, -+<<<<<<< .our - IFetchProgress, - ICompareState, - ComparisonView, -@@ -25,6 +26,10 @@ - ICompareBranch, - ICompareFormUpdate, - ICompareToBranch, -+======= -+ CompareMode, -+ ICompareState, -+>>>>>>> .their - } from '../app-state' - import { Account } from '../../models/account' - import { -@@ -439,6 +444,17 @@ - changedFiles: new Array(), - diff: null, - }, -+ compareState: { -+ selection: { -+ sha: null, -+ file: null, -+ }, -+ branch: null, -+ mode: CompareMode.Default, -+ aheadCount: 0, -+ behindCount: 0, -+ commits: new Array(), -+ }, - changesState: { - workingDirectory: WorkingDirectoryStatus.fromFiles( - new Array() -@@ -511,6 +527,20 @@ - } - - private updateCompareState( -+<<<<<<< .our -+======= -+ repository: Repository, -+ fn: (compareState: ICompareState) => Pick -+ ) { -+ this.updateRepositoryState(repository, state => { -+ const compareState = state.compareState -+ const newValues = fn(compareState) -+ return { compareState: merge(compareState, newValues) } -+ }) -+ } -+ -+ private updateHistoryState( -+>>>>>>> .their - repository: Repository, - fn: (state: ICompareState) => Pick - ) { -@@ -700,6 +730,7 @@ - } - - /** This shouldn't be called directly. See `Dispatcher`. */ -+<<<<<<< .our - public async _changeCommitSelection( - repository: Repository, - sha: string -@@ -713,10 +744,53 @@ - const commitSelection = { sha, file, diff: null, changedFiles } - return { commitSelection } - }) -+======= -+ public async _loadCompareState( -+ repository: Repository, -+ branch: Branch | null, -+ mode: CompareMode -+ ): Promise { -+ const gitStore = this.getGitStore(repository) -+ -+ if (mode === CompareMode.Default) { -+ await gitStore.loadHistory() -+ -+ const state = this.getRepositoryState(repository).historyState -+ const commits = state.history -+ -+ this.updateCompareState(repository, state => ({ -+ mode: mode, -+ commits: commits, -+ branch, -+ aheadCount: 0, -+ behindCount: 0, -+ })) -+ } else { -+ if (branch == null) { -+ log.debug(`oops, we can't compare if the branch isn't selected`) -+ return -+ } -+ -+ const compare = await gitStore.getCompareDetails(branch, mode) -+ -+ if (compare) { -+ const commits = compare.commits.map(c => c.sha) -+ -+ this.updateCompareState(repository, state => ({ -+ mode, -+ commits, -+ branch, -+ aheadCount: compare.ahead, -+ behindCount: compare.behind, -+ })) -+ } -+ } -+>>>>>>> .their - - this.emitUpdate() - } - -+<<<<<<< .our - private updateOrSelectFirstCommit( - repository: Repository, - commitSHAs: ReadonlyArray -@@ -725,6 +799,20 @@ - let selectedSHA = state.commitSelection.sha - if (selectedSHA != null) { - const index = commitSHAs.findIndex(sha => sha === selectedSHA) -+======= -+ /** This shouldn't be called directly. See `Dispatcher`. */ -+ public async _loadHistory(repository: Repository): Promise { -+ const gitStore = this.getGitStore(repository) -+ await gitStore.loadHistory() -+ -+ const state = this.getRepositoryState(repository).historyState -+ let newSelection = state.selection -+ const history = state.history -+ const selectedSHA = state.selection.sha -+ if (selectedSHA) { -+ const index = history.findIndex(sha => sha === selectedSHA) -+ // Our selected SHA disappeared, so clear the selection. -+>>>>>>> .their - if (index < 0) { - // selected SHA is not in this list - // -> clear the selection in the app state -changed in both - base 100644 d5a9ab172983707278c75f9f73fa2a82527a51fe app/src/lib/stores/git-store.ts - our 100644 f8eedeb9d958345be59538b82b1b69cd4326d73b app/src/lib/stores/git-store.ts - their 100644 11c74cbb03a3f5eb590071256708432c27f90433 app/src/lib/stores/git-store.ts -@@ -12,7 +12,11 @@ - import { Tip, TipState } from '../../models/tip' - import { Commit } from '../../models/commit' - import { IRemote } from '../../models/remote' -+<<<<<<< .our - import { IFetchProgress, IRevertProgress, ComparisonView } from '../app-state' -+======= -+import { IFetchProgress, IRevertProgress, CompareMode } from '../app-state' -+>>>>>>> .their - - import { IAppShell } from '../app-shell' - import { ErrorWithMetadata, IErrorMetadata } from '../error-with-metadata' -@@ -29,6 +33,12 @@ - getRecentBranches, - getBranches, - deleteRef, -+<<<<<<< .our -+======= -+ IAheadBehind, -+ getBranchAheadBehind, -+ getAheadBehind, -+>>>>>>> .their - getCommits, - merge, - setRemoteURL, -@@ -50,11 +60,15 @@ - mergeTrailers, - getTrailerSeparatorCharacters, - parseSingleUnfoldedTrailer, -+<<<<<<< .our - isCoAuthoredByTrailer, - getAheadBehind, - revRange, - revSymmetricDifference, - getSymbolicRef, -+======= -+ ICompareResult, -+>>>>>>> .their - } from '../git' - import { IGitAccount } from '../git/authentication' - import { RetryAction, RetryActionType } from '../retry-actions' -@@ -890,6 +904,56 @@ - } - } - -+ /** Calculate the ahead/behind for the current branch. */ -+ public async calculateAheadBehindForCurrentBranch(): Promise { -+ if (this.tip.kind === TipState.Valid) { -+ const branch = this.tip.branch -+ this._aheadBehind = await getBranchAheadBehind(this.repository, branch) -+ } -+ -+ this.emitUpdate() -+ } -+ -+ public async getCompareDetails( -+ branch: Branch, -+ mode: CompareMode -+ ): Promise { -+ if (this.tip.kind !== TipState.Valid) { -+ return null -+ } -+ -+ let compare: ICompareResult | null = null -+ -+ const base = this.tip.branch -+ -+ const range = -+ mode === CompareMode.Behind -+ ? `${base.name}..${branch.name}` -+ : `${branch.name}..${base.name}` -+ -+ const commits = await getCommits(this.repository, range, 250) -+ -+ const aheadBehind = await getAheadBehind( -+ this.repository, -+ `${base.name}...${branch.name}` -+ ) -+ -+ if (aheadBehind) { -+ compare = { -+ ahead: aheadBehind.ahead, -+ behind: aheadBehind.behind, -+ commits, -+ } -+ } -+ -+ if (commits) { -+ this.storeCommits(commits) -+ this.emitNewCommitsLoaded(commits) -+ } -+ -+ return compare -+ } -+ - public async loadStatus(): Promise { - const status = await this.performFailableOperation(() => - getStatus(this.repository) -changed in both - base 100644 386fda7ba4818bba12c354f9b59a89893d760283 app/src/ui/history/commit-list.tsx - our 100644 3e0e90eccd5a8894b7cce153c15009fe732a39cc app/src/ui/history/commit-list.tsx - their 100644 cc0994bd40293e257d7db665dab7185d3f489f6d app/src/ui/history/commit-list.tsx -@@ -8,6 +8,7 @@ - const RowHeight = 50 - - interface ICommitListProps { -+<<<<<<< .our - /** The GitHub repository associated with this commit (if found) */ - readonly gitHubRepository: GitHubRepository | null - -@@ -18,6 +19,15 @@ - readonly commitLookup: Map - - /** The SHA of the selected commit */ -+======= -+ readonly onCommitChanged: (commit: Commit) => void -+ readonly onScroll?: (start: number, end: number) => void -+ readonly onRevertCommit: (commit: Commit) => void -+ readonly onViewCommitOnGitHub: (sha: string) => void -+ readonly repository: Repository -+ readonly list: ReadonlyArray -+ readonly commitLookup: Map -+>>>>>>> .their - readonly selectedSHA: string | null - - /** The lookup for GitHub users related to this repository */ -@@ -28,6 +38,7 @@ - - /** The list of known local commits for the current branch */ - readonly localCommitSHAs: ReadonlyArray -+<<<<<<< .our - - /** The message to display inside the list when no results are displayed */ - readonly emptyListMessage: JSX.Element | string -@@ -43,11 +54,15 @@ - - /** Callback to fire to open a given commit on GitHub */ - readonly onViewCommitOnGitHub: (sha: string) => void -+======= -+ readonly noCommitsMessage: string -+>>>>>>> .their - } - - /** A component which displays the list of commits. */ - export class CommitList extends React.Component { - private renderCommit = (row: number) => { -+<<<<<<< .our - const sha = this.props.commitSHAs[row] - const commit = this.props.commitLookup.get(sha) - -@@ -57,6 +72,13 @@ - `[CommitList]: the commit '${sha}' does not exist in the cache` - ) - } -+======= -+ const sha = this.props.list[row] -+ const commit = this.props.commitLookup.get(sha) -+ -+ if (!commit) { -+ log.debug(`[CommitList] unable to find commit ${sha} in cache`) -+>>>>>>> .their - return null - } - -@@ -76,8 +98,13 @@ - ) - } - -+<<<<<<< .our - private onSelectedRowChanged = (row: number) => { - const sha = this.props.commitSHAs[row] -+======= -+ private onRowChanged = (row: number) => { -+ const sha = this.props.list[row] -+>>>>>>> .their - const commit = this.props.commitLookup.get(sha) - if (commit) { - this.props.onCommitSelected(commit) -@@ -85,6 +112,10 @@ - } - - private onScroll = (scrollTop: number, clientHeight: number) => { -+ if (this.props.onScroll == null) { -+ return -+ } -+ - const numberOfRows = Math.ceil(clientHeight / RowHeight) - const top = Math.floor(scrollTop / RowHeight) - const bottom = top + numberOfRows -@@ -97,6 +128,7 @@ - return -1 - } - -+<<<<<<< .our - return this.props.commitSHAs.findIndex(s => s === sha) - } - -@@ -104,20 +136,37 @@ - if (this.props.commitSHAs.length === 0) { - return ( -
{this.props.emptyListMessage}
-+======= -+ return this.props.list.findIndex(s => s === sha) -+ } -+ -+ public render() { -+ if (this.props.list.length === 0) { -+ return ( -+
{this.props.noCommitsMessage}
-+>>>>>>> .their - ) - } - - return ( -
- >>>>>> .their - rowHeight={RowHeight} - selectedRows={[this.rowForSHA(this.props.selectedSHA)]} - rowRenderer={this.renderCommit} - onSelectedRowChanged={this.onSelectedRowChanged} - onScroll={this.onScroll} - invalidationProps={{ -+<<<<<<< .our - commits: this.props.commitSHAs, -+======= -+ list: this.props.list, -+>>>>>>> .their - gitHubUsers: this.props.gitHubUsers, - }} - /> -added in remote - their 100644 3336dcc56f60b9a4c43323b82839abf6550d2725 app/src/ui/history/compare-sidebar.tsx -@@ -0,0 +1,169 @@ -+import * as React from 'react' -+import { CommitList } from './commit-list' -+import { Repository } from '../../models/repository' -+import { Commit } from '../../models/commit' -+import { Dispatcher } from '../../lib/dispatcher' -+import { IGitHubUser } from '../../lib/databases' -+import { ICompareState, CompareMode } from '../../lib/app-state' -+import { ThrottledScheduler } from '../lib/throttled-scheduler' -+import { TabBar } from '../tab-bar' -+import { Branch } from '../../models/branch' -+import { Select } from '../lib/select' -+ -+interface ICompareSidebarProps { -+ readonly repository: Repository -+ readonly dispatcher: Dispatcher -+ readonly compare: ICompareState -+ readonly gitHubUsers: Map -+ readonly emoji: Map -+ readonly commitLookup: Map -+ readonly branches: ReadonlyArray -+ readonly localCommitSHAs: ReadonlyArray -+ readonly onRevertCommit: (commit: Commit) => void -+ readonly onViewCommitOnGitHub: (sha: string) => void -+} -+ -+/** The Sidebar component. Contains the branch list, the commit list, and the ability to filter commits. */ -+export class CompareSidebar extends React.Component { -+ private readonly loadChangedFilesScheduler = new ThrottledScheduler(200) -+ -+ public constructor() { -+ super() -+ } -+ -+ private onCommitChanged = (commit: Commit) => { -+ this.props.dispatcher.changeHistoryCommitSelection( -+ this.props.repository, -+ commit.sha -+ ) -+ -+ this.loadChangedFilesScheduler.queue(() => { -+ this.props.dispatcher.loadChangedFilesForCurrentSelection( -+ this.props.repository -+ ) -+ }) -+ } -+ -+ public componentWillMount() { -+ this.props.dispatcher.loadCompareState( -+ this.props.repository, -+ null, -+ CompareMode.Default -+ ) -+ } -+ -+ public componentWillUnmount() { -+ this.loadChangedFilesScheduler.clear() -+ } -+ -+ private onBranchChange = (event: React.FormEvent) => { -+ const name = event.currentTarget.value -+ const index = parseInt(name, 10) -+ -+ if (isNaN(index)) { -+ log.debug(`oops, we don't have a number?!??!?!`) -+ return -+ } -+ -+ if (index === -1) { -+ // 'None' is selected, just show history -+ this.props.dispatcher.loadCompareState( -+ this.props.repository, -+ null, -+ CompareMode.Default -+ ) -+ } else { -+ const branch = this.props.branches[index] -+ if (branch == null) { -+ log.debug(`oops, can't find branch: '${name}'`) -+ } -+ -+ this.props.dispatcher.loadCompareState( -+ this.props.repository, -+ branch, -+ CompareMode.Behind -+ ) -+ } -+ } -+ -+ private onTabClicked = (index: number) => { -+ const mode: CompareMode = -+ index === 0 ? CompareMode.Behind : CompareMode.Ahead -+ -+ this.props.dispatcher.loadCompareState( -+ this.props.repository, -+ this.props.compare.branch, -+ mode -+ ) -+ } -+ -+ private renderBranchList(): JSX.Element { -+ const options = new Array() -+ options.push( -+ -+ ) -+ -+ let selectedIndex = -1 -+ for (const [index, branch] of this.props.branches.entries()) { -+ if ( -+ this.props.compare.branch && -+ this.props.compare.branch.name === branch.name -+ ) { -+ selectedIndex = index -+ } -+ -+ options.push( -+ -+ ) -+ } -+ -+ return ( -+ -+ ) -+ } -+ -+ private renderTabBar(): JSX.Element | null { -+ const compare = this.props.compare -+ if (compare.mode === CompareMode.Default) { -+ return null -+ } -+ -+ const selectedTab = compare.mode === CompareMode.Ahead ? 0 : 1 -+ -+ return ( -+ -+ Behind ({compare.behindCount}) -+ Ahead ({compare.aheadCount}) -+ -+ ) -+ } -+ public render() { -+ const compare = this.props.compare -+ return ( -+
-+ {this.renderBranchList()} -+ {this.renderTabBar()} -+ -+ -+
-+ ) -+ } -+} -changed in both - base 100644 caa18019759a791f9a4e2b42c02a348a0cf36a0d app/src/ui/history/index.ts - our 100644 5314aa21a17e6eaad7f73ab8e92c99e6e83f2108 app/src/ui/history/index.ts - their 100644 fc92ceb826bd180f28e78e008f9c89a550858d9e app/src/ui/history/index.ts -@@ -1,2 +1,8 @@ -+<<<<<<< .our - export { SelectedCommit } from './selected-commit' - export { CompareSidebar } from './compare' -+======= -+export { HistorySidebar } from './sidebar' -+export { History } from './history' -+export { CompareSidebar } from './compare-sidebar' -+>>>>>>> .their -removed in local - base 100644 24ee8948d1e538fc58d461106006cb88f899d096 app/src/ui/history/sidebar.tsx - their 100644 729e304c5cfe6f032a5198639abcb038a395f5ce app/src/ui/history/sidebar.tsx -changed in both - base 100644 fa95746b3b525b06246015c03db11b35209b8fb1 app/src/ui/repository.tsx - our 100644 efb00423012b8da0dfa5e8897acacaeb0a5e648a app/src/ui/repository.tsx - their 100644 95f7a860788ad72489106227279578d041393f1c app/src/ui/repository.tsx -@@ -5,9 +5,13 @@ - import { UiView } from './ui-view' - import { Changes, ChangesSidebar } from './changes' - import { NoChanges } from './changes/no-changes' -+<<<<<<< .our - import { MultipleSelection } from './changes/multiple-selection' - import { FilesChangedBadge } from './changes/files-changed-badge' - import { SelectedCommit, CompareSidebar } from './history' -+======= -+import { History, HistorySidebar, CompareSidebar } from './history' -+>>>>>>> .their - import { Resizable } from './resizable' - import { TabBar } from './tab-bar' - import { -@@ -19,9 +23,13 @@ - import { IssuesStore, GitHubUserStore } from '../lib/stores' - import { assertNever } from '../lib/fatal-error' - import { Account } from '../models/account' -+<<<<<<< .our - import { enableNotificationOfBranchUpdates } from '../lib/feature-flag' - import { FocusContainer } from './lib/focus-container' - import { OcticonSymbol, Octicon } from './octicons' -+======= -+import { enableCompareTab } from '../lib/feature-flag' -+>>>>>>> .their - - /** The widest the sidebar can be with the minimum window size. */ - const MaxSidebarWidth = 495 -@@ -111,7 +119,12 @@ - symbol={OcticonSymbol.primitiveDot} - /> - ) : null} -+<<<<<<< .our -
-+======= -+ -+ {enableCompareTab() ? 'Compare' : 'History'} -+>>>>>>> .their - - ) - } -@@ -180,13 +193,37 @@ - ) - } - -+ private renderCompareSidebar(): JSX.Element { -+ return ( -+ -+ ) -+ } -+ - private renderSidebarContents(): JSX.Element { - const selectedSection = this.props.state.selectedSection - - if (selectedSection === RepositorySectionTab.Changes) { - return this.renderChangesSidebar() -+<<<<<<< .our - } else if (selectedSection === RepositorySectionTab.History) { - return this.renderCompareSidebar() -+======= -+ } else if (selectedSection === RepositorySection.History) { -+ return enableCompareTab() -+ ? this.renderCompareSidebar() -+ : this.renderHistorySidebar() -+>>>>>>> .their - } else { - return assertNever(selectedSection, 'Unknown repository section') - } -changed in both - base 100644 867751eb28963ba7f852717ead2d03ce1abecff5 app/styles/ui/history/_history.scss - our 100644 58cea508b02182fa4f45daf88643d33c3b2dd020 app/styles/ui/history/_history.scss - their 100644 0f5e9af48f0d78ed4497fe4d1f91f234c37ae1e5 app/styles/ui/history/_history.scss -@@ -17,6 +17,31 @@ - } - } - -+#compare-view { -+ display: flex; -+ flex-direction: column; -+ flex: 1; -+ -+ .tab-bar { -+ flex-grow: 0; -+ -+ &-item { -+ background: blue; -+ color: white; -+ -+ &.selected { -+ box-shadow: none; -+ background: white; -+ color: blue; -+ } -+ } -+ } -+ -+ .select-component { -+ flex-grow: 0; -+ } -+} -+ - #commit-summary-container { - flex-grow: 0; - } diff --git a/app/test/fixtures/merge-parser/desktop/merge-ask-to-merge-b4-delete-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-ask-to-merge-b4-delete-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index ac5199ea953..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-ask-to-merge-b4-delete-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,127 +0,0 @@ -changed in both - base 100644 4391747c418ed9fe66a952d14148542b8166da72 app/src/lib/app-state.ts - our 100644 b30f0fe080d909b81d2fb683ceb8deb365fb0191 app/src/lib/app-state.ts - their 100644 9560d603f4b04dbf0c39da4dca97fa599266e767 app/src/lib/app-state.ts -@@ -232,6 +232,7 @@ - repository: Repository - branch: Branch - existsOnRemote: boolean -+ aheadBehind: IAheadBehind | null - } - | { - type: PopupType.ConfirmDiscardChanges -changed in both - base 100644 fa753001aaa85c2f4e7be934fa1b22ccc4ba0da9 app/src/ui/app.tsx - our 100644 c38c806e36c237ea70f3cdeee739941530c0c7cd app/src/ui/app.tsx - their 100644 4720f6bc902cf560cf83650003adc345a3c06a17 app/src/ui/app.tsx -@@ -480,9 +480,11 @@ - pullRequest: currentPullRequest, - }) - } else { -- const existsOnRemote = state.state.aheadBehind !== null -+ const aheadBehind = state.state.aheadBehind -+ const existsOnRemote = aheadBehind !== null - - this.props.dispatcher.showPopup({ -+ aheadBehind, - type: PopupType.DeleteBranch, - repository: state.repository, - branch: tip.branch, -@@ -996,7 +998,11 @@ - branch={popup.branch} - existsOnRemote={popup.existsOnRemote} - onDismissed={this.onPopupDismissed} -+<<<<<<< .our - onDeleted={this.onBranchDeleted} -+======= -+ aheadBehind={popup.aheadBehind} -+>>>>>>> .their - /> - ) - case PopupType.ConfirmDiscardChanges: -changed in both - base 100644 da3dac8dfca303eb8512b4031e6da4b6545ba4a7 app/src/ui/delete-branch/delete-branch-dialog.tsx - our 100644 b5c948eb5b4bf338b32d13ebf5656729b009a7c9 app/src/ui/delete-branch/delete-branch-dialog.tsx - their 100644 5261d661964111a7d1b3dee8a54f8cd1c96f54c7 app/src/ui/delete-branch/delete-branch-dialog.tsx -@@ -8,12 +8,14 @@ - import { Checkbox, CheckboxValue } from '../lib/checkbox' - import { Dialog, DialogContent, DialogFooter } from '../dialog' - import { Ref } from '../lib/ref' -+import { IAheadBehind } from '../../lib/app-state' - - interface IDeleteBranchProps { - readonly dispatcher: Dispatcher - readonly repository: Repository - readonly branch: Branch - readonly existsOnRemote: boolean -+ readonly aheadBehind: IAheadBehind | null - readonly onDismissed: () => void - readonly onDeleted: (repository: Repository) => void - } -@@ -35,6 +37,42 @@ - } - - public render() { -+ const aheadBehind = this.props.aheadBehind -+ return aheadBehind !== null && aheadBehind.ahead > 0 -+ ? this.renderDeleteBranchWithUnmergedCommits() -+ : this.renderDeleteBranch() -+ } -+ -+ private renderDeleteBranchWithUnmergedCommits() { -+ const unmergedCommits = this.props.aheadBehind!.ahead -+ -+ return ( -+ -+ -+

-+ {this.props.branch.name} has {unmergedCommits}{' '} -+ unmerged {unmergedCommits === 1 ? 'commit' : 'commits'}. -+
-+ Would you like to merge your changes first? -+

-+
-+ -+ -+ -+ -+ -+ -+ -+
-+ ) -+ } -+ -+ private renderDeleteBranch() { - return ( - -

-+ {this.props.aheadBehind && this.props.aheadBehind.ahead > 0 ? ( -+

Unmerged commits

-+ ) : null} - { -+ await this.props.dispatcher.mergeBranch( -+ this.props.repository, -+ this.props.branch.name -+ ) -+ -+ this.deleteBranch() -+ } - } diff --git a/app/test/fixtures/merge-parser/desktop/merge-branch-list-context-menu-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-branch-list-context-menu-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 8ce8be5d38f..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-branch-list-context-menu-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,399 +0,0 @@ -changed in both - base 100644 127d134f2254d76c375b7185af1f42369b62fed0 app/src/lib/app-state.ts - our 100644 b30f0fe080d909b81d2fb683ceb8deb365fb0191 app/src/lib/app-state.ts - their 100644 d6b50d72651124d3a81bab00a6e4e6db3d7a235c app/src/lib/app-state.ts -@@ -231,7 +231,6 @@ - type: PopupType.DeleteBranch - repository: Repository - branch: Branch -- existsOnRemote: boolean - } - | { - type: PopupType.ConfirmDiscardChanges -@@ -256,6 +255,7 @@ - type: PopupType.CreateBranch - repository: Repository - initialName?: string -+ initialBranch?: Branch - } - | { type: PopupType.SignIn } - | { type: PopupType.About } -changed in both - base 100644 410fbd6dbd6833f45a8a2523bcc15c2ee62655a8 app/src/lib/git/remote.ts - our 100644 7b66498bbdb1a57b4bb465841fb247d2ee2d855a app/src/lib/git/remote.ts - their 100644 7d27a42280ceec6a910a852d8d601faec4e26a5c app/src/lib/git/remote.ts -@@ -1,7 +1,11 @@ - import { git } from './core' - import { Repository } from '../../models/repository' - import { IRemote } from '../../models/remote' -+<<<<<<< .our - import { findDefaultRemote } from '../stores/helpers/find-default-remote' -+======= -+import { Branch } from '../../models/branch' -+>>>>>>> .their - - /** Get the remote names. */ - export async function getRemotes( -@@ -71,3 +75,21 @@ - ): Promise { - await git(['remote', 'set-url', name, url], repository.path, 'setRemoteURL') - } -+ -+export async function checkBranchExistsOnRemote( -+ repository: Repository, -+ branch: Branch -+): Promise { -+ if (branch.upstream == null) { -+ return false -+ } -+ -+ const result = await git( -+ ['show-ref', '--verify', `refs/remotes/${branch.upstream}`], -+ repository.path, -+ 'checkBranchExistsOnRemote', -+ { successExitCodes: new Set([0, 128]) } -+ ) -+ -+ return result.exitCode === 0 -+} -changed in both - base 100644 700d3f933813e7f847a36b6d4955ef5f10bc88c5 app/src/lib/stores/app-store.ts - our 100644 1a4e387e4d192d34abfd0621b4b5ebe8cc34d8d1 app/src/lib/stores/app-store.ts - their 100644 96be41b737456250d8c40862f64593fbbeb7c86c app/src/lib/stores/app-store.ts -@@ -2337,17 +2337,25 @@ - includeRemote: boolean - ): Promise { - return this.withAuthenticatingUser(repository, async (repo, account) => { -- const defaultBranch = this.getRepositoryState(repository).branchesState -- .defaultBranch -- if (!defaultBranch) { -- throw new Error(`No default branch!`) -- } -- -+ const state = this.getRepositoryState(repository) -+ const branchesState = state.branchesState - const gitStore = this.getGitStore(repository) - -- await gitStore.performFailableOperation(() => -- checkoutBranch(repository, account, defaultBranch) -- ) -+ // If we are on the branch about to be deleted then checkout the default branch -+ if ( -+ branchesState.tip.kind === TipState.Valid && -+ branchesState.tip.branch.name === branch.name -+ ) { -+ const defaultBranch = branchesState.defaultBranch -+ if (!defaultBranch) { -+ throw new Error(`No default branch!`) -+ } -+ -+ await gitStore.performFailableOperation(() => -+ checkoutBranch(repository, account, defaultBranch) -+ ) -+ } -+ - await gitStore.performFailableOperation(() => - deleteBranch(repository, branch, account, includeRemote) - ) -changed in both - base 100644 ad5d5eba9271c0a3c016320ae691ba2d231ebff1 app/src/ui/app.tsx - our 100644 c38c806e36c237ea70f3cdeee739941530c0c7cd app/src/ui/app.tsx - their 100644 66fff264a2ab171d481980e7fe2dea6002258633 app/src/ui/app.tsx -@@ -480,13 +480,10 @@ - pullRequest: currentPullRequest, - }) - } else { -- const existsOnRemote = state.state.aheadBehind !== null -- - this.props.dispatcher.showPopup({ - type: PopupType.DeleteBranch, - repository: state.repository, - branch: tip.branch, -- existsOnRemote: existsOnRemote, - }) - } - } -@@ -994,7 +991,6 @@ - dispatcher={this.props.dispatcher} - repository={popup.repository} - branch={popup.branch} -- existsOnRemote={popup.existsOnRemote} - onDismissed={this.onPopupDismissed} - onDeleted={this.onBranchDeleted} - /> -@@ -1135,6 +1131,7 @@ - onDismissed={this.onPopupDismissed} - dispatcher={this.props.dispatcher} - initialName={popup.initialName || ''} -+ initialBranch={popup.initialBranch || null} - /> - ) - } -changed in both - base 100644 ab87ff630fe03d9c24c822f395f086c9b3f50e57 app/src/ui/branches/branch-list.tsx - our 100644 f996cca6bcc1348eedd5f3c852bf8652b60f95aa app/src/ui/branches/branch-list.tsx - their 100644 171d2fe4f62d9d954f2acc377641cbedfcee050b app/src/ui/branches/branch-list.tsx -@@ -89,6 +89,7 @@ - */ - readonly onCreateNewBranch?: (name: string) => void - -+<<<<<<< .our - readonly textbox?: TextBox - - /** -@@ -103,6 +104,13 @@ - * Callback to fire when the items in the filter list are updated - */ - readonly onFilterListResultsChanged?: (resultCount: number) => void -+======= -+ /** Can users perform operations on a branch in the list via a context menu? */ -+ readonly canShowBranchContextMenu: boolean -+ -+ readonly onCreateNewBranchFromStartPoint?: (branch: Branch) => void -+ readonly onDeleteBranch?: (branch: Branch) => void -+>>>>>>> .their - } - - interface IBranchListState { -@@ -169,6 +177,7 @@ - - public render() { - return ( -+<<<<<<< .our - - ref={this.onBranchesFilterListRef} - className="branches-list" -@@ -187,6 +196,19 @@ - renderNoItems={this.onRenderNoItems} - filterTextBox={this.props.textbox} - onFilterListResultsChanged={this.props.onFilterListResultsChanged} -+======= -+ >>>>>> .their - /> - ) - } -removed in local - base 100644 8bf53381567f66aec89c869080a6b63370255bc9 app/src/ui/branches/branch.tsx - their 100644 dd910faed7e44a048ad50cd9b8be32bda1c6b98c app/src/ui/branches/branch.tsx -changed in both - base 100644 cd420b66aae0a2d4b6b67873a7c96615d8d849b7 app/src/ui/branches/branches-container.tsx - our 100644 6a5612ae608b20b3a486f139daf4063209bca568 app/src/ui/branches/branches-container.tsx - their 100644 0be690e0e17b8145499ab1005ba1db57748dd002 app/src/ui/branches/branches-container.tsx -@@ -123,7 +123,13 @@ - onSelectionChanged={this.onBranchSelectionChanged} - canCreateNewBranch={true} - onCreateNewBranch={this.onCreateBranchWithName} -+<<<<<<< .our - renderBranch={this.renderBranch} -+======= -+ canShowBranchContextMenu={true} -+ onCreateNewBranchFromStartPoint={this.onCreateBranchFromStartPoint} -+ onDeleteBranch={this.onDeleteBranch} -+>>>>>>> .their - /> - ) - -@@ -214,6 +220,7 @@ - this.onCreateBranchWithName('') - } - -+<<<<<<< .our - private onPullRequestFilterTextChanged = (text: string) => { - this.setState({ pullRequestFilterText: text }) - } -@@ -222,6 +229,25 @@ - selectedPullRequest: PullRequest | null - ) => { - this.setState({ selectedPullRequest }) -+======= -+ private onCreateBranchFromStartPoint = (branch: Branch) => { -+ this.props.dispatcher.closeFoldout(FoldoutType.Branch) -+ this.props.dispatcher.showPopup({ -+ type: PopupType.CreateBranch, -+ repository: this.props.repository, -+ initialBranch: branch, -+ }) -+ } -+ -+ private onDeleteBranch = (branch: Branch) => { -+ this.props.dispatcher.closeFoldout(FoldoutType.Branch) -+ -+ this.props.dispatcher.showPopup({ -+ type: PopupType.DeleteBranch, -+ repository: this.props.repository, -+ branch: branch, -+ }) -+>>>>>>> .their - } - - private onCreatePullRequest = () => { -changed in both - base 100644 ab931838d66433189cf4cbb0f620aed220c3541c app/src/ui/create-branch/create-branch-dialog.tsx - our 100644 32e07b11abcf52024da6e39cb60a165d3f045b96 app/src/ui/create-branch/create-branch-dialog.tsx - their 100644 607b46f8be838ed96095fcb1dd6bfc2a88df73c8 app/src/ui/create-branch/create-branch-dialog.tsx -@@ -29,11 +29,13 @@ - readonly defaultBranch: Branch | null - readonly allBranches: ReadonlyArray - readonly initialName: string -+ readonly initialBranch: Branch | null - } - - enum StartPoint { - CurrentBranch, - DefaultBranch, -+ InitialBranch, - Head, - } - -@@ -81,6 +83,10 @@ - props: ICreateBranchProps, - preferred: StartPoint - ): StartPoint { -+ if (props.initialBranch !== null) { -+ return StartPoint.InitialBranch -+ } -+ - if (preferred === StartPoint.DefaultBranch && props.defaultBranch) { - return preferred - } -@@ -144,6 +150,18 @@ - } - - private renderBranchSelection() { -+ if ( -+ this.state.startPoint === StartPoint.InitialBranch && -+ this.props.initialBranch !== null -+ ) { -+ const initialBranch = this.props.initialBranch -+ return ( -+

-+ Your new branch will be based on {initialBranch.name}. -+

-+ ) -+ } -+ - const tip = this.state.isCreatingBranch - ? this.state.tipAtCreateStart - : this.props.tip -@@ -308,6 +326,11 @@ - } - - startPoint = this.props.defaultBranch.name -+ } else if ( -+ this.state.startPoint === StartPoint.InitialBranch && -+ this.props.initialBranch !== null -+ ) { -+ startPoint = this.props.initialBranch.name - } - - if (name.length > 0) { -changed in both - base 100644 da3dac8dfca303eb8512b4031e6da4b6545ba4a7 app/src/ui/delete-branch/delete-branch-dialog.tsx - our 100644 b5c948eb5b4bf338b32d13ebf5656729b009a7c9 app/src/ui/delete-branch/delete-branch-dialog.tsx - their 100644 cee22ba52f34ad99f8f83c2b9ae74cee0a0eeefd app/src/ui/delete-branch/delete-branch-dialog.tsx -@@ -8,17 +8,18 @@ - import { Checkbox, CheckboxValue } from '../lib/checkbox' - import { Dialog, DialogContent, DialogFooter } from '../dialog' - import { Ref } from '../lib/ref' -+import { checkBranchExistsOnRemote } from '../../lib/git' - - interface IDeleteBranchProps { - readonly dispatcher: Dispatcher - readonly repository: Repository - readonly branch: Branch -- readonly existsOnRemote: boolean - readonly onDismissed: () => void - readonly onDeleted: (repository: Repository) => void - } - - interface IDeleteBranchState { -+ readonly existsOnRemote: boolean | null - readonly includeRemoteBranch: boolean - } - -@@ -26,14 +27,49 @@ - IDeleteBranchProps, - IDeleteBranchState - > { -+ private checkingRemote = false -+ - public constructor(props: IDeleteBranchProps) { - super(props) - - this.state = { -+ existsOnRemote: null, - includeRemoteBranch: false, - } - } - -+ public componentWillReceiveProps(nextProps: IDeleteBranchProps) { -+ if (this.checkingRemote) { -+ // a check is being performed, don't start another -+ return -+ } -+ -+ const upstreamChanged = -+ this.props.branch.upstream !== nextProps.branch.upstream -+ -+ if (this.state.existsOnRemote == null || upstreamChanged) { -+ this.checkingRemote = true -+ -+ checkBranchExistsOnRemote(this.props.repository, this.props.branch) -+ .then(existsOnRemote => { -+ this.setState({ existsOnRemote }, () => { -+ this.checkingRemote = false -+ }) -+ }) -+ .catch(err => { -+ log.warn( -+ `[DeleteBranch] unable to resolve upstream branch: '${ -+ this.props.branch.upstream -+ }'`, -+ err -+ ) -+ this.setState({ existsOnRemote: false }, () => { -+ this.checkingRemote = false -+ }) -+ }) -+ } -+ } -+ - public render() { - return ( - -

-changed in both - base 100644 66f1ac9540d0b20783d94a33dc206abae4066abc app/src/ui/merge-branch/merge.tsx - our 100644 6a7e6976257ec16e58a7331db61b40096a9bde08 app/src/ui/merge-branch/merge.tsx - their 100644 05e3f12681012e8417df4a5dfe10374049c9fd35 app/src/ui/merge-branch/merge.tsx -@@ -169,7 +169,11 @@ - selectedBranch={selectedBranch} - onSelectionChanged={this.onSelectionChanged} - canCreateNewBranch={false} -+<<<<<<< .our - renderBranch={this.renderBranch} -+======= -+ canShowBranchContextMenu={false} -+>>>>>>> .their - /> - - diff --git a/app/test/fixtures/merge-parser/desktop/merge-check-myself-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-check-myself-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 360d7e380e3..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-check-myself-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,46 +0,0 @@ -changed in both - base 100644 019328fd749b749d0c8241dd48b78a28c3da86ac app/styles/ui/_diff.scss - our 100644 372c4e6b8d6af44922f648559b128e98c085134d app/styles/ui/_diff.scss - their 100644 6ada10edc2ece1c4ffc7290a954ea7431bab56f0 app/styles/ui/_diff.scss -@@ -37,9 +37,13 @@ - // Add a little bit of space to the left of code diff - // `padding-left` here means mouse move events are not raised - padding-left: var(--spacing-half); -+<<<<<<< .our - padding-top: var(--diff-line-padding-y); - padding-bottom: var(--diff-line-padding-y); - display: inline-block; -+======= -+ align-self: center; -+>>>>>>> .their - } - - svg.no-newline { -@@ -210,11 +214,27 @@ - background: var(--diff-selected-background-color); - border-color: var(--diff-selected-border-color); - color: var(--diff-selected-text-color); -+ position: relative; - - &:last-child { - border-color: var(--diff-selected-gutter-color); - } - } -+ -+ .before:before { -+ // https://css-tricks.com/probably-dont-base64-svg/ -+ background: url('data:image/svg+xml;utf,'); -+ background-size: contain; -+ background-repeat: no-repeat; -+ content: ""; -+ -+ height: 12px; -+ width: 7px; -+ -+ position: absolute; -+ left: var(--spacing-half); -+ top: var(--spacing-half); -+ } - } - - .CodeMirror pre.CodeMirror-line .diff-line-hover { diff --git a/app/test/fixtures/merge-parser/desktop/merge-custom-remotes-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-custom-remotes-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 8bf5f0e433a..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-custom-remotes-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,347 +0,0 @@ -changed in both - base 100644 69f6d89b2b8e4538175e2665b3d8ac7572f352dd app/src/lib/app-state.ts - our 100644 b30f0fe080d909b81d2fb683ceb8deb365fb0191 app/src/lib/app-state.ts - their 100644 83b4a4082aca001ae313a23682a17d734f41d307 app/src/lib/app-state.ts -@@ -218,11 +218,15 @@ - GenericGitAuthentication, - ExternalEditorFailed, - OpenShellFailed, -+<<<<<<< .our - InitializeLFS, - LFSAttributeMismatch, - UpstreamAlreadyExists, - DeletePullRequest, - MergeConflicts, -+======= -+ CustomRemote, -+>>>>>>> .their - } - - export type Popup = -@@ -288,6 +292,7 @@ - openPreferences?: boolean - } - | { type: PopupType.OpenShellFailed; message: string } -+<<<<<<< .our - | { type: PopupType.InitializeLFS; repositories: ReadonlyArray } - | { type: PopupType.LFSAttributeMismatch } - | { -@@ -302,6 +307,9 @@ - pullRequest: PullRequest - } - | { type: PopupType.MergeConflicts; repository: Repository } -+======= -+ | { type: PopupType.CustomRemote; repository: Repository } -+>>>>>>> .their - - export enum FoldoutType { - Repository, -removed in local - base 100644 23643984c62c0f40df503da96f8270bef3184342 app/src/lib/dispatcher/app-store.ts - their 100644 ad47b9a6f23c73297ee93eb343189855870394bf app/src/lib/dispatcher/app-store.ts -changed in both - base 100644 17e3db009ef93095824e72a628647dac734e0a6a app/src/lib/dispatcher/dispatcher.ts - our 100644 5e56c00e713342e76f5ccba040062e322e8c90cb app/src/lib/dispatcher/dispatcher.ts - their 100644 649058ff79bc3b0a79a9e63d802ffa4ba85c606a app/src/lib/dispatcher/dispatcher.ts -@@ -323,7 +323,7 @@ - } - - /** Publish the repository to GitHub with the given properties. */ -- public publishRepository( -+ public publishGitHubRepository( - repository: Repository, - name: string, - description: string, -@@ -331,7 +331,7 @@ - account: Account, - org: IAPIUser | null - ): Promise { -- return this.appStore._publishRepository( -+ return this.appStore._publishGitHubRepository( - repository, - name, - description, -@@ -341,6 +341,11 @@ - ) - } - -+ /** Publish the repository to a generic server */ -+ public publishRepository(repository: Repository, url: string) { -+ return this.appStore._publishRepository(repository, url) -+ } -+ - /** - * Post the given error. This will send the error through the standard error - * handler machinery. -changed in both - base 100644 448ad8844bdc47187d3bc3b9e922ed3ae043d4b1 app/src/ui/app.tsx - our 100644 c38c806e36c237ea70f3cdeee739941530c0c7cd app/src/ui/app.tsx - their 100644 c4b6a050bb6c6998ad7a9e44b1437d8b88d379f8 app/src/ui/app.tsx -@@ -73,7 +73,13 @@ - import { InstallGit } from './install-git' - import { EditorError } from './editor' - import { About } from './about' -+<<<<<<< .our - import { Publish } from './publish-repository' -+======= -+import { getVersion, getName } from './lib/app-proxy' -+import { shell } from '../lib/dispatcher/app-shell' -+import { Publish, PublishCustomRemote } from './publish-repository' -+>>>>>>> .their - import { Acknowledgements } from './acknowledgements' - import { UntrustedCertificate } from './untrusted-certificate' - import { BlankSlateView } from './blank-slate' -@@ -1242,6 +1248,7 @@ - showPreferencesDialog={this.onShowAdvancedPreferences} - /> - ) -+<<<<<<< .our - case PopupType.InitializeLFS: - return ( - >>>>>> .their - dispatcher={this.props.dispatcher} - repository={popup.repository} - onDismissed={this.onPopupDismissed} -merged - result 100644 84a3e04a615cc5df1f2b5bdef5e8e279f51036c3 app/src/ui/publish-repository/index.ts - our 100644 f5e47702e7106f1090fd4542e41a43160aea84fc app/src/ui/publish-repository/index.ts -@@ -1 +1,2 @@ - export { Publish } from './publish' -+export { PublishCustomRemote } from './publish-custom-remote' -added in remote - their 100644 023e9ec75b887bc1ef556b1e0fbad48ec415a173 app/src/ui/publish-repository/publish-custom-remote.tsx -@@ -0,0 +1,128 @@ -+import * as React from 'react' -+import { Dialog, DialogContent, DialogFooter, DialogError } from '../dialog' -+// import { Account } from '../../models/account' -+import { Button } from '../lib/button' -+import { ButtonGroup } from '../lib/button-group' -+import { Row } from '../lib/row' -+import { TextBox } from '../lib/text-box' -+import { Dispatcher } from '../../lib/dispatcher/dispatcher' -+import { PopupType } from '../../lib/app-state' -+import { Repository } from '../../models/repository' -+ -+interface IPublishCustomRemoteProps { -+ /** The user to use for publishing. */ -+ //readonly account: Account -+ -+ readonly dispatcher: Dispatcher -+ readonly repository: Repository -+ readonly onDismissed: () => void -+} -+ -+interface IPublishCustomRemoteState { -+ readonly disabled: boolean -+ readonly remoteURL: string -+ readonly errors?: ReadonlyArray -+} -+ -+export class PublishCustomRemote extends React.Component< -+ IPublishCustomRemoteProps, -+ IPublishCustomRemoteState -+> { -+ public constructor(props: IPublishCustomRemoteProps) { -+ super(props) -+ -+ this.state = { -+ disabled: false, -+ remoteURL: '', -+ } -+ } -+ -+ public render() { -+ return ( -+

-+ {this.renderErrors()} -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ ) -+ } -+ -+ private onSubmit = async () => { -+ this.setState({ disabled: true, errors: undefined }) -+ const errors = new Array() -+ -+ try { -+ this.props.dispatcher.publishRepository( -+ this.props.repository, -+ this.state.remoteURL -+ ) -+ } catch (err) { -+ log.error( -+ `PublishCustomRemote: unable to set remote URL at ${this.state -+ .remoteURL}`, -+ err -+ ) -+ -+ errors.push(err) -+ } -+ -+ if (!errors.length) { -+ this.props.onDismissed() -+ } else { -+ this.setState({ disabled: false, errors }) -+ } -+ } -+ -+ private onCancel = () => { -+ this.props.dispatcher.showPopup({ -+ type: PopupType.RepositorySettings, -+ repository: this.props.repository, -+ }) -+ } -+ -+ private onURLChanged = (event: React.FormEvent) => { -+ this.setState({ remoteURL: event.currentTarget.value }) -+ } -+ -+ private renderErrors(): JSX.Element[] | null { -+ const errors = this.state.errors -+ -+ if (!errors || !errors.length) { -+ return null -+ } -+ -+ return errors.map((err, ix) => { -+ const key = `err-${ix}` -+ return ( -+ -+ {err} -+ -+ ) -+ }) -+ } -+} -changed in both - base 100644 e82303171a46f7e6e538ccaaaf1e3d4732c7caec app/src/ui/publish-repository/publish.tsx - our 100644 ffbdef89f9f0f16e966a7d27c2db06bd897c3db6 app/src/ui/publish-repository/publish.tsx - their 100644 ce385de07594200b72c58b9449625a769680b4cd app/src/ui/publish-repository/publish.tsx -@@ -223,7 +223,7 @@ - const settings = this.state.publishSettings - - try { -- await this.props.dispatcher.publishRepository( -+ await this.props.dispatcher.publishGitHubRepository( - this.props.repository, - settings.name, - settings.description, -merged - result 100644 253e05b3b6b6dadfcbd297f717943d188658a734 app/src/ui/repository-settings/no-remote.tsx - our 100644 a9ed19c55cd570767b8846f4db799402371f4411 app/src/ui/repository-settings/no-remote.tsx -@@ -1,28 +1,36 @@ - import * as React from 'react' --import { DialogContent } from '../dialog' -+import { DialogContent, DialogFooter } from '../dialog' -+import { Button } from '../lib/button' - import { LinkButton } from '../lib/link-button' --import { CallToAction } from '../lib/call-to-action' -+import { ButtonGroup } from '../lib/button-group' - - const HelpURL = 'https://help.github.com/articles/about-remote-repositories/' - - interface INoRemoteProps { -- /** The function to call when the users chooses to publish. */ -+ /** The function to call when the users chooses to publish to github. */ - readonly onPublish: () => void -+ readonly onUseCustomRemote: () => void - } - - /** The component for when a repository has no remote. */ - export class NoRemote extends React.Component { - public render() { - return ( -- -- --
-- Publish your repository to GitHub. Need help?{' '} -- Learn more about remote -- repositories. --
--
--
-+
-+ -+ Publish your repository to GitHub. Need help?{' '} -+ Learn more about remote -+ repositories. -+ -+ -+ -+ -+ -+ -+ -+
- ) - } - } -changed in both - base 100644 b5530eb5e8f11fc058f527837d2d02b797f95242 app/src/ui/repository-settings/repository-settings.tsx - our 100644 df6e4cf60b4e535a69c9fc0a585902ada9e70fbb app/src/ui/repository-settings/repository-settings.tsx - their 100644 a65a8f8b98ef5dfdcf5c28d69f4fc5093211c1d9 app/src/ui/repository-settings/repository-settings.tsx -@@ -134,7 +134,12 @@ - /> - ) - } else { -- return -+ return ( -+ -+ ) - } - } - case RepositorySettingsTab.IgnoredFiles: { -@@ -158,6 +163,13 @@ - }) - } - -+ private onUseCustomRemote = () => { -+ this.props.dispatcher.showPopup({ -+ type: PopupType.CustomRemote, -+ repository: this.props.repository, -+ }) -+ } -+ - private onShowGitIgnoreExamples = () => { - this.props.dispatcher.openInBrowser('https://git-scm.com/docs/gitignore') - } diff --git a/app/test/fixtures/merge-parser/desktop/merge-cypress-spike-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-cypress-spike-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 8ddf6a07e5e..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-cypress-spike-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,3432 +0,0 @@ -added in remote - their 100644 0967ef424bce6791893e9a57bb952f80fd536e93 cypress.json -@@ -0,0 +1 @@ -+{} -added in remote - their 100644 da18d9352a17d427321962199a1fa43b8ab5cfe4 cypress/fixtures/example.json -@@ -0,0 +1,5 @@ -+{ -+ "name": "Using fixtures to represent data", -+ "email": "hello@cypress.io", -+ "body": "Fixtures are a great way to mock data for responses to routes" -+} -\ No newline at end of file -added in remote - their 100644 562d88deca0352fa481a766c500cf50f0ebcef5e cypress/integration/test.spec.ts -@@ -0,0 +1,1497 @@ -+// -+// **** Kitchen Sink Tests **** -+// -+// This app was developed to demonstrate -+// how to write tests in Cypress utilizing -+// all of the available commands -+// -+// Feel free to modify this spec in your -+// own application as a jumping off point -+ -+// Please read our "Introduction to Cypress" -+// https://on.cypress.io/introduction-to-cypress -+ -+describe('Kitchen Sink', function () { -+ it('.should() - assert that is correct', function () { -+ // https://on.cypress.io/visit -+ cy.visit('https://example.cypress.io') -+ -+ // Here we've made our first assertion using a '.should()' command. -+ // An assertion is comprised of a chainer, subject, and optional value. -+ -+ // https://on.cypress.io/should -+ // https://on.cypress.io/and -+ -+ // https://on.cypress.io/title -+ cy.title().should('include', 'Kitchen Sink') -+ // ↲ ↲ ↲ -+ // subject chainer value -+ }) -+ -+ context('Querying', function () { -+ beforeEach(function () { -+ // Visiting our app before each test removes any state build up from -+ // previous tests. Visiting acts as if we closed a tab and opened a fresh one -+ cy.visit('https://example.cypress.io/commands/querying') -+ }) -+ -+ // Let's query for some DOM elements and make assertions -+ // The most commonly used query is 'cy.get()', you can -+ // think of this like the '$' in jQuery -+ -+ it('cy.get() - query DOM elements', function () { -+ // https://on.cypress.io/get -+ -+ // Get DOM elements by id -+ cy.get('#query-btn').should('contain', 'Button') -+ -+ // Get DOM elements by class -+ cy.get('.query-btn').should('contain', 'Button') -+ -+ cy.get('#querying .well>button:first').should('contain', 'Button') -+ // ↲ -+ // Use CSS selectors just like jQuery -+ }) -+ -+ it('cy.contains() - query DOM elements with matching content', function () { -+ // https://on.cypress.io/contains -+ cy.get('.query-list') -+ .contains('bananas').should('have.class', 'third') -+ -+ // we can pass a regexp to `.contains()` -+ cy.get('.query-list') -+ .contains(/^b\w+/).should('have.class', 'third') -+ -+ cy.get('.query-list') -+ .contains('apples').should('have.class', 'first') -+ -+ // passing a selector to contains will yield the selector containing the text -+ cy.get('#querying') -+ .contains('ul', 'oranges').should('have.class', 'query-list') -+ -+ // `.contains()` will favor input[type='submit'], -+ // button, a, and label over deeper elements inside them -+ // this will not yield the <span> inside the button, -+ // but the <button> itself -+ cy.get('.query-button') -+ .contains('Save Form').should('have.class', 'btn') -+ }) -+ -+ it('.within() - query DOM elements within a specific element', function () { -+ // https://on.cypress.io/within -+ cy.get('.query-form').within(function () { -+ cy.get('input:first').should('have.attr', 'placeholder', 'Email') -+ cy.get('input:last').should('have.attr', 'placeholder', 'Password') -+ }) -+ }) -+ -+ it('cy.root() - query the root DOM element', function () { -+ // https://on.cypress.io/root -+ // By default, root is the document -+ cy.root().should('match', 'html') -+ -+ cy.get('.query-ul').within(function () { -+ // In this within, the root is now the ul DOM element -+ cy.root().should('have.class', 'query-ul') -+ }) -+ }) -+ }) -+ -+ context('Traversal', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io/commands/traversal') -+ }) -+ -+ // Let's query for some DOM elements and make assertions -+ -+ it('.children() - get child DOM elements', function () { -+ // https://on.cypress.io/children -+ cy.get('.traversal-breadcrumb').children('.active') -+ .should('contain', 'Data') -+ }) -+ -+ it('.closest() - get closest ancestor DOM element', function () { -+ // https://on.cypress.io/closest -+ cy.get('.traversal-badge').closest('ul') -+ .should('have.class', 'list-group') -+ }) -+ -+ it('.eq() - get a DOM element at a specific index', function () { -+ // https://on.cypress.io/eq -+ cy.get('.traversal-list>li').eq(1).should('contain', 'siamese') -+ }) -+ -+ it('.filter() - get DOM elements that match the selector', function () { -+ // https://on.cypress.io/filter -+ cy.get('.traversal-nav>li').filter('.active').should('contain', 'About') -+ }) -+ -+ it('.find() - get descendant DOM elements of the selector', function () { -+ // https://on.cypress.io/find -+ cy.get('.traversal-pagination').find('li').find('a') -+ .should('have.length', 7) -+ }) -+ -+ it('.first() - get first DOM element', function () { -+ // https://on.cypress.io/first -+ cy.get('.traversal-table td').first().should('contain', '1') -+ }) -+ -+ it('.last() - get last DOM element', function () { -+ // https://on.cypress.io/last -+ cy.get('.traversal-buttons .btn').last().should('contain', 'Submit') -+ }) -+ -+ it('.next() - get next sibling DOM element', function () { -+ // https://on.cypress.io/next -+ cy.get('.traversal-ul').contains('apples').next().should('contain', 'oranges') -+ }) -+ -+ it('.nextAll() - get all next sibling DOM elements', function () { -+ // https://on.cypress.io/nextall -+ cy.get('.traversal-next-all').contains('oranges') -+ .nextAll().should('have.length', 3) -+ }) -+ -+ it('.nextUntil() - get next sibling DOM elements until next el', function () { -+ // https://on.cypress.io/nextuntil -+ cy.get('#veggies').nextUntil('#nuts').should('have.length', 3) -+ }) -+ -+ it('.not() - remove DOM elements from set of DOM elements', function () { -+ // https://on.cypress.io/not -+ cy.get('.traversal-disabled .btn').not('[disabled]').should('not.contain', 'Disabled') -+ }) -+ -+ it('.parent() - get parent DOM element from DOM elements', function () { -+ // https://on.cypress.io/parent -+ cy.get('.traversal-mark').parent().should('contain', 'Morbi leo risus') -+ }) -+ -+ it('.parents() - get parent DOM elements from DOM elements', function () { -+ // https://on.cypress.io/parents -+ cy.get('.traversal-cite').parents().should('match', 'blockquote') -+ }) -+ -+ it('.parentsUntil() - get parent DOM elements from DOM elements until el', function () { -+ // https://on.cypress.io/parentsuntil -+ cy.get('.clothes-nav').find('.active').parentsUntil('.clothes-nav') -+ .should('have.length', 2) -+ }) -+ -+ it('.prev() - get previous sibling DOM element', function () { -+ // https://on.cypress.io/prev -+ cy.get('.birds').find('.active').prev().should('contain', 'Lorikeets') -+ }) -+ -+ it('.prevAll() - get all previous sibling DOM elements', function () { -+ // https://on.cypress.io/prevAll -+ cy.get('.fruits-list').find('.third').prevAll().should('have.length', 2) -+ }) -+ -+ it('.prevUntil() - get all previous sibling DOM elements until el', function () { -+ // https://on.cypress.io/prevUntil -+ cy.get('.foods-list').find('#nuts').prevUntil('#veggies') -+ }) -+ -+ it('.siblings() - get all sibling DOM elements', function () { -+ // https://on.cypress.io/siblings -+ cy.get('.traversal-pills .active').siblings().should('have.length', 2) -+ }) -+ }) -+ -+ context('Actions', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io/commands/actions') -+ }) -+ -+ // Let's perform some actions on DOM elements -+ // https://on.cypress.io/interacting-with-elements -+ -+ it('.type() - type into a DOM element', function () { -+ // https://on.cypress.io/type -+ cy.get('.action-email') -+ .type('fake@email.com').should('have.value', 'fake@email.com') -+ -+ // .type() with special character sequences -+ .type('{leftarrow}{rightarrow}{uparrow}{downarrow}') -+ .type('{del}{selectall}{backspace}') -+ -+ // .type() with key modifiers -+ .type('{alt}{option}') //these are equivalent -+ .type('{ctrl}{control}') //these are equivalent -+ .type('{meta}{command}{cmd}') //these are equivalent -+ .type('{shift}') -+ -+ // Delay each keypress by 0.1 sec -+ .type('slow.typing@email.com', { delay: 100 }) -+ .should('have.value', 'slow.typing@email.com') -+ -+ cy.get('.action-disabled') -+ // Ignore error checking prior to type -+ // like whether the input is visible or disabled -+ .type('disabled error checking', { force: true }) -+ .should('have.value', 'disabled error checking') -+ }) -+ -+ it('.focus() - focus on a DOM element', function () { -+ // https://on.cypress.io/focus -+ cy.get('.action-focus').focus() -+ .should('have.class', 'focus') -+ .prev().should('have.attr', 'style', 'color: orange;') -+ }) -+ -+ it('.blur() - blur off a DOM element', function () { -+ // https://on.cypress.io/blur -+ cy.get('.action-blur').type('I\'m about to blur').blur() -+ .should('have.class', 'error') -+ .prev().should('have.attr', 'style', 'color: red;') -+ }) -+ -+ it('.clear() - clears an input or textarea element', function () { -+ // https://on.cypress.io/clear -+ cy.get('.action-clear').type('We are going to clear this text') -+ .should('have.value', 'We are going to clear this text') -+ .clear() -+ .should('have.value', '') -+ }) -+ -+ it('.submit() - submit a form', function () { -+ // https://on.cypress.io/submit -+ cy.get('.action-form') -+ .find('[type="text"]').type('HALFOFF') -+ cy.get('.action-form').submit() -+ .next().should('contain', 'Your form has been submitted!') -+ }) -+ -+ it('.click() - click on a DOM element', function () { -+ // https://on.cypress.io/click -+ cy.get('.action-btn').click() -+ -+ // You can click on 9 specific positions of an element: -+ // ----------------------------------- -+ // | topLeft top topRight | -+ // | | -+ // | | -+ // | | -+ // | left center right | -+ // | | -+ // | | -+ // | | -+ // | bottomLeft bottom bottomRight | -+ // ----------------------------------- -+ -+ // clicking in the center of the element is the default -+ cy.get('#action-canvas').click() -+ -+ cy.get('#action-canvas').click('topLeft') -+ cy.get('#action-canvas').click('top') -+ cy.get('#action-canvas').click('topRight') -+ cy.get('#action-canvas').click('left') -+ cy.get('#action-canvas').click('right') -+ cy.get('#action-canvas').click('bottomLeft') -+ cy.get('#action-canvas').click('bottom') -+ cy.get('#action-canvas').click('bottomRight') -+ -+ // .click() accepts an x and y coordinate -+ // that controls where the click occurs :) -+ -+ cy.get('#action-canvas') -+ .click(80, 75) // click 80px on x coord and 75px on y coord -+ .click(170, 75) -+ .click(80, 165) -+ .click(100, 185) -+ .click(125, 190) -+ .click(150, 185) -+ .click(170, 165) -+ -+ // click multiple elements by passing multiple: true -+ cy.get('.action-labels>.label').click({ multiple: true }) -+ -+ // Ignore error checking prior to clicking -+ // like whether the element is visible, clickable or disabled -+ // this button below is covered by another element. -+ cy.get('.action-opacity>.btn').click({ force: true }) -+ }) -+ -+ it('.dblclick() - double click on a DOM element', function () { -+ // Our app has a listener on 'dblclick' event in our 'scripts.js' -+ // that hides the div and shows an input on double click -+ -+ // https://on.cypress.io/dblclick -+ cy.get('.action-div').dblclick().should('not.be.visible') -+ cy.get('.action-input-hidden').should('be.visible') -+ }) -+ -+ it('cy.check() - check a checkbox or radio element', function () { -+ // By default, .check() will check all -+ // matching checkbox or radio elements in succession, one after another -+ -+ // https://on.cypress.io/check -+ cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]') -+ .check().should('be.checked') -+ -+ cy.get('.action-radios [type="radio"]').not('[disabled]') -+ .check().should('be.checked') -+ -+ // .check() accepts a value argument -+ // that checks only checkboxes or radios -+ // with matching values -+ cy.get('.action-radios [type="radio"]').check('radio1').should('be.checked') -+ -+ // .check() accepts an array of values -+ // that checks only checkboxes or radios -+ // with matching values -+ cy.get('.action-multiple-checkboxes [type="checkbox"]') -+ .check(['checkbox1', 'checkbox2']).should('be.checked') -+ -+ // Ignore error checking prior to checking -+ // like whether the element is visible, clickable or disabled -+ // this checkbox below is disabled. -+ cy.get('.action-checkboxes [disabled]') -+ .check({ force: true }).should('be.checked') -+ -+ cy.get('.action-radios [type="radio"]') -+ .check('radio3', { force: true }).should('be.checked') -+ }) -+ -+ it('.uncheck() - uncheck a checkbox element', function () { -+ // By default, .uncheck() will uncheck all matching -+ // checkbox elements in succession, one after another -+ -+ // https://on.cypress.io/uncheck -+ cy.get('.action-check [type="checkbox"]') -+ .not('[disabled]') -+ .uncheck().should('not.be.checked') -+ -+ // .uncheck() accepts a value argument -+ // that unchecks only checkboxes -+ // with matching values -+ cy.get('.action-check [type="checkbox"]') -+ .check('checkbox1') -+ .uncheck('checkbox1').should('not.be.checked') -+ -+ // .uncheck() accepts an array of values -+ // that unchecks only checkboxes or radios -+ // with matching values -+ cy.get('.action-check [type="checkbox"]') -+ .check(['checkbox1', 'checkbox3']) -+ .uncheck(['checkbox1', 'checkbox3']).should('not.be.checked') -+ -+ // Ignore error checking prior to unchecking -+ // like whether the element is visible, clickable or disabled -+ // this checkbox below is disabled. -+ cy.get('.action-check [disabled]') -+ .uncheck({ force: true }).should('not.be.checked') -+ }) -+ -+ it('.select() - select an option in a <select> element', function () { -+ // https://on.cypress.io/select -+ -+ // Select option with matching text content -+ cy.get('.action-select').select('apples') -+ -+ // Select option with matching value -+ cy.get('.action-select').select('fr-bananas') -+ -+ // Select options with matching text content -+ cy.get('.action-select-multiple') -+ .select(['apples', 'oranges', 'bananas']) -+ -+ // Select options with matching values -+ cy.get('.action-select-multiple') -+ .select(['fr-apples', 'fr-oranges', 'fr-bananas']) -+ }) -+ -+ it('.scrollIntoView() - scroll an element into view', function () { -+ // https://on.cypress.io/scrollintoview -+ -+ // normally all of these buttons are hidden, because they're not within -+ // the viewable area of their parent (we need to scroll to see them) -+ cy.get('#scroll-horizontal button') -+ .should('not.be.visible') -+ -+ // scroll the button into view, as if the user had scrolled -+ cy.get('#scroll-horizontal button').scrollIntoView() -+ .should('be.visible') -+ -+ cy.get('#scroll-vertical button') -+ .should('not.be.visible') -+ -+ // Cypress handles the scroll direction needed -+ cy.get('#scroll-vertical button').scrollIntoView() -+ .should('be.visible') -+ -+ cy.get('#scroll-both button') -+ .should('not.be.visible') -+ -+ // Cypress knows to scroll to the right and down -+ cy.get('#scroll-both button').scrollIntoView() -+ .should('be.visible') -+ }) -+ -+ it('cy.scrollTo() - scroll the window or element to a position', function () { -+ -+ // https://on.cypress.io/scrollTo -+ -+ // You can scroll to 9 specific positions of an element: -+ // ----------------------------------- -+ // | topLeft top topRight | -+ // | | -+ // | | -+ // | | -+ // | left center right | -+ // | | -+ // | | -+ // | | -+ // | bottomLeft bottom bottomRight | -+ // ----------------------------------- -+ -+ // if you chain .scrollTo() off of cy, we will -+ // scroll the entire window -+ cy.scrollTo('bottom') -+ -+ cy.get('#scrollable-horizontal').scrollTo('right') -+ -+ // or you can scroll to a specific coordinate: -+ // (x axis, y axis) in pixels -+ cy.get('#scrollable-vertical').scrollTo(250, 250) -+ -+ // or you can scroll to a specific percentage -+ // of the (width, height) of the element -+ cy.get('#scrollable-both').scrollTo('75%', '25%') -+ -+ // control the easing of the scroll (default is 'swing') -+ cy.get('#scrollable-vertical').scrollTo('center', { easing: 'linear' }) -+ -+ // control the duration of the scroll (in ms) -+ cy.get('#scrollable-both').scrollTo('center', { duration: 2000 }) -+ }) -+ -+ it('.trigger() - trigger an event on a DOM element', function () { -+ // To interact with a range input (slider), we need to set its value and -+ // then trigger the appropriate event to signal it has changed -+ -+ // Here, we invoke jQuery's val() method to set the value -+ // and trigger the 'change' event -+ -+ // Note that some implementations may rely on the 'input' event, -+ // which is fired as a user moves the slider, but is not supported -+ // by some browsers -+ -+ // https://on.cypress.io/trigger -+ cy.get('.trigger-input-range') -+ .invoke('val', 25) -+ .trigger('change') -+ .get('input[type=range]').siblings('p') -+ .should('have.text', '25') -+ -+ // See our example recipes for more examples of using trigger -+ // https://on.cypress.io/examples -+ }) -+ }) -+ -+ context('Window', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io/commands/window') -+ }) -+ -+ it('cy.window() - get the global window object', function () { -+ // https://on.cypress.io/window -+ cy.window().should('have.property', 'top') -+ }) -+ -+ it('cy.document() - get the document object', function () { -+ // https://on.cypress.io/document -+ cy.document().should('have.property', 'charset').and('eq', 'UTF-8') -+ }) -+ -+ it('cy.title() - get the title', function () { -+ // https://on.cypress.io/title -+ cy.title().should('include', 'Kitchen Sink') -+ }) -+ }) -+ -+ context('Viewport', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io/commands/viewport') -+ }) -+ -+ it('cy.viewport() - set the viewport size and dimension', function () { -+ -+ cy.get('#navbar').should('be.visible') -+ -+ // https://on.cypress.io/viewport -+ cy.viewport(320, 480) -+ -+ // the navbar should have collapse since our screen is smaller -+ cy.get('#navbar').should('not.be.visible') -+ cy.get('.navbar-toggle').should('be.visible').click() -+ cy.get('.nav').find('a').should('be.visible') -+ -+ // lets see what our app looks like on a super large screen -+ cy.viewport(2999, 2999) -+ -+ // cy.viewport() accepts a set of preset sizes -+ // to easily set the screen to a device's width and height -+ -+ // We added a cy.wait() between each viewport change so you can see -+ // the change otherwise it's a little too fast to see :) -+ -+ cy.viewport('macbook-15') -+ cy.wait(200) -+ cy.viewport('macbook-13') -+ cy.wait(200) -+ cy.viewport('macbook-11') -+ cy.wait(200) -+ cy.viewport('ipad-2') -+ cy.wait(200) -+ cy.viewport('ipad-mini') -+ cy.wait(200) -+ cy.viewport('iphone-6+') -+ cy.wait(200) -+ cy.viewport('iphone-6') -+ cy.wait(200) -+ cy.viewport('iphone-5') -+ cy.wait(200) -+ cy.viewport('iphone-4') -+ cy.wait(200) -+ cy.viewport('iphone-3') -+ cy.wait(200) -+ -+ // cy.viewport() accepts an orientation for all presets -+ // the default orientation is 'portrait' -+ cy.viewport('ipad-2', 'portrait') -+ cy.wait(200) -+ cy.viewport('iphone-4', 'landscape') -+ cy.wait(200) -+ -+ // The viewport will be reset back to the default dimensions -+ // in between tests (the default is set in cypress.json) -+ }) -+ }) -+ -+ context('Location', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io/commands/location') -+ }) -+ -+ // We look at the url to make assertions -+ // about the page's state -+ -+ it('cy.hash() - get the current URL hash', function () { -+ // https://on.cypress.io/hash -+ cy.hash().should('be.empty') -+ }) -+ -+ it('cy.location() - get window.location', function () { -+ // https://on.cypress.io/location -+ cy.location().should(function (location) { -+ expect(location.hash).to.be.empty -+ expect(location.href).to.eq('https://example.cypress.io/commands/location') -+ expect(location.host).to.eq('example.cypress.io') -+ expect(location.hostname).to.eq('example.cypress.io') -+ expect(location.origin).to.eq('https://example.cypress.io') -+ expect(location.pathname).to.eq('/commands/location') -+ expect(location.port).to.eq('') -+ expect(location.protocol).to.eq('https:') -+ expect(location.search).to.be.empty -+ }) -+ }) -+ -+ it('cy.url() - get the current URL', function () { -+ // https://on.cypress.io/url -+ cy.url().should('eq', 'https://example.cypress.io/commands/location') -+ }) -+ }) -+ -+ context('Navigation', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io') -+ cy.get('.navbar-nav').contains('Commands').click() -+ cy.get('.dropdown-menu').contains('Navigation').click() -+ }) -+ -+ it('cy.go() - go back or forward in the browser\'s history', function () { -+ cy.location('pathname').should('include', 'navigation') -+ -+ // https://on.cypress.io/go -+ cy.go('back') -+ cy.location('pathname').should('not.include', 'navigation') -+ -+ cy.go('forward') -+ cy.location('pathname').should('include', 'navigation') -+ -+ // equivalent to clicking back -+ cy.go(-1) -+ cy.location('pathname').should('not.include', 'navigation') -+ -+ // equivalent to clicking forward -+ cy.go(1) -+ cy.location('pathname').should('include', 'navigation') -+ }) -+ -+ it('cy.reload() - reload the page', function () { -+ // https://on.cypress.io/reload -+ cy.reload() -+ -+ // reload the page without using the cache -+ cy.reload(true) -+ }) -+ -+ it('cy.visit() - visit a remote url', function () { -+ // Visit any sub-domain of your current domain -+ // https://on.cypress.io/visit -+ -+ // Pass options to the visit -+ cy.visit('https://example.cypress.io/commands/navigation', { -+ timeout: 50000, // increase total time for the visit to resolve -+ onBeforeLoad (contentWindow) { -+ // contentWindow is the remote page's window object -+ }, -+ onLoad (contentWindow) { -+ // contentWindow is the remote page's window object -+ }, -+ }) -+ }) -+ }) -+ -+ context('Assertions', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io/commands/assertions') -+ }) -+ -+ describe('Implicit Assertions', function () { -+ -+ it('.should() - make an assertion about the current subject', function () { -+ // https://on.cypress.io/should -+ cy.get('.assertion-table') -+ .find('tbody tr:last').should('have.class', 'success') -+ }) -+ -+ it('.and() - chain multiple assertions together', function () { -+ // https://on.cypress.io/and -+ cy.get('.assertions-link') -+ .should('have.class', 'active') -+ .and('have.attr', 'href') -+ .and('include', 'cypress.io') -+ }) -+ }) -+ -+ describe('Explicit Assertions', function () { -+ // https://on.cypress.io/assertions -+ it('expect - assert shape of an object', function () { -+ const person = { -+ name: 'Joe', -+ age: 20, -+ } -+ expect(person).to.have.all.keys('name', 'age') -+ }) -+ -+ it('expect - make an assertion about a specified subject', function () { -+ // We can use Chai's BDD style assertions -+ expect(true).to.be.true -+ -+ // Pass a function to should that can have any number -+ // of explicit assertions within it. -+ cy.get('.assertions-p').find('p') -+ .should(function ($p) { -+ // return an array of texts from all of the p's -+ let texts = $p.map(function (i, el) { -+ // https://on.cypress.io/$ -+ return Cypress.$(el).text() -+ }) -+ -+ // jquery map returns jquery object -+ // and .get() convert this to simple array -+ texts = texts.get() -+ -+ // array should have length of 3 -+ expect(texts).to.have.length(3) -+ -+ // set this specific subject -+ expect(texts).to.deep.eq([ -+ 'Some text from first p', -+ 'More text from second p', -+ 'And even more text from third p', -+ ]) -+ }) -+ }) -+ }) -+ }) -+ -+ context('Misc', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io/commands/misc') -+ }) -+ -+ it('.end() - end the command chain', function () { -+ // cy.end is useful when you want to end a chain of commands -+ // and force Cypress to re-query from the root element -+ -+ // https://on.cypress.io/end -+ cy.get('.misc-table').within(function () { -+ // ends the current chain and yields null -+ cy.contains('Cheryl').click().end() -+ -+ // queries the entire table again -+ cy.contains('Charles').click() -+ }) -+ }) -+ -+ it('cy.exec() - execute a system command', function () { -+ // cy.exec allows you to execute a system command. -+ // so you can take actions necessary for your test, -+ // but outside the scope of Cypress. -+ -+ // https://on.cypress.io/exec -+ cy.exec('echo Jane Lane') -+ .its('stdout').should('contain', 'Jane Lane') -+ -+ // we can use Cypress.platform string to -+ // select appropriate command -+ // https://on.cypress/io/platform -+ cy.log(`Platform ${Cypress.platform} architecture ${Cypress.arch}`) -+ -+ if (Cypress.platform === 'win32') { -+ cy.exec('print cypress.json') -+ .its('stderr').should('be.empty') -+ } else { -+ cy.exec('cat cypress.json') -+ .its('stderr').should('be.empty') -+ -+ cy.exec('pwd') -+ .its('code').should('eq', 0) -+ } -+ }) -+ -+ it('cy.focused() - get the DOM element that has focus', function () { -+ // https://on.cypress.io/focused -+ cy.get('.misc-form').find('#name').click() -+ cy.focused().should('have.id', 'name') -+ -+ cy.get('.misc-form').find('#description').click() -+ cy.focused().should('have.id', 'description') -+ }) -+ -+ it('cy.screenshot() - take a screenshot', function () { -+ // https://on.cypress.io/screenshot -+ cy.screenshot('my-image') -+ }) -+ -+ it('cy.wrap() - wrap an object', function () { -+ // https://on.cypress.io/wrap -+ cy.wrap({ foo: 'bar' }) -+ .should('have.property', 'foo') -+ .and('include', 'bar') -+ }) -+ }) -+ -+ context('Connectors', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io/commands/connectors') -+ }) -+ -+ it('.each() - iterate over an array of elements', function () { -+ // https://on.cypress.io/each -+ cy.get('.connectors-each-ul>li') -+ .each(function ($el, index, $list) { -+ console.log($el, index, $list) -+ }) -+ }) -+ -+ it('.its() - get properties on the current subject', function () { -+ // https://on.cypress.io/its -+ cy.get('.connectors-its-ul>li') -+ // calls the 'length' property yielding that value -+ .its('length') -+ .should('be.gt', 2) -+ }) -+ -+ it('.invoke() - invoke a function on the current subject', function () { -+ // our div is hidden in our script.js -+ // $('.connectors-div').hide() -+ -+ // https://on.cypress.io/invoke -+ cy.get('.connectors-div').should('be.hidden') -+ -+ // call the jquery method 'show' on the 'div.container' -+ .invoke('show') -+ .should('be.visible') -+ }) -+ -+ it('.spread() - spread an array as individual args to callback function', function () { -+ // https://on.cypress.io/spread -+ let arr = ['foo', 'bar', 'baz'] -+ -+ cy.wrap(arr).spread(function (foo, bar, baz) { -+ expect(foo).to.eq('foo') -+ expect(bar).to.eq('bar') -+ expect(baz).to.eq('baz') -+ }) -+ }) -+ -+ it('.then() - invoke a callback function with the current subject', function () { -+ // https://on.cypress.io/then -+ cy.get('.connectors-list>li').then(function ($lis) { -+ expect($lis).to.have.length(3) -+ expect($lis.eq(0)).to.contain('Walk the dog') -+ expect($lis.eq(1)).to.contain('Feed the cat') -+ expect($lis.eq(2)).to.contain('Write JavaScript') -+ }) -+ }) -+ }) -+ -+ context('Aliasing', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io/commands/aliasing') -+ }) -+ -+ // We alias a DOM element for use later -+ // We don't have to traverse to the element -+ // later in our code, we just reference it with @ -+ -+ it('.as() - alias a route or DOM element for later use', function () { -+ // this is a good use case for an alias, -+ // we don't want to write this long traversal again -+ -+ // https://on.cypress.io/as -+ cy.get('.as-table').find('tbody>tr') -+ .first().find('td').first().find('button').as('firstBtn') -+ -+ // maybe do some more testing here... -+ -+ // when we reference the alias, we place an -+ // @ in front of it's name -+ cy.get('@firstBtn').click() -+ -+ cy.get('@firstBtn') -+ .should('have.class', 'btn-success') -+ .and('contain', 'Changed') -+ }) -+ }) -+ -+ context('Waiting', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io/commands/waiting') -+ }) -+ // BE CAREFUL of adding unnecessary wait times. -+ -+ // https://on.cypress.io/wait -+ it('cy.wait() - wait for a specific amount of time', function () { -+ cy.get('.wait-input1').type('Wait 1000ms after typing') -+ cy.wait(1000) -+ cy.get('.wait-input2').type('Wait 1000ms after typing') -+ cy.wait(1000) -+ cy.get('.wait-input3').type('Wait 1000ms after typing') -+ cy.wait(1000) -+ }) -+ -+ // Waiting for a specific resource to resolve -+ // is covered within the cy.route() test below -+ }) -+ -+ context('Network Requests', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io/commands/network-requests') -+ }) -+ -+ // Manage AJAX / XHR requests in your app -+ -+ it('cy.server() - control behavior of network requests and responses', function () { -+ // https://on.cypress.io/server -+ cy.server().should(function (server) { -+ // the default options on server -+ // you can override any of these options -+ expect(server.delay).to.eq(0) -+ expect(server.method).to.eq('GET') -+ expect(server.status).to.eq(200) -+ expect(server.headers).to.be.null -+ expect(server.response).to.be.null -+ expect(server.onRequest).to.be.undefined -+ expect(server.onResponse).to.be.undefined -+ expect(server.onAbort).to.be.undefined -+ -+ // These options control the server behavior -+ // affecting all requests -+ -+ // pass false to disable existing route stubs -+ expect(server.enable).to.be.true -+ // forces requests that don't match your routes to 404 -+ expect(server.force404).to.be.false -+ // whitelists requests from ever being logged or stubbed -+ expect(server.whitelist).to.be.a('function') -+ }) -+ -+ cy.server({ -+ method: 'POST', -+ delay: 1000, -+ status: 422, -+ response: {}, -+ }) -+ -+ // any route commands will now inherit the above options -+ // from the server. anything we pass specifically -+ // to route will override the defaults though. -+ }) -+ -+ it('cy.request() - make an XHR request', function () { -+ // https://on.cypress.io/request -+ cy.request('https://jsonplaceholder.typicode.com/comments') -+ .should(function (response) { -+ expect(response.status).to.eq(200) -+ expect(response.body).to.have.length(500) -+ expect(response).to.have.property('headers') -+ expect(response).to.have.property('duration') -+ }) -+ }) -+ -+ it('cy.route() - route responses to matching requests', function () { -+ let message = 'whoa, this comment doesn\'t exist' -+ cy.server() -+ -+ // **** GET comments route **** -+ -+ // https://on.cypress.io/route -+ cy.route(/comments\/1/).as('getComment') -+ -+ // we have code that fetches a comment when -+ // the button is clicked in scripts.js -+ cy.get('.network-btn').click() -+ -+ // **** Wait **** -+ -+ // Wait for a specific resource to resolve -+ // continuing to the next command -+ -+ // https://on.cypress.io/wait -+ cy.wait('@getComment').its('status').should('eq', 200) -+ -+ // **** POST comment route **** -+ -+ // Specify the route to listen to method 'POST' -+ cy.route('POST', '/comments').as('postComment') -+ -+ // we have code that posts a comment when -+ // the button is clicked in scripts.js -+ cy.get('.network-post').click() -+ cy.wait('@postComment') -+ -+ // get the route -+ cy.get('@postComment').then(function (xhr) { -+ expect(xhr.requestBody).to.include('email') -+ expect(xhr.requestHeaders).to.have.property('Content-Type') -+ expect(xhr.responseBody).to.have.property('name', 'Using POST in cy.route()') -+ }) -+ -+ // **** Stubbed PUT comment route **** -+ cy.route({ -+ method: 'PUT', -+ url: /comments\/\d+/, -+ status: 404, -+ response: { error: message }, -+ delay: 500, -+ }).as('putComment') -+ -+ // we have code that puts a comment when -+ // the button is clicked in scripts.js -+ cy.get('.network-put').click() -+ -+ cy.wait('@putComment') -+ -+ // our 404 statusCode logic in scripts.js executed -+ cy.get('.network-put-comment').should('contain', message) -+ }) -+ }) -+ -+ context('Files', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io/commands/files') -+ }) -+ it('cy.fixture() - load a fixture', function () { -+ // Instead of writing a response inline you can -+ // connect a response with a fixture file -+ // located in fixtures folder. -+ -+ cy.server() -+ -+ // https://on.cypress.io/fixture -+ cy.fixture('example.json').as('comment') -+ -+ cy.route(/comments/, '@comment').as('getComment') -+ -+ // we have code that gets a comment when -+ // the button is clicked in scripts.js -+ cy.get('.fixture-btn').click() -+ -+ cy.wait('@getComment').its('responseBody') -+ .should('have.property', 'name') -+ .and('include', 'Using fixtures to represent data') -+ -+ // you can also just write the fixture in the route -+ cy.route(/comments/, 'fixture:example.json').as('getComment') -+ -+ // we have code that gets a comment when -+ // the button is clicked in scripts.js -+ cy.get('.fixture-btn').click() -+ -+ cy.wait('@getComment').its('responseBody') -+ .should('have.property', 'name') -+ .and('include', 'Using fixtures to represent data') -+ -+ // or write fx to represent fixture -+ // by default it assumes it's .json -+ cy.route(/comments/, 'fx:example').as('getComment') -+ -+ // we have code that gets a comment when -+ // the button is clicked in scripts.js -+ cy.get('.fixture-btn').click() -+ -+ cy.wait('@getComment').its('responseBody') -+ .should('have.property', 'name') -+ .and('include', 'Using fixtures to represent data') -+ }) -+ -+ it('cy.readFile() - read a files contents', function () { -+ // You can read a file and yield its contents -+ // The filePath is relative to your project's root. -+ -+ // https://on.cypress.io/readfile -+ cy.readFile('cypress.json').then(function (json) { -+ expect(json).to.be.an('object') -+ }) -+ -+ }) -+ -+ it('cy.writeFile() - write to a file', function () { -+ // You can write to a file with the specified contents -+ -+ // Use a response from a request to automatically -+ // generate a fixture file for use later -+ cy.request('https://jsonplaceholder.typicode.com/users') -+ .then(function (response) { -+ // https://on.cypress.io/writefile -+ cy.writeFile('cypress/fixtures/users.json', response.body) -+ }) -+ cy.fixture('users').should(function (users) { -+ expect(users[0].name).to.exist -+ }) -+ -+ // JavaScript arrays and objects are stringified and formatted into text. -+ cy.writeFile('cypress/fixtures/profile.json', { -+ id: 8739, -+ name: 'Jane', -+ email: 'jane@example.com', -+ }) -+ -+ cy.fixture('profile').should(function (profile) { -+ expect(profile.name).to.eq('Jane') -+ }) -+ }) -+ }) -+ -+ context('Local Storage', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io/commands/local-storage') -+ }) -+ // Although local storage is automatically cleared -+ // to maintain a clean state in between tests -+ // sometimes we need to clear the local storage manually -+ -+ it('cy.clearLocalStorage() - clear all data in local storage', function () { -+ // https://on.cypress.io/clearlocalstorage -+ cy.get('.ls-btn').click().should(function () { -+ expect(localStorage.getItem('prop1')).to.eq('red') -+ expect(localStorage.getItem('prop2')).to.eq('blue') -+ expect(localStorage.getItem('prop3')).to.eq('magenta') -+ }) -+ -+ // clearLocalStorage() yields the localStorage object -+ cy.clearLocalStorage().should(function (ls) { -+ expect(ls.getItem('prop1')).to.be.null -+ expect(ls.getItem('prop2')).to.be.null -+ expect(ls.getItem('prop3')).to.be.null -+ }) -+ -+ // **** Clear key matching string in Local Storage **** -+ cy.get('.ls-btn').click().should(function () { -+ expect(localStorage.getItem('prop1')).to.eq('red') -+ expect(localStorage.getItem('prop2')).to.eq('blue') -+ expect(localStorage.getItem('prop3')).to.eq('magenta') -+ }) -+ -+ cy.clearLocalStorage('prop1').should(function (ls) { -+ expect(ls.getItem('prop1')).to.be.null -+ expect(ls.getItem('prop2')).to.eq('blue') -+ expect(ls.getItem('prop3')).to.eq('magenta') -+ }) -+ -+ // **** Clear key's matching regex in Local Storage **** -+ cy.get('.ls-btn').click().should(function () { -+ expect(localStorage.getItem('prop1')).to.eq('red') -+ expect(localStorage.getItem('prop2')).to.eq('blue') -+ expect(localStorage.getItem('prop3')).to.eq('magenta') -+ }) -+ -+ cy.clearLocalStorage(/prop1|2/).should(function (ls) { -+ expect(ls.getItem('prop1')).to.be.null -+ expect(ls.getItem('prop2')).to.be.null -+ expect(ls.getItem('prop3')).to.eq('magenta') -+ }) -+ }) -+ }) -+ -+ context('Cookies', function () { -+ beforeEach(function () { -+ Cypress.Cookies.debug(true) -+ -+ cy.visit('https://example.cypress.io/commands/cookies') -+ -+ // clear cookies again after visiting to remove -+ // any 3rd party cookies picked up such as cloudflare -+ cy.clearCookies() -+ }) -+ -+ it('cy.getCookie() - get a browser cookie', function () { -+ // https://on.cypress.io/getcookie -+ cy.get('#getCookie .set-a-cookie').click() -+ -+ // cy.getCookie() yields a cookie object -+ cy.getCookie('token').should('have.property', 'value', '123ABC') -+ }) -+ -+ it('cy.getCookies() - get browser cookies', function () { -+ // https://on.cypress.io/getcookies -+ cy.getCookies().should('be.empty') -+ -+ cy.get('#getCookies .set-a-cookie').click() -+ -+ // cy.getCookies() yields an array of cookies -+ cy.getCookies().should('have.length', 1).should(function (cookies) { -+ -+ // each cookie has these properties -+ expect(cookies[0]).to.have.property('name', 'token') -+ expect(cookies[0]).to.have.property('value', '123ABC') -+ expect(cookies[0]).to.have.property('httpOnly', false) -+ expect(cookies[0]).to.have.property('secure', false) -+ expect(cookies[0]).to.have.property('domain') -+ expect(cookies[0]).to.have.property('path') -+ }) -+ }) -+ -+ it('cy.setCookie() - set a browser cookie', function () { -+ // https://on.cypress.io/setcookie -+ cy.getCookies().should('be.empty') -+ -+ cy.setCookie('foo', 'bar') -+ -+ // cy.getCookie() yields a cookie object -+ cy.getCookie('foo').should('have.property', 'value', 'bar') -+ }) -+ -+ it('cy.clearCookie() - clear a browser cookie', function () { -+ // https://on.cypress.io/clearcookie -+ cy.getCookie('token').should('be.null') -+ -+ cy.get('#clearCookie .set-a-cookie').click() -+ -+ cy.getCookie('token').should('have.property', 'value', '123ABC') -+ -+ // cy.clearCookies() yields null -+ cy.clearCookie('token').should('be.null') -+ -+ cy.getCookie('token').should('be.null') -+ }) -+ -+ it('cy.clearCookies() - clear browser cookies', function () { -+ // https://on.cypress.io/clearcookies -+ cy.getCookies().should('be.empty') -+ -+ cy.get('#clearCookies .set-a-cookie').click() -+ -+ cy.getCookies().should('have.length', 1) -+ -+ // cy.clearCookies() yields null -+ cy.clearCookies() -+ -+ cy.getCookies().should('be.empty') -+ }) -+ }) -+ -+ context('Spies, Stubs, and Clock', function () { -+ it('cy.spy() - wrap a method in a spy', function () { -+ // https://on.cypress.io/spy -+ cy.visit('https://example.cypress.io/commands/spies-stubs-clocks') -+ -+ let obj = { -+ foo () {}, -+ } -+ -+ let spy = cy.spy(obj, 'foo').as('anyArgs') -+ -+ obj.foo() -+ -+ expect(spy).to.be.called -+ -+ }) -+ -+ it('cy.stub() - create a stub and/or replace a function with a stub', function () { -+ // https://on.cypress.io/stub -+ cy.visit('https://example.cypress.io/commands/spies-stubs-clocks') -+ -+ let obj = { -+ foo () {}, -+ } -+ -+ let stub = cy.stub(obj, 'foo').as('foo') -+ -+ obj.foo('foo', 'bar') -+ -+ expect(stub).to.be.called -+ -+ }) -+ -+ it('cy.clock() - control time in the browser', function () { -+ // create the date in UTC so its always the same -+ // no matter what local timezone the browser is running in -+ let now = new Date(Date.UTC(2017, 2, 14)).getTime() -+ -+ // https://on.cypress.io/clock -+ cy.clock(now) -+ cy.visit('https://example.cypress.io/commands/spies-stubs-clocks') -+ cy.get('#clock-div').click() -+ .should('have.text', '1489449600') -+ }) -+ -+ it('cy.tick() - move time in the browser', function () { -+ // create the date in UTC so its always the same -+ // no matter what local timezone the browser is running in -+ let now = new Date(Date.UTC(2017, 2, 14)).getTime() -+ -+ // https://on.cypress.io/tick -+ cy.clock(now) -+ cy.visit('https://example.cypress.io/commands/spies-stubs-clocks') -+ cy.get('#tick-div').click() -+ .should('have.text', '1489449600') -+ cy.tick(10000) // 10 seconds passed -+ cy.get('#tick-div').click() -+ .should('have.text', '1489449610') -+ }) -+ }) -+ -+ context('Utilities', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io/utilities') -+ }) -+ -+ it('Cypress._.method() - call a lodash method', function () { -+ // use the _.chain, _.map, _.take, and _.value functions -+ // https://on.cypress.io/_ -+ cy.request('https://jsonplaceholder.typicode.com/users') -+ .then(function (response) { -+ let ids = Cypress._.chain(response.body).map('id').take(3).value() -+ -+ expect(ids).to.deep.eq([1, 2, 3]) -+ }) -+ }) -+ -+ it('Cypress.$(selector) - call a jQuery method', function () { -+ // https://on.cypress.io/$ -+ let $li = Cypress.$('.utility-jquery li:first') -+ -+ cy.wrap($li) -+ .should('not.have.class', 'active') -+ .click() -+ .should('have.class', 'active') -+ }) -+ -+ it('Cypress.moment() - format or parse dates using a moment method', function () { -+ // use moment's format function -+ // https://on.cypress.io/cypress-moment -+ let time = Cypress.moment().utc('2014-04-25T19:38:53.196Z').format('h:mm A') -+ -+ cy.get('.utility-moment').contains('3:38 PM') -+ .should('have.class', 'badge') -+ }) -+ -+ it('Cypress.Blob.method() - blob utilities and base64 string conversion', function () { -+ cy.get('.utility-blob').then(function ($div) { -+ // https://on.cypress.io/blob -+ // https://github.com/nolanlawson/blob-util#imgSrcToDataURL -+ // get the dataUrl string for the javascript-logo -+ return Cypress.Blob.imgSrcToDataURL('https://example.cypress.io/assets/img/javascript-logo.png', undefined, 'anonymous') -+ .then(function (dataUrl) { -+ // create an <img> element and set its src to the dataUrl -+ let img = Cypress.$('<img />', { src: dataUrl }) -+ // need to explicitly return cy here since we are initially returning -+ // the Cypress.Blob.imgSrcToDataURL promise to our test -+ // append the image -+ $div.append(img) -+ -+ cy.get('.utility-blob img').click() -+ .should('have.attr', 'src', dataUrl) -+ }) -+ }) -+ }) -+ -+ it('new Cypress.Promise(function) - instantiate a bluebird promise', function () { -+ // https://on.cypress.io/promise -+ let waited = false -+ -+ function waitOneSecond () { -+ // return a promise that resolves after 1 second -+ return new Cypress.Promise(function (resolve, reject) { -+ setTimeout(function () { -+ // set waited to true -+ waited = true -+ -+ // resolve with 'foo' string -+ resolve('foo') -+ }, 1000) -+ }) -+ } -+ -+ cy.then(function () { -+ // return a promise to cy.then() that -+ // is awaited until it resolves -+ return waitOneSecond().then(function (str) { -+ expect(str).to.eq('foo') -+ expect(waited).to.be.true -+ }) -+ }) -+ }) -+ }) -+ -+ -+ context('Cypress.config()', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io/cypress-api/config') -+ }) -+ -+ it('Cypress.config() - get and set configuration options', function () { -+ // https://on.cypress.io/config -+ let myConfig = Cypress.config() -+ -+ expect(myConfig).to.have.property('animationDistanceThreshold', 5) -+ expect(myConfig).to.have.property('baseUrl', null) -+ expect(myConfig).to.have.property('defaultCommandTimeout', 4000) -+ expect(myConfig).to.have.property('requestTimeout', 5000) -+ expect(myConfig).to.have.property('responseTimeout', 30000) -+ expect(myConfig).to.have.property('viewportHeight', 660) -+ expect(myConfig).to.have.property('viewportWidth', 1000) -+ expect(myConfig).to.have.property('pageLoadTimeout', 60000) -+ expect(myConfig).to.have.property('waitForAnimations', true) -+ -+ expect(Cypress.config('pageLoadTimeout')).to.eq(60000) -+ -+ // this will change the config for the rest of your tests! -+ Cypress.config('pageLoadTimeout', 20000) -+ -+ expect(Cypress.config('pageLoadTimeout')).to.eq(20000) -+ -+ Cypress.config('pageLoadTimeout', 60000) -+ }) -+ }) -+ -+ context('Cypress.env()', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io/cypress-api/env') -+ }) -+ -+ // We can set environment variables for highly dynamic values -+ -+ // https://on.cypress.io/environment-variables -+ it('Cypress.env() - get environment variables', function () { -+ // https://on.cypress.io/env -+ // set multiple environment variables -+ Cypress.env({ -+ host: 'veronica.dev.local', -+ api_server: 'http://localhost:8888/v1/', -+ }) -+ -+ // get environment variable -+ expect(Cypress.env('host')).to.eq('veronica.dev.local') -+ -+ // set environment variable -+ Cypress.env('api_server', 'http://localhost:8888/v2/') -+ expect(Cypress.env('api_server')).to.eq('http://localhost:8888/v2/') -+ -+ // get all environment variable -+ expect(Cypress.env()).to.have.property('host', 'veronica.dev.local') -+ expect(Cypress.env()).to.have.property('api_server', 'http://localhost:8888/v2/') -+ }) -+ }) -+ -+ context('Cypress.Cookies', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io/cypress-api/cookies') -+ }) -+ -+ // https://on.cypress.io/cookies -+ it('Cypress.Cookies.debug() - enable or disable debugging', function () { -+ Cypress.Cookies.debug(true) -+ -+ // Cypress will now log in the console when -+ // cookies are set or cleared -+ cy.setCookie('fakeCookie', '123ABC') -+ cy.clearCookie('fakeCookie') -+ cy.setCookie('fakeCookie', '123ABC') -+ cy.clearCookie('fakeCookie') -+ cy.setCookie('fakeCookie', '123ABC') -+ }) -+ -+ it('Cypress.Cookies.preserveOnce() - preserve cookies by key', function () { -+ // normally cookies are reset after each test -+ cy.getCookie('fakeCookie').should('not.be.ok') -+ -+ // preserving a cookie will not clear it when -+ // the next test starts -+ cy.setCookie('lastCookie', '789XYZ') -+ Cypress.Cookies.preserveOnce('lastCookie') -+ }) -+ -+ it('Cypress.Cookies.defaults() - set defaults for all cookies', function () { -+ // now any cookie with the name 'session_id' will -+ // not be cleared before each new test runs -+ Cypress.Cookies.defaults({ -+ whitelist: 'session_id', -+ }) -+ }) -+ }) -+ -+ context('Cypress.dom', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io/cypress-api/dom') -+ }) -+ -+ // https://on.cypress.io/dom -+ it('Cypress.dom.isHidden() - determine if a DOM element is hidden', function () { -+ let hiddenP = Cypress.$('.dom-p p.hidden').get(0) -+ let visibleP = Cypress.$('.dom-p p.visible').get(0) -+ -+ // our first paragraph has css class 'hidden' -+ expect(Cypress.dom.isHidden(hiddenP)).to.be.true -+ expect(Cypress.dom.isHidden(visibleP)).to.be.false -+ }) -+ }) -+ -+ context('Cypress.Server', function () { -+ beforeEach(function () { -+ cy.visit('https://example.cypress.io/cypress-api/server') -+ }) -+ -+ // Permanently override server options for -+ // all instances of cy.server() -+ -+ // https://on.cypress.io/cypress-server -+ it('Cypress.Server.defaults() - change default config of server', function () { -+ Cypress.Server.defaults({ -+ delay: 0, -+ force404: false, -+ whitelist (xhr) { -+ // handle custom logic for whitelisting -+ }, -+ }) -+ }) -+ }) -+}) -added in remote - their 100644 5609d310603b43bf480e9547528c071e176f3a87 cypress/plugins/cy-ts-preprocessor.js -@@ -0,0 +1,26 @@ -+const wp = require('@cypress/webpack-preprocessor') -+ -+const webpackOptions = { -+ resolve: { -+ extensions: ['.ts', '.js'], -+ }, -+ module: { -+ rules: [ -+ { -+ test: /\\spec.ts$/, -+ exclude: [/node_modules/], -+ use: [ -+ { -+ loader: 'ts-loader', -+ }, -+ ], -+ }, -+ ], -+ }, -+} -+ -+const options = { -+ webpackOptions, -+} -+ -+module.exports = wp(options) -added in remote - their 100644 78e782f9690a432e6a965b96f7e544f3e5d2c84d cypress/plugins/index.js -@@ -0,0 +1,5 @@ -+const cypressTypeScriptPreprocessor = require('./cy-ts-preprocessor') -+ -+module.exports = on => { -+ on('file:preprocessor', cypressTypeScriptPreprocessor) -+} -added in remote - their 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 cypress/support/commands.js -added in remote - their 100644 43c03b759d9bed2d8dbd1d5e65febebdd762e8e8 cypress/support/index.js -@@ -0,0 +1 @@ -+import './commands' -changed in both - base 100644 90bd4ac9e8510620022275c9bfe5c0ac2ec103ad package.json - our 100644 2006bfb748810f6ea8bdbd26edf7c09524a1388a package.json - their 100644 f9da3ef35f8fcdc28e4abd360ed78a0fcaf05763 package.json -@@ -51,9 +51,14 @@ - "yarn": ">= 1.9" - }, - "dependencies": { -+<<<<<<< .our - "ajv": "^6.4.0", - "awesome-node-loader": "^1.1.0", - "awesome-typescript-loader": "^5.0.0", -+======= -+ "@bahmutov/add-typescript-to-cypress": "^2.0.0", -+ "awesome-typescript-loader": "^3.4.0", -+>>>>>>> .their - "aws-sdk": "^2.23.0", - "babel-core": "^6.26.3", - "babel-minify-webpack-plugin": "^0.3.1", -@@ -64,8 +69,14 @@ - "chalk": "^2.2.0", - "clean-webpack-plugin": "^0.1.19", - "cross-env": "^5.0.5", -+<<<<<<< .our - "css-loader": "^0.28.11", - "eslint": "^5.2.0", -+======= -+ "css-loader": "^0.28.5", -+ "cypress": "^1.4.2", -+ "eslint": "^4.15.0", -+>>>>>>> .their - "eslint-config-prettier": "^2.9.0", - "eslint-plugin-babel": "^5.1.0", - "eslint-plugin-json": "^1.2.1", -changed in both - base 100644 277ed46c185a8c539e2c44a06c4c539a248d2577 tsconfig.json - our 100644 3162be12e327f202d1aab8c198ad93c33ff738c9 tsconfig.json - their 100644 983810b54a0f2a1f8933aa8a7023fca14e3a3e12 tsconfig.json -@@ -22,7 +22,8 @@ - "app/node_modules", - "dist", - "out", -- "app/src/highlighter" -+ "app/src/highlighter", -+ "app/cypress/**/*.ts" - ], - "compileOnSave": false - } -changed in both - base 100644 46a48fb4cc61ec9e3ba6c40fb240926be3efe089 yarn.lock - our 100644 45ddb8bf6902bbb22708d844324093dccda26c79 yarn.lock - their 100644 b5338cebfd3f4c5d6cc5d7227d8a06ccbf9c1db9 yarn.lock -@@ -13,6 +13,54 @@ - "@types/express" "*" - "@types/node" "*" - -+"@bahmutov/add-typescript-to-cypress@^2.0.0": -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/@bahmutov/add-typescript-to-cypress/-/add-typescript-to-cypress-2.0.0.tgz#5458b630d1d9d309b10941df8757bb59a5db2abf" -+ dependencies: -+ "@cypress/webpack-preprocessor" "1.1.3" -+ am-i-a-dependency "1.1.2" -+ chalk "2.3.0" -+ debug "3.1.0" -+ shelljs "0.8.0" -+ terminal-banner "1.1.0" -+ ts-loader "3.2.0" -+ -+"@cypress/listr-verbose-renderer@0.4.1": -+ version "0.4.1" -+ resolved "https://registry.yarnpkg.com/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#a77492f4b11dcc7c446a34b3e28721afd33c642a" -+ dependencies: -+ chalk "^1.1.3" -+ cli-cursor "^1.0.2" -+ date-fns "^1.27.2" -+ figures "^1.7.0" -+ -+"@cypress/webpack-preprocessor@1.1.3": -+ version "1.1.3" -+ resolved "https://registry.yarnpkg.com/@cypress/webpack-preprocessor/-/webpack-preprocessor-1.1.3.tgz#ee216893714c6e89a171ff4a6ffa03893c308c78" -+ dependencies: -+ babel-core "6.26.0" -+ babel-loader "7.1.2" -+ babel-preset-env "1.6.0" -+ babel-preset-react "6.24.1" -+ bluebird "3.5.0" -+ debug "3.1.0" -+ lodash.clonedeep "4.5.0" -+ webpack "3.6.0" -+ -+"@cypress/xvfb@1.1.3": -+ version "1.1.3" -+ resolved "https://registry.yarnpkg.com/@cypress/xvfb/-/xvfb-1.1.3.tgz#6294a7d1feb751f12302248f2089fc534c4acb7f" -+ dependencies: -+ lodash.once "^4.1.1" -+ -+"@types/blob-util@1.3.3": -+ version "1.3.3" -+ resolved "https://registry.yarnpkg.com/@types/blob-util/-/blob-util-1.3.3.tgz#adba644ae34f88e1dd9a5864c66ad651caaf628a" -+ -+"@types/bluebird@3.5.18": -+ version "3.5.18" -+ resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.18.tgz#6a60435d4663e290f3709898a4f75014f279c4d6" -+ - "@types/byline@^4.2.31": - version "4.2.31" - resolved "https://registry.yarnpkg.com/@types/byline/-/byline-4.2.31.tgz#0e61fcb9c03e047d21c4496554c7116297ab60cd" -@@ -25,13 +73,30 @@ - dependencies: - "@types/chai" "*" - -+"@types/chai-jquery@1.1.35": -+ version "1.1.35" -+ resolved "https://registry.yarnpkg.com/@types/chai-jquery/-/chai-jquery-1.1.35.tgz#9a8f0a39ec0851b2768a8f8c764158c2a2568d04" -+ dependencies: -+ "@types/chai" "*" -+ "@types/jquery" "*" -+ - "@types/chai@*": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.0.4.tgz#fe86315d9a66827feeb16f73bc954688ec950e18" - -+<<<<<<< .our - "@types/chai@^4.1.2": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.2.tgz#f1af664769cfb50af805431c407425ed619daa21" -+======= -+"@types/chai@4.0.8": -+ version "4.0.8" -+ resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.0.8.tgz#d27600e9ba2f371e08695d90a0fe0408d89c7be7" -+ -+"@types/chai@^4.0.5": -+ version "4.0.5" -+ resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.0.5.tgz#b6e250e281b47e0192e236619e9b1afe62fd345c" -+>>>>>>> .their - - "@types/classnames@^2.2.2": - version "2.2.3" -@@ -109,6 +174,7 @@ - dependencies: - "@types/node" "*" - -+<<<<<<< .our - "@types/fs-extra@^5.0.2": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-5.0.2.tgz#235a7e2b56452cc0a6a4809b53e1d1eaffff9c96" -@@ -141,11 +207,21 @@ - dependencies: - "@types/html-minifier" "*" - "@types/webpack" "*" -+======= -+"@types/jquery@*": -+ version "3.3.0" -+ resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.0.tgz#6316ac20a1a13c5d521a2dc661befc7184f73f5b" -+ -+"@types/jquery@3.2.16": -+ version "3.2.16" -+ resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.2.16.tgz#04419c404a3194350e7d3f339a90e72c88db3111" -+>>>>>>> .their - - "@types/keytar@^4.0.0": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/keytar/-/keytar-4.0.1.tgz#e2cf6405dc33861424e59b67516c66d2cf7bc21b" - -+<<<<<<< .our - "@types/legal-eagle@^0.15.0": - version "0.15.0" - resolved "https://registry.yarnpkg.com/@types/legal-eagle/-/legal-eagle-0.15.0.tgz#3a3cf08edca425ffaf9518304c4f1efddea36e42" -@@ -177,6 +253,19 @@ - "@types/mocha@^2.2.48": - version "2.2.48" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.48.tgz#3523b126a0b049482e1c3c11877460f76622ffab" -+======= -+"@types/lodash@4.14.87": -+ version "4.14.87" -+ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.87.tgz#55f92183b048c2c64402afe472f8333f4e319a6b" -+ -+"@types/minimatch@3.0.1": -+ version "3.0.1" -+ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.1.tgz#b683eb60be358304ef146f5775db4c0e3696a550" -+ -+"@types/mocha@2.2.44", "@types/mocha@^2.2.29": -+ version "2.2.44" -+ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.44.tgz#1d4a798e53f35212fd5ad4d04050620171cd5b5e" -+>>>>>>> .their - - "@types/mri@^1.1.0": - version "1.1.0" -@@ -239,6 +328,7 @@ - version "5.5.0" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45" - -+<<<<<<< .our - "@types/serve-static@*": - version "1.13.1" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.1.tgz#1d2801fa635d274cd97d4ec07e26b21b44127492" -@@ -249,6 +339,22 @@ - "@types/source-map@*": - version "0.5.1" - resolved "https://registry.yarnpkg.com/@types/source-map/-/source-map-0.5.1.tgz#7e74db5d06ab373a712356eebfaea2fad0ea2367" -+======= -+"@types/sinon-chai@2.7.29": -+ version "2.7.29" -+ resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-2.7.29.tgz#4db01497e2dd1908b2bd30d1782f456353f5f723" -+ dependencies: -+ "@types/chai" "*" -+ "@types/sinon" "*" -+ -+"@types/sinon@*": -+ version "4.1.3" -+ resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-4.1.3.tgz#2ee25e0e302f31e78a945650a60029e08878eaf8" -+ -+"@types/sinon@4.0.0": -+ version "4.0.0" -+ resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-4.0.0.tgz#9a93ffa4ee1329e85166278a5ed99f81dc4c8362" -+>>>>>>> .their - - "@types/strip-ansi@^3.0.0": - version "3.0.0" -@@ -554,6 +660,10 @@ - version "1.0.2" - resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" - -+am-i-a-dependency@1.1.2: -+ version "1.1.2" -+ resolved "https://registry.yarnpkg.com/am-i-a-dependency/-/am-i-a-dependency-1.1.2.tgz#f9d3422304d6f642f821e4c407565035f6167f1f" -+ - amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" -@@ -564,7 +674,7 @@ - dependencies: - string-width "^2.0.0" - --ansi-escapes@^1.1.0: -+ansi-escapes@^1.0.0, ansi-escapes@^1.1.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" - -@@ -802,11 +912,21 @@ - version "0.1.3" - resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" - -+<<<<<<< .our - async-limiter@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" - - async@^2.0.0: -+======= -+async@2.1.4: -+ version "2.1.4" -+ resolved "https://registry.yarnpkg.com/async/-/async-2.1.4.tgz#2d2160c7788032e4dd6cbe2502f1f9a2c8f6cde4" -+ dependencies: -+ lodash "^4.14.0" -+ -+async@^2.0.0, async@^2.1.2, async@^2.1.5, async@^2.4.1: -+>>>>>>> .their - version "2.5.0" - resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d" - dependencies: -@@ -896,7 +1016,11 @@ - esutils "^2.0.2" - js-tokens "^3.0.2" - -+<<<<<<< .our - babel-core@^6.26.0: -+======= -+babel-core@6.26.0, babel-core@^6.22.1, babel-core@^6.24.1, babel-core@^6.26.0: -+>>>>>>> .their - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" - dependencies: -@@ -957,6 +1081,7 @@ - source-map "^0.5.6" - trim-right "^1.0.1" - -+<<<<<<< .our - babel-helper-evaluate-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.3.0.tgz#2439545e0b6eae5b7f49b790acbebd6b9a73df20" -@@ -964,6 +1089,81 @@ - babel-helper-flip-expressions@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.3.0.tgz#f5b6394bd5219b43cf8f7b201535ed540c6e7fa2" -+======= -+babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" -+ dependencies: -+ babel-helper-explode-assignable-expression "^6.24.1" -+ babel-runtime "^6.22.0" -+ babel-types "^6.24.1" -+ -+babel-helper-builder-react-jsx@^6.24.1: -+ version "6.26.0" -+ resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0" -+ dependencies: -+ babel-runtime "^6.26.0" -+ babel-types "^6.26.0" -+ esutils "^2.0.2" -+ -+babel-helper-call-delegate@^6.24.1: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" -+ dependencies: -+ babel-helper-hoist-variables "^6.24.1" -+ babel-runtime "^6.22.0" -+ babel-traverse "^6.24.1" -+ babel-types "^6.24.1" -+ -+babel-helper-define-map@^6.24.1: -+ version "6.26.0" -+ resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" -+ dependencies: -+ babel-helper-function-name "^6.24.1" -+ babel-runtime "^6.26.0" -+ babel-types "^6.26.0" -+ lodash "^4.17.4" -+ -+babel-helper-evaluate-path@^0.2.0: -+ version "0.2.0" -+ resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.2.0.tgz#0bb2eb01996c0cef53c5e8405e999fe4a0244c08" -+ -+babel-helper-explode-assignable-expression@^6.24.1: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" -+ dependencies: -+ babel-runtime "^6.22.0" -+ babel-traverse "^6.24.1" -+ babel-types "^6.24.1" -+ -+babel-helper-flip-expressions@^0.2.0: -+ version "0.2.0" -+ resolved "https://registry.yarnpkg.com/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.2.0.tgz#160d2090a3d9f9c64a750905321a0bc218f884ec" -+>>>>>>> .their -+ -+babel-helper-function-name@^6.24.1: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" -+ dependencies: -+ babel-helper-get-function-arity "^6.24.1" -+ babel-runtime "^6.22.0" -+ babel-template "^6.24.1" -+ babel-traverse "^6.24.1" -+ babel-types "^6.24.1" -+ -+babel-helper-get-function-arity@^6.24.1: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" -+ dependencies: -+ babel-runtime "^6.22.0" -+ babel-types "^6.24.1" -+ -+babel-helper-hoist-variables@^6.24.1: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" -+ dependencies: -+ babel-runtime "^6.22.0" -+ babel-types "^6.24.1" - - babel-helper-is-nodes-equiv@^0.0.1: - version "0.0.1" -@@ -977,6 +1177,7 @@ - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.3.0.tgz#b4731314fdd7a89091271a5213b4e12d236e29e8" - -+<<<<<<< .our - babel-helper-remove-or-void@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.3.0.tgz#f43c86147c8fcc395a9528cbb31e7ff49d7e16e3" -@@ -984,6 +1185,51 @@ - babel-helper-to-multiple-sequence-expressions@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.3.0.tgz#8da2275ccc26995566118f7213abfd9af7214427" -+======= -+babel-helper-optimise-call-expression@^6.24.1: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" -+ dependencies: -+ babel-runtime "^6.22.0" -+ babel-types "^6.24.1" -+ -+babel-helper-regex@^6.24.1: -+ version "6.26.0" -+ resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" -+ dependencies: -+ babel-runtime "^6.26.0" -+ babel-types "^6.26.0" -+ lodash "^4.17.4" -+ -+babel-helper-remap-async-to-generator@^6.24.1: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" -+ dependencies: -+ babel-helper-function-name "^6.24.1" -+ babel-runtime "^6.22.0" -+ babel-template "^6.24.1" -+ babel-traverse "^6.24.1" -+ babel-types "^6.24.1" -+ -+babel-helper-remove-or-void@^0.2.0: -+ version "0.2.0" -+ resolved "https://registry.yarnpkg.com/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.2.0.tgz#8e46ad5b30560d57d7510b3fd93f332ee7c67386" -+ -+babel-helper-replace-supers@^6.24.1: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" -+ dependencies: -+ babel-helper-optimise-call-expression "^6.24.1" -+ babel-messages "^6.23.0" -+ babel-runtime "^6.22.0" -+ babel-template "^6.24.1" -+ babel-traverse "^6.24.1" -+ babel-types "^6.24.1" -+ -+babel-helper-to-multiple-sequence-expressions@^0.2.0: -+ version "0.2.0" -+ resolved "https://registry.yarnpkg.com/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.2.0.tgz#d1a419634c6cb301f27858c659167cfee0a9d318" -+>>>>>>> .their - - babel-helpers@^6.24.1: - version "6.24.1" -@@ -992,6 +1238,14 @@ - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -+babel-loader@7.1.2: -+ version "7.1.2" -+ resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.1.2.tgz#f6cbe122710f1aa2af4d881c6d5b54358ca24126" -+ dependencies: -+ find-cache-dir "^1.0.0" -+ loader-utils "^1.0.2" -+ mkdirp "^0.5.1" -+ - babel-messages@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" -@@ -1006,9 +1260,21 @@ - babel-preset-minify "^0.3.0" - webpack-sources "^1.0.1" - -+<<<<<<< .our - babel-plugin-minify-builtins@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.3.0.tgz#4740117a6a784063aaf8f092989cf9e4bd484860" -+======= -+babel-plugin-check-es2015-constants@^6.22.0: -+ version "6.22.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" -+ dependencies: -+ babel-runtime "^6.22.0" -+ -+babel-plugin-minify-builtins@^0.2.0: -+ version "0.2.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.2.0.tgz#317f824b0907210b6348671bb040ca072e2e0c82" -+>>>>>>> .their - dependencies: - babel-helper-evaluate-path "^0.3.0" - -@@ -1071,6 +1337,7 @@ - dependencies: - babel-helper-is-void-0 "^0.3.0" - -+<<<<<<< .our - babel-plugin-syntax-dynamic-import@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" -@@ -1078,6 +1345,222 @@ - babel-plugin-transform-inline-consecutive-adds@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.3.0.tgz#f07d93689c0002ed2b2b62969bdd99f734e03f57" -+======= -+babel-plugin-syntax-async-functions@^6.8.0: -+ version "6.13.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" -+ -+babel-plugin-syntax-exponentiation-operator@^6.8.0: -+ version "6.13.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" -+ -+babel-plugin-syntax-flow@^6.18.0: -+ version "6.18.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" -+ -+babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: -+ version "6.18.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" -+ -+babel-plugin-syntax-trailing-function-commas@^6.22.0: -+ version "6.22.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" -+ -+babel-plugin-transform-async-to-generator@^6.22.0: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" -+ dependencies: -+ babel-helper-remap-async-to-generator "^6.24.1" -+ babel-plugin-syntax-async-functions "^6.8.0" -+ babel-runtime "^6.22.0" -+ -+babel-plugin-transform-es2015-arrow-functions@^6.22.0: -+ version "6.22.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" -+ dependencies: -+ babel-runtime "^6.22.0" -+ -+babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: -+ version "6.22.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" -+ dependencies: -+ babel-runtime "^6.22.0" -+ -+babel-plugin-transform-es2015-block-scoping@^6.23.0: -+ version "6.26.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" -+ dependencies: -+ babel-runtime "^6.26.0" -+ babel-template "^6.26.0" -+ babel-traverse "^6.26.0" -+ babel-types "^6.26.0" -+ lodash "^4.17.4" -+ -+babel-plugin-transform-es2015-classes@^6.23.0: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" -+ dependencies: -+ babel-helper-define-map "^6.24.1" -+ babel-helper-function-name "^6.24.1" -+ babel-helper-optimise-call-expression "^6.24.1" -+ babel-helper-replace-supers "^6.24.1" -+ babel-messages "^6.23.0" -+ babel-runtime "^6.22.0" -+ babel-template "^6.24.1" -+ babel-traverse "^6.24.1" -+ babel-types "^6.24.1" -+ -+babel-plugin-transform-es2015-computed-properties@^6.22.0: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" -+ dependencies: -+ babel-runtime "^6.22.0" -+ babel-template "^6.24.1" -+ -+babel-plugin-transform-es2015-destructuring@^6.23.0: -+ version "6.23.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" -+ dependencies: -+ babel-runtime "^6.22.0" -+ -+babel-plugin-transform-es2015-duplicate-keys@^6.22.0: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" -+ dependencies: -+ babel-runtime "^6.22.0" -+ babel-types "^6.24.1" -+ -+babel-plugin-transform-es2015-for-of@^6.23.0: -+ version "6.23.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" -+ dependencies: -+ babel-runtime "^6.22.0" -+ -+babel-plugin-transform-es2015-function-name@^6.22.0: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" -+ dependencies: -+ babel-helper-function-name "^6.24.1" -+ babel-runtime "^6.22.0" -+ babel-types "^6.24.1" -+ -+babel-plugin-transform-es2015-literals@^6.22.0: -+ version "6.22.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" -+ dependencies: -+ babel-runtime "^6.22.0" -+ -+babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" -+ dependencies: -+ babel-plugin-transform-es2015-modules-commonjs "^6.24.1" -+ babel-runtime "^6.22.0" -+ babel-template "^6.24.1" -+ -+babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: -+ version "6.26.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" -+ dependencies: -+ babel-plugin-transform-strict-mode "^6.24.1" -+ babel-runtime "^6.26.0" -+ babel-template "^6.26.0" -+ babel-types "^6.26.0" -+ -+babel-plugin-transform-es2015-modules-systemjs@^6.23.0: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" -+ dependencies: -+ babel-helper-hoist-variables "^6.24.1" -+ babel-runtime "^6.22.0" -+ babel-template "^6.24.1" -+ -+babel-plugin-transform-es2015-modules-umd@^6.23.0: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" -+ dependencies: -+ babel-plugin-transform-es2015-modules-amd "^6.24.1" -+ babel-runtime "^6.22.0" -+ babel-template "^6.24.1" -+ -+babel-plugin-transform-es2015-object-super@^6.22.0: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" -+ dependencies: -+ babel-helper-replace-supers "^6.24.1" -+ babel-runtime "^6.22.0" -+ -+babel-plugin-transform-es2015-parameters@^6.23.0: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" -+ dependencies: -+ babel-helper-call-delegate "^6.24.1" -+ babel-helper-get-function-arity "^6.24.1" -+ babel-runtime "^6.22.0" -+ babel-template "^6.24.1" -+ babel-traverse "^6.24.1" -+ babel-types "^6.24.1" -+ -+babel-plugin-transform-es2015-shorthand-properties@^6.22.0: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" -+ dependencies: -+ babel-runtime "^6.22.0" -+ babel-types "^6.24.1" -+ -+babel-plugin-transform-es2015-spread@^6.22.0: -+ version "6.22.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" -+ dependencies: -+ babel-runtime "^6.22.0" -+ -+babel-plugin-transform-es2015-sticky-regex@^6.22.0: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" -+ dependencies: -+ babel-helper-regex "^6.24.1" -+ babel-runtime "^6.22.0" -+ babel-types "^6.24.1" -+ -+babel-plugin-transform-es2015-template-literals@^6.22.0: -+ version "6.22.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" -+ dependencies: -+ babel-runtime "^6.22.0" -+ -+babel-plugin-transform-es2015-typeof-symbol@^6.23.0: -+ version "6.23.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" -+ dependencies: -+ babel-runtime "^6.22.0" -+ -+babel-plugin-transform-es2015-unicode-regex@^6.22.0: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" -+ dependencies: -+ babel-helper-regex "^6.24.1" -+ babel-runtime "^6.22.0" -+ regexpu-core "^2.0.0" -+ -+babel-plugin-transform-exponentiation-operator@^6.22.0: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" -+ dependencies: -+ babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" -+ babel-plugin-syntax-exponentiation-operator "^6.8.0" -+ babel-runtime "^6.22.0" -+ -+babel-plugin-transform-flow-strip-types@^6.22.0: -+ version "6.22.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" -+ dependencies: -+ babel-plugin-syntax-flow "^6.18.0" -+ babel-runtime "^6.22.0" -+ -+babel-plugin-transform-inline-consecutive-adds@^0.2.0: -+ version "0.2.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.2.0.tgz#15dae78921057f4004f8eafd79e15ddc5f12f426" -+>>>>>>> .their - - babel-plugin-transform-member-expression-literals@^6.9.0: - version "6.9.4" -@@ -1097,9 +1580,49 @@ - dependencies: - esutils "^2.0.2" - -+<<<<<<< .our - babel-plugin-transform-regexp-constructors@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.3.0.tgz#9bb2c8dd082271a5cb1b3a441a7c52e8fd07e0f5" -+======= -+babel-plugin-transform-react-display-name@^6.23.0: -+ version "6.25.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz#67e2bf1f1e9c93ab08db96792e05392bf2cc28d1" -+ dependencies: -+ babel-runtime "^6.22.0" -+ -+babel-plugin-transform-react-jsx-self@^6.22.0: -+ version "6.22.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz#df6d80a9da2612a121e6ddd7558bcbecf06e636e" -+ dependencies: -+ babel-plugin-syntax-jsx "^6.8.0" -+ babel-runtime "^6.22.0" -+ -+babel-plugin-transform-react-jsx-source@^6.22.0: -+ version "6.22.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz#66ac12153f5cd2d17b3c19268f4bf0197f44ecd6" -+ dependencies: -+ babel-plugin-syntax-jsx "^6.8.0" -+ babel-runtime "^6.22.0" -+ -+babel-plugin-transform-react-jsx@^6.24.1: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3" -+ dependencies: -+ babel-helper-builder-react-jsx "^6.24.1" -+ babel-plugin-syntax-jsx "^6.8.0" -+ babel-runtime "^6.22.0" -+ -+babel-plugin-transform-regenerator@^6.22.0: -+ version "6.26.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" -+ dependencies: -+ regenerator-transform "^0.10.0" -+ -+babel-plugin-transform-regexp-constructors@^0.2.0: -+ version "0.2.0" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.2.0.tgz#6aa5dd0acc515db4be929bbcec4ed4c946c534a3" -+>>>>>>> .their - - babel-plugin-transform-remove-console@^6.9.0: - version "6.9.4" -@@ -1119,6 +1642,7 @@ - version "6.9.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.9.4.tgz#f62afe096cab0e1f68a2d753fdf283888471ceb9" - -+<<<<<<< .our - babel-plugin-transform-undefined-to-void@^6.9.0: - version "6.9.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.9.4.tgz#be241ca81404030678b748717322b89d0c8fe280" -@@ -1149,8 +1673,99 @@ - babel-plugin-transform-remove-undefined "^0.3.0" - babel-plugin-transform-simplify-comparison-operators "^6.9.0" - babel-plugin-transform-undefined-to-void "^6.9.0" -+======= -+babel-plugin-transform-strict-mode@^6.24.1: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" -+ dependencies: -+ babel-runtime "^6.22.0" -+ babel-types "^6.24.1" -+ -+babel-plugin-transform-undefined-to-void@^6.8.3: -+ version "6.8.3" -+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.8.3.tgz#fc52707f6ee1ddc71bb91b0d314fbefdeef9beb4" -+ -+babel-preset-env@1.6.0: -+ version "1.6.0" -+ resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.0.tgz#2de1c782a780a0a5d605d199c957596da43c44e4" -+ dependencies: -+ babel-plugin-check-es2015-constants "^6.22.0" -+ babel-plugin-syntax-trailing-function-commas "^6.22.0" -+ babel-plugin-transform-async-to-generator "^6.22.0" -+ babel-plugin-transform-es2015-arrow-functions "^6.22.0" -+ babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" -+ babel-plugin-transform-es2015-block-scoping "^6.23.0" -+ babel-plugin-transform-es2015-classes "^6.23.0" -+ babel-plugin-transform-es2015-computed-properties "^6.22.0" -+ babel-plugin-transform-es2015-destructuring "^6.23.0" -+ babel-plugin-transform-es2015-duplicate-keys "^6.22.0" -+ babel-plugin-transform-es2015-for-of "^6.23.0" -+ babel-plugin-transform-es2015-function-name "^6.22.0" -+ babel-plugin-transform-es2015-literals "^6.22.0" -+ babel-plugin-transform-es2015-modules-amd "^6.22.0" -+ babel-plugin-transform-es2015-modules-commonjs "^6.23.0" -+ babel-plugin-transform-es2015-modules-systemjs "^6.23.0" -+ babel-plugin-transform-es2015-modules-umd "^6.23.0" -+ babel-plugin-transform-es2015-object-super "^6.22.0" -+ babel-plugin-transform-es2015-parameters "^6.23.0" -+ babel-plugin-transform-es2015-shorthand-properties "^6.22.0" -+ babel-plugin-transform-es2015-spread "^6.22.0" -+ babel-plugin-transform-es2015-sticky-regex "^6.22.0" -+ babel-plugin-transform-es2015-template-literals "^6.22.0" -+ babel-plugin-transform-es2015-typeof-symbol "^6.23.0" -+ babel-plugin-transform-es2015-unicode-regex "^6.22.0" -+ babel-plugin-transform-exponentiation-operator "^6.22.0" -+ babel-plugin-transform-regenerator "^6.22.0" -+ browserslist "^2.1.2" -+ invariant "^2.2.2" -+ semver "^5.3.0" -+ -+babel-preset-flow@^6.23.0: -+ version "6.23.0" -+ resolved "https://registry.yarnpkg.com/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d" -+ dependencies: -+ babel-plugin-transform-flow-strip-types "^6.22.0" -+ -+babel-preset-minify@^0.2.0: -+ version "0.2.0" -+ resolved "https://registry.yarnpkg.com/babel-preset-minify/-/babel-preset-minify-0.2.0.tgz#006566552d9b83834472273f306c0131062a0acc" -+ dependencies: -+ babel-plugin-minify-builtins "^0.2.0" -+ babel-plugin-minify-constant-folding "^0.2.0" -+ babel-plugin-minify-dead-code-elimination "^0.2.0" -+ babel-plugin-minify-flip-comparisons "^0.2.0" -+ babel-plugin-minify-guarded-expressions "^0.2.0" -+ babel-plugin-minify-infinity "^0.2.0" -+ babel-plugin-minify-mangle-names "^0.2.0" -+ babel-plugin-minify-numeric-literals "^0.2.0" -+ babel-plugin-minify-replace "^0.2.0" -+ babel-plugin-minify-simplify "^0.2.0" -+ babel-plugin-minify-type-constructors "^0.2.0" -+ babel-plugin-transform-inline-consecutive-adds "^0.2.0" -+ babel-plugin-transform-member-expression-literals "^6.8.5" -+ babel-plugin-transform-merge-sibling-variables "^6.8.6" -+ babel-plugin-transform-minify-booleans "^6.8.3" -+ babel-plugin-transform-property-literals "^6.8.5" -+ babel-plugin-transform-regexp-constructors "^0.2.0" -+ babel-plugin-transform-remove-console "^6.8.5" -+ babel-plugin-transform-remove-debugger "^6.8.5" -+ babel-plugin-transform-remove-undefined "^0.2.0" -+ babel-plugin-transform-simplify-comparison-operators "^6.8.5" -+ babel-plugin-transform-undefined-to-void "^6.8.3" -+>>>>>>> .their - lodash.isplainobject "^4.0.6" - -+babel-preset-react@6.24.1: -+ version "6.24.1" -+ resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.24.1.tgz#ba69dfaea45fc3ec639b6a4ecea6e17702c91380" -+ dependencies: -+ babel-plugin-syntax-jsx "^6.3.13" -+ babel-plugin-transform-react-display-name "^6.23.0" -+ babel-plugin-transform-react-jsx "^6.24.1" -+ babel-plugin-transform-react-jsx-self "^6.22.0" -+ babel-plugin-transform-react-jsx-source "^6.22.0" -+ babel-preset-flow "^6.23.0" -+ - babel-register@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" -@@ -1163,7 +1778,7 @@ - mkdirp "^0.5.1" - source-map-support "^0.4.15" - --babel-runtime@^6.22.0, babel-runtime@^6.26.0: -+babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - dependencies: -@@ -1187,7 +1802,7 @@ - babylon "^6.18.0" - lodash "^4.17.4" - --babel-traverse@^6.26.0: -+babel-traverse@^6.24.1, babel-traverse@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" - dependencies: -@@ -1201,7 +1816,7 @@ - invariant "^2.2.2" - lodash "^4.17.4" - --babel-types@^6.26.0: -+babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - dependencies: -@@ -1293,7 +1908,15 @@ - dependencies: - bluebird "^3.5.1" - -+<<<<<<< .our - bluebird@^3.0.6, bluebird@^3.1.1, bluebird@^3.3.4, bluebird@^3.5.0, bluebird@^3.5.1: -+======= -+bluebird@3.5.0: -+ version "3.5.0" -+ resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c" -+ -+bluebird@^3.0.6, bluebird@^3.1.1, bluebird@^3.3.4, bluebird@^3.4.7, bluebird@^3.5.0, bluebird@^3.5.1: -+>>>>>>> .their - version "3.5.1" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" - -@@ -1455,6 +2078,7 @@ - caniuse-db "^1.0.30000639" - electron-to-chromium "^1.2.7" - -+<<<<<<< .our - buffer-alloc-unsafe@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" -@@ -1467,6 +2091,16 @@ - buffer-fill "^1.0.0" - - buffer-crc32@^0.2.1: -+======= -+browserslist@^2.1.2: -+ version "2.11.3" -+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.11.3.tgz#fe36167aed1bbcde4827ebfe71347a2cc70b99b2" -+ dependencies: -+ caniuse-lite "^1.0.30000792" -+ electron-to-chromium "^1.3.30" -+ -+buffer-crc32@^0.2.1, buffer-crc32@~0.2.3: -+>>>>>>> .their - version "0.2.13" - resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" - -@@ -1619,6 +2253,10 @@ - version "1.0.30000756" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000756.tgz#e938a6b991630f30d2263dd3458beb65d362268b" - -+caniuse-lite@^1.0.30000792: -+ version "1.0.30000808" -+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000808.tgz#7d759b5518529ea08b6705a19e70dbf401628ffc" -+ - capture-stack-trace@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" -@@ -1660,6 +2298,22 @@ - dependencies: - traverse ">=0.3.0 <0.4" - -+chalk@2.1.0: -+ version "2.1.0" -+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.1.0.tgz#ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e" -+ dependencies: -+ ansi-styles "^3.1.0" -+ escape-string-regexp "^1.0.5" -+ supports-color "^4.0.0" -+ -+chalk@2.3.0, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.2.0, chalk@^2.3.0: -+ version "2.3.0" -+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" -+ dependencies: -+ ansi-styles "^3.1.0" -+ escape-string-regexp "^1.0.5" -+ supports-color "^4.0.0" -+ - chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" -@@ -1670,6 +2324,7 @@ - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -+<<<<<<< .our - chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.2.0, chalk@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" -@@ -1690,10 +2345,13 @@ - version "0.4.2" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" - -+======= -+>>>>>>> .their - check-error@^1.0.1, check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - -+<<<<<<< .our - check-types@^7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/check-types/-/check-types-7.3.0.tgz#468f571a4435c24248f5fd0cb0e8d87c3c341e7d" -@@ -1701,6 +2359,15 @@ - chokidar@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.3.tgz#dcbd4f6cbb2a55b4799ba8a840ac527e5f4b1176" -+======= -+check-more-types@2.24.0: -+ version "2.24.0" -+ resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" -+ -+chokidar@^1.7.0: -+ version "1.7.0" -+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" -+>>>>>>> .their - dependencies: - anymatch "^2.0.0" - async-each "^1.0.0" -@@ -1779,12 +2446,29 @@ - version "1.0.0" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" - -+cli-cursor@^1.0.2: -+ version "1.0.2" -+ resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" -+ dependencies: -+ restore-cursor "^1.0.1" -+ - cli-cursor@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - dependencies: - restore-cursor "^2.0.0" - -+cli-spinners@^0.1.2: -+ version "0.1.2" -+ resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c" -+ -+cli-truncate@^0.2.1: -+ version "0.2.1" -+ resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" -+ dependencies: -+ slice-ansi "0.0.4" -+ string-width "^1.0.1" -+ - cli-width@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" -@@ -1900,6 +2584,7 @@ - version "2.11.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" - -+<<<<<<< .our - commander@^2.12.1, commander@^2.13.0, commander@^2.14.1: - version "2.15.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" -@@ -1907,6 +2592,13 @@ - commander@~2.13.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" -+======= -+common-tags@1.4.0: -+ version "1.4.0" -+ resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.4.0.tgz#1187be4f3d4cf0c0427d43f74eef1f73501614c0" -+ dependencies: -+ babel-runtime "^6.18.0" -+>>>>>>> .their - - commondir@^1.0.1: - version "1.0.1" -@@ -2258,6 +2950,7 @@ - dependencies: - array-find-index "^1.0.1" - -+<<<<<<< .our - cycle@1.0.x: - version "1.0.3" - resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" -@@ -2265,6 +2958,54 @@ - cyclist@~0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" -+======= -+cypress@^1.4.2: -+ version "1.4.2" -+ resolved "https://registry.yarnpkg.com/cypress/-/cypress-1.4.2.tgz#d957d631617aa87e64a7eae71502f2e175076638" -+ dependencies: -+ "@cypress/listr-verbose-renderer" "0.4.1" -+ "@cypress/xvfb" "1.1.3" -+ "@types/blob-util" "1.3.3" -+ "@types/bluebird" "3.5.18" -+ "@types/chai" "4.0.8" -+ "@types/chai-jquery" "1.1.35" -+ "@types/jquery" "3.2.16" -+ "@types/lodash" "4.14.87" -+ "@types/minimatch" "3.0.1" -+ "@types/mocha" "2.2.44" -+ "@types/sinon" "4.0.0" -+ "@types/sinon-chai" "2.7.29" -+ bluebird "3.5.0" -+ chalk "2.1.0" -+ check-more-types "2.24.0" -+ commander "2.11.0" -+ common-tags "1.4.0" -+ debug "3.1.0" -+ extract-zip "1.6.6" -+ fs-extra "4.0.1" -+ getos "2.8.4" -+ glob "7.1.2" -+ is-ci "1.0.10" -+ is-installed-globally "0.1.0" -+ lazy-ass "1.6.0" -+ listr "0.12.0" -+ lodash "4.17.4" -+ minimist "1.2.0" -+ progress "1.1.8" -+ ramda "0.24.1" -+ request "2.81.0" -+ request-progress "0.3.1" -+ supports-color "5.1.0" -+ tmp "0.0.31" -+ url "0.11.0" -+ yauzl "2.8.0" -+ -+d@1: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" -+ dependencies: -+ es5-ext "^0.10.9" -+>>>>>>> .their - - dashdash@^1.12.0: - version "1.14.1" -@@ -2272,6 +3013,10 @@ - dependencies: - assert-plus "^1.0.0" - -+date-fns@^1.27.2: -+ version "1.29.0" -+ resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" -+ - date-now@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" -@@ -2687,6 +3432,10 @@ - version "1.3.27" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.27.tgz#78ecb8a399066187bb374eede35d9c70565a803d" - -+electron-to-chromium@^1.3.30: -+ version "1.3.33" -+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.33.tgz#bf00703d62a7c65238136578c352d6c5c042a545" -+ - electron-window@^0.8.0: - version "0.8.1" - resolved "https://registry.yarnpkg.com/electron-window/-/electron-window-0.8.1.tgz#16ca187eb4870b0679274fc8299c5960e6ab2c5e" -@@ -2712,6 +3461,10 @@ - electron-download "^3.0.1" - extract-zip "^1.0.3" - -+elegant-spinner@^1.0.1: -+ version "1.0.1" -+ resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" -+ - elliptic@^6.0.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" -@@ -2748,9 +3501,15 @@ - dependencies: - once "^1.4.0" - -+<<<<<<< .our - enhanced-resolve@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.0.0.tgz#e34a6eaa790f62fccd71d93959f56b2b432db10a" -+======= -+enhanced-resolve@^3.0.0, enhanced-resolve@^3.3.0, enhanced-resolve@^3.4.0: -+ version "3.4.1" -+ resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e" -+>>>>>>> .their - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.4.0" -@@ -3007,9 +3766,21 @@ - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -+<<<<<<< .our - exit@0.1.2, exit@0.1.x: - version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" -+======= -+exit-hook@^1.0.0: -+ version "1.1.1" -+ resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" -+ -+expand-brackets@^0.1.4: -+ version "0.1.5" -+ resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" -+ dependencies: -+ is-posix-bracket "^0.1.0" -+>>>>>>> .their - - expand-brackets@^2.1.4: - version "2.1.4" -@@ -3139,7 +3910,20 @@ - snapdragon "^0.8.1" - to-regex "^3.0.1" - -+<<<<<<< .our - extract-zip@^1.0.3, extract-zip@^1.6.5: -+======= -+extract-text-webpack-plugin@^3.0.0: -+ version "3.0.2" -+ resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz#5f043eaa02f9750a9258b78c0a6e0dc1408fb2f7" -+ dependencies: -+ async "^2.4.1" -+ loader-utils "^1.1.0" -+ schema-utils "^0.3.0" -+ webpack-sources "^1.0.1" -+ -+extract-zip@1.6.6, extract-zip@^1.0.3, extract-zip@^1.6.5: -+>>>>>>> .their - version "1.6.6" - resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.6.tgz#1290ede8d20d0872b429fd3f351ca128ec5ef85c" - dependencies: -@@ -3186,6 +3970,13 @@ - dependencies: - pend "~1.2.0" - -+figures@^1.7.0: -+ version "1.7.0" -+ resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" -+ dependencies: -+ escape-string-regexp "^1.0.5" -+ object-assign "^4.1.0" -+ - figures@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" -@@ -3224,6 +4015,7 @@ - statuses "~1.3.1" - unpipe "~1.0.0" - -+<<<<<<< .our - finalhandler@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" -@@ -3236,6 +4028,8 @@ - statuses "~1.4.0" - unpipe "~1.0.0" - -+======= -+>>>>>>> .their - find-cache-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" -@@ -3372,6 +4166,14 @@ - path-is-absolute "^1.0.0" - rimraf "^2.2.8" - -+fs-extra@4.0.1: -+ version "4.0.1" -+ resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.1.tgz#7fc0c6c8957f983f57f306a24e5b9ddd8d0dd880" -+ dependencies: -+ graceful-fs "^4.1.2" -+ jsonfile "^3.0.0" -+ universalify "^0.1.0" -+ - fs-extra@^0.30.0: - version "0.30.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" -@@ -3542,6 +4344,12 @@ - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - -+getos@2.8.4: -+ version "2.8.4" -+ resolved "https://registry.yarnpkg.com/getos/-/getos-2.8.4.tgz#7b8603d3619c28e38cb0fe7a4f63c3acb80d5163" -+ dependencies: -+ async "2.1.4" -+ - getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" -@@ -3963,6 +4771,10 @@ - dependencies: - repeating "^2.0.0" - -+indent-string@^3.0.0: -+ version "3.2.0" -+ resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" -+ - indexes-of@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" -@@ -4088,9 +4900,15 @@ - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" - -+<<<<<<< .our - is-ci@^1.0.10, is-ci@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5" -+======= -+is-ci@1.0.10, is-ci@^1.0.10: -+ version "1.0.10" -+ resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e" -+>>>>>>> .their - dependencies: - ci-info "^1.0.0" - -@@ -4180,7 +4998,7 @@ - dependencies: - is-extglob "^2.1.1" - --is-installed-globally@^0.1.0: -+is-installed-globally@0.1.0, is-installed-globally@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" - dependencies: -@@ -4479,6 +5297,12 @@ - optionalDependencies: - graceful-fs "^4.1.6" - -+jsonfile@^3.0.0: -+ version "3.0.1" -+ resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66" -+ optionalDependencies: -+ graceful-fs "^4.1.6" -+ - jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" -@@ -4554,6 +5378,21 @@ - dependencies: - package-json "^4.0.0" - -+<<<<<<< .our -+======= -+lazy-ass@1.6.0: -+ version "1.6.0" -+ resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" -+ -+lazy-cache@^0.2.3: -+ version "0.2.7" -+ resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-0.2.7.tgz#7feddf2dcb6edb77d11ef1d117ab5ffdf0ab1b65" -+ -+lazy-cache@^1.0.3: -+ version "1.0.4" -+ resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" -+ -+>>>>>>> .their - lazy-cache@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264" -@@ -4594,6 +5433,53 @@ - prelude-ls "~1.1.2" - type-check "~0.3.2" - -+listr-silent-renderer@^1.1.1: -+ version "1.1.1" -+ resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" -+ -+listr-update-renderer@^0.2.0: -+ version "0.2.0" -+ resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz#ca80e1779b4e70266807e8eed1ad6abe398550f9" -+ dependencies: -+ chalk "^1.1.3" -+ cli-truncate "^0.2.1" -+ elegant-spinner "^1.0.1" -+ figures "^1.7.0" -+ indent-string "^3.0.0" -+ log-symbols "^1.0.2" -+ log-update "^1.0.2" -+ strip-ansi "^3.0.1" -+ -+listr-verbose-renderer@^0.4.0: -+ version "0.4.1" -+ resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35" -+ dependencies: -+ chalk "^1.1.3" -+ cli-cursor "^1.0.2" -+ date-fns "^1.27.2" -+ figures "^1.7.0" -+ -+listr@0.12.0: -+ version "0.12.0" -+ resolved "https://registry.yarnpkg.com/listr/-/listr-0.12.0.tgz#6bce2c0f5603fa49580ea17cd6a00cc0e5fa451a" -+ dependencies: -+ chalk "^1.1.3" -+ cli-truncate "^0.2.1" -+ figures "^1.7.0" -+ indent-string "^2.1.0" -+ is-promise "^2.1.0" -+ is-stream "^1.1.0" -+ listr-silent-renderer "^1.1.1" -+ listr-update-renderer "^0.2.0" -+ listr-verbose-renderer "^0.4.0" -+ log-symbols "^1.0.2" -+ log-update "^1.0.2" -+ ora "^0.2.3" -+ p-map "^1.1.1" -+ rxjs "^5.0.0-beta.11" -+ stream-to-observable "^0.1.0" -+ strip-ansi "^3.0.1" -+ - load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" -@@ -4660,7 +5546,7 @@ - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - --lodash.clonedeep@^4.3.2: -+lodash.clonedeep@4.5.0, lodash.clonedeep@^4.3.2: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - -@@ -4688,6 +5574,10 @@ - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz#150cf0a16791f5903b8891eab154609274bdea55" - -+lodash.once@^4.1.1: -+ version "4.1.1" -+ resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" -+ - lodash.some@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" -@@ -4717,13 +5607,21 @@ - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" - --lodash@^4.0.0, lodash@^4.14.0, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.3.0, lodash@^4.8.0, lodash@~4.17.4: -+lodash@4.17.4, lodash@^4.0.0, lodash@^4.14.0, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.3.0, lodash@^4.8.0, lodash@~4.17.4: - version "4.17.4" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" - -+<<<<<<< .our - lodash@^4.17.5, lodash@~4.17.10: - version "4.17.10" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" -+======= -+log-symbols@^1.0.2: -+ version "1.0.2" -+ resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" -+ dependencies: -+ chalk "^1.0.0" -+>>>>>>> .their - - log-symbols@^2.1.0: - version "2.1.0" -@@ -4731,6 +5629,13 @@ - dependencies: - chalk "^2.0.1" - -+log-update@^1.0.2: -+ version "1.0.2" -+ resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1" -+ dependencies: -+ ansi-escapes "^1.0.0" -+ cli-cursor "^1.0.2" -+ - loglevelnext@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/loglevelnext/-/loglevelnext-1.0.1.tgz#8b17b5a43395338a96c67911a962c44af466d1c8" -@@ -4939,7 +5844,7 @@ - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - --minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0: -+minimist@1.2.0, minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - -@@ -5372,6 +6277,10 @@ - dependencies: - wrappy "1" - -+onetime@^1.0.0: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" -+ - onetime@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" -@@ -5400,6 +6309,15 @@ - type-check "~0.3.2" - wordwrap "~1.0.0" - -+ora@^0.2.3: -+ version "0.2.3" -+ resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" -+ dependencies: -+ chalk "^1.1.1" -+ cli-cursor "^1.0.2" -+ cli-spinners "^0.1.2" -+ object-assign "^4.0.1" -+ - os-browserify@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.2.1.tgz#63fc4ccee5d2d7763d26bbf8601078e6c2e0044f" -@@ -5453,6 +6371,7 @@ - dependencies: - p-limit "^1.1.0" - -+<<<<<<< .our - p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" -@@ -5462,6 +6381,11 @@ - p-try@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" -+======= -+p-map@^1.1.1: -+ version "1.2.0" -+ resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" -+>>>>>>> .their - - package-json@^4.0.0: - version "4.0.1" -@@ -5967,7 +6891,11 @@ - renderkid "^2.0.1" - utila "~0.4" - -+<<<<<<< .our - private@^0.1.7, private@^0.1.8: -+======= -+private@^0.1.6, private@^0.1.7: -+>>>>>>> .their - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - -@@ -5990,7 +6918,11 @@ - speedometer "~0.1.2" - through2 "~0.2.3" - -+<<<<<<< .our - progress@^1.1.8: -+======= -+progress@1.1.8: -+>>>>>>> .their - version "1.1.8" - resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" - -@@ -6109,6 +7041,28 @@ - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - -+<<<<<<< .our -+======= -+rabin-bindings@~1.7.4: -+ version "1.7.4" -+ resolved "https://registry.yarnpkg.com/rabin-bindings/-/rabin-bindings-1.7.4.tgz#174581d3b9a3c1b09ece75dc21f1b4ae0dd79974" -+ dependencies: -+ bindings "^1.3.0" -+ nan "^2.8.0" -+ prebuild-install "^2.3.0" -+ -+ramda@0.24.1: -+ version "0.24.1" -+ resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.24.1.tgz#c3b7755197f35b8dc3502228262c4c91ddb6b857" -+ -+randomatic@^1.1.3: -+ version "1.1.7" -+ resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" -+ dependencies: -+ is-number "^3.0.0" -+ kind-of "^4.0.0" -+ -+>>>>>>> .their - randombytes@^2.0.0, randombytes@^2.0.1: - version "2.0.5" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.5.tgz#dc009a246b8d09a177b4b7a0ae77bc570f4b1b79" -@@ -6278,6 +7232,12 @@ - readable-stream "^2.0.2" - set-immediate-shim "^1.0.1" - -+rechoir@^0.6.2: -+ version "0.6.2" -+ resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" -+ dependencies: -+ resolve "^1.1.6" -+ - redent@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" -@@ -6311,6 +7271,23 @@ - version "0.11.0" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1" - -+<<<<<<< .our -+======= -+regenerator-transform@^0.10.0: -+ version "0.10.1" -+ resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" -+ dependencies: -+ babel-runtime "^6.18.0" -+ babel-types "^6.19.0" -+ private "^0.1.6" -+ -+regex-cache@^0.4.2: -+ version "0.4.4" -+ resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" -+ dependencies: -+ is-equal-shallow "^0.1.3" -+ -+>>>>>>> .their - regex-not@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.0.tgz#42f83e39771622df826b02af176525d6a5f157f9" -@@ -6342,6 +7319,14 @@ - regjsgen "^0.2.0" - regjsparser "^0.1.4" - -+regexpu-core@^2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" -+ dependencies: -+ regenerate "^1.2.1" -+ regjsgen "^0.2.0" -+ regjsparser "^0.1.4" -+ - registry-auth-token@^3.0.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.1.tgz#fb0d3289ee0d9ada2cbb52af5dfe66cb070d3006" -@@ -6397,11 +7382,19 @@ - dependencies: - is-finite "^1.0.0" - -+<<<<<<< .our - request-progress@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-2.0.1.tgz#5d36bb57961c673aa5b788dbc8141fdf23b44e08" - dependencies: - throttleit "^1.0.0" -+======= -+request-progress@0.3.1: -+ version "0.3.1" -+ resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-0.3.1.tgz#0721c105d8a96ac6b2ce8b2c89ae2d5ecfcf6b3a" -+ dependencies: -+ throttleit "~0.0.2" -+>>>>>>> .their - - request@2, request@^2.45.0, request@^2.72.0, request@^2.79.0, request@^2.81.0: - version "2.83.0" -@@ -6515,6 +7508,13 @@ - dependencies: - path-parse "^1.0.5" - -+restore-cursor@^1.0.1: -+ version "1.0.1" -+ resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" -+ dependencies: -+ exit-hook "^1.0.0" -+ onetime "^1.0.0" -+ - restore-cursor@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" -@@ -6563,9 +7563,15 @@ - version "4.1.0" - resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" - -+<<<<<<< .our - rxjs@^5.5.2: - version "5.5.11" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.11.tgz#f733027ca43e3bec6b994473be4ab98ad43ced87" -+======= -+rxjs@^5.0.0-beta.11: -+ version "5.5.6" -+ resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.6.tgz#e31fb96d6fd2ff1fd84bcea8ae9c02d007179c02" -+>>>>>>> .their - dependencies: - symbol-observable "1.0.1" - -@@ -6648,7 +7654,11 @@ - version "5.4.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" - -+<<<<<<< .our - semver@5.5.0, semver@^5.5.0: -+======= -+semver@^5.0.1, semver@^5.5.0: -+>>>>>>> .their - version "5.5.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" - -@@ -6783,9 +7793,19 @@ - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - -+<<<<<<< .our - shelljs@0.3.x: - version "0.3.0" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.3.0.tgz#3596e6307a781544f591f37da618360f31db57b1" -+======= -+shelljs@0.8.0: -+ version "0.8.0" -+ resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.0.tgz#12f561c52ec5d0d3315af15616c011a18ff80d59" -+ dependencies: -+ glob "^7.0.0" -+ interpret "^1.0.0" -+ rechoir "^0.6.2" -+>>>>>>> .their - - signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.2" -@@ -6801,6 +7821,10 @@ - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - -+slice-ansi@0.0.4: -+ version "0.0.4" -+ resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" -+ - slice-ansi@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" -@@ -7043,9 +8067,15 @@ - to-arraybuffer "^1.0.0" - xtend "^4.0.0" - -+<<<<<<< .our - stream-shift@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" -+======= -+stream-to-observable@^0.1.0: -+ version "0.1.0" -+ resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.1.0.tgz#45bf1d9f2d7dc09bed81f1c307c430e68b84cffe" -+>>>>>>> .their - - strict-uri-encode@^1.0.0: - version "1.1.0" -@@ -7162,6 +8192,12 @@ - dependencies: - has-flag "^2.0.0" - -+supports-color@5.1.0: -+ version "5.1.0" -+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.1.0.tgz#058a021d1b619f7ddf3980d712ea3590ce7de3d5" -+ dependencies: -+ has-flag "^2.0.0" -+ - supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" -@@ -7200,9 +8236,15 @@ - version "1.0.1" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" - -+<<<<<<< .our - table@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc" -+======= -+table@^4.0.1: -+ version "4.0.2" -+ resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" -+>>>>>>> .their - dependencies: - ajv "^6.0.1" - ajv-keywords "^3.0.0" -@@ -7266,11 +8308,35 @@ - dependencies: - execa "^0.7.0" - -+<<<<<<< .our - text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - - throttleit@0.0.2: -+======= -+terminal-banner@1.1.0: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/terminal-banner/-/terminal-banner-1.1.0.tgz#ef81ce7d9d7e541a81d09eb2c0257c3d5463c3ea" -+ -+text-table@~0.2.0: -+ version "0.2.0" -+ resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" -+ -+thenify-all@^1.0.0: -+ version "1.6.0" -+ resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" -+ dependencies: -+ thenify ">= 3.1.0 < 4" -+ -+"thenify@>= 3.1.0 < 4": -+ version "3.3.0" -+ resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839" -+ dependencies: -+ any-promise "^1.0.0" -+ -+throttleit@0.0.2, throttleit@~0.0.2: -+>>>>>>> .their - version "0.0.2" - resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-0.0.2.tgz#cfedf88e60c00dd9697b61fdd2a8343a9b680eaf" - -@@ -7312,6 +8378,12 @@ - dependencies: - os-tmpdir "~1.0.1" - -+tmp@0.0.31: -+ version "0.0.31" -+ resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7" -+ dependencies: -+ os-tmpdir "~1.0.1" -+ - tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" -@@ -7416,9 +8488,24 @@ - version "1.0.0" - resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.0.tgz#027b69fa823225e551cace3ef03b11f6ab37c1d7" - -+<<<<<<< .our - ts-node@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.0.tgz#a94a13c75e5e1aa6b82814b84c68deb339ba7bff" -+======= -+ts-loader@3.2.0: -+ version "3.2.0" -+ resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-3.2.0.tgz#23211922179b81f7448754b7fdfca45b8374a15a" -+ dependencies: -+ chalk "^2.3.0" -+ enhanced-resolve "^3.0.0" -+ loader-utils "^1.0.2" -+ semver "^5.0.1" -+ -+ts-node@^3.2.0: -+ version "3.3.0" -+ resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-3.3.0.tgz#c13c6a3024e30be1180dd53038fc209289d4bf69" -+>>>>>>> .their - dependencies: - arrify "^1.0.0" - buffer-from "^1.1.0" -@@ -7696,7 +8783,7 @@ - punycode "1.3.2" - querystring "0.2.0" - --url@^0.11.0, url@~0.11.0: -+url@0.11.0, url@^0.11.0, url@~0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - dependencies: -@@ -7898,9 +8985,42 @@ - source-list-map "^2.0.0" - source-map "~0.5.3" - -+<<<<<<< .our - webpack-sources@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" -+======= -+webpack@3.6.0: -+ version "3.6.0" -+ resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.6.0.tgz#a89a929fbee205d35a4fa2cc487be9cbec8898bc" -+ dependencies: -+ acorn "^5.0.0" -+ acorn-dynamic-import "^2.0.0" -+ ajv "^5.1.5" -+ ajv-keywords "^2.0.0" -+ async "^2.1.2" -+ enhanced-resolve "^3.4.0" -+ escope "^3.6.0" -+ interpret "^1.0.0" -+ json-loader "^0.5.4" -+ json5 "^0.5.1" -+ loader-runner "^2.3.0" -+ loader-utils "^1.1.0" -+ memory-fs "~0.4.1" -+ mkdirp "~0.5.0" -+ node-libs-browser "^2.0.0" -+ source-map "^0.5.3" -+ supports-color "^4.2.1" -+ tapable "^0.2.7" -+ uglifyjs-webpack-plugin "^0.4.6" -+ watchpack "^1.4.0" -+ webpack-sources "^1.0.1" -+ yargs "^8.0.2" -+ -+webpack@^2.2.0: -+ version "2.7.0" -+ resolved "https://registry.yarnpkg.com/webpack/-/webpack-2.7.0.tgz#b2a1226804373ffd3d03ea9c6bd525067034f6b1" -+>>>>>>> .their - dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" -@@ -8170,6 +9290,13 @@ - dependencies: - fd-slicer "~1.0.1" - -+yauzl@2.8.0: -+ version "2.8.0" -+ resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.8.0.tgz#79450aff22b2a9c5a41ef54e02db907ccfbf9ee2" -+ dependencies: -+ buffer-crc32 "~0.2.3" -+ fd-slicer "~1.0.1" -+ - yn@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" diff --git a/app/test/fixtures/merge-parser/desktop/merge-dark-handle-colors-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-dark-handle-colors-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 7d4c9c89db0..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-dark-handle-colors-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,48 +0,0 @@ -changed in both - base 100644 e36247cd551a39899efcd6f2835d023c39f17a20 app/styles/_variables.scss - our 100644 6c89a529c5a8dbfefb127f171468af9ae5651141 app/styles/_variables.scss - their 100644 d6df99e979ae35224a6767759f74dee365b15eba app/styles/_variables.scss -@@ -378,6 +378,10 @@ - --path-segment-background: $blue-000; - --path-segment-padding: var(--spacing-third); - -+ /** Co-author colors **/ -+ --handle-background: $blue-000; -+ --handle-border-color: $blue-200; -+ - /** Diverging notification banner colors */ - --notification-banner-background: $blue-000; - --notification-banner-border-color: $blue-200; -changed in both - base 100644 43d39d75f19c242c1630b9ab243f18fcc733c7e5 app/styles/themes/_dark.scss - our 100644 663d5cb65e7a6b69154193384801a8c63234744f app/styles/themes/_dark.scss - their 100644 50283ed7d75649e199b4921fda025a2981d9944d app/styles/themes/_dark.scss -@@ -295,6 +295,10 @@ - /** Inline paths and code */ - --path-segment-background: $gray-700; - -+ /** Co-author colors **/ -+ --handle-background: rgba($blue-700, .75); -+ --handle-border-color: rgba($blue-600, .75); -+ - .blankslate-image { - filter: #{'invert()'} grayscale(1) brightness(8) contrast(0.6); - } -changed in both - base 100644 7f410ba422cc224a1bf1a644770a555b04eacd29 app/styles/ui/_author-input.scss - our 100644 c1acae40fa98cefd4b9acd874bc3f9564610a6b3 app/styles/ui/_author-input.scss - their 100644 a41ccafd5ecde9921e8a7e223fdf21cc5aa0aadd app/styles/ui/_author-input.scss -@@ -24,8 +24,13 @@ - - .handle { - border-radius: 3px; -+<<<<<<< .our - border: 1px solid var(--co-author-tag-border-color); - background: var(--co-author-tag-background-color); -+======= -+ border: 1px solid var(--handle-border-color); -+ background: var(--handle-background); -+>>>>>>> .their - padding: 1px 1px; - margin: 0px 2px; - diff --git a/app/test/fixtures/merge-parser/desktop/merge-database-field-naming-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-database-field-naming-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index be39572ca23..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-database-field-naming-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,595 +0,0 @@ -merged - result 100644 2a0f74dc77543305562cfdb0d7df871b94f4d622 app/src/lib/databases/base-database.ts - our 100644 3c62963f65df3f6ff54e368c4b1dfac3b3f8953e app/src/lib/databases/base-database.ts -@@ -10,11 +10,9 @@ - } - - /** -- * Register the version of the schema only if `targetVersion` is less than -+ * Register the version of the schema only if `schemaVersion` is less than - * `version` or is `undefined`. - * -- * targetVersion - The version of the schema that is being targetted. If not -- * provided, the given version will be registered. - * version - The version being registered. - * schema - The schema to register. - * upgrade - An upgrade function to call after upgrading to the given -changed in both - base 100644 872c7b726ce1803b9a7e9280dab2ce26484e6aa5 app/src/lib/databases/pull-request-database.ts - our 100644 7446a4ce1ebf104f7825a7757e6be2beccfbe4ef app/src/lib/databases/pull-request-database.ts - their 100644 4c81bea71896008149f396372926584549c4c90d app/src/lib/databases/pull-request-database.ts -@@ -1,13 +1,18 @@ - import Dexie from 'dexie' --import { APIRefState, IAPIRefStatusItem } from '../api' - import { BaseDatabase } from './base-database' - -+export const PullRequestTableName = 'pullRequest' -+export const PullRequestStatusTableName = 'pullRequestStatus' -+ -+/** The combined state of a ref. */ -+export type RefState = 'failure' | 'pending' | 'success' -+ - export interface IPullRequestRef { - /** - * The database ID of the GitHub repository in which this ref lives. It could - * be null if the repository was deleted on the site after the PR was opened. - */ -- readonly repoId: number | null -+ readonly repositoryId: number | null - - /** The name of the ref. */ - readonly ref: string -@@ -16,12 +21,24 @@ - readonly sha: string - } - -+export interface ICombinedRefStatus { -+ readonly id: number -+ /** The state of the status. */ -+ readonly state: RefState -+ /** The target URL to associate with this status. */ -+ readonly targetUrl: string -+ /** A short description of the status. */ -+ readonly description: string -+ /** A string label to differentiate this status from the status of other systems. */ -+ readonly context: string -+} -+ - export interface IPullRequest { - /** - * The database ID. This will be undefined if the pull request hasn't been - * inserted into the DB. - */ -- readonly id?: number -+ readonly _id?: number - - /** The GitHub PR number. */ - readonly number: number -@@ -47,13 +64,13 @@ - * The database ID. This will be undefined if the status hasn't been inserted - * into the DB. - */ -- readonly id?: number -+ readonly _id?: number - - /** The ID of the pull request in the database. */ - readonly pullRequestId: number - - /** The status' state. */ -- readonly state: APIRefState -+ readonly state: RefState - - /** The number of statuses represented in this combined status. */ - readonly totalCount: number -@@ -66,18 +83,23 @@ - * if the database object was created prior to status support - * being added in #3588 - */ -- readonly statuses?: ReadonlyArray<IAPIRefStatusItem> -+ readonly status: ReadonlyArray<ICombinedRefStatus> - } - - export class PullRequestDatabase extends BaseDatabase { -+<<<<<<< .our - public pullRequests!: Dexie.Table<IPullRequest, number> - public pullRequestStatus!: Dexie.Table<IPullRequestStatus, number> -+======= -+ public pullRequest: Dexie.Table<IPullRequest, number> -+ public pullRequestStatus: Dexie.Table<IPullRequestStatus, number> -+>>>>>>> .their - - public constructor(name: string, schemaVersion?: number) { - super(name, schemaVersion) - - this.conditionalVersion(1, { -- pullRequests: 'id++, base.repoId', -+ pullRequest: 'id++, base.repoId', - }) - - this.conditionalVersion(2, { -@@ -91,22 +113,202 @@ - // we need to run the upgrade function to ensure we add - // a status field to all previous records - this.conditionalVersion(4, {}, this.addStatusesField) -+ -+ // we need to copy data to tmp tables -+ // so we can clear all indexes -+ this.conditionalVersion( -+ 5, -+ { -+ pullRequestTmp: '_id++, base.repositoryId', -+ pullRequestStatusTmp: `_id++`, -+ }, -+ this.moveDataToTmpTables -+ ) -+ -+ this.conditionalVersion( -+ 6, -+ { -+ pullRequest: '_id++, base.repositoryId', -+ pullRequestStatus: '_id++', -+ }, -+ this.upgradeFieldNames -+ ) - } - - private addStatusesField = async (transaction: Dexie.Transaction) => { -- const table = this.pullRequestStatus -+ const tableName = 'pullRequestStatus' - -- await table.toCollection().modify(async prStatus => { -- if (prStatus.statuses == null) { -- const newPrStatus = { statuses: [], ...prStatus } -+ await transaction -+ .table(tableName) -+ .toCollection() -+ .modify(async prStatus => { -+ if (prStatus.status == null) { -+ const newPrStatus = { statuses: [], ...prStatus } - -- await table -- .where('[sha+pullRequestId]') -- .equals([prStatus.sha, prStatus.pullRequestId]) -- .delete() -+ await transaction -+ .table(tableName) -+ .where('[sha+pullRequestId]') -+ .equals([prStatus.sha, prStatus.pullRequestId]) -+ .delete() - -- await table.add(newPrStatus) -- } -- }) -+ await transaction.table(tableName).add(newPrStatus) -+ } -+ }) -+ } -+ -+ private moveDataToTmpTables = async (transaction: Dexie.Transaction) => { -+ console.log('moveDataToTmpTables...') -+ let tmpTable: string -+ -+ console.dir(transaction) -+ -+ try { -+ tmpTable = 'pullRequestTmp' -+ -+ const prs = await transaction.table(PullRequestTableName).toArray() -+ console.log('mapping PR data') -+ const updatedPrs = prs.map(pr => { -+ return { -+ _id: pr.id as number, -+ number: pr.number as number, -+ title: pr.title as string, -+ createdAt: pr.createdAt as string, -+ head: { -+ repositoryId: pr.head.repoId, -+ ref: pr.head.ref, -+ sha: pr.head.sha, -+ }, -+ base: { -+ repositoryId: pr.base.repoId, -+ ref: pr.base.ref, -+ sha: pr.base.sha, -+ }, -+ author: pr.author, -+ } -+ }) -+ console.log('adding mapped PR data') -+ await transaction.table(tmpTable).bulkAdd(updatedPrs) -+ console.log(`removing PR data from '${PullRequestTableName}'`) -+ await transaction -+ .table(PullRequestTableName) -+ .toCollection() -+ .delete() -+ } catch (error) { -+ console.error(`Failed to transfer 'pullRequest' data: ${error}`) -+ throw error -+ } -+ -+ try { -+ tmpTable = 'pullRequestStatusTmp' -+ -+ const prStats = await transaction -+ .table(PullRequestStatusTableName) -+ .toArray() -+ console.log('mapping PR Status data') -+ const updatedPrStats = prStats.map(prStat => { -+ return { -+ _id: prStat.id as number, -+ pullRequestId: prStat.pullRequestId as number, -+ state: prStat.state as RefState, -+ totalCount: prStat.totalCount, -+ sha: prStat.sha, -+ status: prStat.map((s: any) => { -+ return { -+ id: s.id as number, -+ state: s.state as RefState, -+ targetUrl: s.target_url as string, -+ description: s.description as string, -+ context: s.context as string, -+ } -+ }), -+ } -+ }) -+ console.log('adding mapped PR Status data') -+ await transaction.table(tmpTable).bulkAdd(updatedPrStats) -+ console.log( -+ `removing PR Status data from '${PullRequestStatusTableName}'` -+ ) -+ await transaction -+ .table(PullRequestStatusTableName) -+ .toCollection() -+ .delete() -+ } catch (error) { -+ console.error(`Failed to transfer 'pullRequestStatus' data: ${error}`) -+ throw error -+ } -+ console.log('completed') -+ } -+ -+ private upgradeFieldNames = async (transaction: Dexie.Transaction) => { -+ console.log('upgradeFieldNames...') -+ try { -+ const oldPRRecords = await transaction.table('pullRequests').toArray() -+ const newPRRecords: IPullRequest[] = oldPRRecords.map(r => { -+ return { -+ _id: r.id as number, -+ number: r.number as number, -+ title: r.title as string, -+ createdAt: r.createdAt as string, -+ head: { -+ repositoryId: r.head.repoId as number, -+ ref: r.head.ref as string, -+ sha: r.head.sha as string, -+ }, -+ base: { -+ repositoryId: r.base.repoId as number, -+ ref: r.base.ref as string, -+ sha: r.base.sha as string, -+ }, -+ author: r.author, -+ } -+ }) -+ -+ console.log(`deleting old indexes on '${PullRequestTableName}'`) -+ await Promise.all( -+ ['id', 'base.repoId'].map(index => -+ transaction.idbtrans -+ .objectStore(PullRequestTableName) -+ .deleteIndex(index) -+ ) -+ ) -+ console.log(`clearing table '${PullRequestTableName}'`) -+ await transaction.table(PullRequestTableName).clear() -+ await this.pullRequest.bulkAdd(newPRRecords) -+ } catch (error) { -+ log.error( -+ `Failed to upgrade field names on 'pullRequest' table: ${error}` -+ ) -+ throw error -+ } -+ -+ try { -+ const oldPrStatusRecords = await transaction -+ .table('pullRequestStatus') -+ .toCollection() -+ .toArray() -+ const newPrStatusRecords: IPullRequestStatus[] = oldPrStatusRecords.map( -+ r => { -+ return { -+ _id: r.id as number, -+ pullRequestId: r.pullRequestId as number, -+ state: r.state as RefState, -+ totalCount: r.totalCount as number, -+ sha: r.sha as string, -+ status: r.statuses as Array<ICombinedRefStatus>, -+ } -+ } -+ ) -+ await transaction -+ .table('pullRequestStatus') -+ .toCollection() -+ .delete() -+ this.pullRequestStatus.bulkAdd(newPrStatusRecords) -+ } catch (error) { -+ log.error( -+ `Failed to upgrade field names on 'pullRequestStatus' table: ${error}` -+ ) -+ throw error -+ } -+ console.log('completed') - } - } -changed in both - base 100644 51508430ccce1f6f0a378949a0c1abbd5b0fc3f2 app/src/lib/stores/pull-request-store.ts - our 100644 d9edf0247ea7c33ae2b508f876aa977d8a81d6d4 app/src/lib/stores/pull-request-store.ts - their 100644 751860efd974cba55ff4c5a3fb1524318bd0908d app/src/lib/stores/pull-request-store.ts -@@ -122,7 +122,7 @@ - ) - } - -- const records = await this.pullRequestDatabase.pullRequests -+ const records = await this.pullRequestDatabase.pullRequest - .where('base.repoId') - .equals(gitHubRepositoryID) - .reverse() -@@ -131,7 +131,7 @@ - const result = new Array<PullRequest>() - - for (const record of records) { -- const repositoryDbId = record.head.repoId -+ const repositoryDbId = record.head.repositoryId - let githubRepository: GitHubRepository | null = null - - if (repositoryDbId != null) { -@@ -144,7 +144,7 @@ - // fetched the PR from in the first place. - const parentRepositoryDbId = forceUnwrap( - 'A pull request cannot have a null base repo id', -- record.base.repoId -+ record.base.repositoryId - ) - const parentGitGubRepository: GitHubRepository | null = await this.repositoryStore.findGitHubRepositoryByID( - parentRepositoryDbId -@@ -158,7 +158,7 @@ - // database. - const pullRequestDbId = forceUnwrap( - 'PR cannot have a null ID after being retrieved from the database', -- record.id -+ record._id - ) - - const pullRequestStatus = await this.findPullRequestStatus( -@@ -270,7 +270,15 @@ - state: combinedRefStatus.state, - totalCount: combinedRefStatus.total_count, - sha: pr.head.sha, -- statuses: combinedRefStatus.statuses, -+ status: combinedRefStatus.statuses.map(x => { -+ return { -+ id: x.id, -+ state: x.state, -+ targetUrl: x.target_url, -+ description: x.description, -+ context: x.context, -+ } -+ }), - }) - } - -@@ -292,7 +300,7 @@ - return null - } - -- const combinedRefStatuses = (result.statuses || []).map(x => { -+ const combinedRefStatuses = (result.status || []).map(x => { - return { - id: x.id, - state: x.state, -@@ -321,7 +329,7 @@ - ) - } - -- const table = this.pullRequestDatabase.pullRequests -+ const table = this.pullRequestDatabase.pullRequest - const prsToInsert = new Array<IPullRequest>() - - for (const pr of pullRequestsFromAPI) { -@@ -374,18 +382,26 @@ - head: { - ref: pr.head.ref, - sha: pr.head.sha, -- repoId: githubRepoDbId, -+ repositoryId: githubRepoDbId, - }, - base: { - ref: pr.base.ref, - sha: pr.base.sha, -- repoId: parentGitHubRepoDbId, -+ repositoryId: parentGitHubRepoDbId, - }, - author: pr.user.login, - }) - } - - return this.pullRequestDatabase.transaction('rw', table, async () => { -+<<<<<<< .our -+======= -+ // since all PRs come from the same repository -+ // using the base repoId of the fist element -+ // is sufficient here -+ const repoDbId = prsToInsert[0].base.repositoryId! -+ -+>>>>>>> .their - // we need to delete the stales PRs from the db - // so we remove all for a repo to avoid having to - // do diffing -@@ -415,7 +431,7 @@ - if (record == null) { - await table.add(status) - } else { -- await table.put({ id: record.id, ...status }) -+ await table.put({ _id: record._id, ...status }) - } - } - }) -merged - result 100644 65be61a7ce9118ccb55f8723246c09ad779c791a app/test/unit/pull-request-database-test.ts - our 100644 84085903d759de2faabe43e55881fb4e3f2c63e8 app/test/unit/pull-request-database-test.ts -@@ -2,39 +2,124 @@ - - import { - PullRequestDatabase, -- IPullRequestStatus, -+ PullRequestStatusTableName, -+ PullRequestTableName, - } from '../../src/lib/databases' - -+const databaseName = 'TestPullRequestDatabase' -+const tmpPullRequestTable = 'pullRequestTmp' -+//const tmpPullRequestStatusTable = 'pullRequestStatusTmp' -+ - describe('PullRequestDatabase', () => { -- it("adds statuses key to records that don't have one on upgrade", async () => { -- const databaseName = 'TestPullRequestDatabase' -- -- let database = new PullRequestDatabase(databaseName, 3) -- await database.delete() -- await database.open() -- -- const prStatus: IPullRequestStatus = { -- pullRequestId: 1, -- state: 'success', -- totalCount: 1, -- sha: 'sha', -- } -- await database.pullRequestStatus.add(prStatus) -- const prStatusFromDb = await database.pullRequestStatus.get(1) -- expect(prStatusFromDb).to.not.be.undefined -- expect(prStatusFromDb!.pullRequestId).to.equal(prStatus.pullRequestId) -- -- database.close() -- database = new PullRequestDatabase(databaseName, 4) -- await database.open() -- -- const upgradedPrStatusFromDb = await database.pullRequestStatus.get(1) -- expect(upgradedPrStatusFromDb).is.not.undefined -- expect(upgradedPrStatusFromDb!.pullRequestId).to.equal( -- prStatus.pullRequestId -- ) -- expect(upgradedPrStatusFromDb!.statuses).is.not.undefined -- -- await database.delete() -+ describe('Upgrade', () => { -+ describe('PullRequestTable', () => { -+ it.only('renames indexes retaining original data when upgrading to version 4 -> 5 -> 6', async () => { -+ let database = new PullRequestDatabase(databaseName, 4) -+ await database.delete() -+ await database.open() -+ -+ // untyped because field names have been updated -+ const pr = { -+ number: 1, -+ title: 'title', -+ createdAt: '2018-01-01', -+ head: { -+ repoId: 1, -+ ref: 'head', -+ sha: 'head.sha', -+ }, -+ base: { -+ repoId: 10, -+ ref: 'base', -+ sha: 'base.sha', -+ }, -+ author: 'me', -+ } -+ // We need to opt-out of type checking here since -+ // the old schema uses an outdated type -+ const originalTable = database.table(PullRequestTableName) -+ await originalTable.add(pr) -+ const prFromDb = await originalTable.get(1) -+ expect(prFromDb).to.not.be.undefined -+ -+ database.close() -+ // we need to run this upgrade first so we can -+ // clear out indexes; new data is in tmp tables -+ // at this point -+ database = new PullRequestDatabase(databaseName, 5) -+ await database.open() -+ -+ const tmpTable = database.table(tmpPullRequestTable) -+ const tmpRecord = await tmpTable.get(1) -+ expect(tmpRecord).is.not.undefined -+ expect(tmpRecord.number).to.equal(pr.number) -+ -+ database.close() -+ // this is the upgrade we actually care about -+ // data should be back into normal tables at this point -+ database = new PullRequestDatabase(databaseName, 6) -+ await database.open() -+ -+ // this is a major change, so make sure no data is lost -+ const upgradedPrFromDb = await database.pullRequest.get(prFromDb.id) -+ expect(upgradedPrFromDb).is.not.undefined -+ expect(upgradedPrFromDb!._id).to.equal(1) -+ expect(upgradedPrFromDb!.number).to.equal(pr.number) -+ expect(upgradedPrFromDb!.title).to.equal(pr.title) -+ expect(upgradedPrFromDb!.createdAt).to.equal(pr.createdAt) -+ expect(upgradedPrFromDb!.head.repositoryId).to.equal(pr.head.repoId) -+ expect(upgradedPrFromDb!.base.repositoryId).to.equal(pr.base.repoId) -+ expect(upgradedPrFromDb!.head.ref).to.equal(pr.head.ref) -+ expect(upgradedPrFromDb!.base.sha).to.equal(pr.base.sha) -+ expect(upgradedPrFromDb!.author).to.equal(pr.author) -+ -+ database.close() -+ await database.delete() -+ }) -+ }) -+ -+ describe('PullRequestStatusTable', () => { -+ it('adds default value for the statuses key when upgrading to version 4', async () => { -+ const databaseName = 'TestPullRequestDatabase' -+ -+ let database = new PullRequestDatabase(databaseName, 3) -+ await database.delete() -+ await database.open() -+ -+ // insert record that is compatible with v3 of db -+ const prStatus = { -+ pullRequestId: 1, -+ state: 'success', -+ totalCount: 1, -+ sha: 'sha', -+ } -+ // Cannot use the safety of types here: -+ // the type is no longer valid with this version of the d -+ await database.table(PullRequestStatusTableName).add(prStatus) -+ const prStatusFromDb = await database -+ .table(PullRequestStatusTableName) -+ .get(1) -+ expect(prStatusFromDb).to.not.be.undefined -+ expect(prStatusFromDb!.pullRequestId).to.equal(prStatus.pullRequestId) -+ -+ database.close() -+ // update to v4 of db -+ database = new PullRequestDatabase(databaseName, 4) -+ await database.open() -+ -+ // get the upgraded record from the db -+ // note: there is no type-safety here -+ const upgradedPrStatusFromDb = await database -+ .table(PullRequestStatusTableName) -+ .get(1) -+ expect(upgradedPrStatusFromDb).is.not.undefined -+ expect(upgradedPrStatusFromDb!.pullRequestId).to.equal( -+ prStatus.pullRequestId -+ ) -+ expect(upgradedPrStatusFromDb!.statuses).is.not.undefined -+ -+ await database.delete() -+ }) -+ }) - }) - }) diff --git a/app/test/fixtures/merge-parser/desktop/merge-diff-too-large-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-diff-too-large-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 646e8fbecfd..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-diff-too-large-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,487 +0,0 @@ -changed in both - base 100644 b7fc04813074a6cb7cb041abf9f2f656f80bc05d app/src/lib/git/diff.ts - our 100644 c7b70925514f334e2076ddb67f208c2f3f12672f app/src/lib/git/diff.ts - their 100644 f961cf2783b01412c6a7be9bdd137dfa5f669e90 app/src/lib/git/diff.ts -@@ -18,7 +18,10 @@ - LineEndingsChange, - parseLineEndingText, - ILargeTextDiff, -+<<<<<<< .our - IUnrenderableDiff, -+======= -+>>>>>>> .their - } from '../../models/diff' - - import { spawnAndComplete } from './spawn' -@@ -32,13 +35,29 @@ - * This is a hard limit on how big a buffer can be and still be converted into - * a string. - */ -+<<<<<<< .our - const MaxDiffBufferSize = 70e6 // 70MB in decimal -+======= -+const MaxDiffBufferSize = 268435441 //~268MB -+>>>>>>> .their - - /** - * Where `MaxDiffBufferSize` is a hard limit, this is a suggested limit. Diffs - * bigger than this _could_ be displayed but it might cause some slowness. - */ -+<<<<<<< .our - const MaxReasonableDiffSize = MaxDiffBufferSize / 16 // ~4.375MB in decimal -+======= -+const MaxReasonableDiffSize = MaxDiffBufferSize / 64 //~4MB -+ -+/** -+ * Where `MaxReasonableDiffSize` is a soft limit, and `MaxDiffBufferSize` -+ * is an absolute limit, this is the MAX number of bytes to read from the -+ * buffer before _assuming_ the current buffer being read is `MaxDiffBufferSize`. -+ * This is done so that the UI isn't waiting for the entire buffer to be read. -+ */ -+const MaxBytesToRead = MaxDiffBufferSize / 8 //~32MB -+>>>>>>> .their - - /** - * The longest line length we should try to display. If a diff has a line longer -@@ -115,13 +134,26 @@ - args.push(file.oldPath) - } - -- const { output } = await spawnAndComplete( -+ const { output, didReadAllBytes } = await spawnAndComplete( - args, - repository.path, -- 'getCommitDiff' -+ 'getCommitDiff', -+ undefined, -+ MaxBytesToRead - ) -+<<<<<<< .our - - return buildDiff(output, repository, file, commitish) -+======= -+ -+ const largeDiff = buildLargeTextDiff(output, didReadAllBytes) -+ if (largeDiff != null) { -+ return largeDiff -+ } -+ -+ const diffText = diffFromRawDiffOutput(output) -+ return convertDiff(repository, file, diffText, commitish) -+>>>>>>> .their - } - - /** -@@ -192,15 +224,31 @@ - ] - } - -- const { output, error } = await spawnAndComplete( -+ const { output, error, didReadAllBytes } = await spawnAndComplete( - args, - repository.path, - 'getWorkingDirectoryDiff', -- successExitCodes -+ successExitCodes, -+ MaxBytesToRead - ) - const lineEndingsChange = parseLineEndingsWarning(error) - -+<<<<<<< .our - return buildDiff(output, repository, file, 'HEAD', lineEndingsChange) -+======= -+ const largeDiff = buildLargeTextDiff( -+ output, -+ didReadAllBytes, -+ lineEndingsChange -+ ) -+ if (largeDiff != null) { -+ return largeDiff -+ } -+ -+ const diffText = diffFromRawDiffOutput(output) -+ -+ return convertDiff(repository, file, diffText, 'HEAD', lineEndingsChange) -+>>>>>>> .their - } - - async function getImageDiff( -@@ -437,3 +485,50 @@ - contents.length - ) - } -+ -+/** -+ * Utility function that takes a buffer and outputs -+ * either a largeTextDiff or null -+ */ -+function buildLargeTextDiff( -+ buffer: Buffer, -+ didReadAllBytes: boolean, -+ lineEndingsChange?: LineEndingsChange -+): ILargeTextDiff | null { -+ if (!didReadAllBytes || !isValidBuffer(buffer)) { -+ // we know we can't transform this process output into a diff, so let's -+ // just return a placeholder for now that we can display to the user -+ // to say we're at the limits of the runtime -+ return { kind: DiffType.LargeText, length: buffer.length } -+ } -+ -+ const diffText = diffFromRawDiffOutput(buffer) -+ -+ if (isBufferTooLarge(buffer)) { -+ // we don't want to render by default -+ // but we keep it as an option by -+ // passing in text and hunks -+ const largeTextDiff: ILargeTextDiff = { -+ kind: DiffType.LargeText, -+ length: buffer.length, -+ text: diffText.contents, -+ hunks: diffText.hunks, -+ lineEndingsChange, -+ } -+ -+ return largeTextDiff -+ } -+ -+ if (isDiffTooLarge(diffText)) { -+ const largeTextDiff: ILargeTextDiff = { -+ kind: DiffType.LargeText, -+ text: diffText.contents, -+ hunks: diffText.hunks, -+ lineEndingsChange, -+ } -+ -+ return largeTextDiff -+ } -+ -+ return null -+} -changed in both - base 100644 d911e4235f5a1e8e056f9d98d4a6fda3d76dcaea app/src/lib/git/spawn.ts - our 100644 143168d54995f923711aa352fff4365067b90676 app/src/lib/git/spawn.ts - their 100644 79576b0f30fd4b538b4a0c98b1b7a0bb7f68373a app/src/lib/git/spawn.ts -@@ -4,7 +4,11 @@ - type ProcessOutput = { - /** The contents of stdout received from the spawned process */ - output: Buffer -+<<<<<<< .our - /** The contents of stderr received from the spawned process */ -+======= -+ didReadAllBytes: boolean -+>>>>>>> .their - error: Buffer - /** The exit code returned by the spawned process */ - exitCode: number -@@ -38,6 +42,7 @@ - const process = GitProcess.spawn(args, path) - let totalStdoutLength = 0 - let killSignalSent = false -+ let didReadAllBytes = true - - const stdoutChunks = new Array<Buffer>() - process.stdout.on('data', (chunk: Buffer) => { -@@ -53,6 +58,7 @@ - ) { - process.kill() - killSignalSent = true -+ didReadAllBytes = false - } - }) - -@@ -84,6 +90,7 @@ - if (exitCodes.has(code) || signal) { - resolve({ - output: stdout, -+ didReadAllBytes, - error: stderr, - exitCode: code, - }) -removed in local - base 100644 e4d51575a72468d893a82b6dea7589e4443974c1 app/src/models/diff.ts - their 100644 93622965bdfa473e1d9e61e23b2a66270ca1798a app/src/models/diff.ts -changed in both - base 100644 c0d9dfc2ede51b53ffda7330d5bc301a44765f52 app/src/ui/diff/index.tsx - our 100644 8695c640dc0a5184c74a112f131a2e2a07ef572d app/src/ui/diff/index.tsx - their 100644 d025925faa5170a694e42b0fe8bedde37319fa7f app/src/ui/diff/index.tsx -@@ -18,6 +18,11 @@ - IDiff, - IImageDiff, - ITextDiff, -+<<<<<<< .our -+======= -+ DiffLine, -+ DiffLineType, -+>>>>>>> .their - ILargeTextDiff, - } from '../../models/diff' - -@@ -33,12 +38,43 @@ - import { DiffLineGutter } from './diff-line-gutter' - import { DiffSyntaxMode } from './diff-syntax-mode' - -+<<<<<<< .our - import { ISelectionStrategy } from './selection/selection-strategy' - import { TextDiff } from './text-diff' -+======= -+import { fatalError } from '../../lib/fatal-error' -+ -+import { RangeSelectionSizePixels } from './edge-detection' -+import { relativeChanges } from './changed-range' -+import { getPartialBlobContents } from '../../lib/git/show' -+import { readPartialFile } from '../../lib/file-system' -+ -+import { DiffSyntaxMode, IDiffSyntaxModeSpec } from './diff-syntax-mode' -+import { highlight } from '../../lib/highlighter/worker' -+import { ITokens } from '../../lib/highlighter/types' -+import { Button } from '../lib/button' -+ -+/** The longest line for which we'd try to calculate a line diff. */ -+const MaxIntraLineDiffStringLength = 4096 -+>>>>>>> .their -+ -+// image used when no diff is displayed -+const NoDiffImage = encodePathAsUrl(__dirname, 'static/ufo-alert.svg') -+ -+<<<<<<< .our -+======= -+// This is a custom version of the no-newline octicon that's exactly as -+// tall as it needs to be (8px) which helps with aligning it on the line. -+const narrowNoNewlineSymbol = new OcticonSymbol( -+ 16, -+ 8, -+ 'm 16,1 0,3 c 0,0.55 -0.45,1 -1,1 l -3,0 0,2 -3,-3 3,-3 0,2 2,0 0,-2 2,0 z M 8,4 C 8,6.2 6.2,8 4,8 1.8,8 0,6.2 0,4 0,1.8 1.8,0 4,0 6.2,0 8,1.8 8,4 Z M 1.5,5.66 5.66,1.5 C 5.18,1.19 4.61,1 4,1 2.34,1 1,2.34 1,4 1,4.61 1.19,5.17 1.5,5.66 Z M 7,4 C 7,3.39 6.81,2.83 6.5,2.34 L 2.34,6.5 C 2.82,6.81 3.39,7 4,7 5.66,7 7,5.66 7,4 Z' -+) - - // image used when no diff is displayed - const NoDiffImage = encodePathAsUrl(__dirname, 'static/ufo-alert.svg') - -+>>>>>>> .their - type ChangedFile = WorkingDirectoryFileChange | CommittedFileChange - - /** The props for the Diff component. */ -@@ -71,6 +107,21 @@ - interface IDiffState { - readonly forceShowLargeDiff: boolean - } -+<<<<<<< .our -+======= -+ -+/** A component which renders a diff for a file. */ -+export class Diff extends React.Component<IDiffProps, IDiffState> { -+ private codeMirror: Editor | null -+ private gutterWidth: number | null -+ -+ /** -+ * We store the scroll position before reloading the same diff so that we can -+ * restore it when we're done. If we're not reloading the same diff, this'll -+ * be null. -+ */ -+ private scrollPositionToRestore: { left: number; top: number } | null = null -+>>>>>>> .their - - /** A component which renders a diff for a file. */ - export class Diff extends React.Component<IDiffProps, IDiffState> { -@@ -88,6 +139,22 @@ - - public constructor(props: IDiffProps) { - super(props) -+<<<<<<< .our -+======= -+ -+ this.state = { -+ forceShowLargeDiff: false, -+ } -+ } -+ -+ public componentWillReceiveProps(nextProps: IDiffProps) { -+ // If we're reloading the same file, we want to save the current scroll -+ // position and restore it after the diff's been updated. -+ const sameFile = -+ nextProps.file && -+ this.props.file && -+ nextProps.file.id === this.props.file.id -+>>>>>>> .their - - this.state = { - forceShowLargeDiff: false, -@@ -221,6 +288,65 @@ - } - - private renderLargeTextDiff() { -+<<<<<<< .our -+======= -+ return ( -+ <div className="panel empty large-diff"> -+ <img src={NoDiffImage} /> -+ <p> -+ The diff is too large to be displayed by default. -+ <br /> -+ You can try to show it anyway, but performance may be negatively -+ impacted. -+ </p> -+ <Button onClick={this.showLargeDiff}>Show diff</Button> -+ </div> -+ ) -+ } -+ -+ private renderDiffTooLarge() { -+ return ( -+ <div className="panel empty large-diff"> -+ <img src={NoDiffImage} /> -+ <p>The diff is too large to be displayed.</p> -+ </div> -+ ) -+ } -+ -+ private renderLargeText(diff: ILargeTextDiff) { -+ // gauranteed to be set since this function won't be called if text or hunks are null -+ const textDiff: ITextDiff = { -+ text: diff.text!, -+ hunks: diff.hunks!, -+ kind: DiffType.Text, -+ lineEndingsChange: diff.lineEndingsChange, -+ } -+ -+ return this.renderTextDiff(textDiff) -+ } -+ -+ private renderText(diff: ITextDiff) { -+ if (diff.hunks.length === 0) { -+ if (this.props.file.status === AppFileStatus.New) { -+ return <div className="panel empty">The file is empty</div> -+ } -+ -+ if (this.props.file.status === AppFileStatus.Renamed) { -+ return ( -+ <div className="panel renamed"> -+ The file was renamed but not changed -+ </div> -+ ) -+ } -+ -+ return <div className="panel empty">No content changes found</div> -+ } -+ -+ return this.renderTextDiff(diff) -+ } -+ -+ private renderBinaryFile() { -+>>>>>>> .their - return ( - <div className="panel empty large-diff"> - <img src={NoDiffImage} className="blankslate-image" /> -@@ -258,6 +384,7 @@ - return this.renderTextDiff(textDiff) - } - -+<<<<<<< .our - private renderText(diff: ITextDiff) { - if (diff.hunks.length === 0) { - if (this.props.file.status === AppFileStatus.New) { -@@ -303,5 +430,36 @@ - - private showLargeDiff = () => { - this.setState({ forceShowLargeDiff: true }) -+======= -+ private renderDiff(diff: IDiff): JSX.Element | null { -+ switch (diff.kind) { -+ case DiffType.Text: -+ return this.renderText(diff) -+ case DiffType.Binary: -+ return this.renderBinaryFile() -+ case DiffType.Image: -+ return this.renderImage(diff) -+ case DiffType.LargeText: { -+ const largeTextDiff = diff as ILargeTextDiff -+ if (largeTextDiff.hunks == null || largeTextDiff.text == null) { -+ return this.renderDiffTooLarge() -+ } -+ -+ return this.state.forceShowLargeDiff -+ ? this.renderLargeText(largeTextDiff) -+ : this.renderLargeTextDiff() -+ } -+ default: -+ return null -+ } -+ } -+ -+ public render() { -+ return this.renderDiff(this.props.diff) -+ } -+ -+ private showLargeDiff = () => { -+ this.setState({ forceShowLargeDiff: !this.state.forceShowLargeDiff }) -+>>>>>>> .their - } - } -changed in both - base 100644 72a39e960959b860b8f3662b83a83dc4c849afcc app/styles/ui/_blank-slate.scss - our 100644 87ceb1fcd23a13f3f1f6a4e56881f01ae7133902 app/styles/ui/_blank-slate.scss - their 100644 15b5862c419ad1249d6d9b5ec20aae6a7cdb39e7 app/styles/ui/_blank-slate.scss -@@ -97,6 +97,17 @@ - } - } - -+.blankslate-image { -+ max-width: 400px; -+ width: 80%; -+ flex-grow: 0.6; -+ // Background image url is set in react since we need to -+ // calculate it at runtime. -+ background-repeat: no-repeat; -+ background-position: center bottom; -+ background-size: contain; -+} -+ - // For all views other than the dedicated blank slate - // view. Yes, this is confusing. - .ui-view:not(#blank-slate) .blankslate-image { -changed in both - base 100644 1f4e8010da7360a39efa3147b01bcfb927e4a6a0 app/styles/ui/changes/_changes-view.scss - our 100644 94ed12c8ef668212eaa0f41d6f741a8cc444b2da app/styles/ui/changes/_changes-view.scss - their 100644 65c5af2ea88cf23e747e2b83a4de02734e02ec5a app/styles/ui/changes/_changes-view.scss -@@ -59,10 +59,13 @@ - margin: var(--spacing-double); - text-align: center; - justify-content: initial; -+<<<<<<< .our - - .blankslate-image { - max-height: 150px; - } -+======= -+>>>>>>> .their - } - } - } -changed in both - base 100644 867751eb28963ba7f852717ead2d03ce1abecff5 app/styles/ui/history/_history.scss - our 100644 58cea508b02182fa4f45daf88643d33c3b2dd020 app/styles/ui/history/_history.scss - their 100644 c1638efb77d0655fc644fcf702887a7577365324 app/styles/ui/history/_history.scss -@@ -42,10 +42,15 @@ - justify-content: center; - align-items: center; - } -+<<<<<<< .our -+======= -+ -+>>>>>>> .their - &.large-diff { - margin: var(--spacing-double); - text-align: center; - justify-content: initial; -+<<<<<<< .our - - .blankslate-image { - max-height: 150px; -@@ -154,6 +159,8 @@ - - .ref-component { - word-break: break-word; -+======= -+>>>>>>> .their - } - } - } diff --git a/app/test/fixtures/merge-parser/desktop/merge-diverge-prototype-spike-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-diverge-prototype-spike-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 728f979f509..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-diverge-prototype-spike-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,342 +0,0 @@ -changed in both - base 100644 c521e553d1a11b607a994fcbc4d3590c5b7203fc app/src/lib/app-state.ts - our 100644 b30f0fe080d909b81d2fb683ceb8deb365fb0191 app/src/lib/app-state.ts - their 100644 789cf613e7c1df5994e59a439a137c7c1ed2d9a2 app/src/lib/app-state.ts -@@ -189,9 +189,13 @@ - readonly selectedBranchesTab: BranchesTab - - /** Show the diverging notification banner */ -+<<<<<<< .our - readonly isDivergingBranchBannerVisible: boolean - /** The currently selected appearance (aka theme) */ - readonly selectedTheme: ApplicationTheme -+======= -+ readonly isDivergingBannerVisible: boolean -+>>>>>>> .their - } - - export enum PopupType { -changed in both - base 100644 99a2c7d01fb2ea70977e58590f06fc970284b1d5 app/src/lib/dispatcher/dispatcher.ts - our 100644 5e56c00e713342e76f5ccba040062e322e8c90cb app/src/lib/dispatcher/dispatcher.ts - their 100644 f3e59ad64ad00e45ed32ae6ed570afc8c3203281 app/src/lib/dispatcher/dispatcher.ts -@@ -466,10 +466,18 @@ - } - - /** -+<<<<<<< .our - * Set the divering branch notification banner's visibility - */ - public setDivergingBranchBannerVisibility(isVisible: boolean) { - return this.appStore._setDivergingBranchBannerVisibility(isVisible) -+======= -+ * Set the update banner's visibility -+ */ -+ public setDivergingBannerVisible(isVisible: boolean) { -+ console.log('hello from dispatcher!!!!!!!') -+ return this.appStore._setDivergingBannerVisible(isVisible) -+>>>>>>> .their - } - - /** -changed in both - base 100644 4cee841bc4c314fa326fcd00d2a037b661073822 app/src/lib/stores/app-store.ts - our 100644 1a4e387e4d192d34abfd0621b4b5ebe8cc34d8d1 app/src/lib/stores/app-store.ts - their 100644 04241406fccef40ca879aad3bda611660ada1919 app/src/lib/stores/app-store.ts -@@ -291,6 +291,8 @@ - private selectedTheme = ApplicationTheme.Light - private isDivergingBranchBannerVisible = false - -+ private isDivergingBannerVisible: boolean = false -+ - public constructor( - gitHubUserStore: GitHubUserStore, - cloningRepositoriesStore: CloningRepositoriesStore, -@@ -611,8 +613,12 @@ - repositoryFilterText: this.repositoryFilterText, - selectedCloneRepositoryTab: this.selectedCloneRepositoryTab, - selectedBranchesTab: this.selectedBranchesTab, -+<<<<<<< .our - isDivergingBranchBannerVisible: this.isDivergingBranchBannerVisible, - selectedTheme: this.selectedTheme, -+======= -+ isDivergingBannerVisible: this.isDivergingBannerVisible, -+>>>>>>> .their - } - } - -@@ -3186,6 +3192,7 @@ - this.emitUpdate() - } - -+<<<<<<< .our - public _setDivergingBranchBannerVisibility(visible: boolean) { - if (this.isDivergingBranchBannerVisible !== visible) { - this.isDivergingBranchBannerVisible = visible -@@ -3196,6 +3203,14 @@ - - this.emitUpdate() - } -+======= -+ public _setDivergingBannerVisible(visibility: boolean) { -+ console.log('hello from app store!!!!!!!!!!!') -+ -+ this.isDivergingBannerVisible = visibility -+ -+ this.emitUpdate() -+>>>>>>> .their - } - - public _reportStats() { -changed in both - base 100644 d67117115eac84151c211af50ce249ee557c91d5 app/src/ui/app.tsx - our 100644 c38c806e36c237ea70f3cdeee739941530c0c7cd app/src/ui/app.tsx - their 100644 03aed455ddef0f2d51844ea722adc16e1deb3bd7 app/src/ui/app.tsx -@@ -1704,7 +1704,11 @@ - accounts={state.accounts} - externalEditorLabel={externalEditorLabel} - onOpenInExternalEditor={this.openFileInExternalEditor} -+<<<<<<< .our - isDivergingBranchBannerVisible={state.isDivergingBranchBannerVisible} -+======= -+ hasDiverged={this.state.isDivergingBannerVisible} -+>>>>>>> .their - /> - ) - } else if (selectedState.type === SelectionType.CloningRepository) { -changed in both - base 100644 2c937c5f439252828e8397251948aacceee8f081 app/src/ui/changes/commit-message.tsx - our 100644 0a0e18fc9f4c8956a648726827dc496f3d5f98db app/src/ui/changes/commit-message.tsx - their 100644 0fad97ef7ca35381fc99f37f1b2e88ab7b5b57b0 app/src/ui/changes/commit-message.tsx -@@ -229,6 +229,11 @@ - } - - private onSubmit = () => { -+ setTimeout(() => { -+ console.log(this) -+ this.props.dispatcher.setDivergingBannerVisible(true) -+ }, 2000) -+ - this.createCommit() - } - -changed in both - base 100644 6744747929eeb10cd3e1a1e162d12f05d11612bc app/src/ui/history/compare.tsx - our 100644 c0be0e26ce79b9a590edfa3a9fd3718fa58782d4 app/src/ui/history/compare.tsx - their 100644 a22e1c207edbc9210db2ac711fedfda6e93fd2b0 app/src/ui/history/compare.tsx -@@ -24,12 +24,16 @@ - import { SelectionSource } from '../lib/filter-list' - import { IMatches } from '../../lib/fuzzy-find' - import { Ref } from '../lib/ref' -+<<<<<<< .our - import { - NewCommitsBanner, - DismissalReason, - } from '../notification/new-commits-banner' - import { enableNotificationOfBranchUpdates } from '../../lib/feature-flag' - import { MergeCallToAction } from './merge-call-to-action' -+======= -+import { NotificationBanner } from '../notification-banner'; -+>>>>>>> .their - - interface ICompareSidebarProps { - readonly repository: Repository -@@ -152,6 +156,7 @@ - - return ( - <div id="compare-view"> -+<<<<<<< .our - <CSSTransitionGroup - transitionName="diverge-banner" - transitionAppear={true} -@@ -161,6 +166,9 @@ - > - {this.renderNotificationBanner()} - </CSSTransitionGroup> -+======= -+ <NotificationBanner /> -+>>>>>>> .their - - <div className="compare-form"> - <FancyTextBox -added in remote - their 100644 4546992a97ba5b9bd5aef3e6b724a81c6a26b398 app/src/ui/notification-banner/index.tsx -@@ -0,0 +1,36 @@ -+import * as React from 'react' -+import { ButtonGroup } from '../lib/button-group'; -+import { Button } from '../lib/button'; -+import { Ref } from '../lib/ref'; -+import { Octicon, OcticonSymbol } from '../octicons'; -+ -+interface INotificationBannerProps { -+} -+ -+export class NotificationBanner extends React.Component<INotificationBannerProps, {}> { -+ public render() { -+ return (<div className="notification-banner diverge-banner"> -+ <div className="notification-banner-content"> -+ <p> -+ Your branch is <strong>42 commits</strong> behind <Ref>origin/master</Ref> -+ </p> -+ -+ <a className="close" aria-label="Dismiss banner"> -+ <Octicon symbol={OcticonSymbol.x} /> -+ </a> -+ </div> -+ -+ <ButtonGroup> -+ <Button type="submit" onClick={this.noop}> -+ Merge... -+ </Button> -+ -+ <Button onClick={this.noop}> -+ Compare -+ </Button> -+ </ButtonGroup> -+ </div>) -+ } -+ -+ private noop = () => {} -+} -changed in both - base 100644 f56d583b254f9167699125105c753492fd59fa33 app/src/ui/repository.tsx - our 100644 efb00423012b8da0dfa5e8897acacaeb0a5e648a app/src/ui/repository.tsx - their 100644 913672d601bbe40dac1fbeaad0e2eb2132388d61 app/src/ui/repository.tsx -@@ -50,11 +50,15 @@ - */ - readonly onOpenInExternalEditor: (fullPath: string) => void - -+<<<<<<< .our - /** - * Determines if the notification banner and associated dot - * on this history tab will be rendered - */ - readonly isDivergingBranchBannerVisible: boolean -+======= -+ readonly hasDiverged: boolean -+>>>>>>> .their - } - - interface IRepositoryViewState { -@@ -111,7 +115,22 @@ - symbol={OcticonSymbol.primitiveDot} - /> - ) : null} -+<<<<<<< .our - </div> -+======= -+ </span> -+ -+ <span className="with-indicator"> -+ <span>History</span> -+ -+ {this.props.hasDiverged ? ( -+ <Octicon -+ className="indicator" -+ symbol={OcticonSymbol.primitiveDot} -+ /> -+ ) : null} -+ </span> -+>>>>>>> .their - </TabBar> - ) - } -changed in both - base 100644 2c54d4b7728a6487ddd3f6fd4ac7d7c641b10459 app/styles/_mixins.scss - our 100644 2547663981e9047637d8e4edf9b40db74c9d5c51 app/styles/_mixins.scss - their 100644 d8eaaa11ac3816418fae454ec2cda3dbb1647425 app/styles/_mixins.scss -@@ -3,4 +3,8 @@ - @import 'mixins/octicon-status'; - @import 'mixins/textboxish'; - @import 'mixins/checkboard-background'; -+<<<<<<< .our -+======= -+ -+>>>>>>> .their - @import 'mixins/close-button'; -changed in both - base 100644 e496a16bd915366f9b11d9d0e63a21a8732099f4 app/styles/ui/_dialog.scss - our 100644 94b86d54fb9b0314deb1ef48cc9e1466578ed390 app/styles/ui/_dialog.scss - their 100644 971c11206672d1816b1ce06c3629ffd4988e9371 app/styles/ui/_dialog.scss -added in both - our 100644 ec2aae86b8d44d23f35f56cb9684489301016d6b app/styles/ui/_notification-banner.scss - their 100644 46736e371cff3d4823c7e53d86d6ad4df0215b7d app/styles/ui/_notification-banner.scss -@@ -1,5 +1,6 @@ - @import '../mixins'; - -+<<<<<<< .our - .notification-banner + .compare-form { - border-top: var(--base-border); - } -@@ -30,21 +31,39 @@ - & + p { - margin-top: var(--spacing-half); - } -+======= -+.notification-banner { -+ padding: var(--spacing-half); -+ -+ &-content { -+ display: flex; -+ -+ p { -+ flex-grow: 1; -+>>>>>>> .their - } - } - - @include close-button; - - .ref-component { -+<<<<<<< .our - background: var(--notification-ref-background); -+======= -+>>>>>>> .their - word-break: normal; - } - - .close { -+<<<<<<< .our - position: absolute; - margin: 0; - top: var(--spacing); - right: var(--spacing); -+======= -+ flex-grow: 0; -+ margin: 0; -+>>>>>>> .their - text-align: center; - - .octicon { -@@ -54,6 +73,7 @@ - } - - .diverge-banner { -+<<<<<<< .our - margin: var(--spacing-half); - overflow: hidden; - -@@ -98,5 +118,23 @@ - .button-component { - margin-top: var(--spacing-half); - margin-right: var(--spacing-half); -+======= -+ p { -+ margin-top: 0; -+ } -+ -+ .button-group { -+ display: flex; -+ } -+ -+ .button-component { -+ flex: 1; -+ margin-right: var(--spacing-half); -+ -+ -+ &:last-of-type { -+ margin-right: 0; -+ } -+>>>>>>> .their - } - } diff --git a/app/test/fixtures/merge-parser/desktop/merge-drop-back-to-classic-api-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-drop-back-to-classic-api-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 7b63414ee3d..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-drop-back-to-classic-api-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,434 +0,0 @@ -added in remote - their 100644 a309d474e0ebfbd83ab04a460c27dd2b8906c4e8 .eslintignore -@@ -0,0 +1,3 @@ -+node_modules -+app/node_modules/ -+script/changelog/node_modules -\ No newline at end of file -merged - result 100644 22724fb6c88b57702fe40d191883a455f70b01a1 .prettierignore - our 100644 d247d9a68070ec5848c5feb83bddbfab02adbb6c .prettierignore -@@ -1,16 +1,17 @@ --out/ -+app/static/common -+app/test/fixtures - dist/ -+gemoji - node_modules/ -+out/ -+ - npm-debug.log - yarn-error.log --app/node_modules/ -+ - .DS_Store - .awcache - .idea/ - .eslintcache - --app/static/common --app/test/fixtures --gemoji - *.json - *.md -changed in both - base 100644 25df97959715b124e8108bef0b086939d7e328c9 package.json - our 100644 2006bfb748810f6ea8bdbd26edf7c09524a1388a package.json - their 100644 da16d51d663474cc2456eb1920c4d7974e7f82a3 package.json -@@ -10,6 +10,7 @@ - "test:unit": "ts-node script/unit-tests.ts", - "test:script": "mocha -t 10000 --require ts-node/register script/changelog/test/*.ts", - "test": "yarn test:unit && yarn test:script && yarn test:integration", -+<<<<<<< .our - "test:setup": "ts-node -P script/tsconfig.json script/test-setup.ts", - "test:review": "ts-node -P script/tsconfig.json script/test-review.ts", - "postinstall": "ts-node -P script/tsconfig.json script/post-install.ts", -@@ -19,6 +20,20 @@ - "compile:prod": "cross-env NODE_ENV=production parallel-webpack --config app/webpack.production.ts", - "build:dev": "yarn compile:dev && cross-env NODE_ENV=development ts-node -P script/tsconfig.json script/build.ts", - "build:prod": "yarn compile:prod && cross-env NODE_ENV=production ts-node -P script/tsconfig.json script/build.ts", -+======= -+ "test:setup": "ts-node script/test-setup.ts", -+ "test:review": "ts-node script/test-review.ts", -+ "postinstall": "yarn install-app && yarn install-changelog && yarn update-submodules && yarn compile:tslint", -+ "install-app": "cd app && yarn install --force && cd ..", -+ "install-changelog": "cd script/changelog && yarn install && cd ../..", -+ "update-submodules": "git submodule update --recursive --init", -+ "start": "cross-env NODE_ENV=development node script/start", -+ "start:prod": "cross-env NODE_ENV=production node script/start", -+ "compile:dev": "cross-env NODE_ENV=development parallel-webpack --config app/webpack.development.js", -+ "compile:prod": "cross-env NODE_ENV=production parallel-webpack --config app/webpack.production.js", -+ "build:dev": "yarn compile:dev && cross-env NODE_ENV=development ts-node script/build.ts", -+ "build:prod": "yarn compile:prod && cross-env NODE_ENV=production ts-node script/build.ts", -+>>>>>>> .their - "package": "ts-node -P script/tsconfig.json script/package.ts", - "generate-octicons": "ts-node -P script/tsconfig.json script/generate-octicons.ts", - "clean:tslint": "rimraf tslint-rules/*.js", -merged - result 100644 f723edfaa45b088c09cc8feef59b701e163fe639 script/changelog/api.ts - our 100644 9cd75d75226643dd9d12c9e42de23c33fdd44a8b script/changelog/api.ts -@@ -1,60 +1,129 @@ --import * as HTTPS from 'https' -+const octokit = require('@octokit/rest')({ -+ timeout: 0, -+ requestMedia: 'application/vnd.github.v3+json', -+ headers: { -+ 'User-Agent': 'what-the-changelog', -+ }, -+}) - --export interface IAPIPR { -+export interface IDesktopPullRequest { - readonly title: string - readonly body: string -+ readonly collaborators: ReadonlySet<string> -+ readonly commits: ReadonlyArray<string> - } - --type GraphQLResponse = { -- readonly data: { -- readonly repository: { -- readonly pullRequest: IAPIPR -- } -- } -+interface IAPIUser { -+ readonly login: string - } - --export function fetchPR(id: number): Promise<IAPIPR | null> { -- return new Promise((resolve, reject) => { -- const options: HTTPS.RequestOptions = { -- host: 'api.github.com', -- protocol: 'https:', -- path: '/graphql', -- method: 'POST', -- headers: { -- Authorization: `bearer ${process.env.GITHUB_ACCESS_TOKEN}`, -- 'User-Agent': 'what-the-changelog', -- }, -- } -+interface IAPIPullRequest { -+ readonly title: string -+ readonly body: string -+ readonly user: IAPIUser -+} -+ -+interface IAPICommit { -+ readonly sha: string -+ readonly author?: IAPIUser -+ readonly committer?: IAPIUser -+} - -- const request = HTTPS.request(options, response => { -- let received = '' -- response.on('data', chunk => { -- received += chunk -- }) -- -- response.on('end', () => { -- try { -- const json: GraphQLResponse = JSON.parse(received) -- const pr = json.data.repository.pullRequest -- resolve(pr) -- } catch (e) { -- resolve(null) -- } -- }) -+interface IAPITeam { -+ readonly name: string -+ readonly id: number -+} -+ -+interface IAPITeamMember { -+ readonly login: string -+} -+ -+// this account is assigned by GitHub as the committer for merged pull requests -+// and should be excluded from being considered an external contributor -+const webflowAccount = ['web-flow'] -+ -+export function initialize(token: string) { -+ octokit.authenticate({ -+ type: 'token', -+ token, -+ }) -+} -+ -+export async function getCoreTeamMembers(): Promise<ReadonlySet<string>> { -+ try { -+ let response = await octokit.orgs.getTeams({ -+ org: 'desktop', -+ per_page: 100, - }) -+ const teams: ReadonlyArray<IAPITeam> = response.data -+ const coreTeam = teams.find(t => t.name === 'Core') || null - -- const graphql = ` --{ -- repository(owner: "desktop", name: "desktop") { -- pullRequest(number: ${id}) { -- title -- body -+ if (coreTeam == null) { -+ console.error('Unable to find core team on API') -+ return new Set<string>() - } -+ -+ const id = coreTeam.id -+ -+ response = await octokit.orgs.getTeamMembers({ -+ id, -+ role: 'all', -+ per_page: 100, -+ }) -+ const members: ReadonlyArray<IAPITeamMember> = response.data -+ -+ return new Set(members.map(m => m.login).concat(webflowAccount)) -+ } catch (err) { -+ console.error('API lookup failed for getCoreTeamMembers', err) -+ return new Set<string>() - } - } --` -- request.write(JSON.stringify({ query: graphql })) - -- request.end() -- }) -+export async function fetchPR(id: number): Promise<IDesktopPullRequest | null> { -+ try { -+ const pullRequestResponse = await octokit.pullRequests.get({ -+ owner: 'desktop', -+ repo: 'desktop', -+ number: id, -+ }) -+ const { title, body } = pullRequestResponse.data as IAPIPullRequest -+ -+ let commitsResponse = await octokit.pullRequests.getCommits({ -+ owner: 'desktop', -+ repo: 'desktop', -+ number: id, -+ per_page: 100, -+ }) -+ -+ let data: Array<IAPICommit> = commitsResponse.data -+ while (octokit.hasNextPage(commitsResponse)) { -+ commitsResponse = await octokit.getNextPage(commitsResponse) -+ data = data.concat(commitsResponse.data) -+ } -+ -+ const collaborators = new Set<string>() -+ const commits = new Array<string>() -+ -+ for (const commit of data) { -+ const { sha, author, committer } = commit -+ -+ commits.push(sha) -+ if (author != null && !collaborators.has(author.login)) { -+ collaborators.add(author.login) -+ } -+ if (committer != null && !collaborators.has(committer.login)) { -+ collaborators.add(committer.login) -+ } -+ } -+ -+ return { -+ title: title, -+ body: body, -+ collaborators, -+ commits, -+ } -+ } catch (err) { -+ console.error('API lookup failed for fetchPR', err) -+ return null -+ } - } -added in remote - their 100644 2b223d9eca4c82f03969d8ca5d9d8a80a270a041 script/changelog/package.json -@@ -0,0 +1,24 @@ -+{ -+ "name": "changelog", -+ "repository": { -+ "type": "git", -+ "url": "https://github.com/desktop/desktop.git" -+ }, -+ "description": "GitHub Desktop changelog dependencies", -+ "author": { -+ "name": "GitHub, Inc.", -+ "email": "opensource+desktop@github.com", -+ "url": "https://desktop.github.com/" -+ }, -+ "license": "MIT", -+ "engines": { -+ "node": ">= 7", -+ "yarn": ">= 1.2.0" -+ }, -+ "dependencies": { -+ "@octokit/rest": "^14.0.8", -+ "listify": "^1.0.0" -+ }, -+ "devDependencies": { -+ } -+} -changed in both - base 100644 b0a88cf77391d915e28566a1695cbf31c2ab7bbb script/changelog/parser.ts - our 100644 9151c4beab26fe203f7b045e0c32eb99f2da72ce script/changelog/parser.ts - their 100644 ff08e0ef253ffb980b0ed57114f9fefea05d7fc1 script/changelog/parser.ts -@@ -2,10 +2,11 @@ - import * as Fs from 'fs' - import { gt as greaterThan } from 'semver' - --import { fetchPR, IAPIPR } from './api' -+import { fetchPR, IDesktopPullRequest } from './api' -+ -+const listify: (values: Array<any>) => string = require('listify') - - const PlaceholderChangeType = '???' --const OfficialOwner = 'desktop' - - const ChangelogEntryRegex = /^\[(new|fixed|improved|removed|added)\]\s(.*)/i - -@@ -55,7 +56,11 @@ - return issueRef - } - --function getChangelogEntry(commit: IParsedCommit, pr: IAPIPR): string { -+function getChangelogEntry( -+ commit: IParsedCommit, -+ pr: IDesktopPullRequest, -+ externalContributors: ReadonlySet<string> -+): string { - let type = PlaceholderChangeType - const description = capitalized(pr.title) - -@@ -68,15 +73,19 @@ - } - - let attribution = '' -- if (commit.owner !== OfficialOwner) { -- attribution = `. Thanks @${commit.owner}!` -+ -+ if (externalContributors.size > 0) { -+ const mentions = [...externalContributors].map(c => `@${c}`) -+ const combinedMentions = listify(mentions) -+ attribution = `. Thanks ${combinedMentions}!` - } - - return `[${type}] ${description} -${issueRef}${attribution}` - } - - export async function convertToChangelogFormat( -- lines: ReadonlyArray<string> -+ lines: ReadonlyArray<string>, -+ coreMembers: ReadonlySet<string> - ): Promise<ReadonlyArray<string>> { - const entries = [] - for (const line of lines) { -@@ -87,7 +96,13 @@ - throw new Error(`Unable to get PR from API: ${commit.prID}`) - } - -- const entry = getChangelogEntry(commit, pr) -+ const collaborators = pr.collaborators -+ -+ const externalContributors = new Set( -+ [...collaborators].filter(c => !coreMembers.has(c)) -+ ) -+ -+ const entry = getChangelogEntry(commit, pr, externalContributors) - entries.push(entry) - } catch (e) { - console.warn('Unable to parse line, using the full message.', e) -merged - result 100644 8259a4c42f949aa6b07249546bddad9e5a341816 script/changelog/run.ts - our 100644 d324476ff6f0b766693c2b4c2aa8656852a3a4f8 script/changelog/run.ts -@@ -1,4 +1,5 @@ - import { spawn } from './spawn' -+import { getCoreTeamMembers } from './api' - import { getLogLines } from './git' - import { convertToChangelogFormat } from './parser' - import { sort as semverSort } from 'semver' -@@ -47,7 +48,8 @@ - ) - } - -+ const coreMembers = await getCoreTeamMembers() - const lines = await getLogLines(previousVersion) -- const changelogEntries = await convertToChangelogFormat(lines) -+ const changelogEntries = await convertToChangelogFormat(lines, coreMembers) - console.log(jsonStringify(changelogEntries)) - } -added in remote - their 100644 05d54aba4df2a44bee37177eebc9e559e391e602 script/changelog/yarn.lock -@@ -0,0 +1,48 @@ -+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -+# yarn lockfile v1 -+ -+ -+"@octokit/rest@^14.0.8": -+ version "14.0.9" -+ resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-14.0.9.tgz#d5e0a00dcb78901dd7b2ef852acfc0aea7c479ef" -+ dependencies: -+ before-after-hook "^1.1.0" -+ debug "^3.1.0" -+ is-array-buffer "^1.0.0" -+ is-stream "^1.1.0" -+ lodash "^4.17.4" -+ url-template "^2.0.8" -+ -+before-after-hook@^1.1.0: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-1.1.0.tgz#83165e15a59460d13702cb8febd6a1807896db5a" -+ -+debug@^3.1.0: -+ version "3.1.0" -+ resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" -+ dependencies: -+ ms "2.0.0" -+ -+is-array-buffer@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-1.0.0.tgz#f32497a0509d109423f472003f98bab6a8ea34cb" -+ -+is-stream@^1.1.0: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" -+ -+listify@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/listify/-/listify-1.0.0.tgz#03ca7ba2d150d4267773f74e57558d1053d2bee3" -+ -+lodash@^4.17.4: -+ version "4.17.5" -+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" -+ -+ms@2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" -+ -+url-template@^2.0.8: -+ version "2.0.8" -+ resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21" -changed in both - base 100644 c017ace71061eb0f6db7f42290cb63cca40ab5cb script/draft-release/run.ts - our 100644 9c6f2a3aa1c3766de5635266d05f85bf4131e499 script/draft-release/run.ts - their 100644 bcb2b3c76a15cdcae1cdb7f5d26d02e9e8ce9935 script/draft-release/run.ts -@@ -6,6 +6,7 @@ - convertToChangelogFormat, - getChangelogEntriesSince, - } from '../changelog/parser' -+import { getCoreTeamMembers, initialize } from '../changelog/api' - - import { Channel } from './channel' - import { getNextVersionNumber } from './version' -@@ -88,7 +89,10 @@ - if (noChangesFound) { - printInstructions(nextVersion, []) - } else { -- const changelogEntries = await convertToChangelogFormat(lines) -+ initialize(process.env.GITHUB_ACCESS_TOKEN) -+ -+ const coreMembers = await getCoreTeamMembers() -+ const changelogEntries = await convertToChangelogFormat(lines, coreMembers) - - console.log("Here's what you should do next:\n") - diff --git a/app/test/fixtures/merge-parser/desktop/merge-experiment-file-watcher-on-lock-file-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-experiment-file-watcher-on-lock-file-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 502a05723cb..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-experiment-file-watcher-on-lock-file-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,208 +0,0 @@ -changed in both - base 100644 dfd9598f71c569e16f2a43e5ea61638af55c7417 app/src/lib/app-state.ts - our 100644 b30f0fe080d909b81d2fb683ceb8deb365fb0191 app/src/lib/app-state.ts - their 100644 ee5e509a6fae15273535d5e9f076be72dc7dea74 app/src/lib/app-state.ts -@@ -385,6 +385,9 @@ - /** Is a commit in progress? */ - readonly isCommitting: boolean - -+ /** Is the index lockfile currently present in the repository? */ -+ readonly isIndexLocked: boolean -+ - /** The date the repository was last fetched. */ - readonly lastFetched: Date | null - -removed in local - base 100644 c73d6ac64904f79320bb3aab8699dd2051c26f34 app/src/lib/dispatcher/app-store.ts - their 100644 228a09b7eb27d2a0ed7ffe421a0641b94b3ffca4 app/src/lib/dispatcher/app-store.ts -added in remote - their 100644 daacbb89a9229bdb2cc38953916cb8efcf223cf3 app/src/lib/dispatcher/index-watcher.ts -@@ -0,0 +1,92 @@ -+import { Repository } from '../../models/repository' -+import { EventEmitter } from 'events' -+import * as Path from 'path' -+import * as Fs from 'fs' -+ -+/** -+ * A component designed to monitor the repository filesystem for events -+ * involving the index.lock file. These events are raised using EventEmitter -+ * so the application can detect the presence of the lock file and prevent -+ * the user from committing at this time. -+ * -+ * This work leverages knowledge from reading the source of `file-watcher` -+ * (https://github.com/xpensia/file-watcher/) without requiring the full -+ * API surface. -+ */ -+export class IndexWatcher extends EventEmitter { -+ private readonly gitDir: string -+ -+ private watcher: Fs.FSWatcher | null -+ -+ public constructor(repository: Repository) { -+ super() -+ -+ this.gitDir = Path.join(repository.path, '.git') -+ } -+ -+ public on( -+ event: 'index-changed', -+ listener: (isIndexLocked: boolean) => void -+ ): this { -+ return super.on(event, listener) -+ } -+ -+ private onChanged = (isIndexLocked: boolean) => { -+ this.emit('index-changed', isIndexLocked) -+ } -+ -+ private onChange = (event: string, filename: string) => { -+ const isValidPath = filename === 'index.lock' -+ if (!isValidPath) { -+ return -+ } -+ -+ Fs.stat(Path.join(this.gitDir, filename), (err, stats) => { -+ if (err) { -+ if (err.code === 'ENOENT') { -+ this.onChanged(false) -+ } else { -+ log.warn('IndexWatcher encounted an unexpected error', err) -+ } -+ return -+ } -+ -+ if (event === 'rename') { -+ this.onChanged(true) -+ return -+ } -+ -+ log.warn(`IndexWatcher did not handle event '${event}'`) -+ }) -+ } -+ -+ /** -+ * Start monitoring the git directory for index.lock changes. -+ * -+ * Will error if the .git directory doesn't exist, or if the path provided -+ * isn't a valid repository. -+ */ -+ public start() { -+ Fs.stat(this.gitDir, (err, stats) => { -+ if (err) { -+ throw err -+ } -+ -+ if (!stats.isDirectory()) { -+ throw new Error('IndexWatcher not configured to watch a directory') -+ } -+ -+ this.watcher = Fs.watch(this.gitDir, this.onChange) -+ }) -+ } -+ -+ /** -+ * Stop the watcher and cleanup any internal resources. -+ */ -+ public stop() { -+ if (this.watcher) { -+ this.watcher.close() -+ this.watcher = null -+ } -+ } -+} -changed in both - base 100644 0eb8418eb61309fccbf76303843a677fd8da9155 app/src/ui/changes/changes-list.tsx - our 100644 f785abb2624c245a3387a304168d5fc629e1430e app/src/ui/changes/changes-list.tsx - their 100644 f999c5420b7f1df504123231fc9b41266641fd2b app/src/ui/changes/changes-list.tsx -@@ -63,6 +63,7 @@ - readonly dispatcher: Dispatcher - readonly availableWidth: number - readonly isCommitting: boolean -+ readonly isIndexLocked: boolean - - /** - * Click event handler passed directly to the onRowClick prop of List, see -@@ -405,8 +406,12 @@ - contextualCommitMessage={this.props.contextualCommitMessage} - autocompletionProviders={this.props.autocompletionProviders} - isCommitting={this.props.isCommitting} -+<<<<<<< .our - showCoAuthoredBy={this.props.showCoAuthoredBy} - coAuthors={this.props.coAuthors} -+======= -+ isIndexLocked={this.props.isIndexLocked} -+>>>>>>> .their - /> - </div> - ) -changed in both - base 100644 c620c6fd1f272a657ced3a46eb7f0dede18f1207 app/src/ui/changes/commit-message.tsx - our 100644 0a0e18fc9f4c8956a648726827dc496f3d5f98db app/src/ui/changes/commit-message.tsx - their 100644 07cbd6984c2fbdfc0dfc7a3d9daa486314f58420 app/src/ui/changes/commit-message.tsx -@@ -49,6 +49,7 @@ - readonly dispatcher: Dispatcher - readonly autocompletionProviders: ReadonlyArray<IAutocompletionProvider<any>> - readonly isCommitting: boolean -+<<<<<<< .our - - /** - * Whether or not to show a field for adding co-authors to -@@ -64,6 +65,9 @@ - * the user has chosen to do so. - */ - readonly coAuthors: ReadonlyArray<IAuthor> -+======= -+ readonly isIndexLocked: boolean -+>>>>>>> .their - } - - interface ICommitMessageState { -@@ -470,7 +474,8 @@ - - public render() { - const branchName = this.props.branch ? this.props.branch : 'master' -- const buttonEnabled = this.canCommit() && !this.props.isCommitting -+ const buttonEnabled = -+ this.canCommit() && !this.props.isCommitting && !this.props.isIndexLocked - - const loading = this.props.isCommitting ? <Loading /> : undefined - const className = classNames({ -changed in both - base 100644 d950085a2ba2550df97783b087eab331cf671410 app/src/ui/changes/sidebar.tsx - our 100644 ff1760bbd4b1a3d5ea8ac084b1282e99b2ea288b app/src/ui/changes/sidebar.tsx - their 100644 12a7a87c27d9d551e2216ff5709dcf4fa6728d98 app/src/ui/changes/sidebar.tsx -@@ -46,6 +46,7 @@ - readonly isCommitting: boolean - readonly isPushPullFetchInProgress: boolean - readonly gitHubUserStore: GitHubUserStore -+ readonly isIndexLocked: boolean - readonly askForConfirmationOnDiscardChanges: boolean - readonly accounts: ReadonlyArray<Account> - /** The name of the currently selected external editor */ -@@ -310,10 +311,14 @@ - availableWidth={this.props.availableWidth} - onIgnore={this.onIgnore} - isCommitting={this.props.isCommitting} -+<<<<<<< .our - showCoAuthoredBy={this.props.changes.showCoAuthoredBy} - coAuthors={this.props.changes.coAuthors} - externalEditorLabel={this.props.externalEditorLabel} - onOpenInExternalEditor={this.props.onOpenInExternalEditor} -+======= -+ isIndexLocked={this.props.isIndexLocked} -+>>>>>>> .their - /> - {this.renderMostRecentLocalCommit()} - </div> -changed in both - base 100644 5a428da019fc9c742d02e758a0503288463be322 app/src/ui/repository.tsx - our 100644 efb00423012b8da0dfa5e8897acacaeb0a5e648a app/src/ui/repository.tsx - their 100644 043bc5e7ba3cbc056ba3242f20b6dbcf547fd314 app/src/ui/repository.tsx -@@ -145,6 +145,7 @@ - availableWidth={availableWidth} - gitHubUserStore={this.props.gitHubUserStore} - isCommitting={this.props.state.isCommitting} -+ isIndexLocked={this.props.state.isIndexLocked} - isPushPullFetchInProgress={this.props.state.isPushPullFetchInProgress} - askForConfirmationOnDiscardChanges={ - this.props.askForConfirmationOnDiscardChanges diff --git a/app/test/fixtures/merge-parser/desktop/merge-experimental-ssh-setup-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-experimental-ssh-setup-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 9f7a09905f8..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-experimental-ssh-setup-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,3013 +0,0 @@ -changed in both - base 100644 e4c97b5a507a78e0ae64a236e85f2a97f14a166a app/package.json - our 100644 4ec686d8ad22d3aea1ebe4bddd16f4a7447c3acd app/package.json - their 100644 959ed4ff23f809e1ed2250f1a705a22c8658c0e8 app/package.json -@@ -37,6 +37,7 @@ - "moment": "^2.17.1", - "mri": "^1.1.0", - "primer-support": "^4.0.0", -+ "process-exists": "^3.1.0", - "queue": "^4.4.2", - "react": "^16.3.2", - "react-addons-shallow-compare": "^15.6.2", -changed in both - base 100644 d4b62dbf30e18eb25f0eab0014d38984b1e80c6c app/src/lib/api.ts - our 100644 e77c79b5d20fbcffe9af534504dac98509135263 app/src/lib/api.ts - their 100644 0a507731c02eea0a0511eeddfb8e27ad24cda726 app/src/lib/api.ts -@@ -25,7 +25,7 @@ - } - - /** The OAuth scopes we need. */ --const Scopes = ['repo', 'user'] -+const Scopes = ['repo', 'user', 'write:public_key'] - - enum HttpStatusCode { - NotModified = 304, -@@ -183,6 +183,7 @@ - /** The partial server response when creating a new authorization on behalf of a user */ - interface IAPIAuthorization { - readonly token: string -+ readonly scopes: ReadonlyArray<string> - } - - /** The response we receive from fetching mentionables. */ -@@ -196,6 +197,16 @@ - readonly items: ReadonlyArray<T> - } - -+interface IAPIPublicKey { -+ id: number -+ key: string -+ url: string -+ title: string -+ verified: boolean -+ created_at: string -+ read_only: boolean -+} -+ - /** - * Parses the Link header from GitHub and returns the 'next' path - * if one is present. -@@ -232,6 +243,11 @@ - return date.toISOString().replace(/\.\d{3}Z$/, 'Z') - } - -+type UserWithTokenScopes = { -+ user: IAPIUser -+ scopes: ReadonlyArray<string> -+} -+ - /** - * An object for making authenticated requests to the GitHub API - */ -@@ -280,12 +296,18 @@ - } - } - -- /** Fetch the logged in account. */ -- public async fetchAccount(): Promise<IAPIUser> { -+ /** Fetch the logged in account and the current scopes associated with the token. */ -+ public async fetchAccount(): Promise<UserWithTokenScopes> { - try { - const response = await this.request('GET', 'user') -- const result = await parsedResponse<IAPIUser>(response) -- return result -+ const user = await parsedResponse<IAPIUser>(response) -+ const scopeHeader = response.headers.get('X-OAuth-Scopes') -+ const scopes = -+ scopeHeader == null -+ ? [] -+ : scopeHeader.split(',').map(scope => scope.trim()) -+ -+ return { user, scopes } - } catch (e) { - log.warn(`fetchAccount: failed with endpoint ${this.endpoint}`, e) - throw e -@@ -577,6 +599,27 @@ - throw e - } - } -+ -+ public async createPublicKey( -+ title: string, -+ key: string -+ ): Promise<IAPIPublicKey | null> { -+ try { -+ const response = await this.request('POST', `user/keys`, { -+ title, -+ key, -+ }) -+ -+ if (response.status === 404) { -+ return null -+ } -+ -+ return await parsedResponse<IAPIPublicKey>(response) -+ } catch (e) { -+ log.warn(`createPublicKey: failed with endpoint ${this.endpoint}`, e) -+ throw e -+ } -+ } - } - - export enum AuthorizationResponseKind { -@@ -711,7 +754,7 @@ - ): Promise<Account> { - const api = new API(endpoint, token) - try { -- const user = await api.fetchAccount() -+ const { user, scopes } = await api.fetchAccount() - const emails = await api.fetchEmails() - const defaultEmail = emails[0].email || '' - const avatarURL = getAvatarWithEnterpriseFallback( -@@ -726,7 +769,8 @@ - emails, - avatarURL, - user.id, -- user.name || user.login -+ user.name || user.login, -+ scopes - ) - } catch (e) { - log.warn(`fetchUser: failed with endpoint ${endpoint}`, e) -changed in both - base 100644 86b3c6de0194dc7492ad693937f515e539e85002 app/src/lib/app-state.ts - our 100644 b30f0fe080d909b81d2fb683ceb8deb365fb0191 app/src/lib/app-state.ts - their 100644 60f91ffa3783d076aaaf5f5b83ee6df48fa3af87 app/src/lib/app-state.ts -@@ -27,7 +27,11 @@ - import { PullRequest } from '../models/pull-request' - import { IAuthor } from '../models/author' - import { ComparisonCache } from './comparison-cache' -+<<<<<<< .our - import { ApplicationTheme } from '../ui/lib/application-theme' -+======= -+import { TroubleshootingState } from '../models/ssh' -+>>>>>>> .their - - export { ICommitMessage } - -@@ -89,6 +93,8 @@ - */ - readonly signInState: SignInState | null - -+ readonly troubleshootingState: TroubleshootingState | null -+ - /** - * The current state of the window, ie maximized, minimized full-screen etc. - */ -@@ -222,7 +228,11 @@ - LFSAttributeMismatch, - UpstreamAlreadyExists, - DeletePullRequest, -+<<<<<<< .our - MergeConflicts, -+======= -+ TroubleshootSSH, -+>>>>>>> .their - } - - export type Popup = -@@ -301,7 +311,14 @@ - branch: Branch - pullRequest: PullRequest - } -+<<<<<<< .our - | { type: PopupType.MergeConflicts; repository: Repository } -+======= -+ | { -+ type: PopupType.TroubleshootSSH -+ repository: Repository -+ } -+>>>>>>> .their - - export enum FoldoutType { - Repository, -changed in both - base 100644 760b02c3045adfd175c5e95574dedb44b6d391b8 app/src/lib/dispatcher/dispatcher.ts - our 100644 5e56c00e713342e76f5ccba040062e322e8c90cb app/src/lib/dispatcher/dispatcher.ts - their 100644 e5b1337149f1d811958144452169a9a4e26b8947 app/src/lib/dispatcher/dispatcher.ts -@@ -56,8 +56,12 @@ - import { PullRequest } from '../../models/pull-request' - import { IAuthor } from '../../models/author' - import { ITrailer } from '../git/interpret-trailers' -+<<<<<<< .our - import { isGitRepository } from '../git' - import { ApplicationTheme } from '../../ui/lib/application-theme' -+======= -+import { IValidateHostState, INoRunningAgentState } from '../../models/ssh' -+>>>>>>> .their - - /** - * An error handler function. -@@ -1238,6 +1242,7 @@ - return this.appStore._recordCompareInitiatedMerge() - } - -+<<<<<<< .our - /** - * Set the application-wide theme - */ -@@ -1300,5 +1305,35 @@ - */ - public recordDivergingBranchBannerInitatedMerge() { - return this.appStore._recordDivergingBranchBannerInitatedMerge() -+======= -+ public resetTroubleshooting() { -+ return this.appStore._resetTroubleshooting() -+ } -+ -+ public startTroubleshooting(repository: Repository) { -+ return this.appStore._startTroubleshooting(repository) -+ } -+ -+ public validateHost(state: IValidateHostState) { -+ return this.appStore._validateHost(state) -+ } -+ -+ public launchSSHAgent(state: INoRunningAgentState) { -+ return this.appStore._launchSSHAgent(state) -+ } -+ -+ public createSSHKey( -+ account: Account, -+ emailAddress: string, -+ passphrase: string, -+ outputFile: string -+ ) { -+ return this.appStore._createSSHKey( -+ account, -+ emailAddress, -+ passphrase, -+ outputFile -+ ) -+>>>>>>> .their - } - } -changed in both - base 100644 e4bcde44c63c77e4be9175742b2312202cb79018 app/src/lib/dispatcher/error-handlers.ts - our 100644 850a08047c6abd12850890e02ebd7c4b6085d2ce app/src/lib/dispatcher/error-handlers.ts - their 100644 87abc60a0527d53cb5cda45ff2eadc3cde45e320 app/src/lib/dispatcher/error-handlers.ts -@@ -245,6 +245,45 @@ - return error - } - -+export async function sshAuthenticationErrorHandler( -+ error: Error, -+ dispatcher: Dispatcher -+): Promise<Error | null> { -+ const e = asErrorWithMetadata(error) -+ if (!e) { -+ return error -+ } -+ -+ const gitError = asGitError(e.underlyingError) -+ if (!gitError) { -+ return error -+ } -+ -+ const dugiteError = gitError.result.gitError -+ if (!dugiteError) { -+ return error -+ } -+ -+ const repository = e.metadata.repository -+ if (!(repository instanceof Repository)) { -+ return error -+ } -+ -+ if ( -+ dugiteError === DugiteError.SSHAuthenticationFailed || -+ dugiteError === DugiteError.SSHPermissionDenied || -+ dugiteError === DugiteError.SSHRepositoryNotFound -+ ) { -+ dispatcher.showPopup({ -+ type: PopupType.TroubleshootSSH, -+ repository, -+ }) -+ return null -+ } -+ -+ return error -+} -+ - /** - * Handler for detecting when a merge conflict is reported to direct the user - * to a different dialog than the generic Git error dialog. -changed in both - base 100644 e769a502c81a2d83efba958ed0cd6adfb4da8de7 app/src/lib/feature-flag.ts - our 100644 716a3c2396b0db5e84ec87d6529001e633b08700 app/src/lib/feature-flag.ts - their 100644 52379a9a2bd9f52206d8252ba3073fd4cb055332 app/src/lib/feature-flag.ts -@@ -41,3 +41,8 @@ - export function enableRepoInfoIndicators(): boolean { - return true - } -+ -+/** Should Desktop use the new troubleshooting flow */ -+export function enableSSHTroubleshooting(): boolean { -+ return enableDevelopmentFeatures() -+} -added in remote - their 100644 67ec5ef544b4aa1f52130a728004e6549699d5ed app/src/lib/find-executable.ts -@@ -0,0 +1,106 @@ -+import { spawn } from 'child_process' -+import * as Path from 'path' -+ -+export function isExecutableOnPath(executableName: string): Promise<boolean> { -+ // adapted from http://stackoverflow.com/a/34953561/1363815 -+ if (__WIN32__) { -+ return new Promise<boolean>((resolve, reject) => { -+ const windowsRoot = process.env.SystemRoot || 'C:\\Windows' -+ const wherePath = Path.join(windowsRoot, 'System32', 'where.exe') -+ -+ const cp = spawn(wherePath, [executableName]) -+ -+ cp.on('error', error => { -+ log.warn('Unable to spawn where.exe', error) -+ resolve(false) -+ }) -+ -+ // `where` will return 0 when the executable -+ // is found under PATH, or 1 if it cannot be found -+ cp.on('close', function(code) { -+ resolve(code === 0) -+ }) -+ return -+ }) -+ } -+ -+ if (__LINUX__ || __DARWIN__) { -+ return new Promise<boolean>((resolve, reject) => { -+ const process = spawn('which', [executableName]) -+ -+ // `which` will return 0 when the executable -+ // is found under PATH, or 1 if it cannot be found -+ process.on('close', function(code) { -+ resolve(code === 0) -+ }) -+ }) -+ } -+ -+ return Promise.resolve(false) -+} -+ -+export function findExecutableOnPath( -+ executableName: string -+): Promise<string | null> { -+ // adapted from http://stackoverflow.com/a/34953561/1363815 -+ if (__WIN32__) { -+ return new Promise<string | null>((resolve, reject) => { -+ const windowsRoot = process.env.SystemRoot || 'C:\\Windows' -+ const wherePath = Path.join(windowsRoot, 'System32', 'where.exe') -+ -+ const stdoutChunks = new Array<Buffer>() -+ let totalStdoutLength = 0 -+ -+ const cp = spawn(wherePath, [executableName]) -+ -+ cp.stdout.on('data', (chunk: Buffer) => { -+ stdoutChunks.push(chunk) -+ totalStdoutLength += chunk.length -+ }) -+ -+ cp.on('error', error => { -+ log.warn('Unable to spawn where.exe', error) -+ resolve(null) -+ }) -+ -+ // `where` will return 0 when the executable -+ // is found under PATH, or 1 if it cannot be found -+ cp.on('close', function(code) { -+ if (code === 0) { -+ const stdout = Buffer.concat(stdoutChunks, totalStdoutLength) -+ resolve(stdout.toString().trim()) -+ } else { -+ resolve(null) -+ } -+ }) -+ return -+ }) -+ } -+ -+ if (__LINUX__ || __DARWIN__) { -+ return new Promise<string | null>((resolve, reject) => { -+ const cp = spawn('which', [executableName]) -+ -+ const stdoutChunks = new Array<Buffer>() -+ let totalStdoutLength = 0 -+ -+ cp.stdout.on('data', (chunk: Buffer) => { -+ stdoutChunks.push(chunk) -+ totalStdoutLength += chunk.length -+ }) -+ -+ // `which` will return 0 when the executable -+ // is found under PATH, or 1 if it cannot be found -+ cp.on('close', function(code) { -+ if (code === 0) { -+ const stdout = Buffer.concat(stdoutChunks, totalStdoutLength) -+ resolve(stdout.toString().trim()) -+ } else { -+ resolve(null) -+ } -+ }) -+ }) -+ } -+ -+ return Promise.resolve(null) -+} -merged - result 100644 2b2c3d048d963952969093e5e38c94ce827169bf app/src/lib/git/authentication.ts - our 100644 1b3e09da9e0ab747b09e736a7ba2b66f2eef892d app/src/lib/git/authentication.ts -@@ -23,6 +23,7 @@ - // for credentials - even as a fallback - GIT_TERMINAL_PROMPT: '0', - GIT_TRACE: localStorage.getItem('git-trace') || '0', -+ GIT_SSH_COMMAND: `ssh -o 'StrictHostKeyChecking=yes'`, - } - - if (!auth) { -changed in both - base 100644 25f5e58c8ceb7199146a603c42fbb7d88e6c431c app/src/lib/is-git-on-path.ts - our 100644 efb13fb0c1c8db7af2da3feffa6157cdfcffc386 app/src/lib/is-git-on-path.ts - their 100644 fdc939e8402b7dc507bb3ef4f052a34937eb90cc app/src/lib/is-git-on-path.ts -@@ -1,5 +1,4 @@ --import { spawn } from 'child_process' --import * as Path from 'path' -+import { isExecutableOnPath } from './find-executable' - - export function isGitOnPath(): Promise<boolean> { - // Modern versions of macOS ship with a Git shim that guides you through -@@ -9,6 +8,7 @@ - return Promise.resolve(true) - } - -+<<<<<<< .our - // adapted from http://stackoverflow.com/a/34953561/1363815 - if (__WIN32__) { - return new Promise<boolean>((resolve, reject) => { -@@ -44,4 +44,7 @@ - } - - return Promise.resolve(false) -+======= -+ return isExecutableOnPath('git') -+>>>>>>> .their - } -added in remote - their 100644 ea4fc79f187ec4f921bf7600b52adab38e48442f app/src/lib/ssh/error-parsing.ts -@@ -0,0 +1,36 @@ -+type HostVerificationError = { -+ host: string -+ fingerprint: string -+ rawOutput: string -+} -+ -+export function isHostVerificationError( -+ stderr: string -+): HostVerificationError | null { -+ const noValidHostKeyFoundRe = /No RSA host key is known for (.*) and you have requested strict checking/ -+ const hostMatch = noValidHostKeyFoundRe.exec(stderr) -+ -+ if (hostMatch == null) { -+ return null -+ } -+ -+ const host = hostMatch[1] -+ -+ const fingerprintRe = /Server host key: (.*) (.*)/ -+ const match = fingerprintRe.exec(stderr) -+ -+ if (match == null) { -+ log.debug(`Server host key entry was not found in output from ssh process`) -+ return null -+ } -+ -+ const fingerprint = match[2] -+ const rawOutput = `The authenticity of host '${host}' can't be established.\nRSA key fingerprint is ${fingerprint}.` -+ -+ return { host, fingerprint, rawOutput } -+} -+ -+export function isPermissionError(stderr: string): boolean { -+ const permissionDeniedRe = /.*: Permission denied \(publickey\)\./ -+ return permissionDeniedRe.test(stderr) -+} -added in remote - their 100644 252e103b9ebbbde9bf6352e0c4e495a07ad6d393 app/src/lib/ssh/generate-log-file.ts -@@ -0,0 +1,29 @@ -+import { remote } from 'electron' -+import { writeFile } from 'fs' -+import * as moment from 'moment' -+ -+export function saveLogFile(stderr: string) { -+ const timestamp = moment().format('YYYYMMDD-HHmmss') -+ const defaultPath = `ssh-output-${timestamp}.txt` -+ -+ return new Promise<void>((resolve, reject) => { -+ // TODO: null should be a valid argument here -+ const window: any = null -+ remote.dialog.showSaveDialog(window, { defaultPath }, filename => { -+ if (filename == null) { -+ log.warn( -+ 'TODO: filename returned null, this needs to be in the signature' -+ ) -+ resolve() -+ } else { -+ writeFile(filename, stderr, err => { -+ if (err) { -+ reject(err) -+ } else { -+ resolve() -+ } -+ }) -+ } -+ }) -+ }) -+} -added in remote - their 100644 c9f1e7e1b70ece7d7159ab02d28cefd6291062e1 app/src/lib/ssh/index.ts -@@ -0,0 +1,5 @@ -+export * from './error-parsing' -+export * from './generate-log-file' -+export * from './ssh-interop' -+export * from './ssh-environment' -+export * from './ssh-agent-manager' -added in remote - their 100644 910bad4ec3c76032f4b6e3556e0a068e8ced9c79 app/src/lib/ssh/ssh-agent-manager.ts -@@ -0,0 +1,124 @@ -+import { exec } from 'child_process' -+ -+import { findExecutableOnPath } from '../find-executable' -+ -+const processExists = require('process-exists') -+ -+export enum AgentStateKind { -+ NotFound = 'NotFound', -+ NotStarted = 'NotStarted', -+ Running = 'Running', -+} -+ -+type AgentNotFoundState = { -+ readonly kind: AgentStateKind.NotFound -+} -+ -+type AgentNotStartedState = { -+ readonly kind: AgentStateKind.NotStarted -+ readonly executablePath: string -+} -+ -+type AgentRunningState = { -+ readonly kind: AgentStateKind.Running -+ readonly executablePath: string -+ readonly env: object -+} -+ -+export type AgentState = -+ | AgentNotFoundState -+ | AgentNotStartedState -+ | AgentRunningState -+ -+type SSHAgentProcess = { -+ readonly pid: number -+ readonly env: object -+} -+ -+export class SSHAgentManager { -+ private env: object = {} -+ private executablePath: string | null = null -+ -+ public async reset(): Promise<void> { -+ this.executablePath = await findExecutableOnPath('ssh-agent') -+ } -+ -+ public async getState(): Promise<AgentState> { -+ if (this.executablePath == null) { -+ return { kind: AgentStateKind.NotFound } -+ } -+ -+ const running: boolean = await processExists( -+ __WIN32__ ? 'ssh-agent.exe' : 'ssh-agent' -+ ) -+ -+ if (!running) { -+ return { -+ kind: AgentStateKind.NotStarted, -+ executablePath: this.executablePath, -+ } -+ } -+ -+ const existingEnv = process.env -+ if ( -+ existingEnv.SSH_AUTH_SOCK != null && -+ existingEnv.SSH_AGENT_PID != null -+ ) { -+ log.debug( -+ '[SSHAgentManager] found existing environment variables for SSH agent, using that...' -+ ) -+ this.env = { -+ SSH_AUTH_SOCK: existingEnv.SSH_AUTH_SOCK, -+ SSH_AGENT_PID: existingEnv.SSH_AGENT_PID, -+ } -+ } -+ -+ // TODO: get environment variable from shell without needing to poke at this? -+ // This looks interesting: -+ // https://github.com/wwalker/ssh-find-agent/blob/master/ssh-find-agent.sh -+ return { -+ kind: AgentStateKind.Running, -+ executablePath: this.executablePath, -+ env: this.env, -+ } -+ } -+ -+ public async launch(): Promise<SSHAgentProcess> { -+ if (this.executablePath == null) { -+ throw new Error( -+ `Unable to launch when the executable isn't found on the machine` -+ ) -+ } -+ -+ return new Promise<SSHAgentProcess>((resolve, reject) => { -+ let pid = 0 -+ const command = `"${this.executablePath}"` -+ const sshAgent = exec(command, (error, stdout, stderr) => { -+ if (error != null) { -+ reject(error) -+ return -+ } -+ -+ const sshAuthSocketRe = /SSH_AUTH_SOCK=(.*)\; export SSH_AUTH_SOCK;/ -+ const sshAgentPidRe = /SSH_AGENT_PID=(.*)\; export SSH_AGENT_PID;/ -+ -+ const sshAuthSockMatch = sshAuthSocketRe.exec(stdout) -+ const sshAgentPidMatch = sshAgentPidRe.exec(stdout) -+ -+ if (sshAuthSockMatch != null && sshAgentPidMatch != null) { -+ this.env = { -+ SSH_AUTH_SOCK: sshAuthSockMatch[1], -+ SSH_AGENT_PID: sshAgentPidMatch[1], -+ } -+ resolve({ pid, env: this.env }) -+ } else { -+ reject('Unable to retrieve environment variables from ssh-agent') -+ } -+ }) -+ pid = sshAgent.pid -+ -+ // TODO: do we need to do this? -+ sshAgent.unref() -+ }) -+ } -+} -added in remote - their 100644 9ad3ef0fd3d7a3f6a2d6d0db037a777f8892bc9c app/src/lib/ssh/ssh-environment.ts -@@ -0,0 +1,89 @@ -+import * as Path from 'path' -+import { enumerateValues, HKEY, RegistryValueType } from 'registry-js' -+import { pathExists } from 'fs-extra' -+ -+import { isExecutableOnPath } from '../find-executable' -+import { getPathSegments } from '../process/win32' -+ -+async function findGitForWindowsInstall(): Promise<string | null> { -+ const registryPath = enumerateValues( -+ HKEY.HKEY_LOCAL_MACHINE, -+ 'SOFTWARE\\GitForWindows' -+ ) -+ -+ if (registryPath.length === 0) { -+ return null -+ } -+ -+ const installPathEntry = registryPath.find(e => e.name === 'InstallPath') -+ if (installPathEntry && installPathEntry.type === RegistryValueType.REG_SZ) { -+ const path = Path.join(installPathEntry.data, 'git-bash.exe') -+ -+ if (await pathExists(path)) { -+ return installPathEntry.data -+ } else { -+ log.debug( -+ `[hasGitForWindowsInstall] registry entry found but git-bash.exe does not exist at '${path}'` -+ ) -+ } -+ } -+ -+ return null -+} -+ -+async function appendToPath(directory: string) { -+ const paths = await getPathSegments() -+ const updatedPaths = [...paths, directory] -+ const path = updatedPaths.join(';') -+ -+ const env = Object.assign({}, process.env, { path }) -+ -+ if (env.Path != null) { -+ // this is a stupid win32 hack because `Path` and `path` are distinct keys -+ // on a Javascript hash, but Windows will choose Path and ignore the other value -+ delete env.Path -+ } -+ -+ return env -+} -+ -+export async function getSSHEnvironment(executable: string, env: object = {}) { -+ // don't even bother checking for macOS as it should be there by default -+ if (__DARWIN__) { -+ return Object.assign({}, process.env, env) -+ } -+ -+ const found = await isExecutableOnPath(executable) -+ -+ if (found) { -+ // no need to setup our own environment, inherit the default -+ log.debug( -+ `[getSSHEnvironment] found ${executable} on PATH, no need to tweak the environment` -+ ) -+ return Object.assign({}, process.env, env) -+ } -+ -+ if (__LINUX__) { -+ log.warn( -+ '[getSSHEnvironment] TODO: what should we be doing for the Linux support?' -+ ) -+ return Object.assign({}, process.env, env) -+ } -+ -+ const foundGitInstall = await findGitForWindowsInstall() -+ if (foundGitInstall != null) { -+ const pathToSSHTools = Path.join(foundGitInstall, 'usr', 'bin') -+ return appendToPath(pathToSSHTools) -+ } -+ -+ const localGitDir = process.env['LOCAL_GIT_DIRECTORY'] -+ if (localGitDir != null) { -+ const pathToSSHTools = Path.join(localGitDir, 'usr', 'bin') -+ return appendToPath(pathToSSHTools) -+ } -+ -+ log.warn( -+ '[getSSHEnvironment] unable to find path to the embedded Git installation' -+ ) -+ return Object.assign({}, process.env, env) -+} -added in remote - their 100644 03fbed12881a6501b7f3fdf3c3316599d65e8ac1 app/src/lib/ssh/ssh-interop.ts -@@ -0,0 +1,152 @@ -+import { exec, spawn } from 'child_process' -+import { getSSHEnvironment } from './ssh-environment' -+ -+import { createWriteStream } from 'fs' -+import { homedir } from 'os' -+import { join } from 'path' -+ -+import { ensureDir } from 'fs-extra' -+ -+export async function scanAndWriteToKnownHostsFile( -+ host: string -+): Promise<void> { -+ const sshDir = join(homedir(), '.ssh') -+ await ensureDir(sshDir) -+ -+ const command = 'ssh-keyscan' -+ const env = await getSSHEnvironment(command) -+ -+ return new Promise<void>((resolve, reject) => { -+ const keyscan = spawn(command, [host], { shell: true, env }) -+ const knownHostsPath = join(homedir(), '.ssh', 'known_hosts') -+ -+ keyscan.stdout.pipe(createWriteStream(knownHostsPath)) -+ -+ keyscan.on('error', err => { -+ log.warn( -+ 'Unable to execute ssh-keyscan and append to known_hosts file', -+ err -+ ) -+ }) -+ -+ keyscan.on('close', code => { -+ if (code !== 0) { -+ reject( -+ new Error( -+ `ssh-keyscan exited with code '${code}' while adding '${host}' which was not expected` -+ ) -+ ) -+ return -+ } -+ resolve() -+ }) -+ }) -+} -+ -+type KeyGenResult = { -+ readonly publicKeyFile: string -+ readonly privateKeyFile: string -+} -+ -+export async function createSSHKey( -+ emailAddress: string, -+ passphrase: string, -+ outputFile: string -+): Promise<KeyGenResult> { -+ // TODO: ssh-keygen will block if the file exists - need to handle the situation here -+ const command = 'ssh-keygen' -+ const args = `${command} -b 4096 -t rsa -C '${emailAddress}' -N '${passphrase}' -f ${outputFile}` -+ const env = await getSSHEnvironment(command) -+ return new Promise<KeyGenResult>((resolve, reject) => { -+ exec(args, { timeout: 15000, env }, (error, stdout, stderr) => { -+ if (error != null) { -+ reject(error) -+ return -+ } -+ -+ const privateKeyFileRe = /Your identification has been saved in (.*)\./ -+ const publicKeyFileRe = /Your public key has been saved in (.*)\./ -+ -+ const privateKeyMatch = privateKeyFileRe.exec(stdout) -+ const publicKeyMatch = publicKeyFileRe.exec(stdout) -+ -+ if (privateKeyMatch && publicKeyMatch) { -+ resolve({ -+ publicKeyFile: publicKeyMatch[1], -+ privateKeyFile: privateKeyMatch[1], -+ }) -+ } else { -+ resolve({ publicKeyFile: '', privateKeyFile: '' }) -+ } -+ }) -+ }) -+} -+ -+export async function addToSSHAgent( -+ privateKeyFile: string, -+ passphrase: string, -+ sshEnvironment: object -+): Promise<void> { -+ const command = 'ssh-add' -+ const env = await getSSHEnvironment(command, sshEnvironment) -+ -+ return new Promise<void>((resolve, reject) => { -+ const sshAdd = spawn(command, [privateKeyFile], { shell: true, env }) -+ -+ const stdoutBuffers = new Array<Buffer>() -+ let stdoutLength = 0 -+ -+ sshAdd.stdout.on('data', (chunk: Buffer) => { -+ stdoutBuffers.push(chunk) -+ stdoutLength += chunk.length -+ }) -+ -+ const stderrBuffers = new Array<Buffer>() -+ let stderrLength = 0 -+ sshAdd.stderr.on('data', (chunk: Buffer) => { -+ stderrBuffers.push(chunk) -+ stderrLength += chunk.length -+ }) -+ -+ if (passphrase.length > 0) { -+ sshAdd.stdin.end(passphrase) -+ } -+ -+ sshAdd.on('close', code => { -+ const stdout = Buffer.concat(stdoutBuffers, stdoutLength) -+ const stderr = Buffer.concat(stderrBuffers, stderrLength) -+ -+ log.debug(`[addToSSHAgent] got stdout: '${stdout}'`) -+ log.debug(`[addToSSHAgent] got stderr: '${stderr}'`) -+ -+ debugger -+ -+ if (code !== 0) { -+ reject('Probably unable to pass in a passphrase with this coding trick') -+ } -+ resolve() -+ }) -+ }) -+} -+ -+export async function executeSSHTest( -+ sshUrl: string, -+ environmentVariables: object -+): Promise<string> { -+ const command = 'ssh' -+ const env = await getSSHEnvironment(command, environmentVariables) -+ return new Promise<string>((resolve, reject) => { -+ exec( -+ `${command} -Tv -o 'StrictHostKeyChecking=yes' ${sshUrl}`, -+ { timeout: 15000, env }, -+ (error, stdout, stderr) => { -+ if (error != null) { -+ // TODO: poke at these details, pass them through? -+ log.warn(`[executeSSHTest] - an error occurred when invoking ssh`) -+ } -+ -+ resolve(stderr) -+ } -+ ) -+ }) -+} -merged - result 100644 2d268b3d00e80a8fe7cf7aed2af48cfb2720e63d app/src/lib/stores/accounts-store.ts - our 100644 f11d691b980015ca4a257c25f28433f4a7514376 app/src/lib/stores/accounts-store.ts -@@ -43,6 +43,7 @@ - readonly avatarURL: string - readonly id: number - readonly name: string -+ readonly scopes?: ReadonlyArray<string> - } - - /** The store for logged in accounts. */ -@@ -182,7 +183,8 @@ - account.emails, - account.avatarURL, - account.id, -- account.name -+ account.name, -+ account.scopes || [] - ) - - const key = getKeyForAccount(accountWithoutToken) -changed in both - base 100644 3664497681402ef660531130f999ac3e39892b4d app/src/lib/stores/app-store.ts - our 100644 1a4e387e4d192d34abfd0621b4b5ebe8cc34d8d1 app/src/lib/stores/app-store.ts - their 100644 c20711bd525012f3195a7cbcbd6eb47b6169bae7 app/src/lib/stores/app-store.ts -@@ -116,7 +116,12 @@ - EmojiStore, - GitHubUserStore, - CloningRepositoriesStore, -+<<<<<<< .our - } from '.' -+======= -+ TroubleshootingStore, -+} from '../stores' -+>>>>>>> .their - import { validatedRepositoryPath } from './helpers/validated-repository-path' - import { IGitAccount } from '../git/authentication' - import { getGenericHostname, getGenericUsername } from '../generic-git-auth' -@@ -145,6 +150,7 @@ - import { IAuthor } from '../../models/author' - import { ComparisonCache } from '../comparison-cache' - import { AheadBehindUpdater } from './helpers/ahead-behind-updater' -+<<<<<<< .our - import { enableRepoInfoIndicators } from '../feature-flag' - import { inferComparisonBranch } from './helpers/infer-comparison-branch' - import { -@@ -154,6 +160,10 @@ - } from '../../ui/lib/application-theme' - import { findAccountForRemoteURL } from '../find-account' - import { inferLastPushForRepository } from '../infer-last-push-for-repository' -+======= -+import { enableCompareSidebar } from '../feature-flag' -+import { IValidateHostState, INoRunningAgentState } from '../../models/ssh' -+>>>>>>> .their - - /** - * Enum used by fetch to determine if -@@ -238,6 +248,7 @@ - private readonly repositoriesStore: RepositoriesStore - private readonly statsStore: StatsStore - private readonly pullRequestStore: PullRequestStore -+ private readonly troubleshootingStore: TroubleshootingStore - - /** The issues store for all repositories. */ - public get issuesStore(): IssuesStore { -@@ -300,7 +311,8 @@ - signInStore: SignInStore, - accountsStore: AccountsStore, - repositoriesStore: RepositoriesStore, -- pullRequestStore: PullRequestStore -+ pullRequestStore: PullRequestStore, -+ troubleshootingStore: TroubleshootingStore - ) { - super() - -@@ -313,6 +325,7 @@ - this.accountsStore = accountsStore - this.repositoriesStore = repositoriesStore - this.pullRequestStore = pullRequestStore -+ this.troubleshootingStore = troubleshootingStore - this.showWelcomeFlow = !hasShownWelcomeFlow() - - const window = remote.getCurrentWindow() -@@ -380,6 +393,11 @@ - this.pullRequestStore.onDidUpdate(gitHubRepository => - this.onPullRequestStoreUpdated(gitHubRepository) - ) -+ -+ this.troubleshootingStore.onDidError(error => this.emitError(error)) -+ this.troubleshootingStore.onDidUpdate(() => { -+ this.onTroubleshootingStoreDidUpdate() -+ }) - } - - /** Load the emoji from disk. */ -@@ -592,6 +610,7 @@ - appIsFocused: this.appIsFocused, - selectedState: this.getSelectedState(), - signInState: this.signInStore.getState(), -+ troubleshootingState: this.troubleshootingStore.getState(), - currentPopup: this.currentPopup, - currentFoldout: this.currentFoldout, - errors: this.errors, -@@ -3698,6 +3717,10 @@ - this.emitUpdate() - } - -+ private async onTroubleshootingStoreDidUpdate() { -+ this.emitUpdate() -+ } -+ - private findAssociatedPullRequest( - branch: Branch, - pullRequests: ReadonlyArray<PullRequest>, -@@ -3948,6 +3971,7 @@ - this.statsStore.recordCompareInitiatedMerge() - } - -+<<<<<<< .our - /** - * Set the application-wide theme - */ -@@ -4021,6 +4045,36 @@ - */ - public _recordDivergingBranchBannerInitatedMerge() { - this.statsStore.recordDivergingBranchBannerInitatedMerge() -+======= -+ public _resetTroubleshooting() { -+ this.troubleshootingStore.reset() -+ } -+ -+ public _startTroubleshooting(repository: Repository) { -+ this.troubleshootingStore.start(repository) -+ } -+ -+ public _validateHost(state: IValidateHostState): Promise<void> { -+ return this.troubleshootingStore.validateHost(state) -+ } -+ -+ public _launchSSHAgent(state: INoRunningAgentState): Promise<void> { -+ return this.troubleshootingStore.launchSSHAgent(state) -+ } -+ -+ public _createSSHKey( -+ account: Account, -+ emailAddress: string, -+ passphrase: string, -+ outputFile: string -+ ) { -+ return this.troubleshootingStore.createSSHKey( -+ account, -+ emailAddress, -+ passphrase, -+ outputFile -+ ) -+>>>>>>> .their - } - } - -merged - result 100644 1cf29fec8cdafb4151239aaef8a87ecc38b1f264 app/src/lib/stores/index.ts - our 100644 c81b89a78ad286db4607a8912813e4e384d8e401 app/src/lib/stores/index.ts -@@ -10,4 +10,5 @@ - export * from './token-store' - export * from './pull-request-store' - export * from './repository-settings-store' -+export * from './troubleshooting-store' - export { UpstreamRemoteName } from './helpers/find-upstream-remote' -added in remote - their 100644 fc8ceffd9d50ebc729aeb23298d4cf7e3fc59c21 app/src/lib/stores/troubleshooting-store.ts -@@ -0,0 +1,237 @@ -+import { ipcRenderer } from 'electron' -+import { readFile } from 'fs-extra' -+ -+import { TypedBaseStore } from './base-store' -+import { AccountsStore } from './accounts-store' -+ -+import { -+ TroubleshootingState, -+ TroubleshootingStep, -+ IValidateHostState, -+ INoRunningAgentState, -+} from '../../models/ssh' -+import { Account, accountHasScope } from '../../models/account' -+import { Repository } from '../../models/repository' -+import { -+ scanAndWriteToKnownHostsFile, -+ isHostVerificationError, -+ isPermissionError, -+ executeSSHTest, -+ createSSHKey, -+ addToSSHAgent, -+ SSHAgentManager, -+ AgentStateKind, -+} from '../ssh' -+import { getRemotes } from '../git' -+import { parseRemote } from '../remote-parsing' -+import { API } from '../api' -+ -+const initialState: TroubleshootingState = { -+ kind: TroubleshootingStep.WelcomeState, -+ sshUrl: '', -+ isLoading: false, -+} -+ -+export class TroubleshootingStore extends TypedBaseStore<TroubleshootingState> { -+ private state = initialState -+ private accounts: ReadonlyArray<Account> = [] -+ private sshAgentManager = new SSHAgentManager() -+ -+ public constructor(private accountsStore: AccountsStore) { -+ super() -+ -+ this.accountsStore.onDidUpdate(async () => { -+ const accounts = await this.accountsStore.getAll() -+ this.accounts = accounts -+ }) -+ } -+ -+ /** -+ * Update the internal state of the store and emit an update -+ * event. -+ */ -+ private setState(state: TroubleshootingState) { -+ this.state = state -+ this.emitUpdate(this.getState()) -+ } -+ -+ /** -+ * Returns the current state of the sign in store or null if -+ * no sign in process is in flight. -+ */ -+ public getState(): TroubleshootingState { -+ return this.state -+ } -+ -+ public reset() { -+ this.setState(initialState) -+ this.sshAgentManager.reset() -+ } -+ -+ public async start(repository: Repository) { -+ this.setState({ -+ kind: TroubleshootingStep.WelcomeState, -+ sshUrl: '', -+ isLoading: true, -+ }) -+ -+ const remotes = await getRemotes(repository) -+ -+ const sshRemotes: Array<string> = [] -+ for (const remote of remotes) { -+ const gitRemote = parseRemote(remote.url) -+ if (gitRemote != null && gitRemote.protocol === 'ssh') { -+ sshRemotes.push(gitRemote.hostname) -+ } -+ } -+ -+ // TODO: it'd be nice to know the specific remote associated with this error -+ // for multi-remote scenarios, but these are less common than the -+ // single-remote scenario so this isn't a priority. Maybe we can show a UI -+ // for displaying the remotes to work with, where there are multiple SSH -+ // remotes? -+ const sshUrl = `git@${sshRemotes[0]}` -+ await this.validateSSHConnection(sshUrl) -+ } -+ -+ public async validateHost(state: IValidateHostState) { -+ this.setState({ ...state, isLoading: true }) -+ await scanAndWriteToKnownHostsFile(state.host) -+ await this.validateSSHConnection(state.sshUrl) -+ } -+ -+ public async launchSSHAgent(state: INoRunningAgentState) { -+ this.setState({ ...state, isLoading: true }) -+ -+ const { pid, env } = await this.sshAgentManager.launch() -+ -+ // TODO: we should make the main process spawn this process so we can leverage -+ // the OS to cleanup the process when the main process exits. The alternative -+ // would be to rely on Electron's lifecycle events but an initial test suggests -+ // this is Problematic(TM) on Windows at least -+ -+ ipcRenderer.send('track-new-process', { name: 'ssh-agent', pid }) -+ // TODO: how to pass environment variables through when invoking Git -+ log.debug( -+ `[TroubleshootingStore] found environment variables to pass through: '${JSON.stringify( -+ env -+ )}'` -+ ) -+ -+ await this.validateSSHConnection(state.sshUrl) -+ } -+ -+ public async createSSHKey( -+ account: Account, -+ emailAddress: string, -+ passphrase: string, -+ outputFile: string -+ ) { -+ const state = this.state -+ if (state.kind !== TroubleshootingStep.CreateSSHKey) { -+ return -+ } -+ -+ this.setState({ -+ ...state, -+ isLoading: true, -+ }) -+ -+ const { publicKeyFile, privateKeyFile } = await createSSHKey( -+ emailAddress, -+ passphrase, -+ outputFile -+ ) -+ -+ const agentState = await this.sshAgentManager.getState() -+ -+ if (agentState.kind !== AgentStateKind.Running) { -+ log.warn( -+ 'Creating an SSH key before ssh-agent is running. This is not the right order. Skipping...' -+ ) -+ return -+ } -+ -+ await addToSSHAgent(privateKeyFile, passphrase, agentState.env) -+ -+ if (accountHasScope(account, 'write:public_key')) { -+ const api = new API(account.endpoint, account.token) -+ const title = 'GitHub Desktop on [MACHINE NAME GOES HERE]' -+ const keyContents = await readFile(publicKeyFile) -+ const key = await api.createPublicKey(title, keyContents.toString()) -+ if (key == null) { -+ log.warn('[TroubleshootingStore] unable to create key through API') -+ // TODO: error handling for this flow? -+ return -+ } -+ await this.validateSSHConnection(state.sshUrl) -+ } else { -+ this.setState({ -+ kind: TroubleshootingStep.AuthorizeAgain, -+ account: account, -+ }) -+ } -+ } -+ -+ private async validateSSHConnection(sshUrl: string) { -+ const agentState = await this.sshAgentManager.getState() -+ -+ if (agentState.kind === AgentStateKind.NotFound) { -+ // TODO: how to handle this sitatuion? -+ return -+ } -+ -+ const sshAgentLocation = agentState.executablePath -+ -+ if (agentState.kind === AgentStateKind.NotStarted) { -+ this.setState({ -+ kind: TroubleshootingStep.NoRunningAgent, -+ sshAgentLocation, -+ sshUrl, -+ }) -+ return -+ } -+ -+ const stderr = await executeSSHTest(sshUrl, agentState.env) -+ -+ const verificationError = isHostVerificationError(stderr) -+ if (verificationError !== null) { -+ const { rawOutput, host } = verificationError -+ this.setState({ -+ kind: TroubleshootingStep.ValidateHost, -+ rawOutput, -+ host, -+ sshUrl, -+ }) -+ return -+ } -+ -+ if (isPermissionError(stderr)) { -+ // TODO: nail down this flow -+ // - if we have existing keys, show and let the user choose -+ // - they may wish to skip to instead create a new key -+ // - choose a GitHub or GitHub Enterprise account -+ // - detect whether these accounts have -+ -+ const foundKeys = 0 -+ -+ if (foundKeys > 0) { -+ // TODO: list keys and let the user select a key -+ } else { -+ this.setState({ -+ kind: TroubleshootingStep.CreateSSHKey, -+ accounts: this.accounts, -+ sshAgentLocation, -+ sshUrl, -+ }) -+ return -+ } -+ return -+ } -+ -+ this.setState({ -+ kind: TroubleshootingStep.Unknown, -+ error: stderr, -+ }) -+ } -+} -changed in both - base 100644 2bbce98d75a6e5e03d9184c46b2af1a43b8fa55a app/src/main-process/main.ts - our 100644 a406ea4cd47e8c9a733faee41a125eab3f743aa2 app/src/main-process/main.ts - their 100644 deb067ecb23bf35a8fa26ca361098993ac9d98cf app/src/main-process/main.ts -@@ -2,6 +2,7 @@ - - import { app, Menu, ipcMain, BrowserWindow, shell } from 'electron' - import * as Fs from 'fs' -+import { exec } from 'child_process' - - import { AppWindow } from './app-window' - import { buildDefaultMenu, MenuEvent, findMenuItemByID } from './menu' -@@ -33,6 +34,8 @@ - let preventQuit = false - let readyTime: number | null = null - -+const spawnedProcessIds = new Array<number>() -+ - type OnDidLoadFn = (window: AppWindow) => void - /** See the `onDidLoad` function. */ - let onDidLoadFns: Array<OnDidLoadFn> | null = [] -@@ -376,6 +379,19 @@ - }) - } - ) -+ -+ ipcMain.on( -+ 'track-new-process', -+ ( -+ event: Electron.IpcMessageEvent, -+ { name, pid }: { name: string; pid: number } -+ ) => { -+ log.info( -+ `Process ${name} spawned with pid ${pid} and should be killed when Desktop exits` -+ ) -+ spawnedProcessIds.push(pid) -+ } -+ ) - }) - - app.on('activate', () => { -@@ -403,6 +419,22 @@ - } - ) - -+app.on('before-quit', () => { -+ spawnedProcessIds.forEach(pid => { -+ if (__WIN32__) { -+ exec(`taskkill /PID ${pid}`, (error, stdout, stderr) => { -+ if (error != null) { -+ log.debug(`Unable to terminate process ${pid}, giving up...`) -+ return -+ } -+ log.debug(`Able to terminate process ${pid} successfully...`) -+ }) -+ } else { -+ process.kill(pid) -+ } -+ }) -+}) -+ - function createWindow() { - const window = new AppWindow() - -merged - result 100644 37976910efbf23449a3321c5e5424124a40a6247 app/src/models/account.ts - our 100644 8400b1e41845964df7e675b460454ac5f90de185 app/src/models/account.ts -@@ -8,7 +8,7 @@ - export class Account { - /** Create an account which can be used to perform unauthenticated API actions */ - public static anonymous(): Account { -- return new Account('', getDotComAPIEndpoint(), '', [], '', -1, '') -+ return new Account('', getDotComAPIEndpoint(), '', [], '', -1, '', []) - } - - public constructor( -@@ -25,7 +25,9 @@ - /** The database id for this account */ - public readonly id: number, - /** The friendly name associated with this account */ -- public readonly name: string -+ public readonly name: string, -+ /** The OAuth scopes associated with the token */ -+ public readonly scopes: ReadonlyArray<string> - ) {} - - public withToken(token: string): Account { -@@ -36,7 +38,12 @@ - this.emails, - this.avatarURL, - this.id, -- this.name -+ this.name, -+ this.scopes - ) - } - } -+ -+export function accountHasScope(account: Account, scope: string) { -+ return account.scopes.includes(scope) -+} -added in remote - their 100644 52638bf0d07ab61f48b076487a8fd359076b6242 app/src/models/ssh.ts -@@ -0,0 +1,58 @@ -+import { Account } from './account' -+ -+export enum TroubleshootingStep { -+ WelcomeState = 'WelcomeState', -+ ValidateHost = 'ValidateHost', -+ NoRunningAgent = 'NoRunningAgent', -+ CreateSSHKey = 'CreateSSHKey', -+ AuthorizeAgain = 'AuthorizeAgain', -+ Unknown = 'Unknown', -+} -+ -+export interface IWelcomeState { -+ readonly kind: TroubleshootingStep.WelcomeState -+ readonly sshUrl: string -+ readonly isLoading?: boolean -+} -+ -+export interface IValidateHostState { -+ readonly kind: TroubleshootingStep.ValidateHost -+ readonly host: string -+ readonly rawOutput: string -+ readonly sshUrl: string -+ readonly isLoading?: boolean -+} -+ -+export interface INoRunningAgentState { -+ readonly kind: TroubleshootingStep.NoRunningAgent -+ readonly sshAgentLocation: string -+ readonly sshUrl: string -+ readonly isLoading?: boolean -+} -+ -+export interface ICreateSSHKeyState { -+ readonly kind: TroubleshootingStep.CreateSSHKey -+ readonly accounts: ReadonlyArray<Account> -+ readonly sshAgentLocation: string -+ readonly sshUrl: string -+ readonly isLoading?: boolean -+} -+ -+export interface IAuthorizeGitHubAgainState { -+ readonly kind: TroubleshootingStep.AuthorizeAgain -+ readonly account: Account -+ readonly isLoading?: boolean -+} -+ -+export interface IUnknownResultState { -+ readonly kind: TroubleshootingStep.Unknown -+ readonly error: string -+} -+ -+export type TroubleshootingState = -+ | IWelcomeState -+ | IValidateHostState -+ | INoRunningAgentState -+ | ICreateSSHKeyState -+ | IAuthorizeGitHubAgainState -+ | IUnknownResultState -changed in both - base 100644 2cc39415021d56afee6df52411dd5466e5fcb84b app/src/ui/app.tsx - our 100644 c38c806e36c237ea70f3cdeee739941530c0c7cd app/src/ui/app.tsx - their 100644 596ec900cc14d8e9fe6e79f1dc8fa38869a40330 app/src/ui/app.tsx -@@ -84,6 +84,7 @@ - import { GenericGitAuthentication } from './generic-git-auth' - import { ShellError } from './shell' - import { InitializeLFS, AttributeMismatch } from './lfs' -+import { TroubleshootSSH } from './ssh' - import { UpstreamAlreadyExists } from './upstream-already-exists' - import { DeletePullRequest } from './delete-branch/delete-pull-request-dialog' - import { MergeConflictsWarning } from './merge-conflicts' -@@ -1250,6 +1251,21 @@ - onInitialize={this.initializeLFS} - /> - ) -+ case PopupType.TroubleshootSSH: -+ const state = this.props.appStore.getState() -+ if (state.troubleshootingState == null) { -+ return null -+ } -+ -+ return ( -+ <TroubleshootSSH -+ dispatcher={this.props.dispatcher} -+ repository={popup.repository} -+ onDismissed={this.onPopupDismissed} -+ troubleshootingState={state.troubleshootingState} -+ signInState={state.signInState} -+ /> -+ ) - case PopupType.LFSAttributeMismatch: - return ( - <AttributeMismatch -changed in both - base 100644 68dedd34f265a41733b16e76f0ce3b07e05f865e app/src/ui/index.tsx - our 100644 f8f8200917327048c8f002fcfade473dfd6668d1 app/src/ui/index.tsx - their 100644 eb14ae24e33a47850d87815b99d3dea2bf302d01 app/src/ui/index.tsx -@@ -14,6 +14,7 @@ - openShellErrorHandler, - mergeConflictHandler, - lfsAttributeMismatchHandler, -+ sshAuthenticationErrorHandler, - defaultErrorHandler, - missingRepositoryHandler, - backgroundTaskHandler, -@@ -31,6 +32,7 @@ - TokenStore, - AccountsStore, - PullRequestStore, -+ TroubleshootingStore, - } from '../lib/stores' - import { GitHubUserDatabase } from '../lib/databases' - import { URLActionType } from '../lib/parse-app-url' -@@ -52,6 +54,8 @@ - } from '../lib/source-map-support' - import { UiActivityMonitor } from './lib/ui-activity-monitor' - -+import { enableSSHTroubleshooting } from '../lib/feature-flag' -+ - if (__DEV__) { - installDevGlobals() - } -@@ -125,6 +129,8 @@ - repositoriesStore - ) - -+const troubleshootingStore = new TroubleshootingStore(accountsStore) -+ - const appStore = new AppStore( - gitHubUserStore, - cloningRepositoriesStore, -@@ -134,7 +140,8 @@ - signInStore, - accountsStore, - repositoriesStore, -- pullRequestStore -+ pullRequestStore, -+ troubleshootingStore - ) - - const dispatcher = new Dispatcher(appStore) -@@ -145,6 +152,9 @@ - dispatcher.registerErrorHandler(openShellErrorHandler) - dispatcher.registerErrorHandler(mergeConflictHandler) - dispatcher.registerErrorHandler(lfsAttributeMismatchHandler) -+if (enableSSHTroubleshooting()) { -+ dispatcher.registerErrorHandler(sshAuthenticationErrorHandler) -+} - dispatcher.registerErrorHandler(gitAuthenticationErrorHandler) - dispatcher.registerErrorHandler(pushNeedsPullHandler) - dispatcher.registerErrorHandler(backgroundTaskHandler) -added in remote - their 100644 53500935a715eec35d7d0c5c2b1eae5e784d914c app/src/ui/ssh/authorize-github-again.tsx -@@ -0,0 +1,72 @@ -+import * as React from 'react' -+ -+import { IAuthorizeGitHubAgainState } from '../../models/ssh' -+ -+import { Button } from '../lib/button' -+import { ButtonGroup } from '../lib/button-group' -+import { Loading } from '../lib/loading' -+import { SignIn } from '../lib/sign-in' -+ -+import { Dialog, DialogContent, DialogFooter } from '../dialog' -+ -+import { Dispatcher } from '../../lib/dispatcher' -+import { SignInState } from '../../lib/stores' -+ -+interface IAuthorizeGitHubAgainProps { -+ readonly state: IAuthorizeGitHubAgainState -+ readonly signInState: SignInState | null -+ readonly dispatcher: Dispatcher -+ readonly onDismissed: () => void -+} -+ -+export class AuthorizeGitHubAgain extends React.Component< -+ IAuthorizeGitHubAgainProps, -+ {} -+> { -+ private keepOnKeepingOn = () => { -+ this.props.onDismissed() -+ } -+ public render() { -+ const { state } = this.props -+ const disabled = state.isLoading -+ -+ if (this.props.signInState == null) { -+ log.warn(`Unable to authorize again because we're not in a valid state`) -+ return null -+ } -+ -+ return ( -+ <Dialog -+ id="troubleshoot-ssh" -+ title="Troubleshoot SSH Authentication" -+ onDismissed={this.props.onDismissed} -+ onSubmit={this.keepOnKeepingOn} -+ > -+ <DialogContent> -+ <p> -+ The token associated with the {state.account.login} account ({ -+ state.account.name -+ }) does not have permission to publish SSH keys for this account. -+ </p> -+ <p>To continue, you need to sign in again:</p> -+ -+ <p> -+ <SignIn -+ signInState={this.props.signInState} -+ dispatcher={this.props.dispatcher} -+ /> -+ </p> -+ </DialogContent> -+ <DialogFooter> -+ <ButtonGroup> -+ <Button type="submit" disabled={disabled}> -+ {state.isLoading ? <Loading /> : null} -+ Start -+ </Button> -+ <Button onClick={this.props.onDismissed}>Cancel</Button> -+ </ButtonGroup> -+ </DialogFooter> -+ </Dialog> -+ ) -+ } -+} -added in remote - their 100644 e7842936bed758f6710f673d27cda500e9b681c2 app/src/ui/ssh/index.ts -@@ -0,0 +1 @@ -+export { TroubleshootSSH } from './troubleshoot-ssh' -added in remote - their 100644 44fea58ca6cec019b36b82434925c9bf9fa77257 app/src/ui/ssh/setup-new-ssh-key.tsx -@@ -0,0 +1,314 @@ -+import * as React from 'react' -+import { remote } from 'electron' -+import * as os from 'os' -+import * as Path from 'path' -+ -+import { lookupPreferredEmail } from '../../lib/email' -+import { IAvatarUser } from '../../models/avatar' -+import { Account, accountHasScope } from '../../models/account' -+ -+import { Button } from '../lib/button' -+import { ButtonGroup } from '../lib/button-group' -+import { Row } from '../lib/row' -+import { TextBox } from '../lib/text-box' -+import { Ref } from '../lib/ref' -+ -+import { Avatar } from '../lib/avatar' -+import { Loading } from '../lib/loading' -+ -+import { Dialog, DialogContent, DialogFooter } from '../dialog' -+import { List } from '../lib/list' -+import { Dispatcher } from '../../lib/dispatcher' -+import { ICreateSSHKeyState } from '../../models/ssh' -+import { pathExists } from 'fs-extra' -+import { OcticonSymbol, Octicon } from '../octicons' -+ -+function getPathForNewSSHKey(fileName: string) { -+ const homeDir = os.homedir() -+ return Path.join(homeDir, '.ssh', fileName) -+} -+ -+interface ISetupNewSSHKeyProps { -+ readonly dispatcher: Dispatcher -+ readonly state: ICreateSSHKeyState -+ readonly onDismissed: () => void -+} -+ -+interface ISetupNewSSHKeyState { -+ readonly selectedAccount?: number -+ readonly emailAddress: string -+ readonly passphrase: string -+ readonly confirmPassPhrase: string -+ readonly outputFile: string -+ readonly outputFileExists: boolean | null -+} -+ -+export class SetupNewSSHKey extends React.Component< -+ ISetupNewSSHKeyProps, -+ ISetupNewSSHKeyState -+> { -+ public constructor(props: ISetupNewSSHKeyProps) { -+ super(props) -+ -+ this.state = { -+ emailAddress: '', -+ passphrase: '', -+ confirmPassPhrase: '', -+ outputFile: getPathForNewSSHKey('github_desktop'), -+ outputFileExists: null, -+ } -+ } -+ -+ private onContinue = () => { -+ if (this.state.selectedAccount == null) { -+ return -+ } -+ -+ const account = this.props.state.accounts[this.state.selectedAccount] -+ -+ this.props.dispatcher.createSSHKey( -+ account, -+ this.state.emailAddress, -+ this.state.passphrase, -+ this.state.outputFile -+ ) -+ } -+ -+ private updateFile = async (outputFile: string) => { -+ const outputFileExists = await pathExists(outputFile) -+ this.setState({ outputFile, outputFileExists }) -+ } -+ -+ private showFilePicker = async () => { -+ const defaultPath = this.state.outputFile -+ const window: any = null -+ remote.dialog.showSaveDialog( -+ window, -+ { -+ defaultPath, -+ }, -+ async outputFile => { -+ if (outputFile == null) { -+ return -+ } -+ -+ await this.updateFile(outputFile) -+ } -+ ) -+ } -+ -+ private onEmailAddressChanged = (emailAddress: string) => { -+ this.setState({ emailAddress }) -+ } -+ -+ private onPassPhraseChanged = (passphrase: string) => { -+ this.setState({ passphrase }) -+ } -+ -+ private onConfirmPassPhraseChanged = (confirmPassPhrase: string) => { -+ this.setState({ confirmPassPhrase }) -+ // TODO: validate that the passphrase and text are the same -+ } -+ -+ private updateState = async (selectedAccount: number) => { -+ // TODO: validate that this is an entry in the array -+ const account = this.props.state.accounts[selectedAccount] -+ const outputFile = getPathForNewSSHKey(`github_desktop_${account.login}`) -+ -+ await this.updateFile(outputFile) -+ -+ const email = lookupPreferredEmail(account.emails) -+ const emailAddress = email == null ? '' : email.email -+ this.setState({ selectedAccount, emailAddress }) -+ } -+ -+ private onAccountSelectionChanged = (rows: ReadonlyArray<number>) => { -+ this.updateState(rows[0]) -+ } -+ -+ private onAccountRowClick = (row: number) => { -+ this.updateState(row) -+ } -+ -+ private onPathChanged = async (outputFile: string) => { -+ await this.updateFile(outputFile) -+ } -+ -+ private renderTokenWarning(account: Account) { -+ if (accountHasScope(account, 'write:public_key')) { -+ return null -+ } -+ -+ return ( -+ <div -+ className="token-alert" -+ title="The token for this account needs to be upgraded to publish your SSH key" -+ > -+ <Octicon symbol={OcticonSymbol.alert} /> -+ </div> -+ ) -+ } -+ -+ private renderRow = (index: number) => { -+ const account = this.props.state.accounts[index] -+ -+ const found = lookupPreferredEmail(account.emails) -+ const email = found ? found.email : '' -+ -+ const avatarUser: IAvatarUser = { -+ name: account.name, -+ email: email, -+ avatarURL: account.avatarURL, -+ } -+ -+ return ( -+ <Row className="account-info"> -+ <Avatar user={avatarUser} /> -+ <div className="user-info"> -+ <div className="name">{account.name}</div> -+ <div className="login">@{account.login}</div> -+ </div> -+ {this.renderTokenWarning(account)} -+ </Row> -+ ) -+ } -+ -+ private renderPasswordMismatch = () => { -+ if (this.state.passphrase === this.state.confirmPassPhrase) { -+ return null -+ } -+ -+ return ( -+ <Row className="warning-helper-text"> -+ <Octicon symbol={OcticonSymbol.alert} /> -+ <p>The passphrase and confirmed passphrase do not match.</p> -+ </Row> -+ ) -+ } -+ -+ private renderExistingKeyWarning = () => { -+ if (!this.state.outputFileExists) { -+ return null -+ } -+ -+ return ( -+ <Row className="warning-helper-text"> -+ <Octicon symbol={OcticonSymbol.alert} /> -+ <p> -+ A file already exists at this path. Choose a new path to ensure that -+ you don't overwrite an existing key. -+ </p> -+ </Row> -+ ) -+ } -+ -+ public render() { -+ const isLoading = this.props.state.isLoading -+ -+ const passphraseMatches = -+ this.state.passphrase === this.state.confirmPassPhrase -+ -+ const disabled = -+ this.state.selectedAccount == null || -+ !passphraseMatches || -+ this.state.outputFileExists || -+ isLoading -+ -+ const selectedRows = -+ this.state.selectedAccount == null ? [] : [this.state.selectedAccount] -+ -+ return ( -+ <Dialog -+ id="troubleshoot-ssh" -+ title="Create SSH Key" -+ onDismissed={this.props.onDismissed} -+ onSubmit={this.onContinue} -+ > -+ <DialogContent> -+ <Row>Choose an account to associate with the new SSH key:</Row> -+ -+ <Row> -+ <div className="account-list-container"> -+ <List -+ rowRenderer={this.renderRow} -+ rowCount={this.props.state.accounts.length} -+ rowHeight={34} -+ selectedRows={selectedRows} -+ selectionMode="single" -+ invalidationProps={this.props.state.accounts} -+ onSelectionChanged={this.onAccountSelectionChanged} -+ onRowClick={this.onAccountRowClick} -+ /> -+ </div> -+ </Row> -+ <Row> -+ <TextBox -+ value={this.state.emailAddress} -+ onValueChanged={this.onEmailAddressChanged} -+ disabled={isLoading} -+ label="Email address (required)" -+ /> -+ </Row> -+ <Row> -+ <span> -+ A passphrase is recommended for extra security. Ensure that you -+ remember this as{' '} -+ <strong> -+ a lost or forgotten passphrase cannot be recovered and a new key -+ must be created -+ </strong>. -+ </span> -+ </Row> -+ <Row> -+ <TextBox -+ value={this.state.passphrase} -+ onValueChanged={this.onPassPhraseChanged} -+ disabled={isLoading} -+ type="password" -+ label="Passphrase (optional)" -+ /> -+ </Row> -+ <Row> -+ <TextBox -+ value={this.state.confirmPassPhrase} -+ onValueChanged={this.onConfirmPassPhraseChanged} -+ disabled={isLoading} -+ type="password" -+ label="Confirm passphrase" -+ /> -+ </Row> -+ -+ {this.renderPasswordMismatch()} -+ -+ <Row> -+ <TextBox -+ value={this.state.outputFile} -+ disabled={isLoading} -+ onValueChanged={this.onPathChanged} -+ label={__DARWIN__ ? 'Key Path' : 'Key path'} -+ placeholder="SSH key path" -+ /> -+ <Button onClick={this.showFilePicker} disabled={isLoading}> -+ Choose… -+ </Button> -+ </Row> -+ -+ {this.renderExistingKeyWarning()} -+ -+ <Row> -+ This will create an <Ref>RSA</Ref> key of <Ref>4096 bits</Ref>. -+ </Row> -+ </DialogContent> -+ <DialogFooter> -+ <ButtonGroup> -+ <Button type="submit" disabled={disabled}> -+ {isLoading ? <Loading /> : null} -+ Create -+ </Button> -+ <Button onClick={this.props.onDismissed}>Cancel</Button> -+ </ButtonGroup> -+ </DialogFooter> -+ </Dialog> -+ ) -+ } -+} -added in remote - their 100644 ceaa8d0e9d9a673f690fabbb19e83022b859fb27 app/src/ui/ssh/start-ssh-agent.tsx -@@ -0,0 +1,58 @@ -+import * as React from 'react' -+ -+import { INoRunningAgentState } from '../../models/ssh' -+ -+import { Dispatcher } from '../../lib/dispatcher' -+ -+import { Button } from '../lib/button' -+import { ButtonGroup } from '../lib/button-group' -+import { Loading } from '../lib/loading' -+import { Ref } from '../lib/ref' -+ -+import { Dialog, DialogContent, DialogFooter } from '../dialog' -+ -+interface IStartSSHAgentProps { -+ readonly dispatcher: Dispatcher -+ readonly state: INoRunningAgentState -+ readonly onDismissed: () => void -+} -+ -+export class StartSSHAgent extends React.Component<IStartSSHAgentProps, {}> { -+ private launchSSHAgent = () => { -+ this.props.dispatcher.launchSSHAgent(this.props.state) -+ } -+ -+ public render() { -+ const { state } = this.props -+ const disabled = state.isLoading -+ -+ return ( -+ <Dialog -+ id="troubleshoot-ssh" -+ title="Troubleshoot SSH Authentication" -+ onDismissed={this.props.onDismissed} -+ onSubmit={this.launchSSHAgent} -+ > -+ <DialogContent> -+ <p> -+ A running <Ref>ssh-agent</Ref> process is required to perform -+ authentication. -+ </p> -+ <p> -+ Do you want to start the <Ref>ssh-agent</Ref> process found at{' '} -+ <Ref>{state.sshAgentLocation}</Ref>? -+ </p> -+ </DialogContent> -+ <DialogFooter> -+ <ButtonGroup> -+ <Button type="submit" disabled={disabled}> -+ {state.isLoading ? <Loading /> : null} -+ Start -+ </Button> -+ <Button onClick={this.props.onDismissed}>Cancel</Button> -+ </ButtonGroup> -+ </DialogFooter> -+ </Dialog> -+ ) -+ } -+} -added in remote - their 100644 9179341ecd05a61f111286a4e11f591343be773c app/src/ui/ssh/troubleshoot-ssh.tsx -@@ -0,0 +1,89 @@ -+import * as React from 'react' -+ -+import { Repository } from '../../models/repository' -+import { TroubleshootingState, TroubleshootingStep } from '../../models/ssh' -+ -+import { Dispatcher } from '../../lib/dispatcher' -+import { assertNever } from '../../lib/fatal-error' -+ -+import { Welcome } from './welcome' -+import { ValidateHost } from './validate-host' -+import { UnknownAction } from './unknown-action' -+import { SetupNewSSHKey } from './setup-new-ssh-key' -+import { StartSSHAgent } from './start-ssh-agent' -+import { AuthorizeGitHubAgain } from './authorize-github-again' -+import { SignInState } from '../../lib/stores' -+ -+interface ITroubleshootSSHProps { -+ readonly dispatcher: Dispatcher -+ readonly repository: Repository -+ readonly troubleshootingState: TroubleshootingState -+ readonly signInState: SignInState | null -+ readonly onDismissed: () => void -+} -+ -+export class TroubleshootSSH extends React.Component< -+ ITroubleshootSSHProps, -+ {} -+> { -+ public componentDidMount() { -+ this.props.dispatcher.resetTroubleshooting() -+ } -+ -+ public render() { -+ const state = this.props.troubleshootingState -+ const stepKind = state.kind -+ -+ switch (state.kind) { -+ case TroubleshootingStep.WelcomeState: -+ return ( -+ <Welcome -+ dispatcher={this.props.dispatcher} -+ repository={this.props.repository} -+ state={state} -+ onDismissed={this.props.onDismissed} -+ /> -+ ) -+ case TroubleshootingStep.ValidateHost: -+ return ( -+ <ValidateHost -+ dispatcher={this.props.dispatcher} -+ repository={this.props.repository} -+ state={state} -+ onDismissed={this.props.onDismissed} -+ /> -+ ) -+ case TroubleshootingStep.NoRunningAgent: -+ return ( -+ <StartSSHAgent -+ dispatcher={this.props.dispatcher} -+ state={state} -+ onDismissed={this.props.onDismissed} -+ /> -+ ) -+ case TroubleshootingStep.CreateSSHKey: -+ return ( -+ <SetupNewSSHKey -+ dispatcher={this.props.dispatcher} -+ state={state} -+ onDismissed={this.props.onDismissed} -+ /> -+ ) -+ case TroubleshootingStep.AuthorizeAgain: -+ return ( -+ <AuthorizeGitHubAgain -+ state={state} -+ dispatcher={this.props.dispatcher} -+ signInState={this.props.signInState} -+ onDismissed={this.props.onDismissed} -+ /> -+ ) -+ case TroubleshootingStep.Unknown: -+ return ( -+ <UnknownAction state={state} onDismissed={this.props.onDismissed} /> -+ ) -+ default: -+ return assertNever(state, `Unknown troubleshooting step: ${stepKind}`) -+ } -+ } -+} -added in remote - their 100644 8532ff183cc6b9b6683b232a6ec8661d6ae3b699 app/src/ui/ssh/unknown-action.tsx -@@ -0,0 +1,63 @@ -+import * as React from 'react' -+ -+import { IUnknownResultState } from '../../models/ssh' -+ -+import { Button } from '../lib/button' -+import { ButtonGroup } from '../lib/button-group' -+import { Dialog, DialogContent, DialogFooter } from '../dialog' -+import { Octicon, OcticonSymbol } from '../octicons' -+ -+import { LinkButton } from '../lib/link-button' -+import { saveLogFile } from '../../lib/ssh' -+ -+interface IUnknownActionProps { -+ readonly state: IUnknownResultState -+ readonly onDismissed: () => void -+} -+ -+export class UnknownAction extends React.Component<IUnknownActionProps, {}> { -+ private saveFile = async () => { -+ try { -+ await saveLogFile(this.props.state.error) -+ } catch (err) { -+ log.error( -+ `[saveLogFile] an error occurred while trying to save the log file`, -+ err -+ ) -+ } -+ } -+ -+ public render() { -+ return ( -+ <Dialog -+ id="troubleshoot-ssh" -+ title="Unable to resolve issue" -+ onSubmit={this.saveFile} -+ onDismissed={this.props.onDismissed} -+ > -+ <DialogContent> -+ <p> -+ Unfortunately Desktop has exhausted all known troubleshooting tricks -+ for this issue. -+ </p> -+ <p> -+ A trace file has been generated here that will help a human -+ troubleshoot the issue. Please reach out to the{' '} -+ <LinkButton uri="https://github.com/desktop/desktop/issues/new"> -+ GitHub Desktop -+ </LinkButton>{' '} -+ issue tracker for further support. -+ </p> -+ </DialogContent> -+ <DialogFooter> -+ <ButtonGroup> -+ <Button type="submit"> -+ <Octicon symbol={OcticonSymbol.desktopDownload} /> Save log file -+ </Button> -+ <Button onClick={this.props.onDismissed}>Close</Button> -+ </ButtonGroup> -+ </DialogFooter> -+ </Dialog> -+ ) -+ } -+} -added in remote - their 100644 9231cb67363e7ffbd92d2a1a2b76dcb3bd4b4629 app/src/ui/ssh/validate-host.tsx -@@ -0,0 +1,59 @@ -+import * as React from 'react' -+ -+import { Repository } from '../../models/repository' -+import { IValidateHostState } from '../../models/ssh' -+ -+import { Dispatcher } from '../../lib/dispatcher' -+ -+import { Button } from '../lib/button' -+import { ButtonGroup } from '../lib/button-group' -+import { Dialog, DialogContent, DialogFooter } from '../dialog' -+import { Loading } from '../lib/loading' -+import { LinkButton } from '../lib/link-button' -+ -+interface IValidateHostProps { -+ readonly dispatcher: Dispatcher -+ readonly repository: Repository -+ readonly state: IValidateHostState -+ readonly onDismissed: () => void -+} -+ -+export class ValidateHost extends React.Component<IValidateHostProps, {}> { -+ private verifyHost = async () => { -+ await this.props.dispatcher.validateHost(this.props.state) -+ } -+ -+ public render() { -+ const { state } = this.props -+ const disabled = state.isLoading -+ return ( -+ <Dialog -+ id="troubleshoot-ssh" -+ title="Verify SSH Server" -+ onDismissed={this.props.onDismissed} -+ onSubmit={this.verifyHost} -+ > -+ <DialogContent> -+ <p>A problem was encountered connecting to the host.</p> -+ <p className="output">{state.rawOutput}</p> -+ <p> -+ You will need to verify that this is the correct host to continue. -+ You can compare the value above with the entries documented in the{' '} -+ <LinkButton uri="https://help.github.com/articles/testing-your-ssh-connection/"> -+ GitHub help documentation -+ </LinkButton>. -+ </p> -+ </DialogContent> -+ <DialogFooter> -+ <ButtonGroup> -+ <Button type="submit" disabled={disabled}> -+ {state.isLoading ? <Loading /> : null} -+ Verify -+ </Button> -+ <Button onClick={this.props.onDismissed}>Cancel</Button> -+ </ButtonGroup> -+ </DialogFooter> -+ </Dialog> -+ ) -+ } -+} -added in remote - their 100644 2ed044ea2216a1a6d3588de86c210ea465bf6c1e app/src/ui/ssh/welcome.tsx -@@ -0,0 +1,57 @@ -+import * as React from 'react' -+ -+import { Repository } from '../../models/repository' -+import { IWelcomeState } from '../../models/ssh' -+ -+import { Dispatcher } from '../../lib/dispatcher' -+ -+import { Button } from '../lib/button' -+import { ButtonGroup } from '../lib/button-group' -+import { Dialog, DialogContent, DialogFooter } from '../dialog' -+import { Loading } from '../lib/loading' -+ -+interface IWelcomeProps { -+ readonly dispatcher: Dispatcher -+ readonly repository: Repository -+ readonly state: IWelcomeState -+ readonly onDismissed: () => void -+} -+ -+export class Welcome extends React.Component<IWelcomeProps, {}> { -+ private startTroubleshooting = () => { -+ this.props.dispatcher.startTroubleshooting(this.props.repository) -+ } -+ -+ public render() { -+ const { state } = this.props -+ const disabled = state.isLoading -+ -+ return ( -+ <Dialog -+ id="troubleshoot-ssh" -+ title="Troubleshoot SSH Authentication" -+ onDismissed={this.props.onDismissed} -+ onSubmit={this.startTroubleshooting} -+ > -+ <DialogContent> -+ <p> -+ It looks like you are having an issue connecting to an SSH remote. -+ </p> -+ <p> -+ Do you want to troubleshoot your setup to see if Desktop can get -+ this working? -+ </p> -+ </DialogContent> -+ <DialogFooter> -+ <ButtonGroup> -+ <Button type="submit" disabled={disabled}> -+ {state.isLoading ? <Loading /> : null} -+ Start -+ </Button> -+ <Button onClick={this.props.onDismissed}>Cancel</Button> -+ </ButtonGroup> -+ </DialogFooter> -+ </Dialog> -+ ) -+ } -+} -changed in both - base 100644 e496a16bd915366f9b11d9d0e63a21a8732099f4 app/styles/ui/_dialog.scss - our 100644 94b86d54fb9b0314deb1ef48cc9e1466578ed390 app/styles/ui/_dialog.scss - their 100644 921a624a6a252f6aec33df9f06100fc74c95b4dd app/styles/ui/_dialog.scss -@@ -2,6 +2,7 @@ - @import 'dialogs/merge'; - @import 'dialogs/publish-repository'; - @import 'dialogs/repository-settings'; -+@import 'dialogs/ssh'; - - // The styles herein attempt to follow a flow where margins are only applied - // to the bottom of elements (with the exception of the last child). This to -added in remote - their 100644 03a7239ef47bbd8846e22c30a9cc6b2863439043 app/styles/ui/dialogs/_ssh.scss -@@ -0,0 +1,54 @@ -+#troubleshoot-ssh { -+ .spin { -+ margin-right: var(--spacing-half); -+ } -+ -+ p.output { -+ -webkit-user-select: auto; -+ user-select: auto; -+ cursor: text; -+ -+ // Preserve newlines and other white space in error messages -+ // but make sure we wrap if necessary. -+ white-space: pre-wrap; -+ -+ background: var(--path-segment-background); -+ border: var(--path-segment-background); -+ border-radius: var(--border-radius); -+ -+ font-family: var(--font-family-monospace); -+ } -+ -+ /** A React component holding the currently selected repository's changes */ -+ .account-list-container { -+ flex-grow: 1; -+ display: flex; -+ flex-direction: column; -+ min-height: 34px; -+ -+ .account-info { -+ .avatar { -+ // 32px for the image + 2 on each side for the base border. -+ width: 34px; -+ height: 34px; -+ -+ border: var(--base-border); -+ -+ align-self: center; -+ } -+ -+ .user-info { -+ flex-grow: 1; -+ align-self: flex-start; -+ -+ .name { -+ font-weight: var(--font-weight-semibold); -+ // Tighten it up a little so that the real name and -+ // username lines up with the avatar. -+ margin-top: -2px; -+ margin-bottom: -2px; -+ } -+ } -+ } -+ } -+} -merged - result 100644 395b1944d0a67690181911aef0df4204161dfd17 app/test/unit/accounts-store-test.ts - our 100644 eed3816fb2f76f373f7ae51c5cfa9132619fb879 app/test/unit/accounts-store-test.ts -@@ -17,7 +17,7 @@ - it('contains the added user', async () => { - const newAccountLogin = 'joan' - await accountsStore!.addAccount( -- new Account(newAccountLogin, '', 'deadbeef', [], '', 1, '') -+ new Account(newAccountLogin, '', 'deadbeef', [], '', 1, '', []) - ) - - const users = await accountsStore!.getAll() -changed in both - base 100644 11161765e2eda88e549efb9ec50be911f6c76442 app/test/unit/app-store-test.ts - our 100644 7c7b2a2600b6cdb77d652940772194805df43425 app/test/unit/app-store-test.ts - their 100644 92be09473490e2d370d0426d086ce693623bfe30 app/test/unit/app-store-test.ts -@@ -14,6 +14,7 @@ - RepositoriesStore, - AccountsStore, - PullRequestStore, -+ TroubleshootingStore, - } from '../../src/lib/stores' - import { - TestGitHubUserDatabase, -@@ -62,6 +63,8 @@ - repositoriesStore - ) - -+ const troubleshootingStore = new TroubleshootingStore(accountsStore) -+ - return new AppStore( - new GitHubUserStore(db), - new CloningRepositoriesStore(), -@@ -71,7 +74,8 @@ - new SignInStore(), - accountsStore, - repositoriesStore, -- pullRequestStore -+ pullRequestStore, -+ troubleshootingStore - ) - } - -changed in both - base 100644 cd15b5fd5314d763ed32ce3dd5d2fa8c9bc2b57e app/test/unit/app-test.tsx - our 100644 f5a4bb958cedfdbf76f9144a200a3cfac9613c02 app/test/unit/app-test.tsx - their 100644 7d73caeacc66d4c7cec923f7f88346f4979b3525 app/test/unit/app-test.tsx -@@ -16,6 +16,7 @@ - RepositoriesStore, - AccountsStore, - PullRequestStore, -+ TroubleshootingStore, - } from '../../src/lib/stores' - import { InMemoryDispatcher } from '../helpers/in-memory-dispatcher' - import { -@@ -59,6 +60,8 @@ - repositoriesStore - ) - -+ const troubleshootingStore = new TroubleshootingStore(accountsStore) -+ - appStore = new AppStore( - new GitHubUserStore(db), - new CloningRepositoriesStore(), -@@ -68,7 +71,8 @@ - new SignInStore(), - accountsStore, - repositoriesStore, -- pullRequestStore -+ pullRequestStore, -+ troubleshootingStore - ) - - dispatcher = new InMemoryDispatcher(appStore) -merged - result 100644 389d4c4fef56ffe7f38c8fbf93e3cd2c93ca36e0 app/test/unit/repository-matching-test.ts - our 100644 abc42b9bb58132839bc3cef0828c66584193b2fc app/test/unit/repository-matching-test.ts -@@ -10,7 +10,16 @@ - describe('matchGitHubRepository', () => { - it('matches HTTPS URLs', () => { - const accounts = [ -- new Account('alovelace', 'https://api.github.com', '', [], '', 1, ''), -+ new Account( -+ 'alovelace', -+ 'https://api.github.com', -+ '', -+ [], -+ '', -+ 1, -+ '', -+ [] -+ ), - ] - const repo = matchGitHubRepository( - accounts, -@@ -22,7 +31,16 @@ - - it('matches HTTPS URLs without the git extension', () => { - const accounts = [ -- new Account('alovelace', 'https://api.github.com', '', [], '', 1, ''), -+ new Account( -+ 'alovelace', -+ 'https://api.github.com', -+ '', -+ [], -+ '', -+ 1, -+ '', -+ [] -+ ), - ] - const repo = matchGitHubRepository( - accounts, -@@ -34,7 +52,16 @@ - - it('matches git URLs', () => { - const accounts = [ -- new Account('alovelace', 'https://api.github.com', '', [], '', 1, ''), -+ new Account( -+ 'alovelace', -+ 'https://api.github.com', -+ '', -+ [], -+ '', -+ 1, -+ '', -+ [] -+ ), - ] - const repo = matchGitHubRepository( - accounts, -@@ -46,7 +73,16 @@ - - it('matches SSH URLs', () => { - const accounts = [ -- new Account('alovelace', 'https://api.github.com', '', [], '', 1, ''), -+ new Account( -+ 'alovelace', -+ 'https://api.github.com', -+ '', -+ [], -+ '', -+ 1, -+ '', -+ [] -+ ), - ] - const repo = matchGitHubRepository( - accounts, -@@ -65,7 +101,8 @@ - [], - '', - 1, -- '' -+ '', -+ [] - ), - ] - const repo = matchGitHubRepository( -changed in both - base 100644 b017e5071b105d30e40c12577ba965bef3cfa5c2 app/yarn.lock - our 100644 cd6294bb698115d3ff652d361f00efbf85c1e781 app/yarn.lock - their 100644 f23287610c4f96793e0971118d7c4142cea56961 app/yarn.lock -@@ -95,6 +95,25 @@ - balanced-match "^1.0.0" - concat-map "0.0.1" - -+buffer-alloc-unsafe@^0.1.0: -+ version "0.1.1" -+ resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-0.1.1.tgz#ffe1f67551dd055737de253337bfe853dfab1a6a" -+ -+buffer-alloc@^1.1.0: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.1.0.tgz#05514d33bf1656d3540c684f65b1202e90eca303" -+ dependencies: -+ buffer-alloc-unsafe "^0.1.0" -+ buffer-fill "^0.1.0" -+ -+buffer-fill@^0.1.0: -+ version "0.1.1" -+ resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-0.1.1.tgz#76d825c4d6e50e06b7a31eb520c04d08cc235071" -+ -+buffer-from@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.0.0.tgz#4cb8832d23612589b0406e9e2956c17f06fdf531" -+ - byline@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" -@@ -175,7 +194,7 @@ - version "2.5.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" - --core-util-is@1.0.2: -+core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - -@@ -190,6 +209,27 @@ - version "0.0.2" - resolved "https://registry.yarnpkg.com/cross-unzip/-/cross-unzip-0.0.2.tgz#5183bc47a09559befcf98cc4657964999359372f" - -+<<<<<<< .our -+======= -+cryptiles@3.x.x: -+ version "3.1.2" -+ resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" -+ dependencies: -+ boom "5.x.x" -+ -+csv-parser@^1.6.0: -+ version "1.12.1" -+ resolved "https://registry.yarnpkg.com/csv-parser/-/csv-parser-1.12.1.tgz#391e1ef961b1f9dcb4c7c0f82eb450a1bd916158" -+ dependencies: -+ buffer-alloc "^1.1.0" -+ buffer-from "^1.0.0" -+ generate-function "^1.0.1" -+ generate-object-property "^1.0.0" -+ inherits "^2.0.1" -+ minimist "^1.2.0" -+ ndjson "^1.4.0" -+ -+>>>>>>> .their - cycle@1.0.x: - version "1.0.3" - resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" -@@ -377,6 +417,13 @@ - combined-stream "^1.0.5" - mime-types "^2.1.12" - -+from2@^2.1.1: -+ version "2.3.0" -+ resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" -+ dependencies: -+ inherits "^2.0.1" -+ readable-stream "^2.0.0" -+ - fs-extra@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.0.tgz#0f0afb290bb3deb87978da816fcd3c7797f3a817" -@@ -399,6 +446,23 @@ - version "0.6.0" - resolved "https://registry.yarnpkg.com/fuzzaldrin-plus/-/fuzzaldrin-plus-0.6.0.tgz#832f6489fbe876769459599c914a670ec22947ee" - -+generate-function@^1.0.1: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-1.1.0.tgz#54c21b080192b16d9877779c5bb81666e772365f" -+ -+generate-object-property@^1.0.0: -+ version "1.2.0" -+ resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" -+ dependencies: -+ is-property "^1.0.0" -+ -+get-stream@^2.1.0: -+ version "2.3.1" -+ resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" -+ dependencies: -+ object-assign "^4.0.1" -+ pinkie-promise "^2.0.0" -+ - getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" -@@ -466,10 +530,20 @@ - once "^1.3.0" - wrappy "1" - --inherits@2, inherits@~2.0.0: -+inherits@2, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - -+into-stream@^2.0.0: -+ version "2.0.1" -+ resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-2.0.1.tgz#db9b003694453eae091d8a5c84cc11507b781d31" -+ dependencies: -+ from2 "^2.1.1" -+ -+is-property@^1.0.0: -+ version "1.0.2" -+ resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" -+ - is-stream@^1.0.1, is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" -@@ -478,6 +552,10 @@ - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - -+isarray@~1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" -+ - isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" -@@ -509,7 +587,7 @@ - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - --json-stringify-safe@~5.0.1: -+json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - -@@ -585,6 +663,10 @@ - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - -+minimist@^1.2.0: -+ version "1.2.0" -+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" -+ - minipass@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.2.1.tgz#5ada97538b1027b4cf7213432428578cb564011f" -@@ -627,6 +709,23 @@ - version "2.8.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" - -+ndjson@^1.4.0: -+ version "1.5.0" -+ resolved "https://registry.yarnpkg.com/ndjson/-/ndjson-1.5.0.tgz#ae603b36b134bcec347b452422b0bf98d5832ec8" -+ dependencies: -+ json-stringify-safe "^5.0.1" -+ minimist "^1.2.0" -+ split2 "^2.1.0" -+ through2 "^2.0.3" -+ -+neat-csv@^2.1.0: -+ version "2.1.0" -+ resolved "https://registry.yarnpkg.com/neat-csv/-/neat-csv-2.1.0.tgz#06f58360c4c3b955bd467ddc85ae4511a3907a4c" -+ dependencies: -+ csv-parser "^1.6.0" -+ get-stream "^2.1.0" -+ into-stream "^2.0.0" -+ - node-fetch@^1.0.1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" -@@ -676,10 +775,38 @@ - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - -+pify@^2.2.0: -+ version "2.3.0" -+ resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" -+ -+pify@^3.0.0: -+ version "3.0.0" -+ resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" -+ -+pinkie-promise@^2.0.0: -+ version "2.0.1" -+ resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" -+ dependencies: -+ pinkie "^2.0.0" -+ -+pinkie@^2.0.0: -+ version "2.0.4" -+ resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" -+ - primer-support@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/primer-support/-/primer-support-4.3.0.tgz#c470fef8c0bff2ec8a771a0749783c2b388118fe" - -+process-exists@^3.1.0: -+ version "3.1.0" -+ resolved "https://registry.yarnpkg.com/process-exists/-/process-exists-3.1.0.tgz#86cae049e1e7b51382690ec9fd8dfd74ff7a17c8" -+ dependencies: -+ ps-list "^4.0.0" -+ -+process-nextick-args@~2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" -+ - progress@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" -@@ -698,6 +825,13 @@ - loose-envify "^1.3.1" - object-assign "^4.1.1" - -+ps-list@^4.0.0: -+ version "4.1.0" -+ resolved "https://registry.yarnpkg.com/ps-list/-/ps-list-4.1.0.tgz#8ffd6434add37f9dd1a9f19ab1beb42c9db60dae" -+ dependencies: -+ pify "^3.0.0" -+ tasklist "^3.1.0" -+ - pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" -@@ -770,6 +904,18 @@ - object-assign "^4.1.1" - prop-types "^15.6.0" - -+readable-stream@^2.0.0, readable-stream@^2.1.5: -+ version "2.3.6" -+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" -+ dependencies: -+ core-util-is "~1.0.0" -+ inherits "~2.0.3" -+ isarray "~1.0.0" -+ process-nextick-args "~2.0.0" -+ safe-buffer "~5.1.1" -+ string_decoder "~1.1.1" -+ util-deprecate "~1.0.1" -+ - regenerator-runtime@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1" -@@ -825,6 +971,14 @@ - version "5.1.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" - -+safe-buffer@~5.1.0, safe-buffer@~5.1.1: -+ version "5.1.2" -+ resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" -+ -+sec@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/sec/-/sec-1.0.0.tgz#033d60a3ad20ecf2e00940d14f97823465774335" -+ - semver@^5.3.0: - version "5.4.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" -@@ -843,6 +997,12 @@ - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - -+split2@^2.1.0: -+ version "2.2.0" -+ resolved "https://registry.yarnpkg.com/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493" -+ dependencies: -+ through2 "^2.0.2" -+ - sshpk@^1.7.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" -@@ -861,6 +1021,19 @@ - version "0.0.10" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" - -+<<<<<<< .our -+======= -+string_decoder@~1.1.1: -+ version "1.1.1" -+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" -+ dependencies: -+ safe-buffer "~5.1.0" -+ -+stringstream@~0.0.5: -+ version "0.0.5" -+ resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" -+ -+>>>>>>> .their - strip-ansi@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" -@@ -894,6 +1067,14 @@ - mkdirp "^0.5.0" - yallist "^3.0.2" - -+tasklist@^3.1.0: -+ version "3.1.0" -+ resolved "https://registry.yarnpkg.com/tasklist/-/tasklist-3.1.0.tgz#873a98a4e45cbdecfa2c2ee18865353057e63696" -+ dependencies: -+ neat-csv "^2.1.0" -+ pify "^2.2.0" -+ sec "^1.0.0" -+ - temp@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59" -@@ -905,6 +1086,13 @@ - version "3.0.2" - resolved "https://registry.yarnpkg.com/textarea-caret/-/textarea-caret-3.0.2.tgz#f360c48699aa1abf718680a43a31a850665c2caf" - -+through2@^2.0.2, through2@^2.0.3: -+ version "2.0.3" -+ resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" -+ dependencies: -+ readable-stream "^2.1.5" -+ xtend "~4.0.1" -+ - tough-cookie@~2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" -@@ -940,6 +1128,10 @@ - execa "^0.4.0" - mem "^0.1.0" - -+util-deprecate@~1.0.1: -+ version "1.0.2" -+ resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" -+ - uuid@^3.0.1, uuid@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" -@@ -1009,6 +1201,10 @@ - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - -+xtend@~4.0.1: -+ version "4.0.1" -+ resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" -+ - yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" -added in remote - their 100644 5b9fe3f8d1195e5d5cf3e5e8d20da8c832f8278a docs/technical/ssh-troubleshooting.md -@@ -0,0 +1,122 @@ -+# SSH Troubleshooting -+ -+This document outlines how Desktop inspects the SSH setup to address a number -+of common issues. -+ -+## Host Key Verification -+ -+As part of initializing the SSH connection, `ssh` will check that it knows -+and trusts the server it is connnecting to. When connecting to an unknown -+host, `ssh` will prompt to ask if you wish to trust this server: -+ -+```shellsession -+$ git fetch --progress --prune origin -+The authenticity of host 'github.com (192.30.255.112)' can't be established. -+RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8. -+Are you sure you want to continue connecting (yes/no)? -+``` -+ -+Desktop currently doesn't have a way to support interactive processes like -+this, so we need to hook into some configuration options and manually add this -+to the known hosts file that SSH uses. -+ -+To avoid the interactive prompt, adding `StrictHostKeyChecking=yes` as an -+option to `ssh` ensures that the Git operation will fail rather than hang -+waiting for user input: -+ -+```shellsession -+$ ssh -o StrictHostKeyChecking=yes git@github.com -+``` -+ -+To trust a new server, you can use `ssh-keygen`: -+ -+```shellsession -+$ ssh-keygen github.com >> ~/.ssh/known_hosts -+``` -+ -+This isn't currently available in `dugite`, but we can leverage either the -+OpenSSH environment that comes with Windows 10 Fall Creators Update (should -+be on `PATH`) or the version that comes with Git for Windows (need to add to -+`PATH`). macOS should have a working SSH setup by default, Linux will likely be -+in trouble if it's not on `PATH`. -+ -+## The `ssh-agent` process -+ -+The `ssh-agent` process is important to the SSH connection process, and needs -+to be running for the current user to handle SSH authentication on the local -+machine. -+ -+If no running `ssh-agent` process is found, Desktop could launch it's own -+instance of the process and ensure it is killed when Desktop exits. *This is -+currently out of scope for the proof-of-concept.* -+ -+As part of launching the `ssh-agent` process, it has a number of environment -+variables that help other tools integrate with it: -+ -+```shellsession -+$ ssh-agent -s -+SSH_AUTH_SOCK=/var/folders/dc/ww83254d73g8z6lc9y_msm9r0000gn/T//ssh-oerrG9QXPkWr/agent.15063; export SSH_AUTH_SOCK; -+SSH_AGENT_PID=15064; export SSH_AGENT_PID; -+echo Agent pid 15064; -+``` -+ -+Desktop needs to inspect these and pass them through to Git whenever it needs -+to do anything authentication-related. -+ -+## Working with SSH keys -+ -+After verifying the SSH server, and confirming a valid `ssh-agent` process is running, -+a valid public/private key pair is required that represents the identity of the user. -+ -+We can see the existing keys by running `ssh-add l`: -+ -+``` -+$ ssh-all -l -+4096 SHA256:V+fJ7HbKo3UindVz0x2XlZcZDr5GAd3p4+Ex7NnCCBI /Users/shiftkey/.ssh/id_rsa_new (RSA) -+``` -+ -+I'm not aware of any CLI tools for identifying available SSH keys, but we can assume -+with a good degree of confidence that we have pairs of files at `~/.ssh`: -+ -+``` -+$ ls ~/.ssh/ -+id_rsa id_rsa.pub id_rsa_new id_rsa_new.pub known_hosts -+``` -+ -+Desktop could list these in the application so that a user may add them to the `ssh-agent` -+process. -+ -+We can glean some identity information from the public key file - an email address that -+was used when it was created - and the name of the file. This should be enough to help -+the user identify the right key to add. -+ -+We can tell if a private key requires a passphrase by the header contents. Here's a key -+that doesn't require a passphrase: -+ -+``` -+-----BEGIN RSA PRIVATE KEY----- -+MIIEogIBAAKCAQEA3qKD/4PAc6PMb1yCckTduFl5fA1OpURLR5Z+T4xY1JQt3eTM -+``` -+ -+And this is the header of a key that requires a passphrase: -+ -+``` -+-----BEGIN RSA PRIVATE KEY----- -+Proc-Type: 4,ENCRYPTED -+DEK-Info: DES-EDE3-CBC,556C1115CDA822F5 -+ -+AHi/3++6PEIBv4kfpM57McyoSAAaT2ECxNOA5DRKxJQ9pr2D3aUeMBaBfWGrxd/Q -+``` -+ -+## Creating a new public/private key pair -+ -+If no suitable keys are found, the user should be able to create a new SSH key. This -+can be done from the command line: -+ -+``` -+ssh-keygen -q -b 4096 -t rsa -N new_passphrase -f output_keyfile -+``` -+ -+Desktop should use a naming convention to make it clear that it was the source of the key, -+to ensure it doesn't interfere with existing keys from other sources. Something -+like `~/.ssh/github_desktop_[login]` would be radical. diff --git a/app/test/fixtures/merge-parser/desktop/merge-fancy-text-styles-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-fancy-text-styles-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 020dc584476..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-fancy-text-styles-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,135 +0,0 @@ -changed in both - base 100644 d02e36c9009634ccb346c8a6c1434e7c6f5ad0fd app/src/ui/history/compare-branch-list-item.tsx - our 100644 16d4efb540d90ba9514f7b5da356f9fa5372e2f6 app/src/ui/history/compare-branch-list-item.tsx - their 100644 2d266eae4e2b9acd270381a0ed475ae313dcbb82 app/src/ui/history/compare-branch-list-item.tsx -@@ -46,10 +46,21 @@ - <div className="branches-list-item"> - <Octicon className="icon" symbol={icon} /> - <div className="name" title={branch.name}> -+<<<<<<< .our - <HighlightText - text={branch.name} - highlight={this.props.matches.title} - /> -+======= -+ <HighlightText text={branch.name} highlight={this.props.matches} /> -+ </div> -+ <div className="branch-commit-counter"> -+ {compareState.behind} -+ <Octicon className="icon" symbol={OcticonSymbol.arrowDown} /> -+ -+ {compareState.ahead} -+ <Octicon className="icon" symbol={OcticonSymbol.arrowUp} /> -+>>>>>>> .their - </div> - {aheadBehindElement} - </div> -changed in both - base 100644 139bfeb886fa8e696d4972ab1b03b8b9acf1cb7a app/src/ui/history/compare.tsx - our 100644 c0be0e26ce79b9a590edfa3a9fd3718fa58782d4 app/src/ui/history/compare.tsx - their 100644 55a17f0b4f3862c9159bb6c23fc2f12272244106 app/src/ui/history/compare.tsx -@@ -168,8 +168,14 @@ - type="search" - placeholder={placeholderText} - onFocus={this.onTextBoxFocused} -+<<<<<<< .our - value={filterText} - disabled={allBranches.length === 0} -+======= -+ onBlur={this.onTextBoxBlurred} -+ type="search" -+ value={this.state.filterText} -+>>>>>>> .their - onRef={this.onTextBoxRef} - onValueChanged={this.onBranchFilterTextChanged} - onKeyDown={this.onBranchFilterKeyDown} -@@ -541,10 +547,28 @@ - }) - } - -+<<<<<<< .our - private onTextBoxFocused = () => { - this.props.dispatcher.updateCompareForm(this.props.repository, { - showBranchList: true, - }) -+======= -+ private onTextBoxBlurred = () => { -+ this.setState({ showFilterList: false }) -+ -+ let selectedBranch: Branch | null = this.state.selectedBranch -+ if (selectedBranch === null) { -+ return -+ } -+ -+ let filterText = this.state.filterText -+ -+ if (filterText == "") { -+ this.setState({ selectedBranch: null}) -+ } else { -+ this.setState({ filterText: selectedBranch.name }) -+ } -+>>>>>>> .their - } - - private onTextBoxRef = (textbox: TextBox) => { -changed in both - base 100644 4271917183b0f57f7a03ba7349674c28798a2550 app/styles/ui/_fancy-text-box.scss - our 100644 479e9f6732ddc2b29c19b24585f4bb315001226a app/styles/ui/_fancy-text-box.scss - their 100644 cdda3ebe09db31ac82f504a3b57d17d77cfb6833 app/styles/ui/_fancy-text-box.scss -@@ -9,11 +9,20 @@ - - .fancy-octicon { - height: var(--text-field-height); -+<<<<<<< .our - padding: var(--spacing-half) 0 var(--spacing-half) 7px; - border-right: none; - border-radius: var(--border-radius) 0 0 var(--border-radius); - opacity: 0.5; - transition: opacity 0.2s ease; -+======= -+ padding: var(--spacing-half) var(--spacing-half) var(--spacing-half) 7px; -+ border-right: none; -+ border-radius: var(--border-radius) 0 0 var(--border-radius); -+ -+ opacity: 0.5; -+ transition: opacity 0.15s ease; -+>>>>>>> .their - } - - &.focused { -@@ -29,6 +38,7 @@ - border-radius: 0 var(--border-radius) var(--border-radius) 0; - border: none; - box-shadow: none; -+ padding-left: 0; - - &:focus { - box-shadow: none; -changed in both - base 100644 22c5f28660a40f9788eeb78f33d6c64e1ad7bfd1 app/styles/ui/history/_history.scss - our 100644 58cea508b02182fa4f45daf88643d33c3b2dd020 app/styles/ui/history/_history.scss - their 100644 95d8616b58bad57c8fc2c8b2789483b1e42cfce6 app/styles/ui/history/_history.scss -@@ -94,6 +94,7 @@ - color: var(--text-secondary-color); - display: flex; - justify-content: flex-end; -+<<<<<<< .our - flex: 1; - font-size: var(--font-size-sm); - -@@ -111,6 +112,15 @@ - width: 8px; - margin-left: 1px; - -+======= -+ font-size: var(--font-size-sm); -+ color: var(--text-secondary-color); -+ flex-grow: 1; -+ -+ .octicon { -+ fill: var(--text-secondary-color); -+ -+>>>>>>> .their - &:last-child { - margin-right: 0; - } diff --git a/app/test/fixtures/merge-parser/desktop/merge-gimme-the-goods-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-gimme-the-goods-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 5540d8e229c..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-gimme-the-goods-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,22 +0,0 @@ -changed in both - base 100644 8bf4aa60727c67bb0f9ec9ce46a631ee919daac8 app/src/ui/app.tsx - our 100644 c38c806e36c237ea70f3cdeee739941530c0c7cd app/src/ui/app.tsx - their 100644 f0f8051c637fbfc7f8d273ad2b92d4c56d725ea0 app/src/ui/app.tsx -@@ -139,6 +139,7 @@ - public constructor(props: IAppProps) { - super(props) - -+<<<<<<< .our - registerContextualMenuActionDispatcher() - - props.dispatcher.loadInitialState().then(() => { -@@ -167,6 +168,9 @@ - }, UpdateRepositoryIndicatorInterval) - }, InitialRepositoryIndicatorTimeout) - }) -+======= -+ setTimeout(() => this.props.dispatcher.setUpdateBannerVisibility(true), 3000) -+>>>>>>> .their - - this.state = props.appStore.getState() - props.appStore.onDidUpdate(state => { diff --git a/app/test/fixtures/merge-parser/desktop/merge-ignore-should-remove-tracked-files-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-ignore-should-remove-tracked-files-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 838f1659d6e..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-ignore-should-remove-tracked-files-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,179 +0,0 @@ -changed in both - base 100644 38302823efd1dd629fd5d560fb2a67a3cbafc143 app/src/lib/file-system.ts - our 100644 a696107c681c84a8da5190495b8d23ee51f935e9 app/src/lib/file-system.ts - their 100644 22a97568b80cd2991a010d33d464db2a3e075f65 app/src/lib/file-system.ts -@@ -86,6 +86,7 @@ - } - - /** -+<<<<<<< .our - * Read a specific region from a file. - * - * @param path Path to the file -@@ -110,5 +111,20 @@ - }) - .on('error', reject) - .on('end', () => resolve(Buffer.concat(chunks, total))) -+======= -+ * Helper function to promisify fs.unlink for deleting a file from disk. -+ * -+ * @param path Path to delete from disk. -+ */ -+export function removeFile(path: string): Promise<void> { -+ return new Promise<void>((resolve, reject) => { -+ Fs.unlink(path, error => { -+ if (error) { -+ reject(error) -+ } else { -+ resolve() -+ } -+ }) -+>>>>>>> .their - }) - } -changed in both - base 100644 cc8f049009ace9094a0307160770ffdcd0217554 app/src/lib/stores/git-store.ts - our 100644 f8eedeb9d958345be59538b82b1b69cd4326d73b app/src/lib/stores/git-store.ts - their 100644 a3663f99a48bea061a1ae1a3689c745b31378b21 app/src/lib/stores/git-store.ts -@@ -19,6 +19,7 @@ - import { structuralEquals } from '../../lib/equality' - import { compare } from '../../lib/compare' - import { queueWorkHigh } from '../../lib/queue-work' -+import { removeFile, pathExists } from '../../lib/file-system' - - import { - reset, -@@ -1120,6 +1121,89 @@ - this.emitUpdate() - } - -+<<<<<<< .our -+======= -+ /** -+ * Read the contents of the repository .gitignore. -+ * -+ * Returns a promise which will either be rejected or resolved -+ * with the contents of the file. If there's no .gitignore file -+ * in the repository root the promise will resolve with null. -+ */ -+ public async readGitIgnore(): Promise<string | null> { -+ const repository = this.repository -+ const ignorePath = Path.join(repository.path, '.gitignore') -+ -+ return new Promise<string | null>((resolve, reject) => { -+ Fs.readFile(ignorePath, 'utf8', (err, data) => { -+ if (err) { -+ if (err.code === 'ENOENT') { -+ resolve(null) -+ } else { -+ reject(err) -+ } -+ } else { -+ resolve(data) -+ } -+ }) -+ }) -+ } -+ -+ /** -+ * Persist the given content to the repository root .gitignore. -+ * -+ * If the repository root doesn't contain a .gitignore file one -+ * will be created, otherwise the current file will be overwritten. -+ */ -+ public async saveGitIgnore(text: string): Promise<void> { -+ const repository = this.repository -+ const ignorePath = Path.join(repository.path, '.gitignore') -+ const fileContents = await formatGitIgnoreContents(text, repository) -+ -+ return new Promise<void>((resolve, reject) => { -+ Fs.writeFile(ignorePath, fileContents, err => { -+ if (err) { -+ reject(err) -+ } else { -+ resolve() -+ } -+ }) -+ }) -+ } -+ -+ /** Ignore the given path or pattern. */ -+ public async ignore(pattern: string): Promise<void> { -+ const repository = this.repository -+ -+ if (pattern.startsWith('*')) { -+ // TODO: scan filesystem for all entries matching this expression -+ } else { -+ const status = await getStatus(repository) -+ const match = status.workingDirectory.files.find(p => p.path === pattern) -+ if (match) { -+ // if we have pending changes against this file, discard it -+ // using the workflow defined by the user -+ await this.discardChanges([match]) -+ } -+ -+ // the file is tracked but has no pending changes, just remove it -+ const path = Path.join(repository.path, pattern) -+ const exists = await pathExists(path) -+ if (exists) { -+ await removeFile(path) -+ } -+ } -+ -+ const text = (await this.readGitIgnore()) || '' -+ const currentContents = await formatGitIgnoreContents(text, repository) -+ const newText = await formatGitIgnoreContents( -+ `${currentContents}${pattern}`, -+ repository -+ ) -+ await this.saveGitIgnore(newText) -+ } -+ -+>>>>>>> .their - public async discardChanges( - files: ReadonlyArray<WorkingDirectoryFileChange> - ): Promise<void> { -changed in both - base 100644 27231087354abe691390aa5bacabd63762a47b60 app/test/unit/git-store-test.ts - our 100644 916df52e71502aa756ade2e09be78d7398a4c7f0 app/test/unit/git-store-test.ts - their 100644 e9b803d0240aad0fd503071fde85aca1aeac0765 app/test/unit/git-store-test.ts -@@ -68,6 +68,39 @@ - files = status.workingDirectory.files - - expect(files.length).to.equal(1) -+<<<<<<< .our -+======= -+ expect(files[0].path).to.equal('README.md') -+ expect(files[0].status).to.equal(AppFileStatus.Modified) -+ }) -+ -+ it('discarding a tracked file will remove it from disk', async () => { -+ const repo = await setupEmptyRepository() -+ const gitStore = new GitStore(repo, shell) -+ -+ const relativeFilePath = Path.join('directory', 'README.txt') -+ const filePath = Path.join(repo.path, relativeFilePath) -+ -+ Fs.mkdirSync(Path.join(repo.path, 'directory')) -+ -+ Fs.writeFileSync(filePath, 'SOME WORDS GO HERE\n') -+ -+ // commit the file so it's tracked -+ await GitProcess.exec(['add', relativeFilePath], repo.path) -+ await GitProcess.exec(['commit', '-m', 'added file'], repo.path) -+ -+ // ignore the tracked file -+ await gitStore.ignore(relativeFilePath) -+ -+ const status = await getStatus(repo) -+ const files = status.workingDirectory.files -+ -+ expect(files.length).to.equal(2) -+ expect(files[0].path).equals(relativeFilePath) -+ expect(files[0].status).equals(AppFileStatus.Deleted) -+ expect(files[1].path).equals('.gitignore') -+ expect(files[1].status).equals(AppFileStatus.New) -+>>>>>>> .their - }) - - it('can discard a renamed file', async () => { diff --git a/app/test/fixtures/merge-parser/desktop/merge-introduce-better-replacements-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-introduce-better-replacements-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 68187673aaf..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-introduce-better-replacements-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,576 +0,0 @@ -added in remote - their 100644 ce778fb8220cf3bb06f2a50def39f74aa683fc7d app/app-info.d.ts -@@ -0,0 +1,2 @@ -+export function getReplacements(): any -+export function getCLICommands(): string[] -added in remote - their 100644 e9375cea93e985e937ff8b587b21652a37afb605 app/app-info.js -@@ -0,0 +1,97 @@ -+'use strict' -+ -+const fs = require('fs') -+const path = require('path') -+ -+const gitInfo = require('./git-info') -+const distInfo = require('../script/dist-info') -+ -+const projectRoot = path.join(__dirname, '..') -+ -+const devClientId = '3a723b10ac5575cc5bb9' -+const devClientSecret = '22c34d87789a365981ed921352a7b9a8c3f69d54' -+ -+const channel = distInfo.getReleaseChannel() -+ -+function getCLICommands() { -+ return ( -+ // eslint-disable-next-line no-sync -+ fs -+ .readdirSync(path.resolve(projectRoot, 'app', 'src', 'cli', 'commands')) -+ .filter(name => name.endsWith('.ts')) -+ .map(name => name.replace(/\.ts$/, '')) -+ ) -+} -+ -+function s(text) { -+ return JSON.stringify(text) -+} -+ -+function getMenuPlaceholders() { -+ if (process.platform === 'darwin') { -+ return { -+ __MENU_SHOW_LOGS_IN_FILE_MANAGER__: s('Show Logs in Finder'), -+ __MENU_SHOW_IN_FILE_MANAGER__: s('Show in Finder'), -+ } -+ } -+ if (process.platform === 'win32') { -+ return { -+ __MENU_SHOW_LOGS_IN_FILE_MANAGER__: s('S&how Logs in Explorer'), -+ __MENU_SHOW_IN_FILE_MANAGER__: s('Show in E&xplorer'), -+ } -+ } -+ return { -+ __MENU_SHOW_LOGS_IN_FILE_MANAGER__: s('Show logs in File Manager'), -+ __MENU_SHOW_IN_FILE_MANAGER__: s('Show in File Manager'), -+ } -+} -+ -+function getPlatformPlaceholders() { -+ if (process.platform === 'darwin') { -+ return { -+ __LABEL_SHOW_IN_FILE_MANAGER__: s('Show in Finder'), -+ __LABEL_REVEAL_IN_FILE_MANAGER__: s('Reveal in Finder'), -+ __LABEL_FILE_MANAGER_NAME__: s('Finder'), -+ } -+ } -+ if (process.platform === 'win32') { -+ return { -+ __LABEL_SHOW_IN_FILE_MANAGER__: s('Show in Explorer'), -+ __LABEL_REVEAL_IN_FILE_MANAGER__: s('Show in Explorer'), -+ __LABEL_FILE_MANAGER_NAME__: s('Explorer'), -+ } -+ } -+ return { -+ __LABEL_SHOW_IN_FILE_MANAGER__: s('Show in File Manager'), -+ __LABEL_REVEAL_IN_FILE_MANAGER__: s('Show in File Manager'), -+ __LABEL_FILE_MANAGER_NAME__: s('File Manager'), -+ } -+} -+ -+function getReplacements() { -+ const replacements = { -+ __OAUTH_CLIENT_ID__: s(process.env.DESKTOP_OAUTH_CLIENT_ID || devClientId), -+ __OAUTH_SECRET__: s( -+ process.env.DESKTOP_OAUTH_CLIENT_SECRET || devClientSecret -+ ), -+ __DARWIN__: process.platform === 'darwin', -+ __WIN32__: process.platform === 'win32', -+ __LINUX__: process.platform === 'linux', -+ __DEV__: channel === 'development', -+ __RELEASE_CHANNEL__: s(channel), -+ __UPDATES_URL__: s(distInfo.getUpdatesURL()), -+ __SHA__: s(gitInfo.getSHA()), -+ __CLI_COMMANDS__: s(getCLICommands()), -+ 'process.platform': s(process.platform), -+ 'process.env.NODE_ENV': s(process.env.NODE_ENV || 'development'), -+ 'process.env.TEST_ENV': s(process.env.TEST_ENV), -+ } -+ -+ return Object.assign( -+ replacements, -+ getMenuPlaceholders(), -+ getPlatformPlaceholders() -+ ) -+} -+ -+module.exports = { getReplacements, getCLICommands } -added in remote - their 100644 db784cfd0f0a6592eb885f2049f8afc835d6e910 app/git-info.d.ts -@@ -0,0 +1 @@ -+export function getSHA(): string -added in remote - their 100644 ed5b62cd3a8bd2c5eddea48944f85e3716fb2e4e app/git-info.js -@@ -0,0 +1,45 @@ -+'use strict' -+ -+const fs = require('fs') -+const path = require('path') -+ -+/** -+ * Attempt to dereference the given ref without requiring a Git environment -+ * to be present. Note that this method will not be able to dereference packed -+ * refs but should suffice for simple refs like 'HEAD'. -+ * -+ * Will throw an error for unborn HEAD. -+ * -+ * @param {string} gitDir The path to the Git repository's .git directory -+ * @param {string} ref A qualified git ref such as 'HEAD' or 'refs/heads/master' -+ */ -+function revParse(gitDir, ref) { -+ const refPath = path.join(gitDir, ref) -+ // eslint-disable-next-line no-sync -+ const refContents = fs.readFileSync(refPath) -+ const refRe = /^([a-f0-9]{40})|(?:ref: (refs\/.*))$/m -+ const refMatch = refRe.exec(refContents) -+ -+ if (!refMatch) { -+ throw new Error( -+ `Could not de-reference HEAD to SHA, invalid ref in ${refPath}: ${refContents}` -+ ) -+ } -+ -+ return refMatch[1] || revParse(gitDir, refMatch[2]) -+} -+ -+function getSHA() { -+ // CircleCI does some funny stuff where HEAD points to an packed ref, but -+ // luckily it gives us the SHA we want in the environment. -+ const circleSHA = process.env.CIRCLE_SHA1 -+ if (circleSHA) { -+ return circleSHA -+ } -+ -+ return revParse(path.resolve(__dirname, '../.git'), 'HEAD') -+} -+ -+module.exports = { -+ getSHA, -+} -added in remote - their 100644 5f169d7f8e0a82168c2c13ea3ba71b5b101f0c73 app/package-info.d.ts -@@ -0,0 +1,4 @@ -+export function getProductName(): string -+export function getCompanyName(): string -+export function getVersion(): string -+export function getBundleID(): string -added in remote - their 100644 b63ebe090392d9f6829519ac340cbba3901300cb app/package-info.js -@@ -0,0 +1,33 @@ -+'use strict' -+ -+const path = require('path') -+ -+const projectRoot = __dirname -+// eslint-disable-next-line import/no-dynamic-require -+const appPackage = require(path.join(projectRoot, 'package.json')) -+ -+function getProductName() { -+ const productName = appPackage.productName -+ return process.env.NODE_ENV === 'development' -+ ? `${productName}-dev` -+ : productName -+} -+ -+function getCompanyName() { -+ return appPackage.companyName -+} -+ -+function getVersion() { -+ return appPackage.version -+} -+ -+function getBundleID() { -+ return appPackage.bundleID -+} -+ -+module.exports = { -+ getProductName, -+ getCompanyName, -+ getVersion, -+ getBundleID, -+} -removed in local - base 100644 a58f983c1c4806ad8157926803f1ab7256857ab6 app/src/cli/dev-commands-global.js - their 100644 66965ffb5ca93dbeaa3562652443adc8c8dd4715 app/src/cli/dev-commands-global.js -changed in both - base 100644 3d47d297a07a66a4b8bd3c47a91a7afb05bc89de app/src/lib/globals.d.ts - our 100644 fe0ba976e925a57a73938c30e3022a0b0c08fbde app/src/lib/globals.d.ts - their 100644 9198f6c831eb62c89c9918398040157af4a61d93 app/src/lib/globals.d.ts -@@ -47,6 +47,21 @@ - | 'highlighter' - - /** -+ * These menu entries are separated because Windows and Linux can use -+ * accelerators( ??? TODO: that's not the right phrase) to select a -+ * menu item immediately. They need to be reviewed to ensure no clashes -+ * wtih other shortcuts. -+ */ -+declare const __MENU_SHOW_LOGS_IN_FILE_MANAGER__: string -+declare const __MENU_SHOW_IN_FILE_MANAGER__: string -+ -+/** -+ * These labels are placeholders in the UI which are platform-specific -+ */ -+declare const __LABEL_SHOW_IN_FILE_MANAGER__: string -+declare const __LABEL_REVEAL_IN_FILE_MANAGER__: string -+declare const __LABEL_FILE_MANAGER_NAME__: string -+/** - * The DOMHighResTimeStamp type is a double and is used to store a time value. - * - * The value could be a discrete point in time or the difference in time between -changed in both - base 100644 016352958fee4c32ceec3490f242718d85866eb0 app/src/main-process/menu/build-default-menu.ts - our 100644 7ec8c001136d655a2ecce3d56b9a6804762172fa app/src/main-process/menu/build-default-menu.ts - their 100644 b90b828c557d054bbb2ca270e124c120059c451e app/src/main-process/menu/build-default-menu.ts -@@ -239,7 +239,7 @@ - click: emit('open-in-shell'), - }, - { -- label: __DARWIN__ ? 'Show in Finder' : 'Show in E&xplorer', -+ label: __MENU_SHOW_IN_FILE_MANAGER__, - id: 'open-working-directory', - accelerator: 'CmdOrCtrl+Shift+F', - click: emit('open-working-directory'), -@@ -361,7 +361,11 @@ - : 'S&how logs in your File Manager' - - const showLogsItem: Electron.MenuItemConstructorOptions = { -+<<<<<<< .our - label: showLogsLabel, -+======= -+ label: __MENU_SHOW_LOGS_IN_FILE_MANAGER__, -+>>>>>>> .their - click() { - const logPath = getLogDirectoryPath() - ensureDir(logPath) -changed in both - base 100644 c3a83c0d056030cd4c92a23e0d8a2ac38326de32 app/src/ui/changes/changed-file.tsx - our 100644 e68da78b55ca434ace46ff94982da3e9897bfb4c app/src/ui/changes/changed-file.tsx - their 100644 afba1373ff7fa239c33b089daa5288457375e9f3 app/src/ui/changes/changed-file.tsx -@@ -85,12 +85,61 @@ - ) - } - -+<<<<<<< .our - private onContextMenu = (event: React.MouseEvent<HTMLDivElement>) => { - this.props.onContextMenu( - this.props.id, - this.props.path, - this.props.status, - event -+======= -+ private onContextMenu = (event: React.MouseEvent<any>) => { -+ event.preventDefault() -+ -+ const extension = Path.extname(this.props.path) -+ const fileName = Path.basename(this.props.path) -+ const items: IMenuItem[] = [ -+ { -+ label: __DARWIN__ ? 'Discard Changes…' : 'Discard changes…', -+ action: () => this.props.onDiscardChanges(this.props.path), -+ }, -+ { type: 'separator' }, -+ { -+ label: 'Ignore', -+ action: () => this.props.onIgnore(this.props.path), -+ enabled: fileName !== GitIgnoreFileName, -+ }, -+ ] -+ -+ if (extension.length) { -+ items.push({ -+ label: __DARWIN__ -+ ? `Ignore All ${extension} Files` -+ : `Ignore all ${extension} files`, -+ action: () => this.props.onIgnore(`*${extension}`), -+ enabled: fileName !== GitIgnoreFileName, -+ }) -+ } -+ -+ const isSafeExtension = __WIN32__ -+ ? RestrictedFileExtensions.indexOf(extension.toLowerCase()) === -1 -+ : true -+ -+ items.push( -+ { type: 'separator' }, -+ { -+ label: __LABEL_REVEAL_IN_FILE_MANAGER__, -+ action: () => this.props.onRevealInFileManager(this.props.path), -+ enabled: this.props.status !== AppFileStatus.Deleted, -+ }, -+ { -+ label: __DARWIN__ -+ ? 'Open with Default Program' -+ : 'Open with default program', -+ action: () => this.props.onOpenItem(this.props.path), -+ enabled: isSafeExtension && this.props.status !== AppFileStatus.Deleted, -+ } -+>>>>>>> .their - ) - } - } -changed in both - base 100644 901ac03d27e9d3b6f3a6f56acd7e91afcf61bd02 app/src/ui/changes/no-changes.tsx - our 100644 090ffa423a170c926a8b7fdcd04748ff3bd2d416 app/src/ui/changes/no-changes.tsx - their 100644 3726d27cd5c5ca5058c8841358aa62f41add47cc app/src/ui/changes/no-changes.tsx -@@ -17,11 +17,14 @@ - /** The component to display when there are no local changes. */ - export class NoChanges extends React.Component<INoChangesProps, {}> { - public render() { -+<<<<<<< .our - const opener = __DARWIN__ - ? 'Finder' - : __WIN32__ - ? 'Explorer' - : 'your File Manager' -+======= -+>>>>>>> .their - return ( - <div className="panel blankslate" id="no-changes"> - <img src={BlankSlateImage} className="blankslate-image" /> -@@ -30,7 +33,7 @@ - <div> - Would you like to{' '} - <LinkButton onClick={this.open}>open this repository</LinkButton> in{' '} -- {opener}? -+ {__LABEL_FILE_MANAGER_NAME__}? - </div> - </div> - ) -changed in both - base 100644 b86cbe8974dc08a9094c6325dc75a8aab4e2c2a6 app/src/ui/repositories-list/repository-list-item.tsx - our 100644 6ca3c771c795eba242cc4b795e3a3b0bbb4c7488 app/src/ui/repositories-list/repository-list-item.tsx - their 100644 96859e6008e6261735e64176598dac27b55de88f app/src/ui/repositories-list/repository-list-item.tsx -@@ -163,7 +163,11 @@ - enabled: !missing, - }, - { -+<<<<<<< .our - label: showRepositoryLabel, -+======= -+ label: __LABEL_SHOW_IN_FILE_MANAGER__, -+>>>>>>> .their - action: this.showRepository, - enabled: !missing, - }, -removed in local - base 100644 729101a5c3680282efc1c1b269ca5f691218fc6c app/webpack.common.js - their 100644 6e0b7be8dd3b7d756f24723124ec71399226c3b1 app/webpack.common.js -added in both - our 100644 348333d12c84aba9cf5ec7404d91e9a8c2816d07 docs/technical/placeholders.md - their 100644 c0f6ec5a0026ef52f8f7826f8a15a72f528a2bc0 docs/technical/placeholders.md -@@ -29,12 +29,20 @@ - - ### Replacements - -+<<<<<<< .our - The replacements defined for Desktop are found in [`app/app-info.ts`](https://github.com/desktop/desktop/blob/master/app/app-info.ts) -+======= -+The replacements defined for Desktop are found in [`app/app-info.js`](https://github.com/desktop/desktop/blob/master/app/app-info.js) -+>>>>>>> .their - as a hash of key-value pairs. - - ```ts - function getReplacements() { -+<<<<<<< .our - return { -+======= -+ const replacements = { -+>>>>>>> .their - __OAUTH_CLIENT_ID__: s(process.env.DESKTOP_OAUTH_CLIENT_ID || devClientId), - __OAUTH_SECRET__: s( - process.env.DESKTOP_OAUTH_CLIENT_SECRET || devClientSecret -@@ -51,11 +59,20 @@ - 'process.env.NODE_ENV': s(process.env.NODE_ENV || 'development'), - 'process.env.TEST_ENV': s(process.env.TEST_ENV), - } -+<<<<<<< .our -+======= -+ -+ ... -+>>>>>>> .their - } - ``` - - This means we can embed values at build time based on the current platform. -+<<<<<<< .our - Note the values we are embedding for `__DARWIN__` and `__WIN32__`: -+======= -+Note the values we are embeddeding for `__DARWIN__` and `__WIN32__`: -+>>>>>>> .their - - ```ts - __DARWIN__: process.platform === 'darwin', -@@ -118,3 +135,94 @@ - - As a convention, globals which should be replaced by Webpack should be prefixed - and suffixed with two underscores, e.g. `__DEV__`. -+<<<<<<< .our -+======= -+ -+### Platform-specific Menu Items -+ -+There are a few places in Desktop where a label depends on the platform the -+app is executing on. For the most part, we use "CamelCase" for labels on macOS -+and "Sentence case" on Windows and Linux, like this: -+ -+```ts -+ { -+ id: 'view-repository-on-github', -+ label: __DARWIN__ ? 'View on GitHub' : '&View on GitHub', -+ accelerator: 'CmdOrCtrl+Shift+G', -+ click: emit('view-repository-on-github'), -+ }, -+``` -+ -+Note how the Windows case has a `&` prefixing the `V` - this is so you can -+select the menu item directly by pressing <kbd>ALT</kbd>, then <kbd>V</kbd>. -+ -+For situations where a menu item needs to display something unique for each -+platform, these should be defined as placeholders. The prefix `__MENU_` should -+be used to group these. -+ -+The corresponding platform-specific values must be added to [`app/app-info.js`](https://github.com/desktop/desktop/blob/master/app/app-info.js), -+in the `getMenuPlaceholders()` function: -+ -+```ts -+function getMenuPlaceholders() { -+ if (process.platform === 'darwin') { -+ return { -+ __MENU_SHOW_LOGS_IN_FILE_MANAGER__: s('Show Logs in Finder'), -+ __MENU_SHOW_IN_FILE_MANAGER__: s('Show in Finder'), -+ } -+ } -+ -+ if (process.platform === 'win32') { -+ return { -+ __MENU_SHOW_LOGS_IN_FILE_MANAGER__: s('S&how Logs in Explorer'), -+ __MENU_SHOW_IN_FILE_MANAGER__: s('Show in E&xplorer'), -+ } -+ } -+ -+ // other platforms follow -+} -+``` -+ -+Ensure these placeholders also exist as globals under -+[`app/src/lib/globals.ts`](https://github.com/desktop/desktop/blob/master/app/src/lib/globals.d.ts). -+ -+ -+```ts -+/** -+ * These menu entries are separated because Windows and Linux can use -+ * chords to select a menu item immediately. They need to be reviewed -+ * to ensure no clashes wtih other shortcuts. -+ */ -+declare const __MENU_SHOW_LOGS_IN_FILE_MANAGER__: string -+declare const __MENU_SHOW_IN_FILE_MANAGER__: string -+``` -+ -+### Platform-specific Labels -+ -+For other places in the user interface that will differ per-platform, -+the `getPlatformPlaceholders()` method should contain all the necessary -+values: -+ -+```js -+function getPlatformPlaceholders() { -+ if (process.platform === 'darwin') { -+ return { -+ __LABEL_SHOW_IN_FILE_MANAGER__: s('Show in Finder'), -+ __LABEL_REVEAL_IN_FILE_MANAGER__: s('Reveal in Finder'), -+ __LABEL_FILE_MANAGER_NAME__: s('Finder'), -+ } -+ } -+ if (process.platform === 'win32') { -+ return { -+ __LABEL_SHOW_IN_FILE_MANAGER__: s('Show in Explorer'), -+ __LABEL_REVEAL_IN_FILE_MANAGER__: s('Show in Explorer'), -+ __LABEL_FILE_MANAGER_NAME__: s('Explorer'), -+ } -+ } -+ // other platforms follow -+} -+``` -+ -+These placeholders all use the `__LABEL_` prefix to distinguish them from -+assist with grouping. -+>>>>>>> .their -changed in both - base 100755 fdf7384765afe667e3c7ad464e91c4935df2b730 script/build.ts - our 100755 7ac3a6cca1891f1f8c80839d46bb4d24e786b9ec script/build.ts - their 100755 2de7a081c11075424df87fe4217bc48898304cd8 script/build.ts -removed in local - base 100644 6efaf5dfca90856795f77f2989ad069ca405d2a8 script/dist-info.d.ts - their 100644 761dea8563e41854304fb72b473ef14d0ead525f script/dist-info.d.ts -removed in local - base 100644 f86eb9117e0bdef70457ed926ce65438fef6eb5b script/dist-info.js - their 100644 d5eb68e16988ef0dcebe7a748f61605243af684f script/dist-info.js -changed in both - base 100644 087d65a5c81208b45beeaf4a481c160e2087edef script/eslint.ts - our 100644 c71f2850346b76957d6eb4312308b15714d08361 script/eslint.ts - their 100644 7b1691ce918636c3b0591a1ef8f97dad84324960 script/eslint.ts -@@ -16,7 +16,11 @@ - const report = eslint.executeOnFiles([ - './{script,eslint-rules}/**/*.{j,t}s?(x)', - './tslint-rules/**/*.ts', -+<<<<<<< .our - './app/*.ts', -+======= -+ './app/*.js', -+>>>>>>> .their - './app/{src,typings,test}/**/*.{j,t}s?(x)', - './changelog.json', - ]) -changed in both - base 100644 baf89215dcf90428d5ab228276c63be1a932debc script/package.ts - our 100644 e72d5c172dc7cce7d763ef3579d7df105b2e26a1 script/package.ts - their 100644 a25a47e9ca631b6f926b39b6287c666028475826 script/package.ts -removed in local - base 100644 68f1b2a52f7b60c732f580edb12a5e37839976b6 script/publish - their 100644 f35bab9d856bd56ef8fdaec3842adb4ba6955087 script/publish -changed in both - base 100644 b0018667cb9ff103bf39eba89bc10622556fba0c script/review-logs.ts - our 100644 903faa6e50dc2fafc46924b0438baa3b9e6f634b script/review-logs.ts - their 100644 fc301ecd2b18abd63ca90949cdcd7453de26f832 script/review-logs.ts -@@ -8,6 +8,7 @@ - - function getUserDataPath() { - if (process.platform === 'win32') { -+<<<<<<< .our - if (process.env.APPDATA) { - return path.join(process.env.APPDATA, getExecutableName()) - } else { -@@ -15,6 +16,9 @@ - `Unable to find the application data directory on Windows :(` - ) - } -+======= -+ return path.join(process.env.APPDATA, getExecutableName()) -+>>>>>>> .their - } else if (process.platform === 'darwin') { - const home = os.homedir() - return path.join(home, 'Library', 'Application Support', getProductName()) -@@ -26,9 +30,13 @@ - return path.join(home, '.config', getProductName()) - } else { - throw new Error( -+<<<<<<< .our - `I dunno how to resolve the user data path for ${process.platform} ${ - process.arch - } :(` -+======= -+ `I dunno how to resolve the user data path for ${process.platform} ${process.arch} :(` -+>>>>>>> .their - ) - } - } diff --git a/app/test/fixtures/merge-parser/desktop/merge-istanbul-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-istanbul-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index e44652752be..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-istanbul-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,1139 +0,0 @@ -added in remote - their 100644 4a2b832008bce10ff9599e6860f11b86d788ead1 app/test/coverage.ts -@@ -0,0 +1,60 @@ -+'use strict' -+ -+const glob = require('glob') -+const { resolve, join } = require('path') -+const { readFileSync: read, writeFileSync: write } = require('fs') -+const { hookRequire } = require('istanbul-lib-hook') -+const { createInstrumenter } = require('istanbul-lib-instrument') -+ -+const instrumenter = createInstrumenter({ debug: true, esModules: true }) -+const transformer = instrumenter.instrumentSync.bind(instrumenter) -+let cov = global.__coverage__ = {} -+ -+const root = resolve(__dirname, '..', '..') -+const tmpd = resolve(root, '.nyc_output') -+ -+const pattern = './app/src/**/*.{ts,tsx}' -+ -+const match = () => { -+ const map = {} -+ const fn = function(file) { return map[file] } -+ -+ fn.files = glob.sync(pattern, { root, realpath: true }) -+ for (let file of fn.files) map[file] = true -+ -+ return fn -+} -+ -+const report = () => { -+ console.log("REPORTING FOR DUTY") -+ console.log("hello ", cov) -+ for (let file of matched.files) { -+ console.log(file) -+ if (!cov[file]) { -+ console.log("no cov for file") -+ // Files that are not touched by code ran by the test runner is -+ // manually instrumented, to illustrate the missing coverage. -+ try { -+ transformer(read(file, 'utf-8'), file) -+ } -+ catch (e) { -+ console.log(e) -+ } -+ console.log("transformed") -+ cov[file] = instrumenter.lastFileCoverage() -+ console.log("done") -+ } -+ } -+ console.log("hello ", cov); -+ write(join(tmpd, `${process.type}.json`), JSON.stringify(cov), 'utf-8') -+ console.log("finished"); -+} -+ -+const matched = match() -+hookRequire(matched, transformer, {}) -+ -+if (process.type === 'browser') { -+ process.on('exit', report) -+} else { -+ window.addEventListener('unload', report) -+} -changed in both - base 100644 5b095a905f723e9742c47751b9fc5d6cc58258ec package.json - our 100644 2006bfb748810f6ea8bdbd26edf7c09524a1388a package.json - their 100644 01cb95ffccdf467c2e334655bb49c04c14e862c5 package.json -@@ -156,6 +156,24 @@ - "electron-builder": "20.27.1", - "electron-mocha": "^6.0.1", - "electron-packager": "^12.0.0", -- "electron-winstaller": "2.5.2" -+ "electron-winstaller": "2.5.2", -+ "istanbul": "^0.4.5", -+ "istanbul-lib-hook": "^1.1.0", -+ "istanbul-lib-instrument": "^1.10.1", -+ "nyc": "^12.0.2", -+ "source-map-support": "^0.5.6" -+ }, -+ "nyc": { -+ "extension": [ -+ ".ts", -+ ".tsx" -+ ], -+ "include": [ -+ "app/src" -+ ], -+ "reporter": [ -+ "html" -+ ], -+ "all": true - } - } -changed in both - base 100644 67afebf6479af930fa36dc6216880f9810e08abe script/unit-tests.ts - our 100644 0dabcf8e2c59df98ac65129f793ad52d98697588 script/unit-tests.ts - their 100644 0ba2a003690f26b8fe3a9a45ce9d28171ab03cbc script/unit-tests.ts -@@ -49,9 +49,13 @@ - '--require', - 'ts-node/register', - '--require', -+ 'source-map-support/register', -+ '--require', - './app/test/globals.ts', -+ '--require', -+ './app/test/coverage.ts', - 'app/test/unit/*.{ts,tsx}', -- 'app/test/unit/**/*.{ts,tsx}', -+ 'app/test/unit/**/*.{ts,tsx}' - ] - - const shouldDebug = process.argv.indexOf('--debug') > -1 -changed in both - base 100644 ebee9944bea9a805e81fb7b86c10d8ad66de2ebf yarn.lock - our 100644 45ddb8bf6902bbb22708d844324093dccda26c79 yarn.lock - their 100644 b3bbb64f4c7be1020fff28d3427773cb49d74769 yarn.lock -@@ -6,6 +6,86 @@ - version "4.0.2" - resolved "https://registry.yarnpkg.com/7zip-bin/-/7zip-bin-4.0.2.tgz#6abbdc22f33cab742053777a26db2e25ca527179" - -+"@babel/code-frame@7.0.0-beta.51": -+ version "7.0.0-beta.51" -+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.51.tgz#bd71d9b192af978df915829d39d4094456439a0c" -+ dependencies: -+ "@babel/highlight" "7.0.0-beta.51" -+ -+"@babel/generator@7.0.0-beta.51": -+ version "7.0.0-beta.51" -+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.51.tgz#6c7575ffde761d07485e04baedc0392c6d9e30f6" -+ dependencies: -+ "@babel/types" "7.0.0-beta.51" -+ jsesc "^2.5.1" -+ lodash "^4.17.5" -+ source-map "^0.5.0" -+ trim-right "^1.0.1" -+ -+"@babel/helper-function-name@7.0.0-beta.51": -+ version "7.0.0-beta.51" -+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.51.tgz#21b4874a227cf99ecafcc30a90302da5a2640561" -+ dependencies: -+ "@babel/helper-get-function-arity" "7.0.0-beta.51" -+ "@babel/template" "7.0.0-beta.51" -+ "@babel/types" "7.0.0-beta.51" -+ -+"@babel/helper-get-function-arity@7.0.0-beta.51": -+ version "7.0.0-beta.51" -+ resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.51.tgz#3281b2d045af95c172ce91b20825d85ea4676411" -+ dependencies: -+ "@babel/types" "7.0.0-beta.51" -+ -+"@babel/helper-split-export-declaration@7.0.0-beta.51": -+ version "7.0.0-beta.51" -+ resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.51.tgz#8a6c3f66c4d265352fc077484f9f6e80a51ab978" -+ dependencies: -+ "@babel/types" "7.0.0-beta.51" -+ -+"@babel/highlight@7.0.0-beta.51": -+ version "7.0.0-beta.51" -+ resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.51.tgz#e8844ae25a1595ccfd42b89623b4376ca06d225d" -+ dependencies: -+ chalk "^2.0.0" -+ esutils "^2.0.2" -+ js-tokens "^3.0.0" -+ -+"@babel/parser@7.0.0-beta.51": -+ version "7.0.0-beta.51" -+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.0.0-beta.51.tgz#27cec2df409df60af58270ed8f6aa55409ea86f6" -+ -+"@babel/template@7.0.0-beta.51": -+ version "7.0.0-beta.51" -+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.51.tgz#9602a40aebcf357ae9677e2532ef5fc810f5fbff" -+ dependencies: -+ "@babel/code-frame" "7.0.0-beta.51" -+ "@babel/parser" "7.0.0-beta.51" -+ "@babel/types" "7.0.0-beta.51" -+ lodash "^4.17.5" -+ -+"@babel/traverse@7.0.0-beta.51": -+ version "7.0.0-beta.51" -+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.51.tgz#981daf2cec347a6231d3aa1d9e1803b03aaaa4a8" -+ dependencies: -+ "@babel/code-frame" "7.0.0-beta.51" -+ "@babel/generator" "7.0.0-beta.51" -+ "@babel/helper-function-name" "7.0.0-beta.51" -+ "@babel/helper-split-export-declaration" "7.0.0-beta.51" -+ "@babel/parser" "7.0.0-beta.51" -+ "@babel/types" "7.0.0-beta.51" -+ debug "^3.1.0" -+ globals "^11.1.0" -+ invariant "^2.2.0" -+ lodash "^4.17.5" -+ -+"@babel/types@7.0.0-beta.51": -+ version "7.0.0-beta.51" -+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.51.tgz#d802b7b543b5836c778aa691797abf00f3d97ea9" -+ dependencies: -+ esutils "^2.0.2" -+ lodash "^4.17.5" -+ to-fast-properties "^2.0.0" -+ - "@types/body-parser@*": - version "1.16.8" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.16.8.tgz#687ec34140624a3bec2b1a8ea9268478ae8f3be3" -@@ -461,6 +541,10 @@ - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - -+abbrev@1.0.x: -+ version "1.0.9" -+ resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" -+ - accepts@~1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.4.tgz#86246758c7dd6d21a6474ff084a4740ec05eb21f" -@@ -550,6 +634,26 @@ - json-schema-traverse "^0.3.0" - uri-js "^3.0.2" - -+<<<<<<< .our -+======= -+ajv@^6.5.1: -+ version "6.5.2" -+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.2.tgz#678495f9b82f7cca6be248dd92f59bff5e1f4360" -+ dependencies: -+ fast-deep-equal "^2.0.1" -+ fast-json-stable-stringify "^2.0.0" -+ json-schema-traverse "^0.4.1" -+ uri-js "^4.2.1" -+ -+align-text@^0.1.1, align-text@^0.1.3: -+ version "0.1.4" -+ resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" -+ dependencies: -+ kind-of "^3.0.2" -+ longest "^1.0.1" -+ repeat-string "^1.5.2" -+ -+>>>>>>> .their - alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" -@@ -640,6 +744,12 @@ - semver "^5.5.0" - temp-file "^3.1.3" - -+append-transform@^0.4.0: -+ version "0.4.0" -+ resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" -+ dependencies: -+ default-require-extensions "^1.0.0" -+ - aproba@^1.0.3, aproba@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" -@@ -669,6 +779,10 @@ - walkdir "^0.0.11" - zip-stream "^1.1.0" - -+archy@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" -+ - are-we-there-yet@~1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" -@@ -723,7 +837,7 @@ - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - --arrify@^1.0.0: -+arrify@^1.0.0, arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - -@@ -806,6 +920,10 @@ - version "1.0.0" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" - -+async@1.x, async@^1.4.0: -+ version "1.5.2" -+ resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" -+ - async@^2.0.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d" -@@ -944,6 +1062,19 @@ - slash "^1.0.0" - source-map "^0.5.7" - -+babel-generator@^6.18.0: -+ version "6.26.1" -+ resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" -+ dependencies: -+ babel-messages "^6.23.0" -+ babel-runtime "^6.26.0" -+ babel-types "^6.26.0" -+ detect-indent "^4.0.0" -+ jsesc "^1.3.0" -+ lodash "^4.17.4" -+ source-map "^0.5.7" -+ trim-right "^1.0.1" -+ - babel-generator@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" -@@ -1177,7 +1308,7 @@ - core-js "^2.4.0" - regenerator-runtime "^0.10.0" - --babel-template@^6.24.1, babel-template@^6.26.0: -+babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" - dependencies: -@@ -1187,7 +1318,7 @@ - babylon "^6.18.0" - lodash "^4.17.4" - --babel-traverse@^6.26.0: -+babel-traverse@^6.18.0, babel-traverse@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" - dependencies: -@@ -1201,7 +1332,7 @@ - invariant "^2.2.2" - lodash "^4.17.4" - --babel-types@^6.26.0: -+babel-types@^6.18.0, babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - dependencies: -@@ -1570,6 +1701,14 @@ - union-value "^1.0.0" - unset-value "^1.0.0" - -+caching-transform@^1.0.0: -+ version "1.0.1" -+ resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-1.0.1.tgz#6dbdb2f20f8d8fbce79f3e94e9d1742dcdf5c0a1" -+ dependencies: -+ md5-hex "^1.2.0" -+ mkdirp "^0.5.1" -+ write-file-atomic "^1.1.4" -+ - caller-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" -@@ -1594,6 +1733,10 @@ - camelcase "^2.0.0" - map-obj "^1.0.0" - -+camelcase@^1.0.2: -+ version "1.2.1" -+ resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" -+ - camelcase@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" -@@ -1631,6 +1774,13 @@ - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - -+center-align@^0.1.1: -+ version "0.1.3" -+ resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" -+ dependencies: -+ align-text "^0.1.3" -+ lazy-cache "^1.0.3" -+ - chai-as-promised@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" -@@ -1796,6 +1946,14 @@ - exit "0.1.2" - glob "^7.1.1" - -+cliui@^2.1.0: -+ version "2.1.0" -+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" -+ dependencies: -+ center-align "^0.1.1" -+ right-align "^0.1.1" -+ wordwrap "0.0.2" -+ - cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" -@@ -2080,6 +2238,13 @@ - lru-cache "^4.0.1" - which "^1.2.9" - -+cross-spawn@^4: -+ version "4.0.2" -+ resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" -+ dependencies: -+ lru-cache "^4.0.1" -+ which "^1.2.9" -+ - cross-spawn@^5.0.1, cross-spawn@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" -@@ -2276,6 +2441,10 @@ - version "0.1.4" - resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" - -+debug-log@^1.0.1: -+ version "1.0.1" -+ resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" -+ - debug@2.6.9, debug@^2.1.2, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" -@@ -2292,7 +2461,7 @@ - version "1.0.1" - resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" - --decamelize@^1.1.1, decamelize@^1.1.2: -+decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - -@@ -2336,6 +2505,12 @@ - version "1.3.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-1.3.2.tgz#1663691629d4dbfe364fa12a2a4f0aa86aa3a050" - -+default-require-extensions@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" -+ dependencies: -+ strip-bom "^2.0.0" -+ - define-properties@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" -@@ -2830,6 +3005,17 @@ - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - -+escodegen@1.8.x: -+ version "1.8.1" -+ resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" -+ dependencies: -+ esprima "^2.7.1" -+ estraverse "^1.9.1" -+ esutils "^2.0.2" -+ optionator "^0.8.1" -+ optionalDependencies: -+ source-map "~0.2.0" -+ - eslint-config-prettier@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-2.9.0.tgz#5ecd65174d486c22dff389fe036febf502d468a3" -@@ -2947,7 +3133,7 @@ - acorn "^5.6.0" - acorn-jsx "^4.1.1" - --esprima@^2.6.0: -+esprima@2.7.x, esprima@^2.6.0, esprima@^2.7.1: - version "2.7.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" - -@@ -2968,6 +3154,10 @@ - estraverse "^4.1.0" - object-assign "^4.0.1" - -+estraverse@^1.9.1: -+ version "1.9.3" -+ resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" -+ - estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" -@@ -3236,6 +3426,14 @@ - statuses "~1.4.0" - unpipe "~1.0.0" - -+find-cache-dir@^0.1.1: -+ version "0.1.1" -+ resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" -+ dependencies: -+ commondir "^1.0.1" -+ mkdirp "^0.5.1" -+ pkg-dir "^1.0.0" -+ - find-cache-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" -@@ -3308,6 +3506,13 @@ - version "2.0.5" - resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" - -+foreground-child@^1.5.3, foreground-child@^1.5.6: -+ version "1.5.6" -+ resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" -+ dependencies: -+ cross-spawn "^4" -+ signal-exit "^3.0.0" -+ - forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" -@@ -3555,7 +3760,7 @@ - is-glob "^3.1.0" - path-dirname "^1.0.0" - --glob@7.1.2, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1: -+glob@7.1.2, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - dependencies: -@@ -3566,6 +3771,19 @@ - once "^1.3.0" - path-is-absolute "^1.0.0" - -+<<<<<<< .our -+======= -+glob@^5.0.15, glob@^5.0.3: -+ version "5.0.15" -+ resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" -+ dependencies: -+ inflight "^1.0.4" -+ inherits "2" -+ minimatch "2 || 3" -+ once "^1.3.0" -+ path-is-absolute "^1.0.0" -+ -+>>>>>>> .their - glob@^6.0.4: - version "6.0.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" -@@ -3586,6 +3804,10 @@ - version "11.7.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673" - -+globals@^11.1.0: -+ version "11.7.0" -+ resolved "https://registry.yarnpkg.com/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673" -+ - globals@^9.18.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" -@@ -3640,6 +3862,16 @@ - duplexer "^0.1.1" - pify "^3.0.0" - -+handlebars@^4.0.1, handlebars@^4.0.11: -+ version "4.0.11" -+ resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" -+ dependencies: -+ async "^1.4.0" -+ optimist "^0.6.1" -+ source-map "^0.4.4" -+ optionalDependencies: -+ uglify-js "^2.6" -+ - har-schema@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" -@@ -4030,6 +4262,12 @@ - version "1.0.4" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.4.tgz#820cdd588b868ffb191a809506d6c9c8f212b1b0" - -+invariant@^2.2.0: -+ version "2.2.4" -+ resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" -+ dependencies: -+ loose-envify "^1.0.0" -+ - invariant@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" -@@ -4342,6 +4580,88 @@ - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - -+istanbul-lib-coverage@^1.1.2, istanbul-lib-coverage@^1.2.0: -+ version "1.2.0" -+ resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz#f7d8f2e42b97e37fe796114cb0f9d68b5e3a4341" -+ -+istanbul-lib-coverage@^2.0.1: -+ version "2.0.1" -+ resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#2aee0e073ad8c5f6a0b00e0dfbf52b4667472eda" -+ -+istanbul-lib-hook@^1.1.0: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz#8538d970372cb3716d53e55523dd54b557a8d89b" -+ dependencies: -+ append-transform "^0.4.0" -+ -+istanbul-lib-instrument@^1.10.1: -+ version "1.10.1" -+ resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz#724b4b6caceba8692d3f1f9d0727e279c401af7b" -+ dependencies: -+ babel-generator "^6.18.0" -+ babel-template "^6.16.0" -+ babel-traverse "^6.18.0" -+ babel-types "^6.18.0" -+ babylon "^6.18.0" -+ istanbul-lib-coverage "^1.2.0" -+ semver "^5.3.0" -+ -+istanbul-lib-instrument@^2.1.0: -+ version "2.3.2" -+ resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-2.3.2.tgz#b287cbae2b5f65f3567b05e2e29b275eaf92d25e" -+ dependencies: -+ "@babel/generator" "7.0.0-beta.51" -+ "@babel/parser" "7.0.0-beta.51" -+ "@babel/template" "7.0.0-beta.51" -+ "@babel/traverse" "7.0.0-beta.51" -+ "@babel/types" "7.0.0-beta.51" -+ istanbul-lib-coverage "^2.0.1" -+ semver "^5.5.0" -+ -+istanbul-lib-report@^1.1.3: -+ version "1.1.3" -+ resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.3.tgz#2df12188c0fa77990c0d2176d2d0ba3394188259" -+ dependencies: -+ istanbul-lib-coverage "^1.1.2" -+ mkdirp "^0.5.1" -+ path-parse "^1.0.5" -+ supports-color "^3.1.2" -+ -+istanbul-lib-source-maps@^1.2.5: -+ version "1.2.5" -+ resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.5.tgz#ffe6be4e7ab86d3603e4290d54990b14506fc9b1" -+ dependencies: -+ debug "^3.1.0" -+ istanbul-lib-coverage "^1.2.0" -+ mkdirp "^0.5.1" -+ rimraf "^2.6.1" -+ source-map "^0.5.3" -+ -+istanbul-reports@^1.4.1: -+ version "1.5.0" -+ resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.5.0.tgz#c6c2867fa65f59eb7dcedb7f845dfc76aaee70f9" -+ dependencies: -+ handlebars "^4.0.11" -+ -+istanbul@^0.4.5: -+ version "0.4.5" -+ resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" -+ dependencies: -+ abbrev "1.0.x" -+ async "1.x" -+ escodegen "1.8.x" -+ esprima "2.7.x" -+ glob "^5.0.15" -+ handlebars "^4.0.1" -+ js-yaml "3.x" -+ mkdirp "0.5.x" -+ nopt "3.x" -+ once "1.x" -+ resolve "1.1.x" -+ supports-color "^3.1.0" -+ which "^1.1.1" -+ wordwrap "^1.0.0" -+ - jest-docblock@^21.0.0: - version "21.2.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414" -@@ -4368,16 +4688,28 @@ - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - -+<<<<<<< .our - js-yaml@^3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" -+======= -+js-yaml@3.x, js-yaml@^3.12.0: -+ version "3.12.0" -+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" -+>>>>>>> .their - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -+<<<<<<< .our - js-yaml@^3.11.0, js-yaml@^3.12.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" -+======= -+js-yaml@^3.10.0, js-yaml@^3.9.1: -+ version "3.10.0" -+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" -+>>>>>>> .their - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" -@@ -4408,6 +4740,10 @@ - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" - -+jsesc@^2.5.1: -+ version "2.5.1" -+ resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.1.tgz#e421a2a8e20d6b0819df28908f782526b96dd1fe" -+ - jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" -@@ -4554,6 +4890,10 @@ - dependencies: - package-json "^4.0.0" - -+lazy-cache@^1.0.3: -+ version "1.0.4" -+ resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" -+ - lazy-cache@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264" -@@ -4739,6 +5079,10 @@ - version "3.2.0" - resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" - -+longest@^1.0.1: -+ version "1.0.1" -+ resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" -+ - loose-envify@^1.0.0, loose-envify@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" -@@ -4806,6 +5150,16 @@ - version "1.2.17" - resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac" - -+md5-hex@^1.2.0: -+ version "1.3.0" -+ resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" -+ dependencies: -+ md5-o-matic "^0.1.1" -+ -+md5-o-matic@^0.1.1: -+ version "0.1.1" -+ resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" -+ - md5.js@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" -@@ -4849,11 +5203,17 @@ - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - -+merge-source-map@^1.1.0: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" -+ dependencies: -+ source-map "^0.6.1" -+ - methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - --micromatch@^3.1.4, micromatch@^3.1.8, micromatch@^3.1.9: -+micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8, micromatch@^3.1.9: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - dependencies: -@@ -4995,7 +5355,7 @@ - dependencies: - minimist "0.0.8" - --mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: -+mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - dependencies: -@@ -5208,7 +5568,7 @@ - is-promise "~1.0.0" - promise "~1.3.0" - --"nopt@2 || 3", nopt@^3.0.1: -+"nopt@2 || 3", nopt@3.x, nopt@^3.0.1: - version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" - dependencies: -@@ -5311,6 +5671,38 @@ - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - -+nyc@^12.0.2: -+ version "12.0.2" -+ resolved "https://registry.yarnpkg.com/nyc/-/nyc-12.0.2.tgz#8a4a4ed690966c11ec587ff87eea0c12c974ba99" -+ dependencies: -+ archy "^1.0.0" -+ arrify "^1.0.1" -+ caching-transform "^1.0.0" -+ convert-source-map "^1.5.1" -+ debug-log "^1.0.1" -+ default-require-extensions "^1.0.0" -+ find-cache-dir "^0.1.1" -+ find-up "^2.1.0" -+ foreground-child "^1.5.3" -+ glob "^7.0.6" -+ istanbul-lib-coverage "^1.2.0" -+ istanbul-lib-hook "^1.1.0" -+ istanbul-lib-instrument "^2.1.0" -+ istanbul-lib-report "^1.1.3" -+ istanbul-lib-source-maps "^1.2.5" -+ istanbul-reports "^1.4.1" -+ md5-hex "^1.2.0" -+ merge-source-map "^1.1.0" -+ micromatch "^3.1.10" -+ mkdirp "^0.5.0" -+ resolve-from "^2.0.0" -+ rimraf "^2.6.2" -+ signal-exit "^3.0.1" -+ spawn-wrap "^1.4.2" -+ test-exclude "^4.2.0" -+ yargs "11.1.0" -+ yargs-parser "^8.0.0" -+ - oauth-sign@~0.8.1, oauth-sign@~0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" -@@ -5366,7 +5758,7 @@ - dependencies: - ee-first "1.1.1" - --once@^1.3.0, once@^1.3.1, once@^1.4.0: -+once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - dependencies: -@@ -5382,14 +5774,14 @@ - version "1.4.3" - resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8" - --optimist@~0.6.1: -+optimist@^0.6.1, optimist@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" - --optionator@^0.8.2: -+optionator@^0.8.1, optionator@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" - dependencies: -@@ -5404,7 +5796,7 @@ - version "0.2.1" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.2.1.tgz#63fc4ccee5d2d7763d26bbf8601078e6c2e0044f" - --os-homedir@^1.0.0: -+os-homedir@^1.0.0, os-homedir@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - -@@ -5661,6 +6053,12 @@ - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - -+pkg-dir@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" -+ dependencies: -+ find-up "^1.0.0" -+ - pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" -@@ -6387,7 +6785,7 @@ - version "1.1.2" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" - --repeat-string@^1.6.1: -+repeat-string@^1.5.2, repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - -@@ -6505,10 +6903,18 @@ - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" - -+resolve-from@^2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" -+ - resolve-url@^0.2.1, resolve-url@~0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - -+resolve@1.1.x: -+ version "1.1.7" -+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" -+ - resolve@^1.1.6, resolve@^1.3.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" -@@ -6530,6 +6936,12 @@ - version "0.1.0" - resolved "https://registry.yarnpkg.com/rgb2hex/-/rgb2hex-0.1.0.tgz#ccd55f860ae0c5c4ea37504b958e442d8d12325b" - -+right-align@^0.1.1: -+ version "0.1.3" -+ resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" -+ dependencies: -+ align-text "^0.1.1" -+ - rimraf@2, rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" -@@ -6787,7 +7199,7 @@ - version "0.3.0" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.3.0.tgz#3596e6307a781544f591f37da618360f31db57b1" - --signal-exit@^3.0.0, signal-exit@^3.0.2: -+signal-exit@^3.0.0, signal-exit@^3.0.1, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - -@@ -6807,7 +7219,7 @@ - dependencies: - is-fullwidth-code-point "^2.0.0" - --slide@~1.1.3: -+slide@^1.1.5, slide@~1.1.3: - version "1.1.6" - resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" - -@@ -6906,7 +7318,7 @@ - version "0.3.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.3.0.tgz#7ecaf13b57bcd09da8a40c5d269db33799d4aaf9" - --source-map@0.5.x, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.3: -+source-map@0.5.x, source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1, source-map@~0.5.3: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - -@@ -6916,7 +7328,7 @@ - dependencies: - amdefine ">=0.0.4" - --source-map@^0.4.2: -+source-map@^0.4.2, source-map@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" - dependencies: -@@ -6926,6 +7338,23 @@ - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - -+source-map@~0.2.0: -+ version "0.2.0" -+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" -+ dependencies: -+ amdefine ">=0.0.4" -+ -+spawn-wrap@^1.4.2: -+ version "1.4.2" -+ resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.4.2.tgz#cff58e73a8224617b6561abdc32586ea0c82248c" -+ dependencies: -+ foreground-child "^1.5.6" -+ mkdirp "^0.5.0" -+ os-homedir "^1.0.1" -+ rimraf "^2.6.2" -+ signal-exit "^3.0.2" -+ which "^1.3.0" -+ - spdx-correct@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" -@@ -7166,7 +7595,7 @@ - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - --supports-color@^3.1.2, supports-color@^3.2.3, supports-color@~3.2.3: -+supports-color@^3.1.0, supports-color@^3.1.2, supports-color@^3.2.3, supports-color@~3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - dependencies: -@@ -7266,7 +7695,21 @@ - dependencies: - execa "^0.7.0" - -+<<<<<<< .our - text-table@^0.2.0: -+======= -+test-exclude@^4.2.0: -+ version "4.2.1" -+ resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.1.tgz#dfa222f03480bca69207ca728b37d74b45f724fa" -+ dependencies: -+ arrify "^1.0.1" -+ micromatch "^3.1.8" -+ object-assign "^4.1.0" -+ read-pkg-up "^1.0.1" -+ require-main-filename "^1.0.1" -+ -+text-table@~0.2.0: -+>>>>>>> .their - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - -@@ -7332,6 +7775,10 @@ - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - -+to-fast-properties@^2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" -+ - to-no-case@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/to-no-case/-/to-no-case-1.0.2.tgz#c722907164ef6b178132c8e69930212d1b4aa16a" -@@ -7559,6 +8006,19 @@ - commander "~2.11.0" - source-map "~0.6.1" - -+uglify-js@^2.6: -+ version "2.8.29" -+ resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" -+ dependencies: -+ source-map "~0.5.1" -+ yargs "~3.10.0" -+ optionalDependencies: -+ uglify-to-browserify "~1.0.0" -+ -+uglify-to-browserify@~1.0.0: -+ version "1.0.2" -+ resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" -+ - uglifyjs-webpack-plugin@^1.2.4: - version "1.2.5" - resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.5.tgz#2ef8387c8f1a903ec5e44fa36f9f3cbdcea67641" -@@ -7954,7 +8414,11 @@ - dependencies: - isexe "^2.0.0" - -+<<<<<<< .our - which@^1.2.10: -+======= -+which@^1.1.1: -+>>>>>>> .their - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - dependencies: -@@ -7972,6 +8436,7 @@ - dependencies: - string-width "^1.0.1" - -+<<<<<<< .our - winston@^2.4.0: - version "2.4.3" - resolved "https://registry.yarnpkg.com/winston/-/winston-2.4.3.tgz#7a9fdab371b6d3d9b63a592947846d856948c517" -@@ -7986,11 +8451,24 @@ - wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" -+======= -+window-size@0.1.0: -+ version "0.1.0" -+ resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" -+>>>>>>> .their - --wordwrap@~1.0.0: -+wordwrap@0.0.2: -+ version "0.0.2" -+ resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" -+ -+wordwrap@^1.0.0, wordwrap@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - -+wordwrap@~0.0.2: -+ version "0.0.3" -+ resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" -+ - worker-farm@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.5.1.tgz#8e9f4a7da4f3c595aa600903051b969390423fa1" -@@ -8015,6 +8493,14 @@ - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - -+write-file-atomic@^1.1.4: -+ version "1.3.4" -+ resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" -+ dependencies: -+ graceful-fs "^4.1.11" -+ imurmurhash "^0.1.4" -+ slide "^1.1.5" -+ - write-file-atomic@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" -@@ -8129,6 +8615,35 @@ - dependencies: - camelcase "^3.0.0" - -+yargs-parser@^8.0.0: -+ version "8.1.0" -+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950" -+ dependencies: -+ camelcase "^4.1.0" -+ -+yargs-parser@^9.0.2: -+ version "9.0.2" -+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" -+ dependencies: -+ camelcase "^4.1.0" -+ -+yargs@11.1.0: -+ version "11.1.0" -+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" -+ dependencies: -+ cliui "^4.0.0" -+ decamelize "^1.1.1" -+ find-up "^2.1.0" -+ get-caller-file "^1.0.1" -+ os-locale "^2.0.0" -+ require-directory "^2.1.1" -+ require-main-filename "^1.0.1" -+ set-blocking "^2.0.0" -+ string-width "^2.0.0" -+ which-module "^2.0.0" -+ y18n "^3.2.1" -+ yargs-parser "^9.0.2" -+ - yargs@^12.0.1: - version "12.0.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.1.tgz#6432e56123bb4e7c3562115401e98374060261c2" -@@ -8164,6 +8679,15 @@ - y18n "^3.2.1" - yargs-parser "^5.0.0" - -+yargs@~3.10.0: -+ version "3.10.0" -+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" -+ dependencies: -+ camelcase "^1.0.2" -+ cliui "^2.1.0" -+ decamelize "^1.0.0" -+ window-size "0.1.0" -+ - yauzl@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005" diff --git a/app/test/fixtures/merge-parser/desktop/merge-know-when-to-give-up-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-know-when-to-give-up-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index d4634b9cdb9..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-know-when-to-give-up-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,117 +0,0 @@ -changed in both - base 100644 b7fc04813074a6cb7cb041abf9f2f656f80bc05d app/src/lib/git/diff.ts - our 100644 c7b70925514f334e2076ddb67f208c2f3f12672f app/src/lib/git/diff.ts - their 100644 ae8fe832c53bbaf4e756eb43dec1f4d4c94c6ce8 app/src/lib/git/diff.ts -@@ -41,6 +41,14 @@ - const MaxReasonableDiffSize = MaxDiffBufferSize / 16 // ~4.375MB in decimal - - /** -+ * Where `MaxReasonableDiffSize` is a soft limit, and `MaxDiffBufferSize` -+ * is an absolute limit, this is the MAX number of bytes to read from the -+ * buffer before _assuming_ the current buffer being read is `MaxDiffBufferSize`. -+ * This is done so that the UI isn't waiting for the entire buffer to be read. -+ */ -+const MaxBytesToRead = MaxDiffBufferSize / 8 //~32MB -+ -+/** - * The longest line length we should try to display. If a diff has a line longer - * than this, we probably shouldn't attempt it - */ -@@ -115,11 +123,24 @@ - args.push(file.oldPath) - } - -- const { output } = await spawnAndComplete( -+ const { output, didReadAllBytes } = await spawnAndComplete( - args, - repository.path, -- 'getCommitDiff' -+ 'getCommitDiff', -+ undefined, -+ MaxBytesToRead - ) -+<<<<<<< .our -+======= -+ if (!didReadAllBytes || isBufferTooLarge(output)) { -+ return { kind: DiffType.TooLarge, length: output.length } -+ } -+ -+ const diffText = diffFromRawDiffOutput(output) -+ if (isDiffTooLarge(diffText)) { -+ return { kind: DiffType.TooLarge, length: output.length } -+ } -+>>>>>>> .their - - return buildDiff(output, repository, file, commitish) - } -@@ -192,12 +213,28 @@ - ] - } - -- const { output, error } = await spawnAndComplete( -+ const { output, error, didReadAllBytes } = await spawnAndComplete( - args, - repository.path, - 'getWorkingDirectoryDiff', -- successExitCodes -+ successExitCodes, -+ MaxBytesToRead - ) -+<<<<<<< .our -+======= -+ if (!didReadAllBytes || isBufferTooLarge(output)) { -+ // we know we can't transform this process output into a diff, so let's -+ // just return a placeholder for now that we can display to the user -+ // to say we're at the limits of the runtime -+ return { kind: DiffType.TooLarge, length: output.length } -+ } -+ -+ const diffText = diffFromRawDiffOutput(output) -+ if (isDiffTooLarge(diffText)) { -+ return { kind: DiffType.TooLarge, length: output.length } -+ } -+ -+>>>>>>> .their - const lineEndingsChange = parseLineEndingsWarning(error) - - return buildDiff(output, repository, file, 'HEAD', lineEndingsChange) -changed in both - base 100644 d911e4235f5a1e8e056f9d98d4a6fda3d76dcaea app/src/lib/git/spawn.ts - our 100644 143168d54995f923711aa352fff4365067b90676 app/src/lib/git/spawn.ts - their 100644 79576b0f30fd4b538b4a0c98b1b7a0bb7f68373a app/src/lib/git/spawn.ts -@@ -4,7 +4,11 @@ - type ProcessOutput = { - /** The contents of stdout received from the spawned process */ - output: Buffer -+<<<<<<< .our - /** The contents of stderr received from the spawned process */ -+======= -+ didReadAllBytes: boolean -+>>>>>>> .their - error: Buffer - /** The exit code returned by the spawned process */ - exitCode: number -@@ -38,6 +42,7 @@ - const process = GitProcess.spawn(args, path) - let totalStdoutLength = 0 - let killSignalSent = false -+ let didReadAllBytes = true - - const stdoutChunks = new Array<Buffer>() - process.stdout.on('data', (chunk: Buffer) => { -@@ -53,6 +58,7 @@ - ) { - process.kill() - killSignalSent = true -+ didReadAllBytes = false - } - }) - -@@ -84,6 +90,7 @@ - if (exitCodes.has(code) || signal) { - resolve({ - output: stdout, -+ didReadAllBytes, - error: stderr, - exitCode: code, - }) diff --git a/app/test/fixtures/merge-parser/desktop/merge-make-cli-work-under-wsl-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-make-cli-work-under-wsl-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index a1bdabb7ba1..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-make-cli-work-under-wsl-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,95 +0,0 @@ -changed in both - base 100644 b13703f3e3796ee821d21e064667c25a04b8b3a0 app/package.json - our 100644 4ec686d8ad22d3aea1ebe4bddd16f4a7447c3acd app/package.json - their 100644 e9d531afe0249f4443fe4f49b08c15d54c092af7 app/package.json -@@ -3,7 +3,11 @@ - "productName": "GitHub Desktop", - "bundleID": "com.github.GitHubClient", - "companyName": "GitHub, Inc.", -+<<<<<<< .our - "version": "1.3.4", -+======= -+ "version": "1.3.3-test10", -+>>>>>>> .their - "main": "./main.js", - "repository": { - "type": "git", -merged - result 100644 9816ea99ea5d4c3d087ff4c597e475e91d7b39de app/src/main-process/squirrel-updater.ts - our 100644 5f8bcfd5aa2b2f30f81fe1cd9a2973bcc9b9f14f app/src/main-process/squirrel-updater.ts -@@ -66,7 +66,11 @@ - - function resolveVersionedPath(binPath: string, relativePath: string): string { - const appFolder = Path.resolve(process.execPath, '..') -- return Path.relative(binPath, Path.join(appFolder, relativePath)) -+ const computedPath = Path.relative( -+ binPath, -+ Path.join(appFolder, relativePath) -+ ) -+ return Path.normalize(computedPath) - } - - /** -merged - result 100644 cf35271e198c33e39f3944490d0c8620bdecde6a app/static/win32/github.sh - our 100644 f0b800ac6aec942dbb1ac6e7dae646097ea194de app/static/win32/github.sh -@@ -2,7 +2,26 @@ - - CONTENTS="$(dirname "$(dirname "$(dirname "$(dirname "$(realpath "$0")")")")")" - ELECTRON="$CONTENTS/GitHubDesktop.exe" --CLI="$CONTENTS/Resources/app/cli.js" -+ -+if grep -q Microsoft /proc/version; then -+ if [ -x /bin/wslpath ]; then -+ # On recent WSL builds, we just need to set WSLENV so that -+ # ELECTRON_RUN_AS_NODE is visible to the win32 process -+ export WSLENV=ELECTRON_RUN_AS_NODE/w:$WSLENV -+ CLI=$(wslpath -m "$CONTENTS/resources/app/cli.js") -+ else -+ # If running under older WSL, don't pass cli.js to Electron as -+ # environment vars cannot be transferred from WSL to Windows -+ # See: https://github.com/Microsoft/BashOnWindows/issues/1363 -+ # https://github.com/Microsoft/BashOnWindows/issues/1494 -+ "$ELECTRON" "$@" -+ exit $? -+ fi -+elif [ "$(expr substr $(uname -s) 1 9)" == "CYGWIN_NT" ]; then -+ CLI=$(cygpath -m "$CONTENTS/resources/app/cli.js") -+else -+ CLI="$CONTENTS/resources/app/cli.js" -+fi - - ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" "$@" - -changed in both - base 100644 52bffc3fc39049f5f0ef995bf6f11b9f81e9a5ac changelog.json - our 100644 13ed8d504719e064f71338f54d32111020190af5 changelog.json - their 100644 b260ca958409aebfedbefd96ed9f2db017d896cc changelog.json -@@ -1,5 +1,6 @@ - { - "releases": { -+<<<<<<< .our - "1.3.4": [ - "[Improved] Cloning message uses remote repo name not file destination - #5413. Thanks @lisavogtsf!", - "[Improved] Support VSCode user scope installation - #5281. Thanks @saschanaz!" -@@ -15,6 +16,10 @@ - "[Fixed] 'Clone repository' menu item label is obscured on Windows - #5348. Thanks @Daniel-McCarthy!", - "[Fixed] User can toggle files when commit is in progress - #5341. Thanks @masungwon!", - "[Improved] Repository indicator background work - #5317 #5326 #5363 #5241 #5320" -+======= -+ "1.3.3-test10": [ -+ "Testing command line integration changes to support WSL" -+>>>>>>> .their - ], - "1.3.3-beta1": [ - "[Fixed] Maximize and restore app on Windows does not fill available space - #5033", -@@ -22,6 +27,9 @@ - "[Fixed] User can toggle files when commit is in progress - #5341. Thanks @masungwon!", - "[Improved] Repository indicator background work - #5317 #5326 #5363 #5241 #5320" - ], -+ "1.3.3-test7": [ -+ "Testing command line integration changes to support WSL" -+ ], - "1.3.3-test6": [ - "Testing infrastructure changes" - ], diff --git a/app/test/fixtures/merge-parser/desktop/merge-mr-clean-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-mr-clean-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 33db2357620..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-mr-clean-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,1961 +0,0 @@ -changed in both - base 100644 eead3dcf0fdacf7030ad7c485f203f058ebf96bf app/src/lib/databases/pull-request-database.ts - our 100644 7446a4ce1ebf104f7825a7757e6be2beccfbe4ef app/src/lib/databases/pull-request-database.ts - their 100644 c914a57b5e785438f9475dde8880490601fd47b7 app/src/lib/databases/pull-request-database.ts -@@ -1,8 +1,21 @@ - import Dexie from 'dexie' -+<<<<<<< .our - import { APIRefState, IAPIRefStatusItem } from '../api' - import { BaseDatabase } from './base-database' -+======= -+>>>>>>> .their - --export interface IPullRequestRef { -+export type RefState = 'failure' | 'pending' | 'success' -+ -+export interface IRefStatus { -+ readonly id: number -+ readonly state: RefState -+ readonly targetURL: string -+ readonly description: string -+ readonly context: string -+} -+ -+export interface IRefEntity { - /** - * The database ID of the GitHub repository in which this ref lives. It could - * be null if the repository was deleted on the site after the PR was opened. -@@ -16,7 +29,7 @@ - readonly sha: string - } - --export interface IPullRequest { -+export interface IPullRequestEntity { - /** - * The database ID. This will be undefined if the pull request hasn't been - * inserted into the DB. -@@ -33,16 +46,16 @@ - readonly createdAt: string - - /** The ref from which the pull request's changes are coming. */ -- readonly head: IPullRequestRef -+ readonly head: IRefEntity - - /** The ref which the pull request is targetting. */ -- readonly base: IPullRequestRef -+ readonly base: IRefEntity - - /** The login of the author. */ - readonly author: string - } - --export interface IPullRequestStatus { -+export interface IPullRequestStatusEntity { - /** - * The database ID. This will be undefined if the status hasn't been inserted - * into the DB. -@@ -53,7 +66,7 @@ - readonly pullRequestId: number - - /** The status' state. */ -- readonly state: APIRefState -+ readonly state: 'failure' | 'pending' | 'success' - - /** The number of statuses represented in this combined status. */ - readonly totalCount: number -@@ -66,12 +79,21 @@ - * if the database object was created prior to status support - * being added in #3588 - */ -+<<<<<<< .our - readonly statuses?: ReadonlyArray<IAPIRefStatusItem> - } - - export class PullRequestDatabase extends BaseDatabase { - public pullRequests!: Dexie.Table<IPullRequest, number> - public pullRequestStatus!: Dexie.Table<IPullRequestStatus, number> -+======= -+ readonly statuses: ReadonlyArray<IRefStatus> | undefined -+} -+ -+export class PullRequestDatabase extends Dexie { -+ public pullRequests: Dexie.Table<IPullRequestEntity, number> -+ public pullRequestStatus: Dexie.Table<IPullRequestStatusEntity, number> -+>>>>>>> .their - - public constructor(name: string, schemaVersion?: number) { - super(name, schemaVersion) -changed in both - base 100644 6af2df2cfc1b91598cba2821fff1162a89c901f2 app/src/lib/repository-matching.ts - our 100644 320c31614eb7012348f2ae7877bfb5a0b11cf5af app/src/lib/repository-matching.ts - their 100644 ffd9c672b3e24afaa09ce84c0d019b78a32bbea4 app/src/lib/repository-matching.ts -@@ -48,26 +48,25 @@ - ): IMatchedGitHubRepository | null { - const htmlURL = getHTMLURL(account.endpoint) - const parsed = URL.parse(htmlURL) -- const host = parsed.hostname - - const parsedRemote = parseRemote(remote) - if (!parsedRemote) { - return null - } - -+ const host = parsed.hostname - const owner = parsedRemote.owner - const name = parsedRemote.name -- - if ( -- host && -- parsedRemote.hostname.toLowerCase() === host.toLowerCase() && -- owner && -- name -+ host == null || -+ name == null || -+ owner == null || -+ parsedRemote.hostname.toLocaleLowerCase() !== host.toLocaleLowerCase() - ) { -- return { name, owner, endpoint: account.endpoint } -+ return null - } - -- return null -+ return { name, owner, endpoint: account.endpoint } - } - - /** -changed in both - base 100644 700d3f933813e7f847a36b6d4955ef5f10bc88c5 app/src/lib/stores/app-store.ts - our 100644 1a4e387e4d192d34abfd0621b4b5ebe8cc34d8d1 app/src/lib/stores/app-store.ts - their 100644 e98175838c3c8006048a1876a557d0295c793a85 app/src/lib/stores/app-store.ts -@@ -2212,9 +2212,9 @@ - repository: Repository - ): Promise<Repository> { - const oldGitHubRepository = repository.gitHubRepository -- - const matchedGitHubRepository = await this.matchGitHubRepository(repository) -- if (!matchedGitHubRepository) { -+ -+ if (matchedGitHubRepository == null) { - // TODO: We currently never clear GitHub repository associations (see - // https://github.com/desktop/desktop/issues/1144). So we can bail early - // at this point. -@@ -3348,10 +3348,12 @@ - public async _addRepositories( - paths: ReadonlyArray<string> - ): Promise<ReadonlyArray<Repository>> { -- const addedRepositories = new Array<Repository>() -- const lfsRepositories = new Array<Repository>() -+ const addedRepositories: Array<Repository> = [] -+ const lfsRepositories: Array<Repository> = [] -+ - for (const path of paths) { - const validatedPath = await validatedRepositoryPath(path) -+ - if (validatedPath) { - log.info(`[AppStore] adding repository at ${validatedPath} to store`) - -changed in both - base 100644 b692ad47edc1ec903fa137c97c0207a46d7dc97a app/src/lib/stores/pull-request-store.ts - our 100644 d9edf0247ea7c33ae2b508f876aa977d8a81d6d4 app/src/lib/stores/pull-request-store.ts - their 100644 cd86fe5febba7d37db6e7b2ff50acb6797ba6e21 app/src/lib/stores/pull-request-store.ts -@@ -1,13 +1,14 @@ - import { - PullRequestDatabase, -- IPullRequest, -- IPullRequestStatus, -+ IPullRequestEntity, -+ IPullRequestStatusEntity, -+ RefState, -+ IRefStatus, - } from '../databases' - import { GitHubRepository } from '../../models/github-repository' - import { Account } from '../../models/account' --import { API, IAPIPullRequest } from '../api' -+import { API, IAPIPullRequest, IAPIRefStatusItem, IAPIRepository } from '../api' - import { fatalError, forceUnwrap } from '../fatal-error' --import { RepositoriesStore } from './repositories-store' - import { - PullRequest, - PullRequestRef, -@@ -21,20 +22,77 @@ - const Decrement = (n: number) => n - 1 - const Increment = (n: number) => n + 1 - -+const mapAPIToEntityPullRequestStatus = ( -+ prStatus: ReadonlyArray<IAPIRefStatusItem> -+): ReadonlyArray<IRefStatus> => { -+ return prStatus.map(apiRefStatus => { -+ return { -+ id: apiRefStatus.id, -+ state: apiRefStatus.state, -+ targetURL: apiRefStatus.target_url, -+ description: apiRefStatus.description, -+ context: apiRefStatus.context, -+ } -+ }) -+} -+ -+const mapAPIToEntityPullRequest = ( -+ pr: IAPIPullRequest, -+ base: GitHubRepository, -+ head: GitHubRepository | null = null -+): IPullRequestEntity => { -+ return { -+ number: pr.number, -+ title: pr.title, -+ createdAt: pr.created_at, -+ head: { -+ ref: pr.head.ref, -+ sha: pr.head.sha, -+ repoId: (head && head.dbID) || null, -+ }, -+ base: { -+ ref: pr.base.ref, -+ sha: pr.base.sha, -+ repoId: base.dbID, -+ }, -+ author: pr.user.login, -+ } -+} -+ - /** The store for GitHub Pull Requests. */ - export class PullRequestStore extends TypedBaseStore<GitHubRepository> { - private readonly pullRequestDatabase: PullRequestDatabase -+<<<<<<< .our - private readonly repositoryStore: RepositoriesStore - private readonly activeFetchCountPerRepository = new Map<number, number>() -+======= -+ private activeFetchCountPerRepository = new Map<number, number>() -+ private findOrAddGitHubRepository: ( -+ endpoint: string, -+ apiRepository: IAPIRepository -+ ) => Promise<GitHubRepository> -+ private findGitHubRepositoryById: ( -+ id: number -+ ) => Promise<GitHubRepository | null> -+>>>>>>> .their - - public constructor( - db: PullRequestDatabase, -- repositoriesStore: RepositoriesStore -+ findOrPutGitHubRepository: ( -+ endpoint: string, -+ apiRepository: IAPIRepository -+ ) => Promise<GitHubRepository>, -+ findGitHubRepositoryById: (id: number) => Promise<GitHubRepository | null> - ) { - super() - - this.pullRequestDatabase = db -+<<<<<<< .our - this.repositoryStore = repositoriesStore -+======= -+ this.findOrAddGitHubRepository = findOrPutGitHubRepository -+ this.findGitHubRepositoryById = findGitHubRepositoryById -+>>>>>>> .their - } - - /** Loads all pull requests against the given repository. */ -@@ -46,27 +104,52 @@ - 'Can only refresh pull requests for GitHub repositories', - repository.gitHubRepository - ) -+<<<<<<< .our - const apiClient = API.fromAccount(account) -+======= -+>>>>>>> .their - - this.updateActiveFetchCount(githubRepo, Increment) - - try { -+<<<<<<< .our - const apiResult = await apiClient.fetchPullRequests( -+======= -+ const api = API.fromAccount(account) -+ const apiResults = await api.fetchPullRequests( -+>>>>>>> .their - githubRepo.owner.login, - githubRepo.name, - 'open' - ) - -+<<<<<<< .our - await this.cachePullRequests(apiResult, githubRepo) -+======= -+ await this.writePRs(apiResults, githubRepo) -+>>>>>>> .their - - const prs = await this.fetchPullRequestsFromCache(githubRepo) - -+<<<<<<< .our - await this.fetchAndCachePullRequestStatus(prs, githubRepo, account) - await this.pruneForkedRemotes(repository, prs) - - this.emitUpdate(githubRepo) - } catch (error) { - log.warn(`Error refreshing pull requests for '${repository.name}'`, error) -+======= -+ await Promise.all([ -+ this.refreshStatusForPRs(prs, githubRepo, account), -+ this.pruneForkedRemotes(repository, prs), -+ ]) -+ } catch (error) { -+ log.error( -+ `Error refreshing pull requests for '${repository.name}'`, -+ error -+ ) -+ this.emitError(error) -+>>>>>>> .their - } finally { - this.updateActiveFetchCount(githubRepo, Decrement) - } -@@ -255,8 +338,14 @@ - repository: GitHubRepository, - account: Account - ): Promise<void> { -+<<<<<<< .our - const apiClient = API.fromAccount(account) - const statuses: Array<IPullRequestStatus> = [] -+======= -+ const api = API.fromAccount(account) -+ const statuses: Array<IPullRequestStatusEntity> = [] -+ const prs: Array<PullRequest> = [] -+>>>>>>> .their - - for (const pr of pullRequests) { - const combinedRefStatus = await apiClient.fetchCombinedRefStatus( -@@ -267,10 +356,17 @@ - - statuses.push({ - pullRequestId: pr.id, -+<<<<<<< .our - state: combinedRefStatus.state, - totalCount: combinedRefStatus.total_count, - sha: pr.head.sha, - statuses: combinedRefStatus.statuses, -+======= -+ state: apiStatus.state as RefState, -+ totalCount: apiStatus.total_count, -+ sha: pr.head.sha, -+ statuses: mapAPIToEntityPullRequestStatus(apiStatus.statuses), -+>>>>>>> .their - }) - } - -@@ -313,15 +409,20 @@ - pullRequestsFromAPI: ReadonlyArray<IAPIPullRequest>, - repository: GitHubRepository - ): Promise<void> { -+<<<<<<< .our - const repoDbId = repository.dbID - - if (repoDbId == null) { -+======= -+ if (repository.dbID == null) { -+>>>>>>> .their - return fatalError( - "Cannot store pull requests for a repository that hasn't been inserted into the database!" - ) - } - - const table = this.pullRequestDatabase.pullRequests -+<<<<<<< .our - const prsToInsert = new Array<IPullRequest>() - - for (const pr of pullRequestsFromAPI) { -@@ -402,6 +503,38 @@ - - private async cachePullRequestStatuses( - statuses: Array<IPullRequestStatus> -+======= -+ const insertablePRs = new Array<IPullRequestEntity>() -+ for (const pr of pullRequests) { -+ // base repo isn't null since that's where we got the PR from -+ const baseRepo = forceUnwrap( -+ 'A pull request must have a base repository before it can be inserted', -+ pr.base.repo -+ ) -+ const base = await this.findOrAddGitHubRepository( -+ repository.endpoint, -+ baseRepo -+ ) -+ const head = -+ (pr.head.repo && -+ (await this.findOrAddGitHubRepository( -+ repository.endpoint, -+ pr.head.repo -+ ))) || -+ null -+ const thingToInsert = mapAPIToEntityPullRequest(pr, base, head) -+ insertablePRs.push(thingToInsert) -+ } -+ -+ await this.pullRequestDatabase.transaction('rw', table, async () => { -+ await table.clear() -+ await table.bulkAdd(insertablePRs) -+ }) -+ } -+ -+ private async writePRStatus( -+ statuses: Array<IPullRequestStatusEntity> -+>>>>>>> .their - ): Promise<void> { - const table = this.pullRequestDatabase.pullRequestStatus - -@@ -420,4 +553,73 @@ - } - }) - } -+<<<<<<< .our -+======= -+ -+ /** Gets the pull requests against the given repository. */ -+ public async getPullRequests( -+ repository: GitHubRepository -+ ): Promise<ReadonlyArray<PullRequest>> { -+ const gitHubRepositoryID = repository.dbID -+ -+ if (!gitHubRepositoryID) { -+ return fatalError( -+ "Cannot get pull requests for a repository that hasn't been inserted into the database!" -+ ) -+ } -+ -+ const raw = await this.pullRequestDatabase.pullRequests -+ .where('base.repoId') -+ .equals(gitHubRepositoryID) -+ .reverse() -+ .sortBy('number') -+ -+ const pullRequests = new Array<PullRequest>() -+ -+ for (const pr of raw) { -+ const headId = pr.head.repoId -+ -+ let head: GitHubRepository | null = null -+ -+ if (headId) { -+ head = await this.findGitHubRepositoryById(headId) -+ } -+ -+ // We know the base repo ID can't be null since it's the repository we -+ // fetched the PR from in the first place. -+ const baseId = forceUnwrap( -+ 'PR cannot have a null base repo id', -+ pr.base.repoId -+ ) -+ const base = forceUnwrap( -+ 'PR cannot have a null base repo', -+ await this.findGitHubRepositoryById(baseId) -+ ) -+ -+ // We can be certain the PR ID is valid since we just got it from the -+ // database. -+ const prID = forceUnwrap( -+ 'PR cannot have a null ID after being retrieved from the database', -+ pr.id -+ ) -+ -+ const pullRequestStatus = await this.getPRStatusById(pr.head.sha, prID) -+ -+ const pullRequest = new PullRequest( -+ prID, -+ new Date(pr.createdAt), -+ pullRequestStatus, -+ pr.title, -+ pr.number, -+ new PullRequestRef(pr.head.ref, pr.head.sha, head), -+ new PullRequestRef(pr.base.ref, pr.base.sha, base), -+ pr.author -+ ) -+ -+ pullRequests.push(pullRequest) -+ } -+ -+ return pullRequests -+ } -+>>>>>>> .their - } -changed in both - base 100644 f3314ebfa4a006dfe567e597d9b9874623736798 app/src/lib/stores/repositories-store.ts - our 100644 1c0981c70e593bda2422a96ca43b130cedd5db06 app/src/lib/stores/repositories-store.ts - their 100644 d4601ff4f24fcb907d7047d938287e0412e26feb app/src/lib/stores/repositories-store.ts -@@ -6,7 +6,7 @@ - import { Owner } from '../../models/owner' - import { GitHubRepository } from '../../models/github-repository' - import { Repository } from '../../models/repository' --import { fatalError } from '../fatal-error' -+import { fatalError, forceUnwrap } from '../fatal-error' - import { IAPIRepository } from '../api' - import { BaseStore } from './base-store' - -@@ -31,16 +31,20 @@ - this.db.gitHubRepositories, - this.db.owners, - async () => { -- const gitHubRepository = await this.db.gitHubRepositories -+ const record = await this.db.gitHubRepositories - .where('cloneURL') - .equals(apiRepository.clone_url) - .limit(1) - .first() - -+<<<<<<< .our - if (gitHubRepository == null) { -+======= -+ if (record == null) { -+>>>>>>> .their - return this.putGitHubRepository(endpoint, apiRepository) - } else { -- return this.buildGitHubRepository(gitHubRepository) -+ return this.buildGitHubRepository(record) - } - } - ) -@@ -51,12 +55,16 @@ - ): Promise<GitHubRepository> { - const owner = await this.db.owners.get(dbRepo.ownerID) - -+<<<<<<< .our - if (owner == null) { -+======= -+ if (!owner) { -+>>>>>>> .their - throw new Error(`Couldn't find the owner for ${dbRepo.name}`) - } - - let parent: GitHubRepository | null = null -- if (dbRepo.parentID) { -+ if (dbRepo.parentID != null) { - parent = await this.findGitHubRepositoryByID(dbRepo.parentID) - } - -@@ -253,14 +261,19 @@ - endpoint: string, - gitHubRepository: IAPIRepository - ): Promise<GitHubRepository> { -- let parent: GitHubRepository | null = null -- if (gitHubRepository.parent) { -- parent = await this.putGitHubRepository(endpoint, gitHubRepository.parent) -+ let parentRepo: GitHubRepository | null = null -+ -+ if (gitHubRepository.fork) { -+ const parent = forceUnwrap( -+ 'A forked repository must have a parent', -+ gitHubRepository.parent -+ ) -+ -+ parentRepo = await this.putGitHubRepository(endpoint, parent) - } - - const login = gitHubRepository.owner.login.toLowerCase() - const owner = await this.putOwner(endpoint, login) -- - const existingRepo = await this.db.gitHubRepositories - .where('[ownerID+name]') - .equals([owner.id!, gitHubRepository.name]) -@@ -273,13 +286,15 @@ - htmlURL: gitHubRepository.html_url, - defaultBranch: gitHubRepository.default_branch, - cloneURL: gitHubRepository.clone_url, -- parentID: parent ? parent.dbID : null, -+ parentID: parentRepo ? parentRepo.dbID : null, - } -+ - if (existingRepo) { - updatedGitHubRepo = { ...updatedGitHubRepo, id: existingRepo.id } - } - - const id = await this.db.gitHubRepositories.put(updatedGitHubRepo) -+ - return new GitHubRepository( - updatedGitHubRepo.name, - owner, -@@ -288,7 +303,7 @@ - updatedGitHubRepo.htmlURL, - updatedGitHubRepo.defaultBranch, - updatedGitHubRepo.cloneURL, -- parent -+ parentRepo - ) - } - -changed in both - base 100644 aa510beef50c878b8639a69157281c7460e868ab app/src/ui/index.tsx - our 100644 f8f8200917327048c8f002fcfade473dfd6668d1 app/src/ui/index.tsx - their 100644 17edd3e21a277257324770e576786dd04cef3c80 app/src/ui/index.tsx -@@ -122,7 +122,8 @@ - - const pullRequestStore = new PullRequestStore( - new PullRequestDatabase('PullRequestDatabase'), -- repositoriesStore -+ repositoriesStore.findOrPutGitHubRepository, -+ repositoriesStore.findGitHubRepositoryByID - ) - - const appStore = new AppStore( -removed in remote - base 100644 eed3816fb2f76f373f7ae51c5cfa9132619fb879 app/test/unit/accounts-store-test.ts - our 100644 eed3816fb2f76f373f7ae51c5cfa9132619fb879 app/test/unit/accounts-store-test.ts -@@ -1,27 +0,0 @@ --import { expect } from 'chai' -- --import { Account } from '../../src/models/account' --import { AccountsStore } from '../../src/lib/stores' --import { InMemoryStore, AsyncInMemoryStore } from '../helpers/stores' -- --describe('AccountsStore', () => { -- let accountsStore: AccountsStore | null = null -- beforeEach(() => { -- accountsStore = new AccountsStore( -- new InMemoryStore(), -- new AsyncInMemoryStore() -- ) -- }) -- -- describe('adding a new user', () => { -- it('contains the added user', async () => { -- const newAccountLogin = 'joan' -- await accountsStore!.addAccount( -- new Account(newAccountLogin, '', 'deadbeef', [], '', 1, '') -- ) -- -- const users = await accountsStore!.getAll() -- expect(users[0].login).to.equal(newAccountLogin) -- }) -- }) --}) -removed in remote - base 100644 bd8253abfa8404e42377b4b26ffe52f11269f273 app/test/unit/app-store-test.ts - our 100644 7c7b2a2600b6cdb77d652940772194805df43425 app/test/unit/app-store-test.ts -@@ -1,149 +0,0 @@ --import { expect, AssertionError } from 'chai' -- --import * as Path from 'path' --import * as FSE from 'fs-extra' --import { GitProcess } from 'dugite' -- --import { -- AppStore, -- GitHubUserStore, -- CloningRepositoriesStore, -- EmojiStore, -- IssuesStore, -- SignInStore, -- RepositoriesStore, -- AccountsStore, -- PullRequestStore, --} from '../../src/lib/stores' --import { -- TestGitHubUserDatabase, -- TestStatsDatabase, -- TestIssuesDatabase, -- TestRepositoriesDatabase, -- TestPullRequestDatabase, --} from '../helpers/databases' --import { setupEmptyRepository } from '../helpers/repositories' --import { InMemoryStore, AsyncInMemoryStore } from '../helpers/stores' -- --import { StatsStore } from '../../src/lib/stats' -- --import { -- RepositorySectionTab, -- SelectionType, -- IRepositoryState, --} from '../../src/lib/app-state' --import { Repository } from '../../src/models/repository' --import { Commit } from '../../src/models/commit' --import { getCommit } from '../../src/lib/git' --import { TestActivityMonitor } from '../helpers/test-activity-monitor' -- --describe('AppStore', () => { -- async function createAppStore(): Promise<AppStore> { -- const db = new TestGitHubUserDatabase() -- await db.reset() -- -- const issuesDb = new TestIssuesDatabase() -- await issuesDb.reset() -- -- const statsDb = new TestStatsDatabase() -- await statsDb.reset() -- -- const repositoriesDb = new TestRepositoriesDatabase() -- await repositoriesDb.reset() -- const repositoriesStore = new RepositoriesStore(repositoriesDb) -- -- const accountsStore = new AccountsStore( -- new InMemoryStore(), -- new AsyncInMemoryStore() -- ) -- -- const pullRequestStore = new PullRequestStore( -- new TestPullRequestDatabase(), -- repositoriesStore -- ) -- -- return new AppStore( -- new GitHubUserStore(db), -- new CloningRepositoriesStore(), -- new EmojiStore(), -- new IssuesStore(issuesDb), -- new StatsStore(statsDb, new TestActivityMonitor()), -- new SignInStore(), -- accountsStore, -- repositoriesStore, -- pullRequestStore -- ) -- } -- -- it('can select a repository', async () => { -- const appStore = await createAppStore() -- -- const repo = await setupEmptyRepository() -- -- await appStore._selectRepository(repo) -- -- const state = appStore.getState() -- expect(state.selectedState).is.not.null -- expect(state.selectedState!.repository.path).to.equal(repo.path) -- }) -- -- describe('undo first commit', () => { -- function getAppState(appStore: AppStore): IRepositoryState { -- const selectedState = appStore.getState().selectedState -- if (selectedState == null) { -- throw new AssertionError('No selected state for AppStore') -- } -- -- switch (selectedState.type) { -- case SelectionType.Repository: -- return selectedState.state -- default: -- throw new AssertionError( -- `Got selected state of type ${ -- selectedState.type -- } which is not supported.` -- ) -- } -- } -- -- let repo: Repository | null = null -- let firstCommit: Commit | null = null -- -- beforeEach(async () => { -- repo = await setupEmptyRepository() -- -- const file = 'README.md' -- const filePath = Path.join(repo.path, file) -- -- await FSE.writeFile(filePath, 'SOME WORDS GO HERE\n') -- -- await GitProcess.exec(['add', file], repo.path) -- await GitProcess.exec(['commit', '-m', 'added file'], repo.path) -- -- firstCommit = await getCommit(repo, 'master') -- expect(firstCommit).to.not.equal(null) -- expect(firstCommit!.parentSHAs.length).to.equal(0) -- }) -- -- it('clears the undo commit dialog', async () => { -- const repository = repo! -- -- const appStore = await createAppStore() -- -- // select the repository and show the changes view -- await appStore._selectRepository(repository) -- await appStore._changeRepositorySection( -- repository, -- RepositorySectionTab.Changes -- ) -- -- let state = getAppState(appStore) -- expect(state.localCommitSHAs.length).to.equal(1) -- -- await appStore._undoCommit(repository, firstCommit!) -- -- state = getAppState(appStore) -- expect(state.localCommitSHAs).to.be.empty -- }) -- }) --}) -changed in both - base 100644 0bbac36c08afbbd66754513e6f476caf3155de3c app/test/unit/app-test.tsx - our 100644 f5a4bb958cedfdbf76f9144a200a3cfac9613c02 app/test/unit/app-test.tsx - their 100644 e79103f1df9b5ad5ec5640735a4c2d56fe4905b0 app/test/unit/app-test.tsx -@@ -56,7 +56,8 @@ - - const pullRequestStore = new PullRequestStore( - new TestPullRequestDatabase(), -- repositoriesStore -+ repositoriesStore.findOrPutGitHubRepository, -+ repositoriesStore.findGitHubRepositoryByID - ) - - appStore = new AppStore( -removed in remote - base 100644 b69dfb902e2537440f7b72b9537c1de1aaf8b113 app/test/unit/git-store-test.ts - our 100644 916df52e71502aa756ade2e09be78d7398a4c7f0 app/test/unit/git-store-test.ts -@@ -1,226 +0,0 @@ --import { expect } from 'chai' --import * as FSE from 'fs-extra' --import * as Path from 'path' --import { GitProcess } from 'dugite' -- --import { shell } from '../helpers/test-app-shell' --import { -- setupEmptyRepository, -- setupFixtureRepository, -- setupConflictedRepo, --} from '../helpers/repositories' --import { GitStore } from '../../src/lib/stores' --import { AppFileStatus } from '../../src/models/status' --import { Repository } from '../../src/models/repository' --import { Commit } from '../../src/models/commit' --import { TipState, IValidBranch } from '../../src/models/tip' --import { getCommit } from '../../src/lib/git' --import { getStatusOrThrow } from '../helpers/status' -- --describe('GitStore', () => { -- describe('loadCommitBatch', () => { -- it('includes HEAD when loading commits', async () => { -- const path = await setupFixtureRepository('repository-with-105-commits') -- const repo = new Repository(path, -1, null, false) -- const gitStore = new GitStore(repo, shell) -- -- const commits = await gitStore.loadCommitBatch('HEAD') -- -- expect(commits).is.not.null -- expect(commits!.length).equals(100) -- expect(commits![0]).equals('708a46eac512c7b2486da2247f116d11a100b611') -- }) -- }) -- -- it('can discard changes from a repository', async () => { -- const repo = await setupEmptyRepository() -- const gitStore = new GitStore(repo, shell) -- -- const readmeFile = 'README.md' -- const readmeFilePath = Path.join(repo.path, readmeFile) -- -- await FSE.writeFile(readmeFilePath, 'SOME WORDS GO HERE\n') -- -- const licenseFile = 'LICENSE.md' -- const licenseFilePath = Path.join(repo.path, licenseFile) -- -- await FSE.writeFile(licenseFilePath, 'SOME WORDS GO HERE\n') -- -- // commit the readme file but leave the license -- await GitProcess.exec(['add', readmeFile], repo.path) -- await GitProcess.exec(['commit', '-m', 'added readme file'], repo.path) -- -- await FSE.writeFile(readmeFilePath, 'WRITING SOME NEW WORDS\n') -- // setup requires knowing about the current tip -- await gitStore.loadStatus() -- -- let status = await getStatusOrThrow(repo) -- let files = status.workingDirectory.files -- -- expect(files.length).to.equal(2) -- expect(files[0].path).to.equal('README.md') -- expect(files[0].status).to.equal(AppFileStatus.Modified) -- -- // discard the LICENSE.md file -- await gitStore.discardChanges([files[1]]) -- -- status = await getStatusOrThrow(repo) -- files = status.workingDirectory.files -- -- expect(files.length).to.equal(1) -- }) -- -- it('can discard a renamed file', async () => { -- const repo = await setupEmptyRepository() -- const gitStore = new GitStore(repo, shell) -- -- const file = 'README.md' -- const renamedFile = 'NEW-README.md' -- const filePath = Path.join(repo.path, file) -- -- await FSE.writeFile(filePath, 'SOME WORDS GO HERE\n') -- -- // commit the file, and then rename it -- await GitProcess.exec(['add', file], repo.path) -- await GitProcess.exec(['commit', '-m', 'added file'], repo.path) -- await GitProcess.exec(['mv', file, renamedFile], repo.path) -- -- const statusBeforeDiscard = await getStatusOrThrow(repo) -- const filesToDiscard = statusBeforeDiscard.workingDirectory.files -- -- // discard the renamed file -- await gitStore.discardChanges(filesToDiscard) -- -- const status = await getStatusOrThrow(repo) -- const files = status.workingDirectory.files -- -- expect(files.length).to.equal(0) -- }) -- -- describe('undo first commit', () => { -- let repo: Repository | null = null -- let firstCommit: Commit | null = null -- -- const commitMessage = 'added file' -- -- beforeEach(async () => { -- repo = await setupEmptyRepository() -- -- const file = 'README.md' -- const filePath = Path.join(repo.path, file) -- -- await FSE.writeFile(filePath, 'SOME WORDS GO HERE\n') -- -- await GitProcess.exec(['add', file], repo.path) -- await GitProcess.exec(['commit', '-m', commitMessage], repo.path) -- -- firstCommit = await getCommit(repo!, 'master') -- expect(firstCommit).to.not.equal(null) -- expect(firstCommit!.parentSHAs.length).to.equal(0) -- }) -- -- it('reports the repository is unborn', async () => { -- const gitStore = new GitStore(repo!, shell) -- -- await gitStore.loadStatus() -- expect(gitStore.tip.kind).to.equal(TipState.Valid) -- -- await gitStore.undoCommit(firstCommit!) -- -- const after = await getStatusOrThrow(repo!) -- expect(after.currentTip).to.be.undefined -- }) -- -- it('pre-fills the commit message', async () => { -- const gitStore = new GitStore(repo!, shell) -- -- await gitStore.undoCommit(firstCommit!) -- -- const context = gitStore.contextualCommitMessage -- expect(context).to.not.be.null -- expect(context!.summary).to.equal(commitMessage) -- }) -- -- it('clears the undo commit dialog', async () => { -- const gitStore = new GitStore(repo!, shell) -- -- await gitStore.loadStatus() -- -- const tip = gitStore.tip as IValidBranch -- await gitStore.loadLocalCommits(tip.branch) -- -- expect(gitStore.localCommitSHAs.length).to.equal(1) -- -- await gitStore.undoCommit(firstCommit!) -- -- await gitStore.loadStatus() -- expect(gitStore.tip.kind).to.equal(TipState.Unborn) -- -- await gitStore.loadLocalCommits(null) -- -- expect(gitStore.localCommitSHAs).to.be.empty -- }) -- -- it('has no staged files', async () => { -- const gitStore = new GitStore(repo!, shell) -- -- await gitStore.loadStatus() -- -- const tip = gitStore.tip as IValidBranch -- await gitStore.loadLocalCommits(tip.branch) -- -- expect(gitStore.localCommitSHAs.length).to.equal(1) -- -- await gitStore.undoCommit(firstCommit!) -- -- // compare the index state to some other tree-ish -- // 4b825dc642cb6eb9a060e54bf8d69288fbee4904 is the magic empty tree -- // if nothing is staged, this should return no entries -- const result = await GitProcess.exec( -- [ -- 'diff-index', -- '--name-status', -- '-z', -- '4b825dc642cb6eb9a060e54bf8d69288fbee4904', -- ], -- repo!.path -- ) -- expect(result.stdout.length).to.equal(0) -- }) -- }) -- -- it('hides commented out lines from MERGE_MSG', async () => { -- const repo = await setupConflictedRepo() -- const gitStore = new GitStore(repo, shell) -- -- await gitStore.loadContextualCommitMessage() -- -- const context = gitStore.contextualCommitMessage -- expect(context).to.not.be.null -- expect(context!.summary).to.equal(`Merge branch 'master' into other-branch`) -- expect(context!.description).to.be.null -- }) -- -- describe('repository with HEAD file', () => { -- it('can discard modified change cleanly', async () => { -- const path = await setupFixtureRepository('repository-with-HEAD-file') -- const repo = new Repository(path, 1, null, false) -- const gitStore = new GitStore(repo, shell) -- -- const file = 'README.md' -- const filePath = Path.join(repo.path, file) -- -- await FSE.writeFile(filePath, 'SOME WORDS GO HERE\n') -- -- let status = await getStatusOrThrow(repo!) -- let files = status.workingDirectory.files -- expect(files.length).to.equal(1) -- -- await gitStore.discardChanges([files[0]]) -- -- status = await getStatusOrThrow(repo) -- files = status.workingDirectory.files -- expect(files.length).to.equal(0) -- }) -- }) --}) -removed in remote - base 100644 4f50c70494d77eebb361fea30170605dcfd57f75 app/test/unit/repositories-store-test.ts - our 100644 494c842a7b1384406f5afa4b664134c29366ea2b app/test/unit/repositories-store-test.ts -@@ -1,102 +0,0 @@ --import { expect } from 'chai' -- --import { RepositoriesStore } from '../../src/lib/stores/repositories-store' --import { TestRepositoriesDatabase } from '../helpers/databases' --import { IAPIRepository } from '../../src/lib/api' -- --describe('RepositoriesStore', () => { -- let repositoriesStore: RepositoriesStore | null = null -- -- beforeEach(async () => { -- const db = new TestRepositoriesDatabase() -- await db.reset() -- -- repositoriesStore = new RepositoriesStore(db) -- }) -- -- describe('adding a new repository', () => { -- it('contains the added repository', async () => { -- const repoPath = '/some/cool/path' -- await repositoriesStore!.addRepository(repoPath) -- -- const repositories = await repositoriesStore!.getAll() -- expect(repositories[0].path).to.equal(repoPath) -- }) -- }) -- -- describe('getting all repositories', () => { -- it('returns multiple repositories', async () => { -- await repositoriesStore!.addRepository('/some/cool/path') -- await repositoriesStore!.addRepository('/some/other/path') -- -- const repositories = await repositoriesStore!.getAll() -- expect(repositories.length).to.equal(2) -- }) -- }) -- -- describe('updating a GitHub repository', () => { -- const gitHubRepo: IAPIRepository = { -- clone_url: 'https://github.com/my-user/my-repo', -- html_url: 'https://github.com/my-user/my-repo', -- name: 'my-repo', -- owner: { -- id: 42, -- url: 'https://github.com/my-user', -- login: 'my-user', -- avatar_url: 'https://github.com/my-user.png', -- email: 'my-user@users.noreply.github.com', -- name: 'My User', -- type: 'User', -- }, -- private: true, -- fork: false, -- default_branch: 'master', -- parent: null, -- pushed_at: '1995-12-17T03:24:00', -- } -- -- it('adds a new GitHub repository', async () => { -- const addedRepo = await repositoriesStore!.addRepository( -- '/some/cool/path' -- ) -- -- await repositoriesStore!.updateGitHubRepository( -- addedRepo, -- 'https://api.github.com', -- gitHubRepo -- ) -- -- const repositories = await repositoriesStore!.getAll() -- const repo = repositories[0] -- expect(repo.gitHubRepository!.private).to.equal(true) -- expect(repo.gitHubRepository!.fork).to.equal(false) -- expect(repo.gitHubRepository!.htmlURL).to.equal( -- 'https://github.com/my-user/my-repo' -- ) -- }) -- -- it('reuses an existing GitHub repository', async () => { -- const firstRepo = await repositoriesStore!.addRepository( -- '/some/cool/path' -- ) -- const updatedFirstRepo = await repositoriesStore!.updateGitHubRepository( -- firstRepo, -- 'https://api.github.com', -- gitHubRepo -- ) -- -- const secondRepo = await repositoriesStore!.addRepository( -- '/some/other/path' -- ) -- const updatedSecondRepo = await repositoriesStore!.updateGitHubRepository( -- secondRepo, -- 'https://api.github.com', -- gitHubRepo -- ) -- -- expect(updatedFirstRepo.gitHubRepository!.dbID).to.equal( -- updatedSecondRepo.gitHubRepository!.dbID -- ) -- }) -- }) --}) -removed in remote - base 100644 c96d616cf971efe5da8283c233918fc7a712c1de app/test/unit/repository-settings-store-test.ts - our 100644 b494a61563050dad05675803d60a24c4bd0becce app/test/unit/repository-settings-store-test.ts -@@ -1,122 +0,0 @@ --import * as FSE from 'fs-extra' --import * as Path from 'path' --import { GitProcess } from 'dugite' --import { expect } from 'chai' -- --import { RepositorySettingsStore } from '../../src/lib/stores' --import { setupEmptyRepository } from '../helpers/repositories' --import { getStatusOrThrow } from '../helpers/status' -- --describe('RepositorySettingsStore', () => { -- it('can create a gitignore file', async () => { -- const repo = await setupEmptyRepository() -- const path = repo.path -- const sut = new RepositorySettingsStore(repo) -- -- // Create git ignore file -- await sut.saveGitIgnore('node_modules\n') -- -- // Make sure file exists on FS -- const exists = await FSE.pathExists(`${path}/.gitignore`) -- -- expect(exists).is.true -- }) -- -- it('deletes gitignore file when no entries provided', async () => { -- const repo = await setupEmptyRepository() -- const path = repo.path -- -- const ignoreFile = `${path}/.gitignore` -- await FSE.writeFile(ignoreFile, 'node_modules\n') -- -- const sut = new RepositorySettingsStore(repo) -- -- // update gitignore file to be empty -- await sut.saveGitIgnore('') -- -- const exists = await FSE.pathExists(ignoreFile) -- expect(exists).is.false -- }) -- -- it('can ignore a file in a repository', async () => { -- const repo = await setupEmptyRepository() -- const sut = new RepositorySettingsStore(repo) -- const path = repo.path -- -- // Ignore txt files -- await sut.saveGitIgnore('*.txt\n') -- await GitProcess.exec(['add', '.gitignore'], path) -- await GitProcess.exec(['commit', '-m', 'create the ignore file'], path) -- -- // Create a txt file -- const file = Path.join(repo.path, 'a.txt') -- -- await FSE.writeFile(file, 'thrvbnmerkl;,iuw') -- -- // Check status of repo -- const status = await getStatusOrThrow(repo) -- const files = status.workingDirectory.files -- -- expect(files.length).to.equal(0) -- }) -- -- describe('autocrlf and safecrlf are true', () => { -- it('appends CRLF to file', async () => { -- const repo = await setupEmptyRepository() -- const sut = new RepositorySettingsStore(repo) -- -- await GitProcess.exec( -- ['config', '--local', 'core.autocrlf', 'true'], -- repo.path -- ) -- await GitProcess.exec( -- ['config', '--local', 'core.safecrlf', 'true'], -- repo.path -- ) -- -- const path = repo.path -- -- await sut.saveGitIgnore('node_modules') -- await GitProcess.exec(['add', '.gitignore'], path) -- -- const commit = await GitProcess.exec( -- ['commit', '-m', 'create the ignore file'], -- path -- ) -- const contents = await sut.readGitIgnore() -- -- expect(commit.exitCode).to.equal(0) -- expect(contents!.endsWith('\r\n')) -- }) -- }) -- -- describe('autocrlf and safecrlf are unset', () => { -- it('appends LF to file', async () => { -- const repo = await setupEmptyRepository() -- const sut = new RepositorySettingsStore(repo) -- -- // ensure this repository only ever sticks to LF -- await GitProcess.exec(['config', '--local', 'core.eol', 'lf'], repo.path) -- -- // do not do any conversion of line endings when committing -- await GitProcess.exec( -- ['config', '--local', 'core.autocrlf', 'input'], -- repo.path -- ) -- -- const path = repo.path -- -- await sut.saveGitIgnore('node_modules') -- await GitProcess.exec(['add', '.gitignore'], path) -- -- const commit = await GitProcess.exec( -- ['commit', '-m', 'create the ignore file'], -- path -- ) -- const contents = await sut.readGitIgnore() -- -- expect(commit.exitCode).to.equal(0) -- expect(contents!.endsWith('\n')) -- }) -- }) --}) -added in remote - their 100644 3a5a0d3e23ab06bce9d346e875f730dc95558357 app/test/unit/stores/accounts-store-test.ts -@@ -0,0 +1,27 @@ -+import { expect } from 'chai' -+ -+import { Account } from '../../../src/models/account' -+import { AccountsStore } from '../../../src/lib/stores' -+import { InMemoryStore, AsyncInMemoryStore } from '../../helpers/stores' -+ -+describe('AccountsStore', () => { -+ let accountsStore: AccountsStore | null = null -+ beforeEach(() => { -+ accountsStore = new AccountsStore( -+ new InMemoryStore(), -+ new AsyncInMemoryStore() -+ ) -+ }) -+ -+ describe('adding a new user', () => { -+ it('contains the added user', async () => { -+ const newAccountLogin = 'joan' -+ await accountsStore!.addAccount( -+ new Account(newAccountLogin, '', 'deadbeef', [], '', 1, '') -+ ) -+ -+ const users = await accountsStore!.getAll() -+ expect(users[0].login).to.equal(newAccountLogin) -+ }) -+ }) -+}) -added in remote - their 100644 5f6d89f86e246507b78f71f823f67dec49b58937 app/test/unit/stores/app-store-test.ts -@@ -0,0 +1,151 @@ -+/* eslint-disable no-sync */ -+ -+import { expect } from 'chai' -+ -+import * as Path from 'path' -+import * as Fs from 'fs' -+import { GitProcess } from 'dugite' -+ -+import { -+ AppStore, -+ GitHubUserStore, -+ CloningRepositoriesStore, -+ EmojiStore, -+ IssuesStore, -+ SignInStore, -+ RepositoriesStore, -+ AccountsStore, -+ PullRequestStore, -+} from '../../../src/lib/stores' -+import { -+ TestGitHubUserDatabase, -+ TestStatsDatabase, -+ TestIssuesDatabase, -+ TestRepositoriesDatabase, -+ TestPullRequestDatabase, -+} from '../../helpers/databases' -+import { setupEmptyRepository } from '../../helpers/repositories' -+import { InMemoryStore, AsyncInMemoryStore } from '../../helpers/stores' -+ -+import { StatsStore } from '../../../src/lib/stats' -+ -+import { -+ RepositorySection, -+ SelectionType, -+ IRepositoryState, -+} from '../../../src/lib/app-state' -+import { Repository } from '../../../src/models/repository' -+import { Commit } from '../../../src/models/commit' -+import { getCommit } from '../../../src/lib/git' -+ -+describe('AppStore', () => { -+ async function createAppStore(): Promise<AppStore> { -+ const db = new TestGitHubUserDatabase() -+ await db.reset() -+ -+ const issuesDb = new TestIssuesDatabase() -+ await issuesDb.reset() -+ -+ const statsDb = new TestStatsDatabase() -+ await statsDb.reset() -+ -+ const repositoriesDb = new TestRepositoriesDatabase() -+ await repositoriesDb.reset() -+ const repositoriesStore = new RepositoriesStore(repositoriesDb) -+ -+ const accountsStore = new AccountsStore( -+ new InMemoryStore(), -+ new AsyncInMemoryStore() -+ ) -+ -+ const pullRequestStore = new PullRequestStore( -+ new TestPullRequestDatabase(), -+ repositoriesStore.findOrPutGitHubRepository, -+ repositoriesStore.findGitHubRepositoryByID -+ ) -+ -+ return new AppStore( -+ new GitHubUserStore(db), -+ new CloningRepositoriesStore(), -+ new EmojiStore(), -+ new IssuesStore(issuesDb), -+ new StatsStore(statsDb), -+ new SignInStore(), -+ accountsStore, -+ repositoriesStore, -+ pullRequestStore -+ ) -+ } -+ -+ it('can select a repository', async () => { -+ const appStore = await createAppStore() -+ -+ const repo = await setupEmptyRepository() -+ -+ await appStore._selectRepository(repo) -+ -+ const state = appStore.getState() -+ expect(state.selectedState).is.not.null -+ expect(state.selectedState!.repository.path).to.equal(repo.path) -+ }) -+ -+ describe('undo first commit', () => { -+ function getAppState(appStore: AppStore): IRepositoryState { -+ const selectedState = appStore.getState().selectedState -+ if (!selectedState) { -+ throw new chai.AssertionError('No selected state for AppStore') -+ } -+ -+ switch (selectedState.type) { -+ case SelectionType.Repository: -+ return selectedState.state -+ default: -+ throw new chai.AssertionError( -+ `Got selected state of type ${ -+ selectedState.type -+ } which is not supported.` -+ ) -+ } -+ } -+ -+ let repo: Repository | null = null -+ let firstCommit: Commit | null = null -+ -+ beforeEach(async () => { -+ repo = await setupEmptyRepository() -+ -+ const file = 'README.md' -+ const filePath = Path.join(repo.path, file) -+ -+ Fs.writeFileSync(filePath, 'SOME WORDS GO HERE\n') -+ -+ await GitProcess.exec(['add', file], repo.path) -+ await GitProcess.exec(['commit', '-m', 'added file'], repo.path) -+ -+ firstCommit = await getCommit(repo, 'master') -+ expect(firstCommit).to.not.equal(null) -+ expect(firstCommit!.parentSHAs.length).to.equal(0) -+ }) -+ -+ it('clears the undo commit dialog', async () => { -+ const repository = repo! -+ -+ const appStore = await createAppStore() -+ -+ // select the repository and show the changes view -+ await appStore._selectRepository(repository) -+ await appStore._changeRepositorySection( -+ repository, -+ RepositorySection.Changes -+ ) -+ -+ let state = getAppState(appStore) -+ expect(state.localCommitSHAs.length).to.equal(1) -+ -+ await appStore._undoCommit(repository, firstCommit!) -+ -+ state = getAppState(appStore) -+ expect(state.localCommitSHAs).to.be.empty -+ }) -+ }) -+}) -added in remote - their 100644 2799672ba597c9fc173b4994f6140993d664fe0f app/test/unit/stores/git-store-test.ts -@@ -0,0 +1,215 @@ -+/* eslint-disable no-sync */ -+ -+import { expect } from 'chai' -+import * as Fs from 'fs' -+import * as Path from 'path' -+import { GitProcess } from 'dugite' -+ -+import { shell } from '../../helpers/test-app-shell' -+import { -+ setupEmptyRepository, -+ setupFixtureRepository, -+ setupConflictedRepo, -+} from '../../helpers/repositories' -+import { GitStore } from '../../../src/lib/stores' -+import { AppFileStatus } from '../../../src/models/status' -+import { Repository } from '../../../src/models/repository' -+import { Commit } from '../../../src/models/commit' -+import { TipState, IValidBranch } from '../../../src/models/tip' -+import { getCommit, getStatus } from '../../../src/lib/git' -+ -+describe('GitStore', () => { -+ it('can discard changes from a repository', async () => { -+ const repo = await setupEmptyRepository() -+ const gitStore = new GitStore(repo, shell) -+ -+ const readmeFile = 'README.md' -+ const readmeFilePath = Path.join(repo.path, readmeFile) -+ -+ Fs.writeFileSync(readmeFilePath, 'SOME WORDS GO HERE\n') -+ -+ const licenseFile = 'LICENSE.md' -+ const licenseFilePath = Path.join(repo.path, licenseFile) -+ -+ Fs.writeFileSync(licenseFilePath, 'SOME WORDS GO HERE\n') -+ -+ // commit the readme file but leave the license -+ await GitProcess.exec(['add', readmeFile], repo.path) -+ await GitProcess.exec(['commit', '-m', 'added readme file'], repo.path) -+ -+ Fs.writeFileSync(readmeFilePath, 'WRITING SOME NEW WORDS\n') -+ // setup requires knowing about the current tip -+ await gitStore.loadStatus() -+ -+ let status = await getStatus(repo) -+ let files = status.workingDirectory.files -+ -+ expect(files.length).to.equal(2) -+ expect(files[0].path).to.equal('README.md') -+ expect(files[0].status).to.equal(AppFileStatus.Modified) -+ -+ // discard the LICENSE.md file -+ await gitStore.discardChanges([files[1]]) -+ -+ status = await getStatus(repo) -+ files = status.workingDirectory.files -+ -+ expect(files.length).to.equal(1) -+ }) -+ -+ it('can discard a renamed file', async () => { -+ const repo = await setupEmptyRepository() -+ const gitStore = new GitStore(repo, shell) -+ -+ const file = 'README.md' -+ const renamedFile = 'NEW-README.md' -+ const filePath = Path.join(repo.path, file) -+ -+ Fs.writeFileSync(filePath, 'SOME WORDS GO HERE\n') -+ -+ // commit the file, and then rename it -+ await GitProcess.exec(['add', file], repo.path) -+ await GitProcess.exec(['commit', '-m', 'added file'], repo.path) -+ await GitProcess.exec(['mv', file, renamedFile], repo.path) -+ -+ const statusBeforeDiscard = await getStatus(repo) -+ const filesToDiscard = statusBeforeDiscard.workingDirectory.files -+ -+ // discard the renamed file -+ await gitStore.discardChanges(filesToDiscard) -+ -+ const status = await getStatus(repo) -+ const files = status.workingDirectory.files -+ -+ expect(files.length).to.equal(0) -+ }) -+ -+ describe('undo first commit', () => { -+ let repo: Repository | null = null -+ let firstCommit: Commit | null = null -+ -+ const commitMessage = 'added file' -+ -+ beforeEach(async () => { -+ repo = await setupEmptyRepository() -+ -+ const file = 'README.md' -+ const filePath = Path.join(repo.path, file) -+ -+ Fs.writeFileSync(filePath, 'SOME WORDS GO HERE\n') -+ -+ await GitProcess.exec(['add', file], repo.path) -+ await GitProcess.exec(['commit', '-m', commitMessage], repo.path) -+ -+ firstCommit = await getCommit(repo!, 'master') -+ expect(firstCommit).to.not.equal(null) -+ expect(firstCommit!.parentSHAs.length).to.equal(0) -+ }) -+ -+ it('reports the repository is unborn', async () => { -+ const gitStore = new GitStore(repo!, shell) -+ -+ await gitStore.loadStatus() -+ expect(gitStore.tip.kind).to.equal(TipState.Valid) -+ -+ await gitStore.undoCommit(firstCommit!) -+ -+ const after = await getStatus(repo!) -+ -+ expect(after).to.not.be.null -+ expect(after!.currentTip).to.be.undefined -+ }) -+ -+ it('pre-fills the commit message', async () => { -+ const gitStore = new GitStore(repo!, shell) -+ -+ await gitStore.undoCommit(firstCommit!) -+ -+ const context = gitStore.contextualCommitMessage -+ expect(context).to.not.be.null -+ expect(context!.summary).to.equal(commitMessage) -+ }) -+ -+ it('clears the undo commit dialog', async () => { -+ const gitStore = new GitStore(repo!, shell) -+ -+ await gitStore.loadStatus() -+ -+ const tip = gitStore.tip as IValidBranch -+ await gitStore.loadLocalCommits(tip.branch) -+ -+ expect(gitStore.localCommitSHAs.length).to.equal(1) -+ -+ await gitStore.undoCommit(firstCommit!) -+ -+ await gitStore.loadStatus() -+ expect(gitStore.tip.kind).to.equal(TipState.Unborn) -+ -+ await gitStore.loadLocalCommits(null) -+ -+ expect(gitStore.localCommitSHAs).to.be.empty -+ }) -+ -+ it('has no staged files', async () => { -+ const gitStore = new GitStore(repo!, shell) -+ -+ await gitStore.loadStatus() -+ -+ const tip = gitStore.tip as IValidBranch -+ await gitStore.loadLocalCommits(tip.branch) -+ -+ expect(gitStore.localCommitSHAs.length).to.equal(1) -+ -+ await gitStore.undoCommit(firstCommit!) -+ -+ // compare the index state to some other tree-ish -+ // 4b825dc642cb6eb9a060e54bf8d69288fbee4904 is the magic empty tree -+ // if nothing is staged, this should return no entries -+ const result = await GitProcess.exec( -+ [ -+ 'diff-index', -+ '--name-status', -+ '-z', -+ '4b825dc642cb6eb9a060e54bf8d69288fbee4904', -+ ], -+ repo!.path -+ ) -+ expect(result.stdout.length).to.equal(0) -+ }) -+ }) -+ -+ it('hides commented out lines from MERGE_MSG', async () => { -+ const repo = await setupConflictedRepo() -+ const gitStore = new GitStore(repo, shell) -+ -+ await gitStore.loadContextualCommitMessage() -+ -+ const context = gitStore.contextualCommitMessage -+ expect(context).to.not.be.null -+ expect(context!.summary).to.equal(`Merge branch 'master' into other-branch`) -+ expect(context!.description).to.be.null -+ }) -+ -+ describe('repository with HEAD file', () => { -+ it('can discard modified change cleanly', async () => { -+ const path = await setupFixtureRepository('repository-with-HEAD-file') -+ const repo = new Repository(path, 1, null, false) -+ const gitStore = new GitStore(repo, shell) -+ -+ const file = 'README.md' -+ const filePath = Path.join(repo.path, file) -+ -+ Fs.writeFileSync(filePath, 'SOME WORDS GO HERE\n') -+ -+ let status = await getStatus(repo!) -+ let files = status.workingDirectory.files -+ expect(files.length).to.equal(1) -+ -+ await gitStore.discardChanges([files[0]]) -+ -+ status = await getStatus(repo) -+ files = status.workingDirectory.files -+ expect(files.length).to.equal(0) -+ }) -+ }) -+}) -added in remote - their 100644 cb5b4dc2d922d6e0291d1dd18496257b2c958945 app/test/unit/stores/pull-request-store-test.ts -@@ -0,0 +1,84 @@ -+import { expect } from 'chai' -+ -+import { PullRequestStore } from '../../../src/lib/stores' -+import { -+ TestPullRequestDatabase, -+ TestRepositoriesDatabase, -+} from '../../helpers/databases' -+import { Repository } from '../../../src/models/repository' -+import { Account } from '../../../src/models/account' -+import { GitHubRepository } from '../../../src/models/github-repository' -+import { Owner } from '../../../src/models/owner' -+import { IAPIRepository } from '../../../src/lib/api' -+ -+const findGitHubRepositoryByIDStub = ( -+ id: number -+): Promise<GitHubRepository | null> => { -+ return Promise.resolve( -+ new GitHubRepository( -+ '', -+ new Owner('login', 'endpoint', 1), -+ 1, -+ false, -+ null, -+ null, -+ null, -+ null -+ ) -+ ) -+} -+ -+const findOrPutGitHubRepositoryStub = ( -+ endpoint: string, -+ apiRepository: IAPIRepository -+): Promise<GitHubRepository> => { -+ return Promise.resolve( -+ new GitHubRepository( -+ '', -+ new Owner('login', 'endpoint', 1), -+ 1, -+ false, -+ null, -+ null, -+ null, -+ null -+ ) -+ ) -+} -+ -+describe('PullRequestStore', () => { -+ const account = new Account('tester', '', 'token', [], '', 1, '') -+ let sut: PullRequestStore | null = null -+ let repository: Repository | null = null -+ -+ beforeEach(async () => { -+ const repositoriesDb = new TestRepositoriesDatabase() -+ const pullRequestDb = new TestPullRequestDatabase() -+ await Promise.all([repositoriesDb.reset(), pullRequestDb.reset()]) -+ -+ sut = new PullRequestStore( -+ pullRequestDb, -+ findOrPutGitHubRepositoryStub, -+ findGitHubRepositoryByIDStub -+ ) -+ }) -+ -+ describe('refreshing pull reqeusts', () => { -+ it.only('insers new prs', async () => { -+ await sut!.refreshPullRequests(repository!, account) -+ const prs = await sut!.getPullRequests( -+ new GitHubRepository( -+ '', -+ new Owner('login', 'endpoint', 1), -+ 1, -+ false, -+ null, -+ null, -+ null, -+ null -+ ) -+ ) -+ expect(prs).is.not.empty -+ }) -+ }) -+}) -added in remote - their 100644 0d221bae3fea70347092c299e47d7e209799d26c app/test/unit/stores/repositories-store-test.ts -@@ -0,0 +1,101 @@ -+import { expect } from 'chai' -+ -+import { RepositoriesStore } from '../../../src/lib/stores/repositories-store' -+import { TestRepositoriesDatabase } from '../../helpers/databases' -+import { IAPIRepository } from '../../../src/lib/api' -+ -+describe('RepositoriesStore', () => { -+ let repositoriesStore: RepositoriesStore | null = null -+ -+ beforeEach(async () => { -+ const db = new TestRepositoriesDatabase() -+ await db.reset() -+ -+ repositoriesStore = new RepositoriesStore(db) -+ }) -+ -+ describe('adding a new repository', () => { -+ it('contains the added repository', async () => { -+ const repoPath = '/some/cool/path' -+ await repositoriesStore!.addRepository(repoPath) -+ -+ const repositories = await repositoriesStore!.getAll() -+ expect(repositories[0].path).to.equal(repoPath) -+ }) -+ }) -+ -+ describe('getting all repositories', () => { -+ it('returns multiple repositories', async () => { -+ await repositoriesStore!.addRepository('/some/cool/path') -+ await repositoriesStore!.addRepository('/some/other/path') -+ -+ const repositories = await repositoriesStore!.getAll() -+ expect(repositories.length).to.equal(2) -+ }) -+ }) -+ -+ describe('updating a GitHub repository', () => { -+ const gitHubRepo: IAPIRepository = { -+ clone_url: 'https://github.com/my-user/my-repo', -+ html_url: 'https://github.com/my-user/my-repo', -+ name: 'my-repo', -+ owner: { -+ id: 42, -+ url: 'https://github.com/my-user', -+ login: 'my-user', -+ avatar_url: 'https://github.com/my-user.png', -+ email: 'my-user@users.noreply.github.com', -+ name: 'My User', -+ type: 'User', -+ }, -+ private: true, -+ fork: false, -+ default_branch: 'master', -+ parent: null, -+ } -+ -+ it('adds a new GitHub repository', async () => { -+ const addedRepo = await repositoriesStore!.addRepository( -+ '/some/cool/path' -+ ) -+ -+ await repositoriesStore!.updateGitHubRepository( -+ addedRepo, -+ 'https://api.github.com', -+ gitHubRepo -+ ) -+ -+ const repositories = await repositoriesStore!.getAll() -+ const repo = repositories[0] -+ expect(repo.gitHubRepository!.private).to.equal(true) -+ expect(repo.gitHubRepository!.fork).to.equal(false) -+ expect(repo.gitHubRepository!.htmlURL).to.equal( -+ 'https://github.com/my-user/my-repo' -+ ) -+ }) -+ -+ it('reuses an existing GitHub repository', async () => { -+ const firstRepo = await repositoriesStore!.addRepository( -+ '/some/cool/path' -+ ) -+ const updatedFirstRepo = await repositoriesStore!.updateGitHubRepository( -+ firstRepo, -+ 'https://api.github.com', -+ gitHubRepo -+ ) -+ -+ const secondRepo = await repositoriesStore!.addRepository( -+ '/some/other/path' -+ ) -+ const updatedSecondRepo = await repositoriesStore!.updateGitHubRepository( -+ secondRepo, -+ 'https://api.github.com', -+ gitHubRepo -+ ) -+ -+ expect(updatedFirstRepo.gitHubRepository!.dbID).to.equal( -+ updatedSecondRepo.gitHubRepository!.dbID -+ ) -+ }) -+ }) -+}) -added in remote - their 100644 4372375111e1a70687a21fad975651a1a3f5f93a app/test/unit/stores/repository-settings-store-test.ts -@@ -0,0 +1,109 @@ -+/* eslint-disable no-sync */ -+ -+import * as FS from 'fs' -+import * as Path from 'path' -+import { GitProcess } from 'dugite' -+import { expect } from 'chai' -+ -+import { RepositorySettingsStore } from '../../../src/lib/stores' -+import { setupEmptyRepository } from '../../helpers/repositories' -+import { getStatus } from '../../../src/lib/git' -+import { pathExists } from '../../../src/lib/file-system' -+ -+describe('RepositorySettingsStore', () => { -+ it('can create a gitignore file', async () => { -+ const repo = await setupEmptyRepository() -+ const path = repo.path -+ const sut = new RepositorySettingsStore(repo) -+ -+ // Create git ignore file -+ await sut.saveGitIgnore('node_modules\n') -+ -+ // Make sure file exists on FS -+ const exists = await pathExists(`${path}/.gitignore`) -+ -+ expect(exists).is.true -+ }) -+ -+ it('can ignore a file in a repository', async () => { -+ const repo = await setupEmptyRepository() -+ const sut = new RepositorySettingsStore(repo) -+ const path = repo.path -+ -+ // Ignore txt files -+ await sut.saveGitIgnore('*.txt\n') -+ await GitProcess.exec(['add', '.gitignore'], path) -+ await GitProcess.exec(['commit', '-m', 'create the ignore file'], path) -+ -+ // Create a txt file -+ const file = Path.join(repo.path, 'a.txt') -+ -+ FS.writeFileSync(file, 'thrvbnmerkl;,iuw') -+ -+ // Check status of repo -+ const status = await getStatus(repo) -+ const files = status.workingDirectory.files -+ -+ expect(files.length).to.equal(0) -+ }) -+ -+ describe('autocrlf and safecrlf are true', () => { -+ it('appends CRLF to file', async () => { -+ const repo = await setupEmptyRepository() -+ const sut = new RepositorySettingsStore(repo) -+ -+ await GitProcess.exec( -+ ['config', '--local', 'core.autocrlf', 'true'], -+ repo.path -+ ) -+ await GitProcess.exec( -+ ['config', '--local', 'core.safecrlf', 'true'], -+ repo.path -+ ) -+ -+ const path = repo.path -+ -+ await sut.saveGitIgnore('node_modules') -+ await GitProcess.exec(['add', '.gitignore'], path) -+ -+ const commit = await GitProcess.exec( -+ ['commit', '-m', 'create the ignore file'], -+ path -+ ) -+ const contents = await sut.readGitIgnore() -+ -+ expect(commit.exitCode).to.equal(0) -+ expect(contents!.endsWith('\r\n')) -+ }) -+ }) -+ -+ describe('autocrlf and safecrlf are unset', () => { -+ it('appends LF to file', async () => { -+ const repo = await setupEmptyRepository() -+ const sut = new RepositorySettingsStore(repo) -+ -+ // ensure this repository only ever sticks to LF -+ await GitProcess.exec(['config', '--local', 'core.eol', 'lf'], repo.path) -+ -+ // do not do any conversion of line endings when committing -+ await GitProcess.exec( -+ ['config', '--local', 'core.autocrlf', 'input'], -+ repo.path -+ ) -+ -+ const path = repo.path -+ -+ await sut.saveGitIgnore('node_modules') -+ await GitProcess.exec(['add', '.gitignore'], path) -+ -+ const commit = await GitProcess.exec( -+ ['commit', '-m', 'create the ignore file'], -+ path -+ ) -+ const contents = await sut.readGitIgnore() -+ -+ expect(commit.exitCode).to.equal(0) -+ expect(contents!.endsWith('\n')) -+ }) -+ }) -+}) diff --git a/app/test/fixtures/merge-parser/desktop/merge-no-more-dexie-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-no-more-dexie-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 81db6fe7939..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-no-more-dexie-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,1621 +0,0 @@ -changed in both - base 100644 e4c97b5a507a78e0ae64a236e85f2a97f14a166a app/package.json - our 100644 4ec686d8ad22d3aea1ebe4bddd16f4a7447c3acd app/package.json - their 100644 36077c186aacb4a754ace1aeab392f4d65c8a3e0 app/package.json -@@ -24,6 +24,7 @@ - "codemirror": "^5.31.0", - "codemirror-mode-elixir": "1.1.1", - "deep-equal": "^1.0.1", -+ "lokijs": "^1.5.3", - "dexie": "^2.0.0", - "double-ended-queue": "^2.1.0-0", - "dugite": "^1.67.0", -@@ -61,6 +62,7 @@ - "electron-debug": "^2.0.0", - "electron-devtools-installer": "^2.2.4", - "temp": "^0.8.3", -- "webpack-hot-middleware": "^2.10.0" -+ "webpack-hot-middleware": "^2.10.0", -+ "@types/lokijs": "1.5.2" - } - } -added in remote - their 100644 600991b61a0b68507cefcc1f4f72fc0049447a3b app/src/database/collections.ts -@@ -0,0 +1,3 @@ -+export enum Collections { -+ Repository = 'repository', -+} -added in remote - their 100644 ab444ae2ecf25c444dceb833bdbc3df77eff5d2d app/src/database/command-query/pull-request.ts -@@ -0,0 +1,69 @@ -+import { -+ getGHDatabase, -+ RepositoryKey, -+ Collections, -+ toPullRequestModel, -+ GHDatabase, -+} from '..' -+import { IPullRequestAPIResult } from '../../lib/api' -+import { IPullRequestStatus } from '../../lib/databases' -+import { forceUnwrap } from '../../lib/fatal-error' -+ -+const ghDb = getGHDatabase() -+ -+async function updatePullRequests( -+ key: RepositoryKey, -+ apiResults: ReadonlyArray<IPullRequestAPIResult>, -+ ghDatabase: GHDatabase = ghDb() -+): Promise<void> { -+ const collection = ghDatabase.getCollection(Collections.Repository) -+ await collection.findAndUpdate({ name: key.name, path: key.path }, d => { -+ const ghRepo = d.ghRepository -+ return { -+ ...d, -+ ghRepository: { -+ ...ghRepo, -+ pullRequests: apiResults.map(toPullRequestModel), -+ }, -+ } -+ }) -+ -+ ghDatabase.save() -+} -+ -+async function updatePullRequestStatuses( -+ key: RepositoryKey, -+ prStatusList: Array<IPullRequestStatus>, -+ ghDatabase: GHDatabase = ghDb() -+): Promise<void> { -+ const collection = ghDatabase.getCollection(Collections.Repository) -+ const repo = collection.findOne({ name: key.name, path: key.path }) -+ -+ if (repo === null) { -+ return log.error( -+ `Repository with key ${key.name}+${key.path} cannot be found` -+ ) -+ } -+ -+ const ghRepo = forceUnwrap( -+ 'Cannot update pull request on unpublished repository', -+ repo.ghRepository -+ ) -+ const updated = { -+ ...repo, -+ ghRepository: { -+ ...ghRepo, -+ prStatusList, -+ }, -+ } -+ -+ collection.update(updated) -+ ghDatabase.save() -+} -+ -+export const Command = { -+ updatePullRequests, -+ updatePullRequestStatuses, -+} -+ -+export const Query = {} -added in remote - their 100644 aac17ef31fe7ee555b655c8675e012ffe9cf01eb app/src/database/command-query/repository.ts -@@ -0,0 +1,197 @@ -+import * as Path from 'path' -+ -+import { -+ Collections, -+ IRepository, -+ toGHRepositoryModel, -+ toRepositoryModel, -+ IGHRepository, -+ getGHDatabase, -+ RepositoryKey, -+ GHDatabase, -+} from '..' -+import { IRepositoryAPIResult } from '../../lib/api' -+ -+const ghDb = getGHDatabase() -+ -+function repositoryNotFound(key: RepositoryKey) { -+ return `Repository with key ${key.name}+${key.path} cannot be found` -+} -+ -+function repositoryAlreadyExists(key: RepositoryKey) { -+ return `Repository with key ${key.name}+${key.path} already exists` -+} -+ -+function noAssociatedGHRepository(key: RepositoryKey) { -+ return `Repository with key ${key.name}+${ -+ key.path -+ } has no associated GH Repositroy` -+} -+ -+function associatedGHRepositry(key: RepositoryKey) { -+ return `Repository with key ${key.name}+${ -+ key.path -+ } already has an associated GH Repository` -+} -+ -+async function addParentGHRepository( -+ key: RepositoryKey, -+ endpoint: string, -+ head: IGHRepository, -+ base: IGHRepository, -+ ghDatabase: GHDatabase = ghDb() -+): Promise<void> { -+ const collection = ghDatabase.getCollection(Collections.Repository) -+ const document = collection.findOne({ -+ name: key.name, -+ path: key.path, -+ }) -+ -+ if (document === null) { -+ return log.warn(repositoryNotFound(key)) -+ } -+ -+ if (document.ghRepository === undefined) { -+ return log.warn(noAssociatedGHRepository(key)) -+ } -+ -+ await collection.findAndUpdate( -+ { -+ name: key.name, -+ path: key.path, -+ }, -+ r => ({ -+ kind: 'repository', -+ ...r, -+ ghRepository: { -+ ...head, -+ parent: { -+ ...base, -+ }, -+ }, -+ }) -+ ) -+ -+ await ghDatabase.save() -+} -+ -+async function addGHRepository( -+ key: RepositoryKey, -+ ghRepository: IGHRepository, -+ ghDatabase: GHDatabase = ghDb() -+): Promise<void> { -+ const collection = ghDatabase.getCollection(Collections.Repository) -+ const document = collection.findOne({ -+ name: key.name, -+ path: key.path, -+ }) -+ -+ if (document === null) { -+ return log.warn(repositoryNotFound(key)) -+ } -+ -+ if (document.ghRepository != null) { -+ return log.warn(associatedGHRepositry(key)) -+ } -+ -+ const updated: IRepository & LokiObj = { -+ ...document, -+ ghRepository, -+ } -+ -+ await collection.update(updated) -+ await ghDatabase.save() -+} -+ -+async function getAll( -+ ghDatabase: GHDatabase = ghDb() -+): Promise<ReadonlyArray<IRepository>> { -+ const collection = ghDatabase.getCollection(Collections.Repository) -+ const repos = await collection.find().map(toRepositoryModel) -+ -+ return repos -+} -+ -+async function addRepository( -+ path: string, -+ ghDatabase: GHDatabase = ghDb() -+): Promise<void> { -+ const collection = ghDatabase.getCollection(Collections.Repository) -+ const key = { name: Path.basename(path), path } -+ const repo = collection.findOne({ name: key.name, path: key.path }) -+ -+ if (repo !== null) { -+ return log.warn(repositoryAlreadyExists(key)) -+ } -+ -+ const newRepo = await collection.insertOne({ -+ kind: 'repository', -+ name: Path.basename(path), -+ isMissing: false, -+ path, -+ }) -+ -+ if (newRepo === undefined) { -+ return log.error('Unable to add repository') -+ } -+ -+ await ghDatabase.save() -+} -+ -+async function updateMissingStatus( -+ key: RepositoryKey, -+ isMissing: boolean, -+ ghDatabase: GHDatabase = ghDb() -+): Promise<void> { -+ const collection = ghDatabase.getCollection(Collections.Repository) -+ await collection.findAndUpdate({ name: key.name, path: key.path }, r => ({ -+ ...r, -+ isMissing: isMissing, -+ })) -+ -+ await ghDatabase.save() -+} -+ -+async function updatePath( -+ key: RepositoryKey, -+ path: string, -+ ghDatabase: GHDatabase = ghDb() -+): Promise<void> { -+ const collection = ghDatabase.getCollection(Collections.Repository) -+ await collection.findAndUpdate({ name: key.name, path: key.path }, r => ({ -+ ...r, -+ path, -+ isMissing: false, -+ })) -+ -+ await ghDatabase.save() -+} -+ -+async function updateGHRepository<K extends keyof IRepository>( -+ key: RepositoryKey, -+ ghRepository: Pick<IRepository, K>, -+ ghDatabase: GHDatabase = ghDb() -+): Promise<void> { -+ const collection = ghDatabase.getCollection(Collections.Repository) -+ await collection.findAndUpdate({ name: key.name, path: key.path }, r => ({ -+ ...r, -+ ghRepository: { -+ ghRepository, -+ }, -+ })) -+ -+ ghDatabase.save() -+} -+ -+export const Command = { -+ addRepository, -+ addGHRepository, -+ addParentGHRepository, -+ updateMissingStatus, -+ updatePath, -+ updateGHRepository, -+} -+ -+export const Query = { -+ getAll, -+} -added in remote - their 100644 b7068815397ad608c53ddfc711d3f410e58ab2bb app/src/database/gh-database.ts -@@ -0,0 +1,51 @@ -+import * as Loki from 'lokijs' -+import { Collections, IRepository } from '.' -+import { assertNever } from '../lib/fatal-error' -+ -+const DbPath = '/Users/williamshepherd/Desktop/gh.db' -+ -+export function getGHDatabase() { -+ let ghDb: GHDatabase | null = null -+ -+ return function() { -+ if (ghDb === null) { -+ ghDb = new GHDatabase(DbPath) -+ } -+ -+ return ghDb -+ } -+} -+ -+export class GHDatabase { -+ private readonly db: Loki -+ -+ public constructor(path: string) { -+ this.db = new Loki(path) -+ this.initCollections() -+ } -+ -+ public getCollection(collection: Collections) { -+ switch (collection) { -+ case Collections.Repository: -+ return this.db.getCollection<IRepository>(Collections.Repository) -+ default: -+ return assertNever(collection, `unknown collection ${collection}`) -+ } -+ } -+ -+ public async save() { -+ await this.db.save(this.onSaveError) -+ } -+ -+ private initCollections() { -+ if (this.db.getCollection(Collections.Repository) == null) { -+ this.db.addCollection<IRepository>(Collections.Repository) -+ } -+ } -+ -+ private onSaveError = (error?: any) => { -+ if (error != null) { -+ log.error(error) -+ } -+ } -+} -added in remote - their 100644 2c746de6c43c9928f79b18b1f1a9e25b48167769 app/src/database/helpers.ts -@@ -0,0 +1,132 @@ -+import * as Path from 'path' -+import { IUser, IRepository, IGHRepository, IPullRequest } from '.' -+import { IRepositoryAPIResult, IPullRequestAPIResult } from '../lib/api' -+ -+export type RepositoryKey = { name: string; path: string } -+ -+export function keyOf(repository: IRepository): RepositoryKey { -+ return { -+ name: repository.name, -+ path: repository.path, -+ } -+} -+ -+export function getFullName(repository: IGHRepository | IRepository) { -+ let name: string = repository.name -+ -+ if (repository.kind === 'repository') { -+ name = -+ repository.ghRepository == null -+ ? repository.name || Path.basename(repository.path) -+ : `${repository.ghRepository.owner.login}/${repository.name}` -+ } else if (repository.kind === 'gh-repository') { -+ name = `${repository.owner.login}/${repository.name}` -+ } -+ -+ return name -+} -+ -+export function computeUserHash(user: IUser): string { -+ return `${user.login}+${user.endpoint}+${user.avatarUrl}` -+} -+ -+export function computeGHRepositoryHash(ghRepo: IGHRepository): string { -+ return `${ghRepo.defaultBranch}+ -+ ${ghRepo.isPrivate}+ -+ ${ghRepo.cloneUrl}+ -+ ${ghRepo.name}+ -+ ${ghRepo.htmlUrl}+ -+ ${computeUserHash(ghRepo.owner)}+ -+ ${ghRepo.parent && computeGHRepositoryHash(ghRepo.parent)}` -+} -+ -+export function computeRepositoryHash(repo: IRepository): string { -+ return `${repo.name}+ -+ ${repo.path}+ -+ ${repo.isMissing}+ -+ ${repo.ghRepository && computeGHRepositoryHash(repo.ghRepository)}` -+} -+ -+export function isFork(ghRepository: IGHRepository) { -+ return ghRepository.parent != null -+} -+ -+export function getEndpoint(repository: IGHRepository): string { -+ return repository.owner.endpoint -+} -+ -+export function createRepositoryModel( -+ path: string, -+ isMissing: boolean = false, -+ ghRepository?: IGHRepository -+): IRepository { -+ const model: IRepository = { -+ kind: 'repository', -+ name: (ghRepository && ghRepository.name) || Path.basename(path), -+ path, -+ isMissing, -+ ghRepository, -+ } -+ -+ return model -+} -+ -+export function toRepositoryModel(document: IRepository & LokiObj) { -+ const result: IRepository = { -+ kind: 'repository', -+ name: document.name, -+ path: document.path, -+ isMissing: document.isMissing, -+ ghRepository: document.ghRepository, -+ } -+ -+ return result -+} -+ -+export function toGHRepositoryModel( -+ apiResult: IRepositoryAPIResult, -+ endpoint?: string -+): IGHRepository { -+ const ghRepo: IGHRepository = { -+ kind: 'gh-repository', -+ name: apiResult.name, -+ defaultBranch: apiResult.default_branch, -+ isPrivate: apiResult.private, -+ cloneUrl: apiResult.clone_url, -+ htmlUrl: apiResult.html_url, -+ owner: { -+ name: apiResult.owner.name, -+ login: apiResult.owner.login, -+ email: apiResult.owner.email, -+ endpoint: endpoint || '', // what is endpoint? -+ avatarUrl: apiResult.owner.avatar_url, -+ }, -+ parent: apiResult.parent && toGHRepositoryModel(apiResult.parent), // where do forked repos get their endpoint from -+ issues: [], -+ mentionables: [], -+ pullRequests: [], -+ } -+ -+ return ghRepo -+} -+ -+export function toPullRequestModel( -+ apiResult: IPullRequestAPIResult -+): IPullRequest { -+ const model: IPullRequest = { -+ number: apiResult.number, -+ title: apiResult.title, -+ createdAt: apiResult.created_at, -+ head: { -+ ref: apiResult.head.ref, -+ sha: apiResult.head.sha, -+ }, -+ base: { -+ ref: apiResult.base.ref, -+ sha: apiResult.base.sha, -+ }, -+ author: apiResult.user.login, -+ } -+ -+ return model -+} -added in remote - their 100644 7671ad538e80517882ca29d1051953eff4e2e4c3 app/src/database/index.ts -@@ -0,0 +1,12 @@ -+export * from './models' -+export * from './collections' -+export * from './helpers' -+export * from './gh-database' -+export { -+ Command as RepositoryCommands, -+ Query as RepositoryQueries, -+} from './command-query/repository' -+export { -+ Command as PullRequestCommands, -+ Query as PullRequestQueries, -+} from './command-query/pull-request' -added in remote - their 100644 47c351d6d7cb94d19c659c76961d23d7ad46cf3f app/src/database/models.ts -@@ -0,0 +1,90 @@ -+export type CIStatus = 'failure' | 'pending' | 'success' -+ -+export interface IRepository { -+ readonly kind: 'repository' -+ readonly name: string -+ readonly path: string -+ readonly isMissing: boolean -+ readonly ghRepository?: IGHRepository -+} -+ -+export interface IGHRepository { -+ readonly kind: 'gh-repository' -+ readonly name: string -+ readonly defaultBranch: string -+ readonly isPrivate: boolean -+ readonly cloneUrl: string -+ readonly htmlUrl: string | null -+ readonly issues: ReadonlyArray<IIssue> -+ readonly owner: IUser -+ readonly parent: IGHRepository | null -+ readonly mentionables: ReadonlyArray<IUser> -+ readonly pullRequests: ReadonlyArray<IPullRequest> -+} -+ -+export interface IIssue { -+ readonly number: number -+ readonly title: string -+ readonly updatedAt: Date -+} -+ -+export interface IUser { -+ readonly name: string | null -+ readonly login: string //key -+ readonly email: string | null -+ readonly endpoint: string //key -+ readonly avatarUrl: string -+} -+ -+export interface IPullRequestStatus { -+ /** The status' state. */ -+ readonly state: CIStatus -+ -+ /** The number of statuses represented in this combined status. */ -+ readonly totalCount: number -+ -+ /** The SHA for which this status applies. */ -+ readonly sha: string -+ -+ /** -+ * The list of statuses for this specific ref or undefined -+ * if the database object was created prior to status support -+ * being added in #3588 -+ */ -+ readonly statuses?: ReadonlyArray<IPullRequestStatusItem> -+} -+ -+export interface IPullRequest { -+ /** The GitHub PR number. */ -+ readonly number: number -+ -+ /** The title. */ -+ readonly title: string -+ -+ /** The string formatted date on which the PR was created. */ -+ readonly createdAt: string -+ -+ /** The ref from which the pull request's changes are coming. */ -+ readonly head: IPullRequestRef -+ -+ /** The ref which the pull request is targetting. */ -+ readonly base: IPullRequestRef -+ -+ /** The login of the author. */ -+ readonly author: string -+} -+ -+export interface IPullRequestRef { -+ /** The name of the ref. */ -+ readonly ref: string -+ -+ /** The SHA of the ref. */ -+ readonly sha: string -+} -+ -+export interface IPullRequestStatusItem { -+ readonly state: CIStatus -+ readonly targetUrl: string -+ readonly description: string -+ readonly context: string -+} -changed in both - base 100644 d4b62dbf30e18eb25f0eab0014d38984b1e80c6c app/src/lib/api.ts - our 100644 e77c79b5d20fbcffe9af534504dac98509135263 app/src/lib/api.ts - their 100644 5c6cfde01ed305e7711bd373cc9a1e9a2c8a54b5 app/src/lib/api.ts -@@ -38,30 +38,34 @@ - /** - * Information about a repository as returned by the GitHub API. - */ --export interface IAPIRepository { -+export interface IRepositoryAPIResult { - readonly clone_url: string - readonly html_url: string - readonly name: string -- readonly owner: IAPIUser -+ readonly owner: IUserAPIResult - readonly private: boolean - readonly fork: boolean - readonly default_branch: string -+<<<<<<< .our - readonly pushed_at: string - readonly parent: IAPIRepository | null -+======= -+ readonly parent: IRepositoryAPIResult | null -+>>>>>>> .their - } - - /** - * Information about a commit as returned by the GitHub API. - */ --export interface IAPICommit { -+export interface ICommitAPIResult { - readonly sha: string -- readonly author: IAPIUser | null -+ readonly author: IUserAPIResult | null - } - - /** - * Information about a user as returned by the GitHub API. - */ --export interface IAPIUser { -+export interface IUserAPIResult { - readonly id: number - readonly url: string - readonly login: string -@@ -82,7 +86,7 @@ - } - - /** The users we get from the mentionables endpoint. */ --export interface IAPIMentionableUser { -+export interface IMentionableUserAPIResult { - readonly avatar_url: string - - /** -@@ -106,7 +110,7 @@ - /** - * Information about a user's email as returned by the GitHub API. - */ --export interface IAPIEmail { -+export interface IEmailAPIResult { - readonly email: string - readonly verified: boolean - readonly primary: boolean -@@ -114,7 +118,7 @@ - } - - /** Information about an issue as returned by the GitHub API. */ --export interface IAPIIssue { -+export interface IIssueAPIResult { - readonly number: number - readonly title: string - readonly state: 'open' | 'closed' -@@ -128,7 +132,7 @@ - * The API response for a combined view of a commit - * status for a given ref - */ --export interface IAPIRefStatusItem { -+export interface IRefStatusItemAPIResult { - readonly state: APIRefState - readonly target_url: string - readonly description: string -@@ -137,13 +141,13 @@ - } - - /** The API response to a ref status request. */ --interface IAPIRefStatus { -+interface IRefStatusAPIResult { - readonly state: APIRefState - readonly total_count: number -- readonly statuses: ReadonlyArray<IAPIRefStatusItem> -+ readonly statuses: ReadonlyArray<IRefStatusItemAPIResult> - } - --interface IAPIPullRequestRef { -+interface IPullRequestRefAPIResult { - readonly ref: string - readonly sha: string - -@@ -151,17 +155,17 @@ - * The repository in which this ref lives. It could be null if the repository - * has been deleted since the PR was opened. - */ -- readonly repo: IAPIRepository | null -+ readonly repo: IRepositoryAPIResult | null - } - - /** Information about a pull request as returned by the GitHub API. */ --export interface IAPIPullRequest { -+export interface IPullRequestAPIResult { - readonly number: number - readonly title: string - readonly created_at: string -- readonly user: IAPIUser -- readonly head: IAPIPullRequestRef -- readonly base: IAPIPullRequestRef -+ readonly user: IUserAPIResult -+ readonly head: IPullRequestRefAPIResult -+ readonly base: IPullRequestRefAPIResult - } - - /** The metadata about a GitHub server. */ -@@ -174,21 +178,21 @@ - } - - /** The server response when handling the OAuth callback (with code) to obtain an access token */ --interface IAPIAccessToken { -+interface IAccessTokenAPIResult { - readonly access_token: string - readonly scope: string - readonly token_type: string - } - - /** The partial server response when creating a new authorization on behalf of a user */ --interface IAPIAuthorization { -+interface IAuthorizationAPIResult { - readonly token: string - } - - /** The response we receive from fetching mentionables. */ --interface IAPIMentionablesResponse { -+interface IMentionablesResponseAPIResult { - readonly etag: string | null -- readonly users: ReadonlyArray<IAPIMentionableUser> -+ readonly users: ReadonlyArray<IMentionableUserAPIResult> - } - - /** The response for search results. */ -@@ -254,14 +258,14 @@ - public async fetchRepository( - owner: string, - name: string -- ): Promise<IAPIRepository | null> { -+ ): Promise<IRepositoryAPIResult | null> { - try { - const response = await this.request('GET', `repos/${owner}/${name}`) - if (response.status === HttpStatusCode.NotFound) { - log.warn(`fetchRepository: '${owner}/${name}' returned a 404`) - return null - } -- return await parsedResponse<IAPIRepository>(response) -+ return await parsedResponse<IRepositoryAPIResult>(response) - } catch (e) { - log.warn(`fetchRepository: an error occurred for '${owner}/${name}'`, e) - return null -@@ -270,10 +274,10 @@ - - /** Fetch all repos a user has access to. */ - public async fetchRepositories(): Promise<ReadonlyArray< -- IAPIRepository -+ IRepositoryAPIResult - > | null> { - try { -- return await this.fetchAll<IAPIRepository>('user/repos') -+ return await this.fetchAll<IRepositoryAPIResult>('user/repos') - } catch (error) { - log.warn(`fetchRepositories: ${error}`) - return null -@@ -281,10 +285,10 @@ - } - - /** Fetch the logged in account. */ -- public async fetchAccount(): Promise<IAPIUser> { -+ public async fetchAccount(): Promise<IUserAPIResult> { - try { - const response = await this.request('GET', 'user') -- const result = await parsedResponse<IAPIUser>(response) -+ const result = await parsedResponse<IUserAPIResult>(response) - return result - } catch (e) { - log.warn(`fetchAccount: failed with endpoint ${this.endpoint}`, e) -@@ -293,10 +297,10 @@ - } - - /** Fetch the current user's emails. */ -- public async fetchEmails(): Promise<ReadonlyArray<IAPIEmail>> { -+ public async fetchEmails(): Promise<ReadonlyArray<IEmailAPIResult>> { - try { - const response = await this.request('GET', 'user/emails') -- const result = await parsedResponse<ReadonlyArray<IAPIEmail>>(response) -+ const result = await parsedResponse<ReadonlyArray<IEmailAPIResult>>(response) - - return Array.isArray(result) ? result : [] - } catch (e) { -@@ -310,7 +314,7 @@ - owner: string, - name: string, - sha: string -- ): Promise<IAPICommit | null> { -+ ): Promise<ICommitAPIResult | null> { - try { - const path = `repos/${owner}/${name}/commits/${sha}` - const response = await this.request('GET', path) -@@ -318,7 +322,7 @@ - log.warn(`fetchCommit: '${path}' returned a 404`) - return null - } -- return parsedResponse<IAPICommit>(response) -+ return parsedResponse<ICommitAPIResult>(response) - } catch (e) { - log.warn(`fetchCommit: returned an error '${owner}/${name}@${sha}'`, e) - return null -@@ -326,12 +330,12 @@ - } - - /** Search for a user with the given public email. */ -- public async searchForUserWithEmail(email: string): Promise<IAPIUser | null> { -+ public async searchForUserWithEmail(email: string): Promise<IUserAPIResult | null> { - try { - const params = { q: `${email} in:email type:user` } - const url = urlWithQueryString('search/users', params) - const response = await this.request('GET', url) -- const result = await parsedResponse<ISearchResults<IAPIUser>>(response) -+ const result = await parsedResponse<ISearchResults<IUserAPIResult>>(response) - const items = result.items - if (items.length) { - // The results are sorted by score, best to worst. So the first result -@@ -347,9 +351,9 @@ - } - - /** Fetch all the orgs to which the user belongs. */ -- public async fetchOrgs(): Promise<ReadonlyArray<IAPIUser>> { -+ public async fetchOrgs(): Promise<ReadonlyArray<IUserAPIResult>> { - try { -- return this.fetchAll<IAPIUser>('user/orgs') -+ return this.fetchAll<IUserAPIResult>('user/orgs') - } catch (e) { - log.warn(`fetchOrgs: failed with endpoint ${this.endpoint}`, e) - return [] -@@ -358,11 +362,11 @@ - - /** Create a new GitHub repository with the given properties. */ - public async createRepository( -- org: IAPIUser | null, -+ org: IUserAPIResult | null, - name: string, - description: string, - private_: boolean -- ): Promise<IAPIRepository> { -+ ): Promise<IRepositoryAPIResult> { - try { - const apiPath = org ? `orgs/${org.login}/repos` : 'user/repos' - const response = await this.request('POST', apiPath, { -@@ -371,7 +375,7 @@ - private: private_, - }) - -- return await parsedResponse<IAPIRepository>(response) -+ return await parsedResponse<IRepositoryAPIResult>(response) - } catch (e) { - if (e instanceof APIError) { - throw e -@@ -393,7 +397,7 @@ - name: string, - state: 'open' | 'closed' | 'all', - since: Date | null -- ): Promise<ReadonlyArray<IAPIIssue>> { -+ ): Promise<ReadonlyArray<IIssueAPIResult>> { - const params: { [key: string]: string } = { - state, - } -@@ -403,7 +407,7 @@ - - const url = urlWithQueryString(`repos/${owner}/${name}/issues`, params) - try { -- const issues = await this.fetchAll<IAPIIssue>(url) -+ const issues = await this.fetchAll<IIssueAPIResult>(url) - - // PRs are issues! But we only want Really Seriously Issues. - return issues.filter((i: any) => !i.pullRequest) -@@ -418,10 +422,10 @@ - owner: string, - name: string, - state: 'open' | 'closed' | 'all' -- ): Promise<ReadonlyArray<IAPIPullRequest>> { -+ ): Promise<ReadonlyArray<IPullRequestAPIResult>> { - const url = urlWithQueryString(`repos/${owner}/${name}/pulls`, { state }) - try { -- const prs = await this.fetchAll<IAPIPullRequest>(url) -+ const prs = await this.fetchAll<IPullRequestAPIResult>(url) - return prs - } catch (e) { - log.warn(`fetchPullRequests: failed for repository ${owner}/${name}`, e) -@@ -434,11 +438,11 @@ - owner: string, - name: string, - ref: string -- ): Promise<IAPIRefStatus> { -+ ): Promise<IRefStatusAPIResult> { - const path = `repos/${owner}/${name}/commits/${ref}/status` - try { - const response = await this.request('GET', path) -- const status = await parsedResponse<IAPIRefStatus>(response) -+ const status = await parsedResponse<IRefStatusAPIResult>(response) - return status - } catch (e) { - log.warn( -@@ -523,7 +527,7 @@ - owner: string, - name: string, - etag: string | null -- ): Promise<IAPIMentionablesResponse | null> { -+ ): Promise<IMentionablesResponseAPIResult | null> { - // NB: this custom `Accept` is required for the `mentionables` endpoint. - const headers: any = { - Accept: 'application/vnd.github.jerry-maguire-preview', -@@ -545,7 +549,7 @@ - if (response.status === HttpStatusCode.NotModified) { - return null - } -- const users = await parsedResponse<ReadonlyArray<IAPIMentionableUser>>( -+ const users = await parsedResponse<ReadonlyArray<IMentionableUserAPIResult>>( - response - ) - const etag = response.headers.get('etag') -@@ -560,7 +564,7 @@ - * Retrieve the public profile information of a user with - * a given username. - */ -- public async fetchUser(login: string): Promise<IAPIUser | null> { -+ public async fetchUser(login: string): Promise<IUserAPIResult | null> { - try { - const response = await this.request( - 'GET', -@@ -571,7 +575,7 @@ - return null - } - -- return await parsedResponse<IAPIUser>(response) -+ return await parsedResponse<IUserAPIResult>(response) - } catch (e) { - log.warn(`fetchUser: failed with endpoint ${this.endpoint}`, e) - throw e -@@ -637,7 +641,7 @@ - ) - - try { -- const result = await parsedResponse<IAPIAuthorization>(response) -+ const result = await parsedResponse<IAuthorizationAPIResult>(response) - if (result) { - const token = result.token - if (token && typeof token === 'string' && token.length) { -@@ -874,7 +878,7 @@ - state: state, - } - ) -- const result = await parsedResponse<IAPIAccessToken>(response) -+ const result = await parsedResponse<IAccessTokenAPIResult>(response) - return result.access_token - } catch (e) { - log.warn(`requestOAuthToken: failed with endpoint ${endpoint}`, e) -merged - result 100644 e9f18567505d90c790ed1a9e78cc3d5c7607540d app/src/lib/databases/pull-request-database.ts - our 100644 7446a4ce1ebf104f7825a7757e6be2beccfbe4ef app/src/lib/databases/pull-request-database.ts -@@ -1,5 +1,5 @@ - import Dexie from 'dexie' --import { APIRefState, IAPIRefStatusItem } from '../api' -+import { APIRefState, IRefStatusItemAPIResult } from '../api' - import { BaseDatabase } from './base-database' - - export interface IPullRequestRef { -@@ -66,7 +66,7 @@ - * if the database object was created prior to status support - * being added in #3588 - */ -- readonly statuses?: ReadonlyArray<IAPIRefStatusItem> -+ readonly statuses?: ReadonlyArray<IRefStatusItemAPIResult> - } - - export class PullRequestDatabase extends BaseDatabase { -changed in both - base 100644 760b02c3045adfd175c5e95574dedb44b6d391b8 app/src/lib/dispatcher/dispatcher.ts - our 100644 5e56c00e713342e76f5ccba040062e322e8c90cb app/src/lib/dispatcher/dispatcher.ts - their 100644 d3a21040c57d47665e2454cf71f005b4758f9526 app/src/lib/dispatcher/dispatcher.ts -@@ -25,7 +25,7 @@ - import { Branch } from '../../models/branch' - import { Commit } from '../../models/commit' - import { ExternalEditor } from '../../lib/editors' --import { IAPIUser } from '../../lib/api' -+import { IUserAPIResult } from '../../lib/api' - import { GitHubRepository } from '../../models/github-repository' - import { ICommitMessage } from '../stores/git-store' - import { executeMenuItem } from '../../ui/main-process-proxy' -@@ -329,7 +329,7 @@ - description: string, - private_: boolean, - account: Account, -- org: IAPIUser | null -+ org: IUserAPIResult | null - ): Promise<Repository> { - return this.appStore._publishRepository( - repository, -merged - result 100644 8f5db8c73829182de3f168745e3fa54305542e9d app/src/lib/email.ts - our 100644 3ac283444e4f360757ee5da392edc097c37794bc app/src/lib/email.ts -@@ -1,4 +1,4 @@ --import { IAPIEmail } from './api' -+import { IEmailAPIResult } from './api' - - /** - * Lookup a suitable email address to display in the application, based on the -@@ -14,8 +14,8 @@ - * @param emails array of email addresses associated with an account - */ - export function lookupPreferredEmail( -- emails: ReadonlyArray<IAPIEmail> --): IAPIEmail | null { -+ emails: ReadonlyArray<IEmailAPIResult> -+): IEmailAPIResult | null { - if (emails.length === 0) { - return null - } -@@ -38,7 +38,7 @@ - /** - * Is the email public? - */ --function isEmailPublic(email: IAPIEmail): boolean { -+function isEmailPublic(email: IEmailAPIResult): boolean { - // If an email doesn't have a visibility setting it means it's coming from an - // older Enterprise server which doesn't have the concept of visiblity. - return email.visibility === 'public' || !email.visibility -changed in both - base 100644 3664497681402ef660531130f999ac3e39892b4d app/src/lib/stores/app-store.ts - our 100644 1a4e387e4d192d34abfd0621b4b5ebe8cc34d8d1 app/src/lib/stores/app-store.ts - their 100644 0da783ee96ab4fd9f8643355f356060d44cc2c3b app/src/lib/stores/app-store.ts -@@ -43,6 +43,7 @@ - matchGitHubRepository, - IMatchedGitHubRepository, - repositoryMatchesRemote, -+<<<<<<< .our - } from '../repository-matching' - import { - API, -@@ -51,6 +52,10 @@ - getDotComAPIEndpoint, - getEnterpriseAPIURL, - } from '../api' -+======= -+} from '../../lib/repository-matching' -+import { API, getAccountForEndpoint, IUserAPIResult } from '../../lib/api' -+>>>>>>> .their - import { caseInsensitiveCompare } from '../compare' - import { - Branch, -@@ -2730,7 +2735,7 @@ - description: string, - private_: boolean, - account: Account, -- org: IAPIUser | null -+ org: IUserAPIResult | null - ): Promise<Repository> { - const api = API.fromAccount(account) - const apiRepository = await api.createRepository( -merged - result 100644 3468d42c0ef4395a79e75b4cadaf6ca401c80c58 app/src/lib/stores/issues-store.ts - our 100644 c4b2992a861aecc044e73eeb318e9675d0ee59e7 app/src/lib/stores/issues-store.ts -@@ -1,5 +1,5 @@ - import { IssuesDatabase, IIssue } from '../databases/issues-database' --import { API, IAPIIssue } from '../api' -+import { API, IIssueAPIResult } from '../api' - import { Account } from '../../models/account' - import { GitHubRepository } from '../../models/github-repository' - import { fatalError } from '../fatal-error' -@@ -76,7 +76,7 @@ - } - - private async storeIssues( -- issues: ReadonlyArray<IAPIIssue>, -+ issues: ReadonlyArray<IIssueAPIResult>, - repository: GitHubRepository - ): Promise<void> { - const gitHubRepositoryID = repository.dbID -changed in both - base 100644 23008ccae33cd7a55484a79207c7d3d9543c27d7 app/src/lib/stores/pull-request-store.ts - our 100644 d9edf0247ea7c33ae2b508f876aa977d8a81d6d4 app/src/lib/stores/pull-request-store.ts - their 100644 f1dde026873fcee9f4de25abc66d8c53329bf9d2 app/src/lib/stores/pull-request-store.ts -@@ -5,7 +5,7 @@ - } from '../databases' - import { GitHubRepository } from '../../models/github-repository' - import { Account } from '../../models/account' --import { API, IAPIPullRequest } from '../api' -+import { API, IPullRequestAPIResult } from '../api' - import { fatalError, forceUnwrap } from '../fatal-error' - import { RepositoriesStore } from './repositories-store' - import { -@@ -310,7 +310,7 @@ - } - - private async cachePullRequests( -- pullRequestsFromAPI: ReadonlyArray<IAPIPullRequest>, -+ pullRequestsFromAPI: ReadonlyArray<IPullRequestAPIResult>, - repository: GitHubRepository - ): Promise<void> { - const repoDbId = repository.dbID -merged - result 100644 a302a2e6b935b27ccea24b60fb308f019b956b48 app/src/lib/stores/repositories-store.ts - our 100644 1c0981c70e593bda2422a96ca43b130cedd5db06 app/src/lib/stores/repositories-store.ts -@@ -7,7 +7,7 @@ - import { GitHubRepository } from '../../models/github-repository' - import { Repository } from '../../models/repository' - import { fatalError } from '../fatal-error' --import { IAPIRepository } from '../api' -+import { IRepositoryAPIResult } from '../api' - import { BaseStore } from './base-store' - - /** The store for local repositories. */ -@@ -23,7 +23,7 @@ - /** Find the matching GitHub repository or add it if it doesn't exist. */ - public async upsertGitHubRepository( - endpoint: string, -- apiRepository: IAPIRepository -+ apiRepository: IRepositoryAPIResult - ): Promise<GitHubRepository> { - return this.db.transaction( - 'rw', -@@ -251,7 +251,7 @@ - - private async putGitHubRepository( - endpoint: string, -- gitHubRepository: IAPIRepository -+ gitHubRepository: IRepositoryAPIResult - ): Promise<GitHubRepository> { - let parent: GitHubRepository | null = null - if (gitHubRepository.parent) { -@@ -296,7 +296,7 @@ - public async updateGitHubRepository( - repository: Repository, - endpoint: string, -- gitHubRepository: IAPIRepository -+ gitHubRepository: IRepositoryAPIResult - ): Promise<Repository> { - const repoID = repository.id - if (!repoID) { -merged - result 100644 aab6a484f467bc265ab4217886451e865db504f2 app/src/models/account.ts - our 100644 8400b1e41845964df7e675b460454ac5f90de185 app/src/models/account.ts -@@ -1,4 +1,4 @@ --import { getDotComAPIEndpoint, IAPIEmail } from '../lib/api' -+import { getDotComAPIEndpoint, IEmailAPIResult } from '../lib/api' - - /** - * A GitHub account, representing the user found on GitHub The Website or GitHub Enterprise. -@@ -19,7 +19,7 @@ - /** The access token used to perform operations on behalf of this account */ - public readonly token: string, - /** The current list of email addresses associated with the account */ -- public readonly emails: ReadonlyArray<IAPIEmail>, -+ public readonly emails: ReadonlyArray<IEmailAPIResult>, - /** The profile URL to render for this account */ - public readonly avatarURL: string, - /** The database id for this account */ -changed in both - base 100644 d14189ae128a22845dc39ec28b62ae2e108a42ba app/src/ui/clone-repository/group-repositories.ts - our 100644 b7412f2d5dd94cba15f7a987e719915969a75f6e app/src/ui/clone-repository/group-repositories.ts - their 100644 6cce360d40425ead0bbcc38fd341c00cb77fc1d3 app/src/ui/clone-repository/group-repositories.ts -@@ -1,4 +1,4 @@ --import { IAPIRepository } from '../../lib/api' -+import { IRepositoryAPIResult } from '../../lib/api' - import { IFilterListGroup, IFilterListItem } from '../lib/filter-list' - import { caseInsensitiveCompare } from '../../lib/compare' - import { OcticonSymbol } from '../octicons' -@@ -23,7 +23,7 @@ - readonly url: string - } - --function getIcon(gitHubRepo: IAPIRepository): OcticonSymbol { -+function getIcon(gitHubRepo: IRepositoryAPIResult): OcticonSymbol { - if (gitHubRepo.private) { - return OcticonSymbol.lock - } -@@ -35,7 +35,7 @@ - } - - function convert( -- repositories: ReadonlyArray<IAPIRepository> -+ repositories: ReadonlyArray<IRepositoryAPIResult> - ): ReadonlyArray<ICloneableRepositoryListItem> { - const repos: ReadonlyArray<ICloneableRepositoryListItem> = repositories.map( - repo => { -@@ -55,7 +55,7 @@ - } - - export function groupRepositories( -- repositories: ReadonlyArray<IAPIRepository>, -+ repositories: ReadonlyArray<IRepositoryAPIResult>, - login: string - ): ReadonlyArray<IFilterListGroup<ICloneableRepositoryListItem>> { - const userRepos = repositories.filter(repo => repo.owner.type === 'User') -merged - result 100644 0046063ad8f56f2b7cb21d2a88898cdc0fa75a91 app/src/ui/publish-repository/publish-repository.tsx - our 100644 c14a53943087c492bc981e916b32c2d35eedc78c app/src/ui/publish-repository/publish-repository.tsx -@@ -1,6 +1,6 @@ - import * as React from 'react' - import { Account } from '../../models/account' --import { API, IAPIUser } from '../../lib/api' -+import { API, IUserAPIResult } from '../../lib/api' - import { TextBox } from '../lib/text-box' - import { Select } from '../lib/select' - import { DialogContent } from '../dialog' -@@ -33,11 +33,11 @@ - * The org to which this repository belongs. If null, the repository should be - * published as a personal repository. - */ -- readonly org: IAPIUser | null -+ readonly org: IUserAPIResult | null - } - - interface IPublishRepositoryState { -- readonly orgs: ReadonlyArray<IAPIUser> -+ readonly orgs: ReadonlyArray<IUserAPIResult> - } - - /** The Publish Repository component. */ -@@ -65,7 +65,7 @@ - - private async fetchOrgs(account: Account) { - const api = API.fromAccount(account) -- const orgs = (await api.fetchOrgs()) as Array<IAPIUser> -+ const orgs = (await api.fetchOrgs()) as Array<IUserAPIResult> - orgs.sort((a, b) => caseInsensitiveCompare(a.login, b.login)) - this.setState({ orgs }) - } -merged - result 100644 fadc5d62c89aeeb2ac87efb8af09198fbf3d3278 app/test/helpers/databases/index.ts - our 100644 3db7bdbaa949fd7f7b318dbe44f1785679b6e126 app/test/helpers/databases/index.ts -@@ -3,3 +3,4 @@ - export * from './test-repositories-database' - export * from './test-stats-database' - export * from './test-pull-request-database' -+export * from './test-gh-database' -added in remote - their 100644 96dd276a52363919e479191833e5cc846162a201 app/test/helpers/databases/test-gh-database.ts -@@ -0,0 +1,34 @@ -+import * as FSE from 'fs-extra' -+import { expect } from 'chai' -+import { getTestGHDatabase, TestGHDatabasePath } from '../test-gh-database' -+import { Collections } from '../../../src/database' -+ -+const testDb = getTestGHDatabase() -+ -+describe('Database', () => { -+ describe('Initialization', () => { -+ it('initializes all collections', () => { -+ const repos = testDb().getCollection(Collections.Repository) -+ -+ expect(repos).is.not.null -+ }) -+ }) -+ -+ describe('Adding data', () => { -+ it('persists the data to disk', async () => { -+ const repos = testDb().getCollection(Collections.Repository) -+ await repos.insertOne({ -+ kind: 'repository', -+ name: 'test', -+ path: '~/ghd.test.db', -+ isMissing: false, -+ }) -+ -+ await testDb().save() -+ -+ const exists = FSE.existsSync(TestGHDatabasePath) -+ -+ expect(exists).is.true -+ }) -+ }) -+}) -added in remote - their 100644 8854265709ca4481c2c13489a6daf6f89e0bc788 app/test/helpers/test-gh-database.ts -@@ -0,0 +1,15 @@ -+import { GHDatabase } from '../../src/database' -+ -+export const TestGHDatabasePath = '/Users/iamwillshepherd/Desktop/gh.db.json' -+ -+export function getTestGHDatabase() { -+ let ghDb: GHDatabase | null = null -+ -+ return function() { -+ if (ghDb === null) { -+ ghDb = new GHDatabase(TestGHDatabasePath) -+ } -+ -+ return ghDb -+ } -+} -added in remote - their 100644 7789a4b41a51e928ff54516a9d9988febb824835 app/test/unit/database/repository-command-query-test.ts -@@ -0,0 +1,166 @@ -+import { expect } from 'chai' -+import { getTestGHDatabase } from '../../helpers/test-gh-database' -+import { -+ RepositoryCommands, -+ Collections, -+ RepositoryQueries, -+ RepositoryKey, -+ IGHRepository, -+ IUser, -+ IRepository, -+ keyOf, -+} from '../../../src/database' -+ -+const testDb = getTestGHDatabase() -+ -+describe('Repository Commands', () => { -+ beforeEach(async () => { -+ const collection = testDb().getCollection(Collections.Repository) -+ await collection.clear() -+ await testDb().save() -+ }) -+ -+ describe('addRepository', () => { -+ it('adds the repository', async () => { -+ const testPath = 'test' -+ await RepositoryCommands.addRepository(testPath, testDb()) -+ -+ const addedRepo = testDb() -+ .getCollection(Collections.Repository) -+ .find() -+ -+ expect(addedRepo.length).to.equal(1) -+ }) -+ -+ it('performs no-op when given path that already exists', async () => { -+ const testPath = 'test' -+ await RepositoryCommands.addRepository(testPath, testDb()) -+ await RepositoryCommands.addRepository(testPath, testDb()) -+ -+ const addedRepo = testDb() -+ .getCollection(Collections.Repository) -+ .find() -+ -+ expect(addedRepo.length).to.equal(1) -+ }) -+ }) -+ -+ describe('addGHRepository', () => { -+ it('adds the ghRepository', async () => { -+ // create new repo -+ const testPath = 'path' -+ const key: RepositoryKey = { -+ name: testPath, -+ path: testPath, -+ } -+ -+ await RepositoryCommands.addRepository(testPath, testDb()) -+ -+ // get repo to add a ghRepository to it -+ let repo = await testDb() -+ .getCollection(Collections.Repository) -+ .findOne({ name: key.name, path: key.path }) -+ -+ expect(repo!.ghRepository).to.be.undefined -+ -+ // add ghRepository -+ await RepositoryCommands.addGHRepository( -+ key, -+ createGHRepository(), -+ testDb() -+ ) -+ -+ // get the new repo -+ repo = await testDb() -+ .getCollection(Collections.Repository) -+ .findOne({ name: key.name, path: key.path }) -+ -+ expect(repo!.ghRepository).to.not.be.undefined -+ }) -+ }) -+ -+ describe('addParentGHRepository', () => { -+ it.only('adds gh repository to document', async () => { -+ const repoToInsert = { -+ ...createRepository(), -+ ghRepository: { -+ ...createGHRepository(), -+ }, -+ } -+ const key = keyOf(repoToInsert) -+ await testDb() -+ .getCollection(Collections.Repository) -+ .insertOne(repoToInsert) -+ -+ testDb().save() -+ -+ await RepositoryCommands.addParentGHRepository( -+ key, -+ '', -+ createGHRepository(), -+ createGHRepository(), -+ testDb() -+ ) -+ -+ const updatedRepo = await testDb() -+ .getCollection(Collections.Repository) -+ .findOne({ name: key.name, path: key.path }) -+ -+ expect(updatedRepo!.ghRepository).to.not.be.undefined -+ }) -+ }) -+}) -+ -+describe('Repository Queries', () => { -+ beforeEach(async () => { -+ const collection = testDb().getCollection(Collections.Repository) -+ await collection.clear() -+ await testDb().save() -+ }) -+ -+ describe('getAll', () => { -+ it('returns all repositories', async () => { -+ await RepositoryCommands.addRepository('test-repo-1', testDb()) -+ await RepositoryCommands.addRepository('test-repo-2', testDb()) -+ await RepositoryCommands.addRepository('test-repo-3', testDb()) -+ await RepositoryCommands.addRepository('test-repo-4', testDb()) -+ -+ const repos = await RepositoryQueries.getAll(testDb()) -+ -+ expect(repos.length).to.equal(4) -+ }) -+ }) -+}) -+ -+function createRepository(): IRepository { -+ return { -+ kind: 'repository', -+ name: 'name', -+ path: 'path', -+ isMissing: false, -+ } -+} -+ -+function createGHRepository(): IGHRepository { -+ const owner: IUser = { -+ name: null, -+ login: '', -+ email: null, -+ endpoint: '', -+ avatarUrl: '', -+ } -+ const ghRepository: IGHRepository = { -+ kind: 'gh-repository', -+ name: '', -+ defaultBranch: '', -+ isPrivate: false, -+ cloneUrl: '', -+ htmlUrl: '', -+ issues: [], -+ owner: owner, -+ parent: null, -+ mentionables: [], -+ pullRequests: [], -+ } -+ return ghRepository -+} -merged - result 100644 51e0b11ff0ba9f9fbbc5b903e884ba9c9fcb00eb app/test/unit/email-test.ts - our 100644 55c63b58438949fc7f8a2362f9a990117cc5d936 app/test/unit/email-test.ts -@@ -1,7 +1,7 @@ - import { expect } from 'chai' - - import { lookupPreferredEmail } from '../../src/lib/email' --import { IAPIEmail } from '../../src/lib/api' -+import { IEmailAPIResult } from '../../src/lib/api' - - describe('emails', () => { - it('returns null for empty list', () => { -@@ -9,7 +9,7 @@ - }) - - it('returns the primary if it has public visibility', () => { -- const emails: IAPIEmail[] = [ -+ const emails: IEmailAPIResult[] = [ - { - email: 'shiftkey@example.com', - primary: false, -@@ -36,7 +36,7 @@ - }) - - it('returns the primary if it has null visibility', () => { -- const emails: IAPIEmail[] = [ -+ const emails: IEmailAPIResult[] = [ - { - email: 'shiftkey@example.com', - primary: false, -@@ -63,7 +63,7 @@ - }) - - it('returns the noreply if there is no public address', () => { -- const emails: IAPIEmail[] = [ -+ const emails: IEmailAPIResult[] = [ - { - email: 'shiftkey@example.com', - primary: false, -@@ -90,7 +90,7 @@ - }) - - it('uses first email if nothing special found', () => { -- const emails: IAPIEmail[] = [ -+ const emails: IEmailAPIResult[] = [ - { - email: 'shiftkey@example.com', - primary: false, -changed in both - base 100644 8034e9a41509ef0bedf3e3cc1a10879c5713939b app/test/unit/repositories-clone-grouping-test.ts - our 100644 83c00fb3fa5a862ae8b27e94721b2d5ac962335d app/test/unit/repositories-clone-grouping-test.ts - their 100644 927f59189b4c030a5934364e7b662bcd373eab4d app/test/unit/repositories-clone-grouping-test.ts -@@ -4,7 +4,7 @@ - groupRepositories, - YourRepositoriesIdentifier, - } from '../../src/ui/clone-repository/group-repositories' --import { IAPIRepository, IAPIUser } from '../../src/lib/api' -+import { IRepositoryAPIResult, IUserAPIResult } from '../../src/lib/api' - - const users = { - shiftkey: { -@@ -14,7 +14,7 @@ - avatar_url: '', - name: 'Brendan Forster', - type: 'User', -- } as IAPIUser, -+ } as IUserAPIResult, - desktop: { - id: 2, - url: '', -@@ -22,7 +22,7 @@ - avatar_url: '', - name: 'Desktop', - type: 'Organization', -- } as IAPIUser, -+ } as IUserAPIResult, - octokit: { - id: 3, - url: '', -@@ -30,12 +30,12 @@ - avatar_url: '', - name: 'Octokit', - type: 'Organization', -- } as IAPIUser, -+ } as IUserAPIResult, - } - - describe('clone repository grouping', () => { - it('groups repositories by organization', () => { -- const repositories: Array<IAPIRepository> = [ -+ const repositories: Array<IRepositoryAPIResult> = [ - { - clone_url: '', - html_url: '', -changed in both - base 100644 4f50c70494d77eebb361fea30170605dcfd57f75 app/test/unit/repositories-store-test.ts - our 100644 494c842a7b1384406f5afa4b664134c29366ea2b app/test/unit/repositories-store-test.ts - their 100644 a29ae0bd759983bd2b0561e49afa77901a3ce1d6 app/test/unit/repositories-store-test.ts -@@ -2,7 +2,7 @@ - - import { RepositoriesStore } from '../../src/lib/stores/repositories-store' - import { TestRepositoriesDatabase } from '../helpers/databases' --import { IAPIRepository } from '../../src/lib/api' -+import { IRepositoryAPIResult } from '../../src/lib/api' - - describe('RepositoriesStore', () => { - let repositoriesStore: RepositoriesStore | null = null -@@ -35,7 +35,7 @@ - }) - - describe('updating a GitHub repository', () => { -- const gitHubRepo: IAPIRepository = { -+ const gitHubRepo: IRepositoryAPIResult = { - clone_url: 'https://github.com/my-user/my-repo', - html_url: 'https://github.com/my-user/my-repo', - name: 'my-repo', -changed in both - base 100644 b017e5071b105d30e40c12577ba965bef3cfa5c2 app/yarn.lock - our 100644 cd6294bb698115d3ff652d361f00efbf85c1e781 app/yarn.lock - their 100644 4c3c5a5dd1c1e3959da17bbfd1bfd78855021857 app/yarn.lock -@@ -6,6 +6,10 @@ - version "0.0.6" - resolved "https://registry.yarnpkg.com/7zip/-/7zip-0.0.6.tgz#9cafb171af82329490353b4816f03347aa150a30" - -+"@types/lokijs@1.5.2": -+ version "1.5.2" -+ resolved "https://registry.yarnpkg.com/@types/lokijs/-/lokijs-1.5.2.tgz#ed228f080033ce1fb16eff4acde65cb9ae0f1bf2" -+ - accessibility-developer-tools@^2.11.0: - version "2.12.0" - resolved "https://registry.yarnpkg.com/accessibility-developer-tools/-/accessibility-developer-tools-2.12.0.tgz#3da0cce9d6ec6373964b84f35db7cfc3df7ab514" -@@ -548,6 +552,21 @@ - dependencies: - nan "2.5.1" - -+<<<<<<< .our -+======= -+loader-utils@^1.0.2: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" -+ dependencies: -+ big.js "^3.1.3" -+ emojis-list "^2.0.0" -+ json5 "^0.5.0" -+ -+lokijs@^1.5.3: -+ version "1.5.3" -+ resolved "https://registry.yarnpkg.com/lokijs/-/lokijs-1.5.3.tgz#6952722ffa3049a55a5e1c10ee4a0947a3e5e19b" -+ -+>>>>>>> .their - loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.0, loose-envify@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" diff --git a/app/test/fixtures/merge-parser/desktop/merge-not-too-small-now-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-not-too-small-now-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 4c2fe296536..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-not-too-small-now-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,47 +0,0 @@ -changed in both - base 100644 fa95746b3b525b06246015c03db11b35209b8fb1 app/src/ui/repository.tsx - our 100644 efb00423012b8da0dfa5e8897acacaeb0a5e648a app/src/ui/repository.tsx - their 100644 4d3531ca19c963bdb06019e6d7343e8cf75b68c9 app/src/ui/repository.tsx -@@ -26,7 +26,14 @@ - /** The widest the sidebar can be with the minimum window size. */ - const MaxSidebarWidth = 495 - -+<<<<<<< .our - interface IRepositoryViewProps { -+======= -+/** The narrowist the sidebar can be with the minumum window size. */ -+const MinSideBarWidth = 225 -+ -+interface IRepositoryProps { -+>>>>>>> .their - readonly repository: Repo - readonly state: IRepositoryState - readonly dispatcher: Dispatcher -@@ -202,6 +209,7 @@ - - private renderSidebar(): JSX.Element { - return ( -+<<<<<<< .our - <FocusContainer onFocusWithinChanged={this.onSidebarFocusWithinChanged}> - <Resizable - id="repository-sidebar" -@@ -214,6 +222,19 @@ - {this.renderSidebarContents()} - </Resizable> - </FocusContainer> -+======= -+ <Resizable -+ id="repository-sidebar" -+ width={this.props.sidebarWidth} -+ onReset={this.handleSidebarWidthReset} -+ onResize={this.handleSidebarResize} -+ maximumWidth={MaxSidebarWidth} -+ minimumWidth={MinSideBarWidth} -+ > -+ {this.renderTabs()} -+ {this.renderSidebarContents()} -+ </Resizable> -+>>>>>>> .their - ) - } - diff --git a/app/test/fixtures/merge-parser/desktop/merge-nothing-to-see-here-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-nothing-to-see-here-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index c471d373015..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-nothing-to-see-here-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,23 +0,0 @@ -changed in both - base 100644 454b6d52f2d8373f9222ecf4875ece71ebec3326 app/src/ui/history/compare.tsx - our 100644 c0be0e26ce79b9a590edfa3a9fd3718fa58782d4 app/src/ui/history/compare.tsx - their 100644 4766dbad1115f99d4df3e95afa61665b8cb5d03f app/src/ui/history/compare.tsx -@@ -187,11 +187,18 @@ - } - - private renderNotificationBanner() { -+<<<<<<< .our - if (!enableNotificationOfBranchUpdates()) { - return null - } - - if (!this.props.isDivergingBranchBannerVisible) { -+======= -+ if ( -+ !(enableNotificationOfBranchUpdates && -+ this.props.isDivergingBranchBannerVisible) -+ ) { -+>>>>>>> .their - return null - } - diff --git a/app/test/fixtures/merge-parser/desktop/merge-overlays-are-the-best-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-overlays-are-the-best-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index c5147387dee..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-overlays-are-the-best-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,113 +0,0 @@ -changed in both - base 100644 af19dd9d365b02088b01219e105e23e0146652af app/src/ui/app.tsx - our 100644 c38c806e36c237ea70f3cdeee739941530c0c7cd app/src/ui/app.tsx - their 100644 d56edf28e3caea7701b5830b921a21768623b84c app/src/ui/app.tsx -@@ -79,7 +79,15 @@ - import { BlankSlateView } from './blank-slate' - import { ConfirmRemoveRepository } from './remove-repository' - import { TermsAndConditions } from './terms-and-conditions' -+<<<<<<< .our - import { PushBranchCommits } from './branches' -+======= -+import { ZoomInfo } from './window/zoom-info' -+import { FullScreenInfo } from './window/full-screen-info' -+import { LfsInfo } from './window/lfs-info' -+import { PushBranchCommits } from './branches/push-branch-commits' -+import { Branch } from '../models/branch' -+>>>>>>> .their - import { CLIInstalled } from './cli-installed' - import { GenericGitAuthentication } from './generic-git-auth' - import { ShellError } from './shell' -@@ -1373,10 +1381,19 @@ - return <FullScreenInfo windowState={this.state.windowState} /> - } - -+<<<<<<< .our - private clearError = (error: Error) => this.props.dispatcher.clearError(error) - - private onConfirmDiscardChangesChanged = (value: boolean) => { - this.props.dispatcher.setConfirmDiscardChangesSetting(value) -+======= -+ private renderLfsInfo() { -+ return <LfsInfo /> -+ } -+ -+ private clearError = (error: Error) => { -+ this.props.dispatcher.clearError(error) -+>>>>>>> .their - } - - private renderAppError() { -@@ -1751,9 +1768,18 @@ - <div id="desktop-app-chrome" className={className}> - <AppTheme theme={currentTheme} /> - {this.renderTitlebar()} -+<<<<<<< .our - {this.state.showWelcomeFlow - ? this.renderWelcomeFlow() - : this.renderApp()} -+======= -+ {this.state.showWelcomeFlow ? ( -+ this.renderWelcomeFlow() -+ ) : ( -+ this.renderApp() -+ )} -+ {this.renderLfsInfo()} -+>>>>>>> .their - {this.renderZoomInfo()} - {this.renderFullScreenInfo()} - </div> -added in remote - their 100644 70ab142005052d18540fbfa8c58b9c3fa53e6a72 app/src/ui/window/lfs-info.tsx -@@ -0,0 +1,19 @@ -+import * as React from 'react' -+ -+export class LfsInfo extends React.Component { -+ public render() { -+ return ( -+ <div className='toast-notification-container lfs-info-container'> -+ <div className='toast-notification lfs-info'> -+ <p className='lfs-info-title'>Reverting commit...</p> -+ <p className='lfs-info-detail'> -+ Downloading big_picture.psd -+ </p> -+ <p className='lfs-info-detail lfs-info-tertiary'> -+ 50/300MB -+ </p> -+ </div> -+ </div> -+ ) -+ } -+} -changed in both - base 100644 90a66e96d8ae86db5d645ff31dc5399e5fbdfb2e app/styles/ui/window/_toast-notification.scss - our 100644 69f1e178d8523dc79986e345766ace7b3aa278c2 app/styles/ui/window/_toast-notification.scss - their 100644 1e6156f57268a4d9225adc531736c061dbbdc4c6 app/styles/ui/window/_toast-notification.scss -@@ -52,3 +52,27 @@ - transition: all 250ms ease-out; - } - } -+ -+.lfs-info-container { -+ background: rgba(0,0,0,0.20); -+} -+ -+.toast-notification.lfs-info { -+ background: rgba(0,0,0,0.7); -+ border-radius: var(--border-radius); -+ font-size: var(--font-size); -+} -+ -+.lfs-info-title, -+.lfs-info-detail { -+ margin: 0; -+} -+ -+.lfs-info-detail { -+ font-weight: normal; -+ font-size: var(--font-size-sm); -+} -+ -+.lfs-info-tertiary { -+ opacity: 0.7; -+} diff --git a/app/test/fixtures/merge-parser/desktop/merge-p-p-p-prototype-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-p-p-p-prototype-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 7c213b9668c..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-p-p-p-prototype-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,261 +0,0 @@ -changed in both - base 100644 5e4d7ff5edc9a1a5ac7209a71c2e3e1b47b9711e app/src/ui/changes/commit-message.tsx - our 100644 0a0e18fc9f4c8956a648726827dc496f3d5f98db app/src/ui/changes/commit-message.tsx - their 100644 cd9ac3a59c87bc74d75c7a37ab39ce694c2e55f3 app/src/ui/changes/commit-message.tsx -@@ -244,6 +244,10 @@ - } - - private async createCommit() { -+ setTimeout(() => { -+ this.props.dispatcher.setDivergingBannerVisible(true) -+ }, 3000) -+ - const { summary, description } = this.state - - if (!this.canCommit()) { -changed in both - base 100644 7b6c13edcfe07b4e0d3bc8e034f8c17ae92230ab app/src/ui/history/compare.tsx - our 100644 c0be0e26ce79b9a590edfa3a9fd3718fa58782d4 app/src/ui/history/compare.tsx - their 100644 ce00358b5cec55c6c3db0fbe96ed568e5eb57eea app/src/ui/history/compare.tsx -@@ -24,12 +24,17 @@ - import { SelectionSource } from '../lib/filter-list' - import { IMatches } from '../../lib/fuzzy-find' - import { Ref } from '../lib/ref' -+<<<<<<< .our - import { - NewCommitsBanner, - DismissalReason, - } from '../notification/new-commits-banner' - import { enableNotificationOfBranchUpdates } from '../../lib/feature-flag' - import { MergeCallToAction } from './merge-call-to-action' -+======= -+import { NewCommitsBanner } from '../notification/new-commits-banner' -+import { CSSTransitionGroup } from 'react-transition-group'; -+>>>>>>> .their - - interface ICompareSidebarProps { - readonly repository: Repository -@@ -148,8 +153,26 @@ - public render() { - const { allBranches, filterText, showBranchList } = this.props.compareState - const placeholderText = getPlaceholderText(this.props.compareState) -+<<<<<<< .our - const DivergingBannerAnimationTimeout = 300 - -+======= -+ const DivergingBannerAnimationTimeout = 500 -+ let child: JSX.Element | null = null -+ -+ if (this.props.compareState.defaultBranch !== null && this.props.isDivergingBannerVisible == true) { -+ child = ( -+ <div className="diverge-banner-wrapper"> -+ <NewCommitsBanner -+ numCommits={4} -+ branch={this.props.compareState.defaultBranch} -+ dispatcher={this.props.dispatcher} -+ /> -+ </div> -+ ) -+ } -+ -+>>>>>>> .their - return ( - <div id="compare-view"> - <CSSTransitionGroup -@@ -158,8 +181,13 @@ - transitionAppearTimeout={DivergingBannerAnimationTimeout} - transitionEnterTimeout={DivergingBannerAnimationTimeout} - transitionLeaveTimeout={DivergingBannerAnimationTimeout} -+<<<<<<< .our - > - {this.renderNotificationBanner()} -+======= -+ > -+ {child} -+>>>>>>> .their - </CSSTransitionGroup> - - <div className="compare-form"> -changed in both - base 100644 14032fe4dbf9ac5d26a02694f515e41086a8cc61 app/src/ui/notification/new-commits-banner.tsx - our 100644 fe7b1090d835227962410a64e0f95a32cdd45b6c app/src/ui/notification/new-commits-banner.tsx - their 100644 80c18ed974663dbfc38a4afa6cedd1413df5da83 app/src/ui/notification/new-commits-banner.tsx -@@ -2,6 +2,7 @@ - import { Ref } from '../lib/ref' - import { Octicon, OcticonSymbol } from '../octicons' - import { Branch } from '../../models/branch' -+<<<<<<< .our - import { Button } from '../lib/button' - import { Dispatcher } from '../../lib/dispatcher' - import { Repository } from '../../models/repository' -@@ -33,6 +34,14 @@ - * Callback used to dismiss the banner - */ - readonly onDismiss: (reason: DismissalReason) => void -+======= -+import { Dispatcher } from '../../lib/dispatcher'; -+ -+interface INewCommitsBannerProps { -+ readonly numCommits: number -+ readonly branch: Branch -+ readonly dispatcher: Dispatcher -+>>>>>>> .their - } - - /** -@@ -42,6 +51,10 @@ - INewCommitsBannerProps, - {} - > { -+ private onCloseButtonClick = (e: React.MouseEvent<HTMLAnchorElement>) => { -+ this.props.dispatcher.setDivergingBannerVisible(false) -+ } -+ - public render() { - const pluralize = this.props.commitsBehindBaseBranch > 1 - -@@ -53,6 +66,7 @@ - /> - - <div className="notification-banner-content"> -+<<<<<<< .our - <div className="notification-banner-content-body"> - <p> - We have noticed that your branch is{' '} -@@ -84,6 +98,31 @@ - > - <Octicon symbol={OcticonSymbol.x} /> - </a> -+======= -+ <Octicon symbol={OcticonSymbol.lightBulb} className="notification-icon" /> -+ -+ <div> -+ <p> -+ Your branch is <strong>{this.props.numCommits} commits</strong>{' '} -+ behind <Ref>{this.props.branch.name}</Ref> -+ </p> -+ -+ <ButtonGroup> -+ <Button className="small-button" type="submit" onClick={this.noOp}> -+ Merge... -+ </Button> -+ -+ <Button className="small-button" onClick={this.noOp}> -+ View commits -+ </Button> -+ </ButtonGroup> -+ </div> -+ -+ <a className="close" onClick={this.onCloseButtonClick} aria-label="Dismiss banner"> -+ <Octicon symbol={OcticonSymbol.x} /> -+ </a> -+ </div> -+>>>>>>> .their - </div> - ) - } -changed in both - base 100644 120c6de98e0e7f66eb9d0d0fced3c8fcfbb627ea app/styles/_variables.scss - our 100644 6c89a529c5a8dbfefb127f171468af9ae5651141 app/styles/_variables.scss - their 100644 2e3ff0d12a5fee7774e509740931b44d519556ce app/styles/_variables.scss -@@ -381,7 +381,11 @@ - /** Diverging notification banner colors */ - --notification-banner-background: $blue-000; - --notification-banner-border-color: $blue-200; -+<<<<<<< .our - --notification-ref-background: rgba(255, 255, 255, 0.75); -+======= -+ --notification-ref-background: rgba(255,255,255, 0.75); -+>>>>>>> .their - - // http://easings.net/#easeOutBack - --easing-ease-out-back: cubic-bezier(0.175, 0.885, 0.32, 1.275); -changed in both - base 100644 d088f99cd7b0264beea0bd575733b1d81b45de5a app/styles/ui/_notification-banner.scss - our 100644 ec2aae86b8d44d23f35f56cb9684489301016d6b app/styles/ui/_notification-banner.scss - their 100644 51e0c4d1db459f4db143b1eca11230e3e2fe70ec app/styles/ui/_notification-banner.scss -@@ -9,7 +9,10 @@ - border: var(--base-border); - border-color: var(--notification-banner-border-color); - border-radius: var(--border-radius); -+<<<<<<< .our - display: flex; -+======= -+>>>>>>> .their - padding: var(--spacing); - position: relative; - -@@ -26,10 +29,13 @@ - font-size: var(--font-size-sm); - margin: 0; - padding-right: var(--spacing-double); // Extra space for the close button -+<<<<<<< .our - - & + p { - margin-top: var(--spacing-half); - } -+======= -+>>>>>>> .their - } - } - -@@ -59,6 +65,7 @@ - - &-enter { - max-height: 0; -+<<<<<<< .our - opacity: 0; - - &-active { -@@ -66,6 +73,32 @@ - opacity: 1; - transition: all var(--undo-animation-duration) cubic-bezier(0, 0, 0.2, 1); - } -+======= -+ -+ &-active { -+ max-height: 200px; -+ transition: max-height var(--undo-animation-duration) ease-in; -+ } -+ } -+ -+ &-leave { -+ max-height: 200px; -+ -+ &-active { -+ max-height: 0; -+ transition: max-height 0.5s ease-out; -+ -+ .diverge-banner { -+ transform: translateX(-100%); -+ transition: transform 0.25s ease-in-out; -+ } -+ } -+ } -+ -+ &-wrapper { -+ overflow: hidden; -+ border-bottom: var(--base-border); -+>>>>>>> .their - } - - &-leave { -changed in both - base 100644 9a0a98b7f87142b77f8723419d4401b1e63624a9 app/styles/ui/history/_history.scss - our 100644 58cea508b02182fa4f45daf88643d33c3b2dd020 app/styles/ui/history/_history.scss - their 100644 c30b352d774c42dcb90afa3ee51e6920f24d3608 app/styles/ui/history/_history.scss -@@ -63,13 +63,13 @@ - background: var(--box-alt-background-color); - flex: initial; - padding: var(--spacing-half); -- border-bottom: var(--base-border); - } - - .compare-commit-list { - flex: 1; - display: flex; - flex-direction: column; -+ border-top: var(--base-border); - } - - .merge-cta { diff --git a/app/test/fixtures/merge-parser/desktop/merge-perth-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-perth-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index a85662986b0..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-perth-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,147 +0,0 @@ -removed in local - base 100644 c73d6ac64904f79320bb3aab8699dd2051c26f34 app/src/lib/dispatcher/app-store.ts - their 100644 7f819e503ef633730d9323720fec769c7b3c490d app/src/lib/dispatcher/app-store.ts -changed in both - base 100644 ebeee25a685c6c35ecab70e48552bfafee484bbe app/src/lib/logging/main/install.ts - our 100644 b2a2141977edc35369eb9e5d77ceb946ab0e23a7 app/src/lib/logging/main/install.ts - their 100644 0367ee9b85c798ec98a04c05dbd482cf18b829c4 app/src/lib/logging/main/install.ts -@@ -14,6 +14,10 @@ - log('info', '[main] ' + formatLogMessage(message, error)) - }, - debug(message: string, error?: Error) { -+ if (__RELEASE_CHANNEL__ !== 'development') { -+ return -+ } -+ - log('debug', '[main] ' + formatLogMessage(message, error)) - }, - } as IDesktopLogger -changed in both - base 100644 13da0924748c38d48d64c3c4a87b1cbf08c40d83 app/src/lib/logging/renderer/install.ts - our 100644 c4c24ae3dd53be71b91a1b9c22de630d64018cc7 app/src/lib/logging/renderer/install.ts - their 100644 f877721958807a3eaf850889e3b1feac8f5504c7 app/src/lib/logging/renderer/install.ts -@@ -31,6 +31,10 @@ - console.info(formatLogMessage(message, error)) - }, - debug(message: string, error?: Error) { -+ if (__RELEASE_CHANNEL__ !== 'development') { -+ return -+ } -+ - log('debug', message, error) - console.debug(formatLogMessage(message, error)) - }, -changed in both - base 100644 b530415f847b4f342cddfe700561206cb348954b app/src/ui/app.tsx - our 100644 c38c806e36c237ea70f3cdeee739941530c0c7cd app/src/ui/app.tsx - their 100644 4994bbc845f8e6e249c4bba1156ea156966bf36e app/src/ui/app.tsx -@@ -239,9 +239,7 @@ - } - - private performDeferredLaunchActions() { -- // Loading emoji is super important but maybe less important that loading -- // the app. So defer it until we have some breathing space. -- this.props.appStore.loadEmoji() -+ this.props.appStore.loadDeferredState() - - this.props.dispatcher.reportStats() - setInterval(() => this.props.dispatcher.reportStats(), SendStatsInterval) -changed in both - base 100644 eaf0696bc6fe368ab4f493cfcd8436854d7b765e app/src/ui/lib/update-store.ts - our 100644 043bd6b6ec57efda2974dff91759487d0537202f app/src/ui/lib/update-store.ts - their 100644 4705555385fa26a8732c820b4c24cc5d267ef42f app/src/ui/lib/update-store.ts -@@ -1,8 +1,5 @@ - import { remote } from 'electron' - --// Given that `autoUpdater` is entirely async anyways, I *think* it's safe to --// use with `remote`. --const autoUpdater = remote.autoUpdater - const lastSuccessfulCheckKey = 'last-successful-update-check' - - import { Emitter, Disposable } from 'event-kit' -@@ -53,12 +50,13 @@ - } - } - -- autoUpdater.on('error', this.onAutoUpdaterError) -- autoUpdater.on('checking-for-update', this.onCheckingForUpdate) -- autoUpdater.on('update-available', this.onUpdateAvailable) -- autoUpdater.on('update-not-available', this.onUpdateNotAvailable) -- autoUpdater.on('update-downloaded', this.onUpdateDownloaded) -+ getAutoUpdater().on('error', this.onAutoUpdaterError) -+ getAutoUpdater().on('checking-for-update', this.onCheckingForUpdate) -+ getAutoUpdater().on('update-available', this.onUpdateAvailable) -+ getAutoUpdater().on('update-not-available', this.onUpdateNotAvailable) -+ getAutoUpdater().on('update-downloaded', this.onUpdateDownloaded) - -+<<<<<<< .our - window.addEventListener('beforeunload', () => { - autoUpdater.removeListener('error', this.onAutoUpdaterError) - autoUpdater.removeListener( -@@ -72,6 +70,32 @@ - ) - autoUpdater.removeListener('update-downloaded', this.onUpdateDownloaded) - }) -+======= -+ // This seems to prevent tests from cleanly exiting on Appveyor (see -+ // https://ci.appveyor.com/project/github-windows/desktop/build/1466). So -+ // let's just avoid it. -+ if (!process.env.TEST_ENV) { -+ window.addEventListener('beforeunload', () => { -+ getAutoUpdater().removeListener('error', this.onAutoUpdaterError) -+ getAutoUpdater().removeListener( -+ 'checking-for-update', -+ this.onCheckingForUpdate -+ ) -+ getAutoUpdater().removeListener( -+ 'update-available', -+ this.onUpdateAvailable -+ ) -+ getAutoUpdater().removeListener( -+ 'update-not-available', -+ this.onUpdateNotAvailable -+ ) -+ getAutoUpdater().removeListener( -+ 'update-downloaded', -+ this.onUpdateDownloaded -+ ) -+ }) -+ } -+>>>>>>> .their - } - - private touchLastChecked() { -@@ -161,8 +185,13 @@ - this.userInitiatedUpdate = !inBackground - - try { -+<<<<<<< .our - autoUpdater.setFeedURL({ url: __UPDATES_URL__ }) - autoUpdater.checkForUpdates() -+======= -+ getAutoUpdater().setFeedURL(__UPDATES_URL__) -+ getAutoUpdater().checkForUpdates() -+>>>>>>> .their - } catch (e) { - this.emitError(e) - } -@@ -174,8 +203,18 @@ - // before we call the function to quit. - // eslint-disable-next-line no-sync - sendWillQuitSync() -- autoUpdater.quitAndInstall() -+ getAutoUpdater().quitAndInstall() -+ } -+} -+ -+let autoUpdater_: Electron.AutoUpdater | null = null -+ -+function getAutoUpdater(): Electron.AutoUpdater { -+ if (!autoUpdater_) { -+ autoUpdater_ = remote.autoUpdater - } -+ -+ return autoUpdater_! - } - - /** The store which contains the current state of the auto updater. */ diff --git a/app/test/fixtures/merge-parser/desktop/merge-poke-at-electron-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-poke-at-electron-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index e25532cb506..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-poke-at-electron-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,813 +0,0 @@ -changed in both - base 100644 2cecde52c1e4b8e3aa0313c3780fce9cc4066161 app/.npmrc - our 100644 3169cbf51513c96d00aa269ce03a024f499a47d8 app/.npmrc - their 100644 abdc4fc3b94178f210cc4fc3988302c4bed1e2c6 app/.npmrc -@@ -1,4 +1,8 @@ - runtime = electron - disturl = https://atom.io/download/electron -+<<<<<<< .our - target = 2.0.5 -+======= -+target = 1.6.11 -+>>>>>>> .their - arch = x64 -changed in both - base 100644 bf47089de434c876948ae48cab85a2995530462a app/src/crash/crash-app.tsx - our 100644 d74ab08d432e7f3011711b9f5b4a9c82326b861f app/src/crash/crash-app.tsx - their 100644 98c0095143ceed7afe574fd926fd18037367f9f6 app/src/crash/crash-app.tsx -@@ -102,12 +102,18 @@ - this.setState({ windowState: getWindowState(window) }) - }) - -+<<<<<<< .our - ipcRenderer.on( - 'error', - (event: Electron.IpcMessageEvent, crashDetails: ICrashDetails) => { - this.setState(crashDetails) - } - ) -+======= -+ ipcRenderer.on('error', (event: Electron.IpcMessageEvent, crashDetails: ICrashDetails) => { -+ this.setState(crashDetails) -+ }) -+>>>>>>> .their - - ipcRenderer.send('crash-ready') - } -removed in local - base 100644 d29f875f91f14d3399f3ba8c5f4256913ce5e11f app/src/lib/dispatcher/app-store.ts - their 100644 853b472fe10d08536fabe3fc37ba781d2cd36a30 app/src/lib/dispatcher/app-store.ts -changed in both - base 100644 9cdf93716561976efbd6c0a0f8765209455da4b1 app/src/lib/dispatcher/dispatcher.ts - our 100644 5e56c00e713342e76f5ccba040062e322e8c90cb app/src/lib/dispatcher/dispatcher.ts - their 100644 aacb02c83758e786988eecefe1509299d47cd15d app/src/lib/dispatcher/dispatcher.ts -@@ -81,11 +81,71 @@ - - public constructor(appStore: AppStore) { - this.appStore = appStore -+<<<<<<< .our - } - - /** Load the initial state for the app. */ - public loadInitialState(): Promise<void> { - return this.appStore.loadInitialState() -+======= -+ -+ appStore.onDidAuthenticate((user) => { -+ this.addAccount(user) -+ }) -+ -+ ipcRenderer.on('shared/did-update', (event: Electron.IpcMessageEvent, args: any[]) => this.onSharedDidUpdate(event, args)) -+ } -+ -+ public async loadInitialState(): Promise<void> { -+ const users = await this.loadUsers() -+ const repositories = await this.loadRepositories() -+ this.appStore._loadFromSharedProcess(users, repositories, true) -+ } -+ -+ private dispatchToSharedProcess<T>(action: Action): Promise<T> { -+ return this.send(action.name, action) -+ } -+ -+ private send<T>(name: string, args: Object): Promise<T> { -+ return new Promise<T>((resolve, reject) => { -+ -+ const requestGuid = uuid() -+ ipcRenderer.once(`shared/response/${requestGuid}`, (event: any, args: any[]) => { -+ const response: IPCResponse<T> = args[0] -+ if (response.type === 'result') { -+ resolve(response.result) -+ } else { -+ const errorInfo = response.error -+ const error = new IPCError(errorInfo.name, errorInfo.message, errorInfo.stack || '') -+ if (__DEV__) { -+ } -+ -+ reject(error) -+ } -+ }) -+ -+ ipcRenderer.send('shared/request', [ { guid: requestGuid, name, args } ]) -+ }) -+ } -+ -+ private onSharedDidUpdate(event: Electron.IpcMessageEvent, args: any[]) { -+ const state: { repositories: ReadonlyArray<IRepository>, accounts: ReadonlyArray<IAccount> } = args[0].state -+ const inflatedAccounts = state.accounts.map(Account.fromJSON) -+ const inflatedRepositories = state.repositories.map(Repository.fromJSON) -+ this.appStore._loadFromSharedProcess(inflatedAccounts, inflatedRepositories, false) -+ } -+ -+ /** Get the users */ -+ private async loadUsers(): Promise<ReadonlyArray<Account>> { -+ const json = await this.dispatchToSharedProcess<ReadonlyArray<IAccount>>({ name: 'get-accounts' }) -+ return json.map(Account.fromJSON) -+ } -+ -+ /** Get the repositories the user has added to the app. */ -+ private async loadRepositories(): Promise<ReadonlyArray<Repository>> { -+ const json = await this.dispatchToSharedProcess<ReadonlyArray<IRepository>>({ name: 'get-repositories' }) -+ return json.map(Repository.fromJSON) -+>>>>>>> .their - } - - /** -changed in both - base 100644 f6ac32b3b8b3ec828c89fa4c6db6f083121bb202 app/src/lib/globals.d.ts - our 100644 fe0ba976e925a57a73938c30e3022a0b0c08fbde app/src/lib/globals.d.ts - their 100644 2eb28637921bd47faf2a10723ed165974c4b89e9 app/src/lib/globals.d.ts -@@ -32,9 +32,12 @@ - - declare const __CLI_COMMANDS__: ReadonlyArray<string> - -+<<<<<<< .our - /** The URL for Squirrel's updates. */ - declare const __UPDATES_URL__: string - -+======= -+>>>>>>> .their - /** - * The currently executing process kind, this is specific to desktop - * and identifies the processes that we have. -@@ -75,6 +78,7 @@ - readonly timeRemaining: () => DOMHighResTimeStamp - } - -+<<<<<<< .our - /** - * Contains optional configuration parameters for the requestIdleCallback - * function. -@@ -112,6 +116,51 @@ - ): number - - interface IDesktopLogger { -+======= -+// these changes should be pushed into the Electron declarations -+ -+declare namespace NodeJS { -+ // tslint:disable-next-line:interface-name -+ interface Process extends EventEmitter { -+ once(event: 'uncaughtException', listener: (error: Error) => void): this -+ on(event: 'uncaughtException', listener: (error: Error) => void): this -+ } -+} -+ -+declare namespace Electron { -+ // tslint:disable-next-line:interface-name -+ interface MenuItem { -+ readonly accelerator?: Electron.Accelerator -+ readonly submenu?: Electron.Menu -+ readonly role?: string -+ readonly type: 'normal' | 'separator' | 'submenu' | 'checkbox' | 'radio' -+ } -+ -+ // tslint:disable-next-line:interface-name -+ interface RequestOptions { -+ readonly method: string -+ readonly url: string -+ readonly headers: any -+ } -+ -+ type AppleActionOnDoubleClickPref = 'Maximize' | 'Minimize' | 'None' -+ -+ // tslint:disable-next-line:interface-name -+ interface SystemPreferences { -+ getUserDefault(key: 'AppleActionOnDoubleClick', type: 'string'): AppleActionOnDoubleClickPref -+ } -+ -+ // these methods have been marked with optional parameters, where we hadn't assumed this before -+ // tslint:disable-next-line:interface-name -+ interface App extends EventEmitter { -+ makeSingleInstance(callback: (argv: string[], workingDirectory: string) => void): boolean -+ -+ on(event: 'open-url', listener: (event: Electron.Event, url: string) => void): this -+ } -+} -+ -+declare interface IDesktopLogger { -+>>>>>>> .their - /** - * Writes a log message at the 'error' level. - * -changed in both - base 100644 f5ac8a810391ffca533591ee49e21aea13dcbc01 app/src/lib/shell.ts - our 100644 f77c6e295b680a46baafb43a6ecd079b919b109e app/src/lib/shell.ts - their 100644 e36aea83aa9b48f38185921e64c366ac516a1784 app/src/lib/shell.ts -@@ -77,7 +77,8 @@ - - child.on('close', (code: number, signal) => { - done = true -- process.removeListener('exit', cleanup) -+ const p = process as any -+ p.removeListener('exit', cleanup) - if (buffers.length) { - stdout = Buffer.concat(buffers).toString('utf8') - } -changed in both - base 100644 0367d7504c8571509d8641ff1632f36fdf25b152 app/src/main-process/app-window.ts - our 100644 127b6b7d515d8acf689f1d96cf4c7b078ea2893b app/src/main-process/app-window.ts - their 100644 aabfdad495add832deca037239d0e340c427dd12 app/src/main-process/app-window.ts -@@ -81,6 +81,11 @@ - // renderer. - if (__DARWIN__) { - this.window.on('close', e => { -+ -+ // TODO -+ // we expected this event to be populated here but it is not -+ if (!e) { return } -+ - if (!quitting) { - e.preventDefault() - Menu.sendActionToFirstResponder('hide:') -@@ -147,10 +152,15 @@ - }) - - // TODO: This should be scoped by the window. -+<<<<<<< .our - ipcMain.once( - 'renderer-ready', - (event: Electron.IpcMessageEvent, readyTime: number) => { - this._rendererReadyTime = readyTime -+======= -+ ipcMain.once('renderer-ready', (event: Electron.IpcMessageEvent, readyTime: number) => { -+ this._rendererReadyTime = readyTime -+>>>>>>> .their - - this.maybeEmitDidLoad() - } -changed in both - base 100644 06d131fbf21ffe73bf8bc370f75c0c817468b637 app/src/main-process/main.ts - our 100644 a406ea4cd47e8c9a733faee41a125eab3f743aa2 app/src/main-process/main.ts - their 100644 f0473fd41c33a7c7de640fba201b67373ff5920b app/src/main-process/main.ts -@@ -120,6 +120,11 @@ - app.on('will-finish-launching', () => { - // macOS only - app.on('open-url', (event, url) => { -+ -+ // TODO -+ // both of these parameters we had assumed would be defined -+ if (!event || !url) { return } -+ - event.preventDefault() - handleAppURL(url) - }) -@@ -204,6 +209,7 @@ - let menu = buildDefaultMenu() - Menu.setApplicationMenu(menu) - -+<<<<<<< .our - ipcMain.on( - 'update-preferred-app-menu-item-labels', - ( -@@ -222,6 +228,8 @@ - } - ) - -+======= -+>>>>>>> .their - ipcMain.on('menu-event', (event: Electron.IpcMessageEvent, args: any[]) => { - const { name }: { name: MenuEvent } = event as any - if (mainWindow) { -@@ -233,9 +241,26 @@ - * An event sent by the renderer asking that the menu item with the given id - * is executed (ie clicked). - */ -+<<<<<<< .our - ipcMain.on( - 'execute-menu-item', - (event: Electron.IpcMessageEvent, { id }: { id: string }) => { -+======= -+ ipcMain.on('execute-menu-item', (event: Electron.IpcMessageEvent, { id }: { id: string }) => { -+ const menuItem = findMenuItemByID(menu, id) -+ if (menuItem) { -+ const window = BrowserWindow.fromWebContents(event.sender) -+ const fakeEvent = { preventDefault: () => {}, sender: event.sender } -+ menuItem.click(fakeEvent, window, event.sender) -+ } -+ }) -+ -+ ipcMain.on('update-menu-state', (event: Electron.IpcMessageEvent, items: Array<{ id: string, state: IMenuItemState }>) => { -+ let sendMenuChangedEvent = false -+ -+ for (const item of items) { -+ const { id, state } = item -+>>>>>>> .their - const menuItem = findMenuItemByID(menu, id) - if (menuItem) { - const window = BrowserWindow.fromWebContents(event.sender) -@@ -279,12 +304,25 @@ - } - ) - -+<<<<<<< .our - ipcMain.on( - 'show-contextual-menu', - (event: Electron.IpcMessageEvent, items: ReadonlyArray<IMenuItem>) => { - const menu = buildContextMenu(items, ix => - event.sender.send('contextual-menu-action', ix) - ) -+======= -+ ipcMain.on('show-contextual-menu', (event: Electron.IpcMessageEvent, items: ReadonlyArray<any>) => { -+ const menu = new Menu() -+ const menuItems = items.map((item, i) => { -+ return new MenuItem({ -+ label: item.label, -+ click: () => event.sender.send('contextual-menu-action', i), -+ type: item.type, -+ enabled: item.enabled, -+ }) -+ }) -+>>>>>>> .their - - const window = BrowserWindow.fromWebContents(event.sender) - menu.popup({ window }) -@@ -301,6 +339,7 @@ - } - }) - -+<<<<<<< .our - ipcMain.on( - 'show-certificate-trust-dialog', - ( -@@ -316,9 +355,18 @@ - window.showCertificateTrustDialog(certificate, message) - }) - } -+======= -+ ipcMain.on('show-certificate-trust-dialog', (event: Electron.IpcMessageEvent, { certificate, message }: { certificate: Electron.Certificate, message: string }) => { -+ // This API's only implemented on macOS right now. -+ if (__DARWIN__) { -+ onDidLoad(window => { -+ window.showCertificateTrustDialog(certificate, message) -+ }) -+>>>>>>> .their - } - ) - -+<<<<<<< .our - ipcMain.on( - 'log', - (event: Electron.IpcMessageEvent, level: LogLevel, message: string) => { -@@ -376,6 +424,31 @@ - }) - } - ) -+======= -+ ipcMain.on('log', (event: Electron.IpcMessageEvent, level: LogLevel, message: string) => { -+ writeLog(level, message) -+ }) -+ -+ ipcMain.on('uncaught-exception', (event: Electron.IpcMessageEvent, error: Error) => { -+ uncaughtException(error) -+ }) -+ -+ ipcMain.on('send-error-report', (event: Electron.IpcMessageEvent, { error, extra }: { error: Error, extra: { [key: string]: string } }) => { -+ reportError(error, extra) -+ }) -+ -+ autoUpdater.on('error', err => { -+ // TODO -+ // we expected this event to be populated here but it is not -+ if (!err) { -+ return -+ } -+ -+ onDidLoad(window => { -+ window.sendAutoUpdaterError(err) -+ }) -+ }) -+>>>>>>> .their - }) - - app.on('activate', () => { -@@ -385,17 +458,40 @@ - }) - - app.on('web-contents-created', (event, contents) => { -+ -+ // TODO -+ // we expected this event to be populated here but it is not -+ if (!contents) { return } -+ - contents.on('new-window', (event, url) => { -+ -+ // TODO -+ // we expected this event to be populated here but it is not -+ if (!event) { return } -+ - // Prevent links or window.open from opening new windows - event.preventDefault() - log.warn(`Prevented new window to: ${url}`) - }) - }) - -+<<<<<<< .our - app.on( - 'certificate-error', - (event, webContents, url, error, certificate, callback) => { - callback(false) -+======= -+app.on('certificate-error', (event, webContents, url, error, certificate, callback) => { -+ -+ // TODO -+ // we expected this event to be populated here but it is not -+ -+ if (!callback || !certificate || !error || !url) { -+ return -+ } -+ -+ callback(false) -+>>>>>>> .their - - onDidLoad(window => { - window.sendCertificateError(certificate, error, url) -changed in both - base 100644 490a3a3588751681e05006beeccc79275d8abd79 app/src/main-process/menu/build-default-menu.ts - our 100644 7ec8c001136d655a2ecce3d56b9a6804762172fa app/src/main-process/menu/build-default-menu.ts - their 100644 e3671806fb873c96717bb896a2b9fac6beb270b7 app/src/main-process/menu/build-default-menu.ts -@@ -4,6 +4,7 @@ - import { getLogDirectoryPath } from '../../lib/logging/get-log-path' - import { ensureDir } from 'fs-extra' - -+<<<<<<< .our - import { log } from '../log' - import { openDirectorySafe } from '../shell' - -@@ -22,6 +23,9 @@ - shellLabel: string = defaultShellLabel, - pullRequestLabel: string = defaultPullRequestLabel - ): Electron.Menu { -+======= -+export function buildDefaultMenu(sharedProcess: SharedProcess): Electron.Menu { -+>>>>>>> .their - const template = new Array<Electron.MenuItemConstructorOptions>() - const separator: Electron.MenuItemConstructorOptions = { type: 'separator' } - -@@ -347,8 +351,13 @@ - }, - } - -+<<<<<<< .our - const showUserGuides: Electron.MenuItemConstructorOptions = { - label: 'Show User Guides', -+======= -+ const showLogsItem: Electron.MenuItemConstructorOptions = { -+ label: __DARWIN__ ? 'Show Logs in Finder' : 'S&how logs in Explorer', -+>>>>>>> .their - click() { - shell.openExternal('https://help.github.com/desktop/guides/') - }, -changed in both - base 100644 ba2f59d5334d7f98a1fd334b52501fc2bc6eb55b app/src/main-process/menu/ensure-item-ids.ts - our 100644 70b98c203563f4c9fdb2c59f9a55d91ed872e630 app/src/main-process/menu/ensure-item-ids.ts - their 100644 16d55f9b8e18336b301b08e424b1898cd846746c app/src/main-process/menu/ensure-item-ids.ts -@@ -13,11 +13,15 @@ - * Note that this does not do anything to prevent the case where items have - * explicitly been given duplicate ids. - */ -+<<<<<<< .our - export function ensureItemIds( - template: ReadonlyArray<Electron.MenuItemConstructorOptions>, - prefix = '@', - seenIds = new Set<string>() - ) { -+======= -+export function ensureItemIds(template: ReadonlyArray<Electron.MenuItemConstructorOptions>, prefix = '@', seenIds = new Set<string>()) { -+>>>>>>> .their - for (const item of template) { - let counter = 0 - let id = item.id -@@ -35,9 +39,13 @@ - seenIds.add(id) - - if (item.submenu) { -+<<<<<<< .our - const subMenuTemplate = item.submenu as ReadonlyArray< - Electron.MenuItemConstructorOptions - > -+======= -+ const subMenuTemplate = item.submenu as ReadonlyArray<Electron.MenuItemConstructorOptions> -+>>>>>>> .their - ensureItemIds(subMenuTemplate, item.id, seenIds) - } - } -changed in both - base 100644 5a2231cecfbbdbccb35226a3ac4269408f169b64 app/src/models/app-menu.ts - our 100644 5aaebf59f63ce1bc3d3ff7dca44b2ef668a19b0d app/src/models/app-menu.ts - their 100644 27e474d30979f82122d9fc3b70a299c194b7ae8f app/src/models/app-menu.ts -removed in local - base 100644 46e5f5b50a3b1b2ad7f96c2f0c04f0da148fc5f6 app/src/shared-process/communication.ts - their 100644 b56ffad7380a096347f6d38f74306925c7904892 app/src/shared-process/communication.ts -removed in local - base 100644 432313c156ec448d02765de169008e03d738c2a2 app/src/shared-process/shared-process.ts - their 100644 9c13bf39872c82ef65df1a27e1dcf608ad35fc8a app/src/shared-process/shared-process.ts -changed in both - base 100644 bcf4d1a734aa6217571b14b6f0af97000981b55a app/src/ui/app.tsx - our 100644 c38c806e36c237ea70f3cdeee739941530c0c7cd app/src/ui/app.tsx - their 100644 f1e27ff69e7c6699631a69294d35d8976dbd0658 app/src/ui/app.tsx -@@ -177,12 +177,18 @@ - props.dispatcher.postError(error) - }) - -+<<<<<<< .our - ipcRenderer.on( - 'menu-event', - (event: Electron.IpcMessageEvent, { name }: { name: MenuEvent }) => { - this.onMenuEvent(name) - } - ) -+======= -+ ipcRenderer.on('menu-event', (event: Electron.IpcMessageEvent, { name }: { name: MenuEvent }) => { -+ this.onMenuEvent(name) -+ }) -+>>>>>>> .their - - updateStore.onDidChange(state => { - const status = state.status -@@ -211,9 +217,16 @@ - console.info(`Load time: ${stats.loadTime}ms`) - console.info(`Renderer ready time: ${stats.rendererReadyTime}ms`) - -+<<<<<<< .our - this.props.dispatcher.recordLaunchStats(stats) - } - ) -+======= -+ ipcRenderer.on('launch-timing-stats', (event: Electron.IpcMessageEvent, { stats }: { stats: ILaunchStats }) => { -+ console.info(`App ready time: ${stats.mainReadyTime}ms`) -+ console.info(`Load time: ${stats.loadTime}ms`) -+ console.info(`Renderer ready time: ${stats.rendererReadyTime}ms`) -+>>>>>>> .their - - ipcRenderer.on( - 'certificate-error', -@@ -234,8 +247,18 @@ - ) - } - -+<<<<<<< .our - public componentWillUnmount() { - window.clearInterval(this.updateIntervalHandle) -+======= -+ ipcRenderer.on('certificate-error', (event: Electron.IpcMessageEvent, { certificate, error, url }: { certificate: Electron.Certificate, error: string, url: string }) => { -+ this.props.dispatcher.showPopup({ -+ type: PopupType.UntrustedCertificate, -+ certificate, -+ url, -+ }) -+ }) -+>>>>>>> .their - } - - private performDeferredLaunchActions() { -changed in both - base 100644 349e06c78238860ffddde0c2a56c192b923d96d9 app/src/ui/index.tsx - our 100644 f8f8200917327048c8f002fcfade473dfd6668d1 app/src/ui/index.tsx - their 100644 9d69fef01d8872138546bb13775dcc75ab71bd8f app/src/ui/index.tsx -@@ -174,12 +174,18 @@ - dispatcher.setAppFocusState(false) - }) - -+<<<<<<< .our - ipcRenderer.on( - 'url-action', - (event: Electron.IpcMessageEvent, { action }: { action: URLActionType }) => { - dispatcher.dispatchURLAction(action) - } - ) -+======= -+ipcRenderer.on('url-action', (event: Electron.IpcMessageEvent, { action }: { action: URLActionType }) => { -+ dispatcher.dispatchURLAction(action) -+}) -+>>>>>>> .their - - ReactDOM.render( - <App dispatcher={dispatcher} appStore={appStore} startTime={startTime} />, -changed in both - base 100644 ffbeb3a62a9f9f9cc5aceffa8b263d92dd3d4657 app/src/ui/lib/update-store.ts - our 100644 043bd6b6ec57efda2974dff91759487d0537202f app/src/ui/lib/update-store.ts - their 100644 c9ac3becaf5032297b7fb0430cc40e00691a31c4 app/src/ui/lib/update-store.ts -@@ -53,7 +53,17 @@ - } - } - -+<<<<<<< .our - autoUpdater.on('error', this.onAutoUpdaterError) -+======= -+ // We're using our own error event instead of `autoUpdater`s so that we can -+ // properly serialize the `Error` object for transport over IPC. See -+ // https://github.com/desktop/desktop/issues/1266. -+ ipcRenderer.on('auto-updater-error', (event: Electron.IpcMessageEvent, error: Error) => { -+ this.onAutoUpdaterError(error) -+ }) -+ -+>>>>>>> .their - autoUpdater.on('checking-for-update', this.onCheckingForUpdate) - autoUpdater.on('update-available', this.onUpdateAvailable) - autoUpdater.on('update-not-available', this.onUpdateNotAvailable) -changed in both - base 100644 029ab5c3684b6a3e60d1d963a0377a59d548739e app/src/ui/main-process-proxy.ts - our 100644 3ab029492d92e1c831e2d9ea8307c72e3daab383 app/src/ui/main-process-proxy.ts - their 100644 9eb2744a0e2a28002d12edcac65089a4404d6176 app/src/ui/main-process-proxy.ts -@@ -66,6 +66,7 @@ - * should be called only once, around app load time. - */ - export function registerContextualMenuActionDispatcher() { -+<<<<<<< .our - ipcRenderer.on( - 'contextual-menu-action', - (event: Electron.IpcMessageEvent, index: number) => { -@@ -82,6 +83,17 @@ - action() - currentContextualMenuItems = null - } -+======= -+ ipcRenderer.on('contextual-menu-action', (event: Electron.IpcMessageEvent, index: number) => { -+ if (!currentContextualMenuItems) { return } -+ if (index >= currentContextualMenuItems.length) { return } -+ -+ const item = currentContextualMenuItems[index] -+ const action = item.action -+ if (action) { -+ action() -+ currentContextualMenuItems = null -+>>>>>>> .their - } - ) - } -changed in both - base 100644 014cd67343b58a448ac2b3743dbd6b30a2357074 app/src/ui/window/title-bar.tsx - our 100644 8fe8df4251980f3b61cd747d621ab0206a88f8c9 app/src/ui/window/title-bar.tsx - their 100644 7f47455de9e5e87be61cd78896d07e8cea02b8b6 app/src/ui/window/title-bar.tsx -@@ -31,6 +31,10 @@ - readonly style?: React.CSSProperties - } - -+<<<<<<< .our -+======= -+ -+>>>>>>> .their - function getState(props: ITitleBarProps): ITitleBarState { - // See windowZoomFactor in ITitleBarProps, this is only - // applicable on macOS. -@@ -52,10 +56,14 @@ - } - - private onTitlebarDoubleClickDarwin = () => { -+<<<<<<< .our - const actionOnDoubleClick = remote.systemPreferences.getUserDefault( - 'AppleActionOnDoubleClick', - 'string' - ) -+======= -+ const actionOnDoubleClick = remote.systemPreferences.getUserDefault('AppleActionOnDoubleClick', 'string') -+>>>>>>> .their - const mainWindow = remote.getCurrentWindow() - - switch (actionOnDoubleClick) { -changed in both - base 100644 42b430f128bbe81af43d6a1eca08aa11eee1159a app/src/ui/window/window-controls.tsx - our 100644 06500dcb9df1933061dd5a0b0f238a8ce5f2c4bb app/src/ui/window/window-controls.tsx - their 100644 8a2503c29c49147040f159e9640a1069a27ca734 app/src/ui/window/window-controls.tsx -@@ -50,10 +50,14 @@ - return nextState.windowState !== this.state.windowState - } - -+<<<<<<< .our - private onWindowStateChanged = ( - event: Electron.IpcMessageEvent, - args: any - ) => { -+======= -+ private onWindowStateChanged = (event: Electron.IpcMessageEvent, args: any) => { -+>>>>>>> .their - this.setState({ windowState: args as WindowState }) - } - -changed in both - base 100644 52444d15ac755f2eaf479e2bfa2792121ac14277 app/test/unit/main-process/menu-test.ts - our 100644 0b0db198f51c86f465b1e78f32409595952b4e9e app/test/unit/main-process/menu-test.ts - their 100644 be1eda7cbb087fa010222b546b891ff136eb67e8 app/test/unit/main-process/menu-test.ts -@@ -15,9 +15,13 @@ - }) - - it('assigns ids to items which lack it', () => { -+<<<<<<< .our - const template: Electron.MenuItemConstructorOptions[] = [ - { label: 'File' }, - ] -+======= -+ const template: Electron.MenuItemConstructorOptions[] = [ { label: 'File' } ] -+>>>>>>> .their - - ensureItemIds(template) - -@@ -44,15 +48,23 @@ - - expect(template[0].id).to.equal('foo') - -+<<<<<<< .our - const firstSubmenu = template[0] - .submenu! as Electron.MenuItemConstructorOptions[] -+======= -+ const firstSubmenu = template[0].submenu! as Electron.MenuItemConstructorOptions[] -+>>>>>>> .their - - expect(firstSubmenu[0].id).to.equal('foo.Open') - expect(firstSubmenu[1].id).to.equal('foo.Close') - expect(firstSubmenu[2].id).to.equal('foo.More') - -+<<<<<<< .our - const secondSubmenu = firstSubmenu[2] - .submenu! as Electron.MenuItemConstructorOptions[] -+======= -+ const secondSubmenu = firstSubmenu[2].submenu! as Electron.MenuItemConstructorOptions[] -+>>>>>>> .their - - expect(secondSubmenu[0].id).to.equal('foo.More.Even more') - }) -changed in both - base 100644 c41bdb847b5c540cec431ca1ffd18250ee8bcc7d package.json - our 100644 2006bfb748810f6ea8bdbd26edf7c09524a1388a package.json - their 100644 000f00feea0bf7627c2db0f4e2e7266ab00dd86e package.json -@@ -61,6 +61,7 @@ - "chai": "^4.1.1", - "chai-as-promised": "^7.1.1", - "chai-datetime": "^1.4.1", -+<<<<<<< .our - "chalk": "^2.2.0", - "clean-webpack-plugin": "^0.1.19", - "cross-env": "^5.0.5", -@@ -86,6 +87,26 @@ - "octicons": "^7.0.1", - "parallel-webpack": "^2.3.0", - "prettier": "^1.14.2", -+======= -+ "clean-webpack-plugin": "^0.1.16", -+ "cross-env": "^3.2.3", -+ "css-loader": "^0.26.2", -+ "electron": "1.6.11", -+ "electron-mocha": "^3.5.0", -+ "electron-packager": "8.6.0", -+ "electron-winstaller": "2.5.2", -+ "express": "^4.15.0", -+ "extract-text-webpack-plugin": "^2.1.0", -+ "fs-extra": "^2.1.2", -+ "got": "^6.3.0", -+ "html-webpack-plugin": "^2.28.0", -+ "klaw-sync": "^1.1.2", -+ "legal-eagle": "0.15.0", -+ "mocha": "^3.4.2", -+ "node-native-loader": "^1.1.1", -+ "node-sass": "^4.5.2", -+ "parallel-webpack": "^1.6.1", -+>>>>>>> .their - "request": "^2.72.0", - "rimraf": "^2.5.2", - "sass-loader": "^7.0.1", -@@ -109,6 +130,7 @@ - "xvfb-maybe": "^0.2.1" - }, - "devDependencies": { -+<<<<<<< .our - "@types/byline": "^4.2.31", - "@types/chai": "^4.1.2", - "@types/chai-datetime": "^0.0.31", -@@ -118,6 +140,12 @@ - "@types/double-ended-queue": "^2.1.0", - "@types/electron-packager": "^12.0.0", - "@types/electron-winstaller": "^2.6.0", -+======= -+ "@types/chai": "^3.4.30", -+ "@types/chai-datetime": "0.0.30", -+ "@types/classnames": "^0.0.32", -+ "@types/codemirror": "0.0.38", -+>>>>>>> .their - "@types/event-kit": "^1.2.28", - "@types/express": "^4.11.0", - "@types/extract-text-webpack-plugin": "^3.0.3", -@@ -127,6 +155,7 @@ - "@types/glob": "^5.0.35", - "@types/html-webpack-plugin": "^2.30.3", - "@types/keytar": "^4.0.0", -+<<<<<<< .our - "@types/legal-eagle": "^0.15.0", - "@types/mini-css-extract-plugin": "^0.2.0", - "@types/mocha": "^2.2.48", -@@ -142,6 +171,15 @@ - "@types/temp": "^0.8.29", - "@types/textarea-caret": "^3.0.0", - "@types/to-camel-case": "^1.0.0", -+======= -+ "@types/mocha": "^2.2.29", -+ "@types/node": "^7.0.18", -+ "@types/react": "15.0.23", -+ "@types/react-addons-test-utils": "^0.14.17", -+ "@types/react-dom": "^15.5.0", -+ "@types/react-transition-group": "^1.1.0", -+ "@types/react-virtualized": "^9.7.0", -+>>>>>>> .their - "@types/ua-parser-js": "^0.7.30", - "@types/untildify": "^3.0.0", - "@types/uuid": "^3.4.0", diff --git a/app/test/fixtures/merge-parser/desktop/merge-popup-polish-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-popup-polish-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 3dd45f49d1b..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-popup-polish-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,83 +0,0 @@ -removed in local - base 100644 e1408349a785c2497c28287524602cbbdd34d182 app/src/ui/delete-branch/index.tsx - their 100644 6bd85d0207ddf997b2c8790c99f8eafdd963c23b app/src/ui/delete-branch/index.tsx -changed in both - base 100644 273224c79683bf991d33981212a3bf6272aaad75 app/styles/_variables.scss - our 100644 6c89a529c5a8dbfefb127f171468af9ae5651141 app/styles/_variables.scss - their 100644 9fe12b87e01b77e93d6f53888489efb532ed9adc app/styles/_variables.scss -@@ -5,11 +5,30 @@ - // Primer colors, see https://github.com/primer/primer-css/blob/master/modules/primer-support/lib/variables/color-system.scss - @import '~primer-support/lib/variables/color-system.scss'; - -+<<<<<<< .our - // Extracted as a SCSS variable so that we can define the --overlay-background-color - // on both the :root and the ::backdrop scope. The ::backdrop pseudo-element - // doesn't inherit :root, see - // https://bugs.chromium.org/p/chromium/issues/detail?id=594096 - $overlay-background-color: rgba(0, 0, 0, 0.4); -+======= -+ // Colors -+ // -+ // These are declared here to let us avoid duplicating color constants -+ // in variables. It also makes it easier to read and understand what -+ // color is being used. Note that these variables should _never_ be -+ // used outside of this scope. -+ $blue: #4ca6eb; -+ $orange: #c9510c; -+ $yellow: #d0b44c; -+ $red: #bf2b00; -+ $green: #6cc644; -+ $darkGray: #5f717f; -+ $gray: #ccc; -+ $lightGray: #f2f2f2; -+ $lighterGray: #f9f9f9; -+ $white: #fff; -+>>>>>>> .their - - :root { - --color-new: $green; -@@ -39,6 +58,8 @@ - --secondary-button-focus-shadow-color: rgba($gray-200, 0.75); - --secondary-button-focus-border-color: $gray-300; - -+ --color-danger: $red; -+ - // Typography - // - // Font, line-height, and color for body text, headings, and more. -removed in local - base 100644 06242692dbd6bf6584f50ba8603963c08f409d25 app/styles/ui/_buttons.scss - their 100644 1f1ade4696cb90b66b02043a1e1059866e09845c app/styles/ui/_buttons.scss -changed in both - base 100644 d93b03411b128f27c3810989d821c1cd1fbe0861 app/styles/ui/_popup.scss - our 100644 a6ae13e4773c3b09e14fc9b93428d0ff1629965f app/styles/ui/_popup.scss - their 100644 90e16269a82f9234988e67499c0d0bd65266b9f6 app/styles/ui/_popup.scss -@@ -30,10 +30,28 @@ - white-space: pre-wrap; - } - -+<<<<<<< .our - .popup-overlay { - z-index: var(--popup-overlay-z-index); - - background: black; - opacity: 0.4; - height: 100%; -+======= -+.popup-content { -+ padding: var(--spacing); -+} -+ -+.popup-actions { -+ padding: 0 var(--spacing) var(--spacing); -+ text-align: left; -+ -+ button { -+ margin-right: var(--spacing); -+ } -+} -+ -+.popup-title { -+ font-weight: var(--font-weight-semibold); -+>>>>>>> .their - } diff --git a/app/test/fixtures/merge-parser/desktop/merge-publish-to-a-specific-team-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-publish-to-a-specific-team-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 82485827a69..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-publish-to-a-specific-team-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,285 +0,0 @@ -changed in both - base 100644 d4b62dbf30e18eb25f0eab0014d38984b1e80c6c app/src/lib/api.ts - our 100644 e77c79b5d20fbcffe9af534504dac98509135263 app/src/lib/api.ts - their 100644 891538bef5ffaae9006e4609c90b072a39626c11 app/src/lib/api.ts -@@ -81,6 +81,12 @@ - readonly type: 'User' | 'Organization' - } - -+export interface IAPITeam { -+ readonly id: number -+ /** The identifier for the team */ -+ readonly name: string -+} -+ - /** The users we get from the mentionables endpoint. */ - export interface IAPIMentionableUser { - readonly avatar_url: string -@@ -356,19 +362,34 @@ - } - } - -+ public async fetchTeams(org: IAPIUser): Promise<ReadonlyArray<IAPITeam>> { -+ const url = `orgs/${org.login}/teams` -+ try { -+ return this.fetchAll<IAPITeam>(url) -+ } catch (e) { -+ log.warn(`fetchTeams: failed with endpoint ${this.endpoint}${url}`, e) -+ return [] -+ } -+ } -+ - /** Create a new GitHub repository with the given properties. */ - public async createRepository( - org: IAPIUser | null, -+ team: IAPITeam | null, - name: string, - description: string, - private_: boolean - ): Promise<IAPIRepository> { - try { - const apiPath = org ? `orgs/${org.login}/repos` : 'user/repos' -+ -+ const team_id = team != null ? team.id : undefined -+ - const response = await this.request('POST', apiPath, { - name, - description, - private: private_, -+ team_id, - }) - - return await parsedResponse<IAPIRepository>(response) -changed in both - base 100644 9c822d8df65d53f5fbdb6939e203a7ba2e11a58c app/src/lib/dispatcher/dispatcher.ts - our 100644 5e56c00e713342e76f5ccba040062e322e8c90cb app/src/lib/dispatcher/dispatcher.ts - their 100644 92fb3a62a96e103d4f865147ef5a9ca8df2716f5 app/src/lib/dispatcher/dispatcher.ts -@@ -25,7 +25,7 @@ - import { Branch } from '../../models/branch' - import { Commit } from '../../models/commit' - import { ExternalEditor } from '../../lib/editors' --import { IAPIUser } from '../../lib/api' -+import { IAPIUser, IAPITeam } from '../../lib/api' - import { GitHubRepository } from '../../models/github-repository' - import { ICommitMessage } from '../stores/git-store' - import { executeMenuItem } from '../../ui/main-process-proxy' -@@ -329,7 +329,8 @@ - description: string, - private_: boolean, - account: Account, -- org: IAPIUser | null -+ org: IAPIUser | null, -+ team: IAPITeam | null - ): Promise<Repository> { - return this.appStore._publishRepository( - repository, -@@ -337,7 +338,8 @@ - description, - private_, - account, -- org -+ org, -+ team - ) - } - -changed in both - base 100644 1ed8393b2de89d15fe98af5394808815218893ec app/src/lib/stores/app-store.ts - our 100644 1a4e387e4d192d34abfd0621b4b5ebe8cc34d8d1 app/src/lib/stores/app-store.ts - their 100644 2f587384d3822eb5c702caff56435dc8c92ccc1c app/src/lib/stores/app-store.ts -@@ -43,6 +43,7 @@ - matchGitHubRepository, - IMatchedGitHubRepository, - repositoryMatchesRemote, -+<<<<<<< .our - } from '../repository-matching' - import { - API, -@@ -51,6 +52,10 @@ - getDotComAPIEndpoint, - getEnterpriseAPIURL, - } from '../api' -+======= -+} from '../../lib/repository-matching' -+import { API, getAccountForEndpoint, IAPIUser, IAPITeam } from '../../lib/api' -+>>>>>>> .their - import { caseInsensitiveCompare } from '../compare' - import { - Branch, -@@ -2730,11 +2735,13 @@ - description: string, - private_: boolean, - account: Account, -- org: IAPIUser | null -+ org: IAPIUser | null, -+ team: IAPITeam | null - ): Promise<Repository> { - const api = API.fromAccount(account) - const apiRepository = await api.createRepository( - org, -+ team, - name, - description, - private_ -merged - result 100644 52833651f93201ff5b3259035f62a7153969e552 app/src/ui/publish-repository/publish-repository.tsx - our 100644 c14a53943087c492bc981e916b32c2d35eedc78c app/src/ui/publish-repository/publish-repository.tsx -@@ -1,6 +1,6 @@ - import * as React from 'react' - import { Account } from '../../models/account' --import { API, IAPIUser } from '../../lib/api' -+import { API, IAPIUser, IAPITeam } from '../../lib/api' - import { TextBox } from '../lib/text-box' - import { Select } from '../lib/select' - import { DialogContent } from '../dialog' -@@ -34,10 +34,17 @@ - * published as a personal repository. - */ - readonly org: IAPIUser | null -+ -+ /** -+ * The team which will be granted access to this repository. Only valid when -+ * publishing a repository to an organization. -+ */ -+ readonly team: IAPITeam | null - } - - interface IPublishRepositoryState { - readonly orgs: ReadonlyArray<IAPIUser> -+ readonly teams: ReadonlyArray<IAPITeam> - } - - /** The Publish Repository component. */ -@@ -48,7 +55,7 @@ - public constructor(props: IPublishRepositoryProps) { - super(props) - -- this.state = { orgs: [] } -+ this.state = { orgs: [], teams: [] } - } - - public async componentWillMount() { -@@ -57,7 +64,7 @@ - - public componentWillReceiveProps(nextProps: IPublishRepositoryProps) { - if (this.props.account !== nextProps.account) { -- this.setState({ orgs: [] }) -+ this.setState({ orgs: [], teams: [] }) - - this.fetchOrgs(nextProps.account) - } -@@ -70,6 +77,13 @@ - this.setState({ orgs }) - } - -+ private async fetchTeams(account: Account, org: IAPIUser) { -+ const api = API.fromAccount(account) -+ const teams = (await api.fetchTeams(org)) as Array<IAPITeam> -+ teams.sort((a, b) => caseInsensitiveCompare(a.name, b.name)) -+ this.setState({ teams }) -+ } -+ - private updateSettings<K extends keyof IPublishRepositorySettings>( - subset: Pick<IPublishRepositorySettings, K> - ) { -@@ -94,10 +108,24 @@ - const value = event.currentTarget.value - const index = parseInt(value, 10) - if (index < 0 || isNaN(index)) { -- this.updateSettings({ org: null }) -+ this.updateSettings({ org: null, team: null }) -+ // clear teams -+ this.setState({ teams: [] }) - } else { - const org = this.state.orgs[index] -- this.updateSettings({ org }) -+ this.updateSettings({ org, team: null }) -+ this.fetchTeams(this.props.account, org) -+ } -+ } -+ -+ private onTeamChange = (event: React.FormEvent<HTMLSelectElement>) => { -+ const value = event.currentTarget.value -+ const index = parseInt(value, 10) -+ if (index < 0 || isNaN(index)) { -+ this.updateSettings({ team: null }) -+ } else { -+ const team = this.state.teams[index] -+ this.updateSettings({ team }) - } - } - -@@ -138,6 +166,43 @@ - ) - } - -+ private renderTeams(): JSX.Element | null { -+ if (this.state.teams.length === 0) { -+ return null -+ } -+ -+ const options = new Array<JSX.Element>() -+ options.push( -+ <option value={-1} key={-1}> -+ None -+ </option> -+ ) -+ -+ let selectedIndex = -1 -+ const selectedOrg = this.props.settings.team -+ for (const [index, team] of this.state.teams.entries()) { -+ if (selectedOrg && selectedOrg.id === team.id) { -+ selectedIndex = index -+ } -+ -+ options.push( -+ <option value={index} key={index}> -+ {team.name} -+ </option> -+ ) -+ } -+ -+ return ( -+ <Select -+ label="Team" -+ value={selectedIndex.toString()} -+ onChange={this.onTeamChange} -+ > -+ {options} -+ </Select> -+ ) -+ } -+ - public render() { - return ( - <DialogContent> -@@ -170,6 +235,7 @@ - </Row> - - {this.renderOrgs()} -+ {this.renderTeams()} - </DialogContent> - ) - } -changed in both - base 100644 dbb16e8d0667b3c7f6a9514dda9d6ec8354fe75d app/src/ui/publish-repository/publish.tsx - our 100644 ffbdef89f9f0f16e966a7d27c2db06bd897c3db6 app/src/ui/publish-repository/publish.tsx - their 100644 b7e75c79d8796d670af3f7cd805356b327fcf0e4 app/src/ui/publish-repository/publish.tsx -@@ -70,6 +70,7 @@ - description: '', - private: true, - org: null, -+ team: null, - } - - this.state = { -@@ -229,7 +230,8 @@ - settings.description, - settings.private, - account, -- settings.org -+ settings.org, -+ settings.team - ) - - this.props.onDismissed() diff --git a/app/test/fixtures/merge-parser/desktop/merge-react-transition-group-upgrade-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-react-transition-group-upgrade-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 036a19c284b..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-react-transition-group-upgrade-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,545 +0,0 @@ -changed in both - base 100644 3d921e1f4edacdac5bd0e20ba7990d6f68480457 app/package.json - our 100644 4ec686d8ad22d3aea1ebe4bddd16f4a7447c3acd app/package.json - their 100644 53fac1081a0970ea3edaf53218548200c69a95c8 app/package.json -@@ -40,9 +40,15 @@ - "queue": "^4.4.2", - "react": "^16.3.2", - "react-addons-shallow-compare": "^15.6.2", -+<<<<<<< .our - "react-dom": "^16.3.2", - "react-transition-group": "^1.2.0", - "react-virtualized": "^9.20.0", -+======= -+ "react-dom": "^15.6.2", -+ "react-transition-group": "^2.2.1", -+ "react-virtualized": "^9.10.1", -+>>>>>>> .their - "registry-js": "^1.0.7", - "runas": "^3.1.1", - "source-map-support": "^0.4.15", -merged - result 100644 08f476cd44edbd8362a3e75d5b75dec4dca72782 app/src/ui/app-error.tsx - our 100644 ef5de9855835684262a20e0db2dce0397dff7fba app/src/ui/app-error.tsx -@@ -10,7 +10,7 @@ - import { GitError } from '../lib/git/core' - import { GitError as GitErrorType } from 'dugite' - import { Popup, PopupType } from '../lib/app-state' --import { CSSTransitionGroup } from 'react-transition-group' -+import { CSSTransition } from 'react-transition-group' - - interface IAppErrorProps { - /** The list of queued, app-wide, errors */ -@@ -131,13 +131,7 @@ - return <p className={className}>{error.message}</p> - } - -- private renderDialog() { -- const error = this.state.error -- -- if (!error) { -- return null -- } -- -+ private renderDialog(error: Error): JSX.Element { - return ( - <Dialog - id="app-error" -@@ -174,15 +168,22 @@ - } - - public render() { -+ const error = this.state.error -+ if (error == null) { -+ return null -+ } -+ - return ( -- <CSSTransitionGroup -- transitionName="modal" -+ <CSSTransition -+ classNames="modal" - component="div" -- transitionEnterTimeout={dialogTransitionEnterTimeout} -- transitionLeaveTimeout={dialogTransitionLeaveTimeout} -+ timeout={{ -+ enter: dialogTransitionEnterTimeout, -+ exit: dialogTransitionLeaveTimeout, -+ }} - > -- {this.renderDialog()} -- </CSSTransitionGroup> -+ {this.renderDialog(error)} -+ </CSSTransition> - ) - } - } -changed in both - base 100644 a2acbca598aad851c89baa673c370d6ca9b70455 app/src/ui/app.tsx - our 100644 c38c806e36c237ea70f3cdeee739941530c0c7cd app/src/ui/app.tsx - their 100644 446d391ade9e86fa866dd0e1205223e3a74391d1 app/src/ui/app.tsx -@@ -1,6 +1,11 @@ - import * as React from 'react' -+<<<<<<< .our - import { ipcRenderer, remote } from 'electron' - import { CSSTransitionGroup } from 'react-transition-group' -+======= -+import { ipcRenderer } from 'electron' -+import { CSSTransition } from 'react-transition-group' -+>>>>>>> .their - - import { - IAppState, -@@ -972,8 +977,7 @@ - } - - const popup = this.state.currentPopup -- -- if (!popup) { -+ if (popup == null) { - return null - } - -@@ -1353,15 +1357,22 @@ - } - - private renderPopup() { -+ const content = this.currentPopupContent() -+ if (content == null) { -+ return null -+ } -+ - return ( -- <CSSTransitionGroup -- transitionName="modal" -+ <CSSTransition -+ classNames="modal" - component="div" -- transitionEnterTimeout={dialogTransitionEnterTimeout} -- transitionLeaveTimeout={dialogTransitionLeaveTimeout} -+ timeout={{ -+ enter: dialogTransitionEnterTimeout, -+ exit: dialogTransitionLeaveTimeout, -+ }} - > -- {this.currentPopupContent()} -- </CSSTransitionGroup> -+ {content} -+ </CSSTransition> - ) - } - -changed in both - base 100644 e1a32ff2d68655613d37d40b216f02948a4a3e54 app/src/ui/branches/branches-container.tsx - our 100644 6a5612ae608b20b3a486f139daf4063209bca568 app/src/ui/branches/branches-container.tsx - their 100644 b951ac51a543d6fd350c9aa7d9971c84ba35741c app/src/ui/branches/branches-container.tsx -@@ -15,9 +15,15 @@ - import { BranchList } from './branch-list' - import { PullRequestList } from './pull-request-list' - import { PullRequestsLoading } from './pull-requests-loading' -+<<<<<<< .our - import { IBranchListItem } from './group-branches' - import { renderDefaultBranch } from './branch-renderer' - import { IMatches } from '../../lib/fuzzy-find' -+======= -+import { NoPullRequests } from './no-pull-requests' -+import { PullRequest } from '../../models/pull-request' -+import { CSSTransition } from 'react-transition-group' -+>>>>>>> .their - - const PullRequestsLoadingCrossFadeInTimeout = 300 - const PullRequestsLoadingCrossFadeOutTimeout = 200 -@@ -129,15 +135,17 @@ - - case BranchesTab.PullRequests: { - return ( -- <CSSTransitionGroup -- transitionName="cross-fade" -+ <CSSTransition -+ classNames="cross-fade" - component="div" - id="pr-transition-div" -- transitionEnterTimeout={PullRequestsLoadingCrossFadeInTimeout} -- transitionLeaveTimeout={PullRequestsLoadingCrossFadeOutTimeout} -+ timeout={{ -+ enter: PullRequestsLoadingCrossFadeInTimeout, -+ exit: PullRequestsLoadingCrossFadeOutTimeout, -+ }} - > - {this.renderPullRequests()} -- </CSSTransitionGroup> -+ </CSSTransition> - ) - } - } -@@ -145,8 +153,25 @@ - return assertNever(tab, `Unknown Branches tab: ${tab}`) - } - -+<<<<<<< .our - private renderPullRequests() { - if (this.props.isLoadingPullRequests) { -+======= -+ private renderPullRequests(): JSX.Element { -+ const pullRequests = this.props.pullRequests -+ if (pullRequests.length) { -+ return ( -+ <PullRequestList -+ key="pr-list" -+ pullRequests={pullRequests} -+ onSelectionChanged={this.onPullRequestSelectionChanged} -+ selectedPullRequest={this.state.selectedPullRequest} -+ onItemClick={this.onPullRequestClicked} -+ onDismiss={this.onDismiss} -+ /> -+ ) -+ } else if (this.props.isLoadingPullRequests) { -+>>>>>>> .their - return <PullRequestsLoading key="prs-loading" /> - } - -changed in both - base 100644 0702ae42c36af774c86ae52a284de40078cdd939 app/src/ui/changes/sidebar.tsx - our 100644 ff1760bbd4b1a3d5ea8ac084b1282e99b2ea288b app/src/ui/changes/sidebar.tsx - their 100644 2b24244e5c0a385cc06b6fe9ee7732df20afae33 app/src/ui/changes/sidebar.tsx -@@ -19,7 +19,7 @@ - } from '../autocompletion' - import { ClickSource } from '../lib/list' - import { WorkingDirectoryFileChange } from '../../models/status' --import { CSSTransitionGroup } from 'react-transition-group' -+import { CSSTransition } from 'react-transition-group' - import { openFile } from '../../lib/open-file' - import { ITrailer } from '../../lib/git/interpret-trailers' - import { Account } from '../../models/account' -@@ -242,30 +242,25 @@ - } - } - -- private renderMostRecentLocalCommit() { -+ private renderMostRecentLocalCommit(): JSX.Element | null { - const commit = this.props.mostRecentLocalCommit -- let child: JSX.Element | null = null -- if (commit) { -- child = ( -+ if (commit == null) { -+ return null -+ } -+ -+ return ( -+ <CSSTransition -+ classNames="undo" -+ appear={true} -+ timeout={UndoCommitAnimationTimeout} -+ > - <UndoCommit - isPushPullFetchInProgress={this.props.isPushPullFetchInProgress} - commit={commit} - onUndo={this.onUndo} - emoji={this.props.emoji} - /> -- ) -- } -- -- return ( -- <CSSTransitionGroup -- transitionName="undo" -- transitionAppear={true} -- transitionAppearTimeout={UndoCommitAnimationTimeout} -- transitionEnterTimeout={UndoCommitAnimationTimeout} -- transitionLeaveTimeout={UndoCommitAnimationTimeout} -- > -- {child} -- </CSSTransitionGroup> -+ </CSSTransition> - ) - } - -changed in both - base 100644 a95c57383963d8c769fb6adcfe11d24f238c4772 app/src/ui/window/full-screen-info.tsx - our 100644 72280c87e864846e29096e580b19154017556a2b app/src/ui/window/full-screen-info.tsx - their 100644 f9e4a9cad21636bf91a30125011b130f0c605de4 app/src/ui/window/full-screen-info.tsx -@@ -1,5 +1,5 @@ - import * as React from 'react' --import { CSSTransitionGroup } from 'react-transition-group' -+import { CSSTransition } from 'react-transition-group' - import { WindowState } from '../../lib/window-state' - - interface IFullScreenInfoProps { -@@ -85,11 +85,7 @@ - this.setState({ renderTransitionGroup: false }) - } - -- private renderFullScreenNotification() { -- if (!this.state.renderInfo) { -- return null -- } -- -+ private renderFullScreenNotification(): JSX.Element { - const kbdShortcut = __DARWIN__ ? '⌃⌘F' : 'F11' - - return ( -@@ -104,19 +100,23 @@ - return null - } - -+ if (!this.state.renderInfo) { -+ return null -+ } -+ - return ( -- <CSSTransitionGroup -- className="toast-notification-container" -- transitionName="toast-animation" -- component="div" -- transitionAppear={true} -- transitionEnter={false} -- transitionLeave={true} -- transitionAppearTimeout={transitionAppearDuration} -- transitionLeaveTimeout={transitionLeaveDuration} -+ <CSSTransition -+ classNames="toast-notification-container toast-animation" -+ appear={true} -+ enter={false} -+ exit={true} -+ timeout={{ -+ enter: transitionAppearDuration, -+ exit: transitionLeaveDuration, -+ }} - > - {this.renderFullScreenNotification()} -- </CSSTransitionGroup> -+ </CSSTransition> - ) - } - } -merged - result 100644 debae9e1c6f12e714654324f7ff3d6ce813a09b6 app/src/ui/window/zoom-info.tsx - our 100644 aad4453cc16dd9f16fb2b9a39226d058aab18b4c app/src/ui/window/zoom-info.tsx -@@ -1,5 +1,5 @@ - import * as React from 'react' --import { CSSTransitionGroup } from 'react-transition-group' -+import { CSSTransition } from 'react-transition-group' - - interface IZoomInfoProps { - readonly windowZoomFactor: number -@@ -83,11 +83,7 @@ - this.setState({ renderTransitionGroup: false }) - } - -- private renderZoomInfo() { -- if (!this.state.renderInfo) { -- return null -- } -- -+ private renderZoomInfo(): JSX.Element { - const zoomPercent = `${(this.state.windowZoomFactor * 100).toFixed(0)} %` - - return ( -@@ -102,19 +98,22 @@ - return null - } - -+ if (!this.state.renderInfo) { -+ return null -+ } -+ - return ( -- <CSSTransitionGroup -+ <CSSTransition - id="window-zoom-info" -- transitionName={this.state.transitionName} -+ classNames={this.state.transitionName} - component="div" -- transitionAppear={true} -- transitionEnter={false} -- transitionLeave={true} -- transitionAppearTimeout={transitionDuration} -- transitionLeaveTimeout={transitionDuration} -+ appear={true} -+ enter={false} -+ exit={true} -+ timeout={transitionDuration} - > - {this.renderZoomInfo()} -- </CSSTransitionGroup> -+ </CSSTransition> - ) - } - } -changed in both - base 100644 7054dc0108d02d6120683f328413e7294bbc2bfe app/styles/ui/_branches.scss - our 100644 b9a9ae211132ba7784f37322c2cb317e9c2aa871 app/styles/ui/_branches.scss - their 100644 0ffa4e5c3ac7b7f1bd940bb975b1f85d32719b33 app/styles/ui/_branches.scss -@@ -63,11 +63,11 @@ - transition: opacity 300ms ease-in; - } - -- .cross-fade-leave { -+ .cross-fade-exit { - opacity: 1; - } - -- .cross-fade-leave.cross-fade-leave-active { -+ .cross-fade-exit.cross-fade-exit-active { - opacity: 0; - transition: opacity 200ms ease-in; - } -changed in both - base 100644 8452efb173e669e14878c01f74896e865306cda9 app/styles/ui/_dialog.scss - our 100644 94b86d54fb9b0314deb1ef48cc9e1466578ed390 app/styles/ui/_dialog.scss - their 100644 4618e548a928ddc94a42e4eff6d421d7a9200b37 app/styles/ui/_dialog.scss -@@ -58,7 +58,7 @@ - } - } - -- &-leave { -+ &-exit { - opacity: 1; - transform: scale(1); - pointer-events: none; -@@ -68,7 +68,7 @@ - } - } - -- &-leave-active { -+ &-exit-active { - opacity: 0.01; - transform: scale(0.25); - transition: opacity 100ms ease-in, transform 100ms var(--easing-ease-in-back); -changed in both - base 100644 12ed30b8537694d2d09c4d3d3ae48825cf327697 app/styles/ui/changes/_changes-list.scss - our 100644 0260e1b911a78f4462b998784233f4505a8b1154 app/styles/ui/changes/_changes-list.scss - their 100644 87cdb6bfc823a73833fb9aa1c09d162d2a88ba6b app/styles/ui/changes/_changes-list.scss -@@ -56,11 +56,11 @@ - transition: max-height var(--undo-animation-duration) ease-in; - } - --.undo-leave { -+.undo-exit { - max-height: 200px; - } - --.undo-leave.undo-leave-active { -+.undo-exit.undo-exit-active { - max-height: 0; - - transition: max-height var(--undo-animation-duration) ease-out; -changed in both - base 100644 90a66e96d8ae86db5d645ff31dc5399e5fbdfb2e app/styles/ui/window/_toast-notification.scss - our 100644 69f1e178d8523dc79986e345766ace7b3aa278c2 app/styles/ui/window/_toast-notification.scss - their 100644 97e40af25738303d77fff2ec5423a92ba7321a84 app/styles/ui/window/_toast-notification.scss -@@ -47,8 +47,12 @@ - transition: all 100ms ease-out; - } - -+<<<<<<< .our - &-leave-active { - opacity: 0; - transition: all 250ms ease-out; - } -+======= -+ &-exit-active { opacity: 0; transition: all 250ms ease-out; } -+>>>>>>> .their - } -changed in both - base 100644 4a5aa3684805bbec963628b23480b96772347615 app/styles/ui/window/_zoom-info.scss - our 100644 0e9a54a357e4abc1b90c957b3f2b5b9d770d63a9 app/styles/ui/window/_zoom-info.scss - their 100644 be95e07e73211407b8424fe58dbac0114f528038 app/styles/ui/window/_zoom-info.scss -@@ -40,12 +40,17 @@ - } - } - -+<<<<<<< .our - .zoom-in, - .zoom-out { - &-leave-active { - opacity: 0; - transition: opacity 100ms ease-out; - } -+======= -+ .zoom-in, .zoom-out { -+ &-exit-active { opacity: 0; transition: opacity 100ms ease-out; } -+>>>>>>> .their - &-appear-active { - transform: scale(1); - opacity: 1; -changed in both - base 100644 2e45c4560a31468c69ed80ec86a86848b3611c4a app/yarn.lock - our 100644 cd6294bb698115d3ff652d361f00efbf85c1e781 app/yarn.lock - their 100644 9355fc6b5cc22da467514d6e14ed7bd59bb748a9 app/yarn.lock -@@ -690,7 +690,11 @@ - dependencies: - asap "~2.0.3" - -+<<<<<<< .our - prop-types@^15.5.6, prop-types@^15.6.0: -+======= -+prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8: -+>>>>>>> .their - version "15.6.0" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856" - dependencies: -@@ -740,14 +744,15 @@ - version "3.0.4" - resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" - --react-transition-group@^1.2.0: -- version "1.2.1" -- resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-1.2.1.tgz#e11f72b257f921b213229a774df46612346c7ca6" -+react-transition-group@^2.2.1: -+ version "2.2.1" -+ resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.2.1.tgz#e9fb677b79e6455fd391b03823afe84849df4a10" - dependencies: - chain-function "^1.0.0" -+ classnames "^2.2.5" - dom-helpers "^3.2.0" - loose-envify "^1.3.1" -- prop-types "^15.5.6" -+ prop-types "^15.5.8" - warning "^3.0.0" - - react-virtualized@^9.20.0: -changed in both - base 100644 1320c9a046cf624392543acf1261d554c8d2240f package.json - our 100644 2006bfb748810f6ea8bdbd26edf7c09524a1388a package.json - their 100644 f72adc2033106fe989c10fb73676531a893c1dc3 package.json -@@ -131,6 +131,7 @@ - "@types/mini-css-extract-plugin": "^0.2.0", - "@types/mocha": "^2.2.48", - "@types/mri": "^1.1.0", -+<<<<<<< .our - "@types/node": "^8.10.4", - "@types/react": "^16.3.16", - "@types/react-dom": "^16.0.5", -@@ -138,6 +139,14 @@ - "@types/react-virtualized": "^9.7.12", - "@types/request": "^2.0.9", - "@types/semver": "^5.5.0", -+======= -+ "@types/node": "^7.0.18", -+ "@types/react": "^16.0.19", -+ "@types/react-addons-test-utils": "^0.14.20", -+ "@types/react-dom": "^16.0.2", -+ "@types/react-transition-group": "^2.0.6", -+ "@types/react-virtualized": "^9.7.4", -+>>>>>>> .their - "@types/strip-ansi": "^3.0.0", - "@types/temp": "^0.8.29", - "@types/textarea-caret": "^3.0.0", -changed in both - base 100644 ac6e09215b6e722b659cfbb95cf0d81538e0f669 yarn.lock - our 100644 45ddb8bf6902bbb22708d844324093dccda26c79 yarn.lock - their 100644 a360a005900287a46bc597e7a035db2be03416d1 yarn.lock -@@ -205,9 +205,9 @@ - "@types/node" "*" - "@types/react" "*" - --"@types/react-transition-group@1.1.1": -- version "1.1.1" -- resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-1.1.1.tgz#372fd2b4777b96aa983ac15fb5cc0ce150550aeb" -+"@types/react-transition-group@^2.0.6": -+ version "2.0.6" -+ resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-2.0.6.tgz#8903fa2cf540ba454461590bff811a787889617c" - dependencies: - "@types/react" "*" - diff --git a/app/test/fixtures/merge-parser/desktop/merge-reduce-diff-max-length-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-reduce-diff-max-length-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index a4458d04e05..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-reduce-diff-max-length-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,16 +0,0 @@ -changed in both - base 100644 a4a60d43af58a60992e886cb98ae9807c8df44b8 app/src/lib/git/diff.ts - our 100644 c7b70925514f334e2076ddb67f208c2f3f12672f app/src/lib/git/diff.ts - their 100644 842836abef030ba1cd9af1eb2ffed893c6540395 app/src/lib/git/diff.ts -@@ -44,7 +44,11 @@ - * The longest line length we should try to display. If a diff has a line longer - * than this, we probably shouldn't attempt it - */ -+<<<<<<< .our - const MaxCharactersPerLine = 5000 -+======= -+const MaxLineLength = 5000 -+>>>>>>> .their - - /** - * Utility function to check whether parsing this buffer is going to cause diff --git a/app/test/fixtures/merge-parser/desktop/merge-refactoring-into-discrete-parts-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-refactoring-into-discrete-parts-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 00f02a3e91a..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-refactoring-into-discrete-parts-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,722 +0,0 @@ -changed in both - base 100644 fe48405e5f0bbcfbbd7786e07593c26a1dae33cd app/src/ui/lib/filter-list.tsx - our 100644 a625bab6249781a07060095fe6306dfd832f032f app/src/ui/lib/filter-list.tsx - their 100644 b18e2fb79f6b4c66454c5b92dd09cf535553c8c3 app/src/ui/lib/filter-list.tsx -@@ -253,9 +253,18 @@ - } - - public selectFirstItem(focus: boolean = false) { -+<<<<<<< .our - if (this.list === null) { - return - } -+======= -+ if (this.list !== null) { -+ const next = findNextSelectableRow( -+ this.state.rows.length, -+ { direction: 'down', row: -1 }, -+ this.canSelectRow -+ ) -+>>>>>>> .their - - const next = findNextSelectableRow( - this.state.rows.length, -added in remote - their 100644 967fdf80dd5add442b6cf28658aade9673b28645 app/src/ui/lib/list/filter-list.tsx -@@ -0,0 +1,403 @@ -+import * as React from 'react' -+import * as classnames from 'classnames' -+ -+import { -+ SelectionSource as ListSelectionSource, -+ findNextSelectableRow, -+} from '../../lib/list' -+import { FilterTextBox } from './filter-text-box' -+import { FilterResults } from './filter-results' -+import { Row } from '../../lib/row' -+ -+import { match, IMatch } from '../../../lib/fuzzy-find' -+ -+/** An item in the filter list. */ -+export interface IFilterListItem { -+ /** The text which represents the item. This is used for filtering. */ -+ readonly text: string -+ -+ /** A unique identifier for the item. */ -+ readonly id: string -+} -+ -+/** A group of items in the list. */ -+export interface IFilterListGroup<T extends IFilterListItem> { -+ /** The identifier for this group. */ -+ readonly identifier: string -+ -+ /** The items in the group. */ -+ readonly items: ReadonlyArray<T> -+} -+ -+interface IFlattenedGroup { -+ readonly kind: 'group' -+ readonly identifier: string -+} -+ -+interface IFlattenedItem<T extends IFilterListItem> { -+ readonly kind: 'item' -+ readonly item: T -+ /** Array of indexes in `item.text` that should be highlighted */ -+ readonly matches: ReadonlyArray<number> -+} -+ -+/** -+ * A row in the list. This is used internally after the user-provided groups are -+ * flattened. -+ */ -+type IFilterListRow<T extends IFilterListItem> = -+ | IFlattenedGroup -+ | IFlattenedItem<T> -+ -+interface IFilterListProps<T extends IFilterListItem> { -+ /** A class name for the wrapping element. */ -+ readonly className?: string -+ -+ /** The height of the rows. */ -+ readonly rowHeight: number -+ -+ /** The ordered groups to display in the list. */ -+ readonly groups: ReadonlyArray<IFilterListGroup<T>> -+ -+ /** The selected item. */ -+ readonly selectedItem: T | null -+ -+ /** Called to render each visible item. */ -+ readonly renderItem: ( -+ item: T, -+ matches: ReadonlyArray<number> -+ ) => JSX.Element | null -+ -+ /** Called to render header for the group with the given identifier. */ -+ readonly renderGroupHeader?: (identifier: string) => JSX.Element | null -+ -+ /** Called to render content before/above the filter and list. */ -+ readonly renderPreList?: () => JSX.Element | null -+ -+ /** Called when an item is clicked. */ -+ readonly onItemClick?: (item: T) => void -+ -+ /** -+ * This function will be called when the selection changes as a result of a -+ * user keyboard or mouse action (i.e. not when props change). This function -+ * will not be invoked when an already selected row is clicked on. -+ * -+ * @param selectedItem - The item that was just selected -+ * @param source - The kind of user action that provoked the change, -+ * either a pointer device press, or a keyboard event -+ * (arrow up/down) -+ */ -+ readonly onSelectionChanged?: ( -+ selectedItem: T | null, -+ source: SelectionSource -+ ) => void -+ -+ /** -+ * Called when a key down happens in the filter text input. Users have a -+ * chance to respond or cancel the default behavior by calling -+ * `preventDefault()`. -+ */ -+ readonly onFilterKeyDown?: ( -+ event: React.KeyboardEvent<HTMLInputElement> -+ ) => void -+ -+ /** The current filter text to use in the form */ -+ readonly filterText?: string -+ -+ /** Called when the filter text is changed by the user */ -+ readonly onFilterTextChanged?: (text: string) => void -+ -+ /** -+ * Whether or not the filter list should allow selection -+ * and filtering. Defaults to false. -+ */ -+ readonly disabled?: boolean -+ -+ /** Any props which should cause a re-render if they change. */ -+ readonly invalidationProps: any -+ -+ /** Called to render content after the filter. */ -+ readonly renderPostFilter?: () => JSX.Element | null -+ -+ /** Called when there are no items to render. */ -+ readonly renderNoItems?: () => JSX.Element | null -+} -+ -+interface IFilterListState<T extends IFilterListItem> { -+ readonly rows: ReadonlyArray<IFilterListRow<T>> -+ readonly selectedRow: number -+} -+ -+/** -+ * Interface describing a user initiated selection change event -+ * originating from changing the filter text. -+ */ -+export interface IFilterSelectionSource { -+ kind: 'filter' -+ -+ /** The filter text at the time the selection event was raised. */ -+ filterText: string -+} -+ -+export type SelectionSource = ListSelectionSource | IFilterSelectionSource -+ -+/** A List which includes the ability to filter based on its contents. */ -+export class FilterList<T extends IFilterListItem> extends React.Component< -+ IFilterListProps<T>, -+ IFilterListState<T> -+> { -+ private list: FilterResults | null = null -+ private filterTextBox: FilterTextBox | null = null -+ -+ public constructor(props: IFilterListProps<T>) { -+ super(props) -+ -+ this.state = createStateUpdate(props) -+ } -+ -+ public componentWillReceiveProps(nextProps: IFilterListProps<T>) { -+ this.setState(createStateUpdate(nextProps)) -+ } -+ -+ public componentDidUpdate( -+ prevProps: IFilterListProps<T>, -+ prevState: IFilterListState<T> -+ ) { -+ if (this.props.onSelectionChanged) { -+ const oldSelectedItemId = getItemIdFromRowIndex( -+ prevState.rows, -+ prevState.selectedRow -+ ) -+ const newSelectedItemId = getItemIdFromRowIndex( -+ this.state.rows, -+ this.state.selectedRow -+ ) -+ -+ if (oldSelectedItemId !== newSelectedItemId) { -+ const propSelectionId = this.props.selectedItem -+ ? this.props.selectedItem.id -+ : null -+ -+ if (propSelectionId !== newSelectedItemId) { -+ const newSelectedItem = getItemFromRowIndex( -+ this.state.rows, -+ this.state.selectedRow -+ ) -+ this.props.onSelectionChanged(newSelectedItem, { -+ kind: 'filter', -+ filterText: this.props.filterText || '', -+ }) -+ } -+ } -+ } -+ } -+ -+ public componentDidMount() { -+ if (this.filterTextBox != null) { -+ this.filterTextBox.selectAll() -+ } -+ } -+ -+ public render() { -+ return ( -+ <div className={classnames('filter-list', this.props.className)}> -+ {this.props.renderPreList ? this.props.renderPreList() : null} -+ -+ <Row className="filter-field-row"> -+ <FilterTextBox -+ ref={this.onTextBoxRef} -+ rowCount={this.state.rows.length} -+ onMoveToRow={this.onMoveToRow} -+ filterText={this.props.filterText} -+ disabled={this.props.disabled} -+ onFilterTextChanged={this.onFilterValueChanged} -+ onSelectFirstRow={this.onSelectFirstRow} -+ /> -+ -+ {this.props.renderPostFilter ? this.props.renderPostFilter() : null} -+ </Row> -+ -+ <div className="filter-list-container">{this.renderContent()}</div> -+ </div> -+ ) -+ } -+ -+ private renderContent() { -+ if (this.state.rows.length === 0 && this.props.renderNoItems) { -+ return this.props.renderNoItems() -+ } else { -+ return ( -+ <FilterResults -+ ref={this.onListRef} -+ rowCount={this.state.rows.length} -+ renderRow={this.renderRow} -+ onFocusTextBox={this.onFocusTextBox} -+ rowHeight={this.props.rowHeight} -+ selectedRows={[this.state.selectedRow]} -+ onSelectedRowChanged={this.onSelectedRowChanged} -+ canSelectRow={this.canSelectRow} -+ invalidationProps={{ -+ ...this.props, -+ ...this.props.invalidationProps, -+ }} -+ /> -+ ) -+ } -+ } -+ -+ private onFocusTextBox = () => { -+ if (this.filterTextBox != null) { -+ this.filterTextBox.focus() -+ } -+ } -+ -+ private onSelectFirstRow = () => { -+ const rowCount = this.state.rows.length -+ -+ const selectedRow = findNextSelectableRow( -+ rowCount, -+ { direction: 'down', row: -1 }, -+ this.canSelectRow -+ ) -+ -+ if (selectedRow != null) { -+ this.onRowClick(selectedRow) -+ } -+ } -+ -+ private onMoveToRow = (direction: 'down' | 'up', currentRow: number) => { -+ const rowCount = this.state.rows.length -+ -+ const selectedRow = findNextSelectableRow( -+ rowCount, -+ { direction, row: currentRow }, -+ this.canSelectRow -+ ) -+ if (selectedRow != null) { -+ this.setState({ selectedRow }, () => { -+ if (this.list != null) { -+ this.list.focus() -+ } -+ }) -+ } -+ } -+ -+ private onRowClick = (index: number) => { -+ if (this.props.onItemClick) { -+ const row = this.state.rows[index] -+ -+ if (row.kind === 'item') { -+ this.props.onItemClick(row.item) -+ } -+ } -+ } -+ -+ private renderRow = (index: number) => { -+ const row = this.state.rows[index] -+ if (row.kind === 'item') { -+ return this.props.renderItem(row.item, row.matches) -+ } else if (this.props.renderGroupHeader) { -+ return this.props.renderGroupHeader(row.identifier) -+ } else { -+ return null -+ } -+ } -+ -+ private onTextBoxRef = (component: FilterTextBox | null) => { -+ this.filterTextBox = component -+ } -+ -+ private onListRef = (instance: FilterResults | null) => { -+ this.list = instance -+ } -+ -+ private onFilterValueChanged = (text: string) => { -+ if (this.props.onFilterTextChanged) { -+ this.props.onFilterTextChanged(text) -+ } -+ } -+ -+ private onSelectedRowChanged = (index: number, source: SelectionSource) => { -+ this.setState({ selectedRow: index }) -+ -+ if (this.props.onSelectionChanged) { -+ const row = this.state.rows[index] -+ if (row.kind === 'item') { -+ this.props.onSelectionChanged(row.item, source) -+ } -+ } -+ } -+ -+ private canSelectRow = (index: number) => { -+ if (this.props.disabled) { -+ return false -+ } -+ -+ const row = this.state.rows[index] -+ return row.kind === 'item' -+ } -+} -+ -+function createStateUpdate<T extends IFilterListItem>( -+ props: IFilterListProps<T> -+) { -+ const flattenedRows = new Array<IFilterListRow<T>>() -+ const filter = (props.filterText || '').toLowerCase() -+ -+ for (const group of props.groups) { -+ const items: ReadonlyArray<IMatch<T>> = filter -+ ? match(filter, group.items, 'text') -+ : group.items.map(item => ({ score: 1, matches: [], item })) -+ -+ if (!items.length) { -+ continue -+ } -+ -+ if (props.renderGroupHeader) { -+ flattenedRows.push({ kind: 'group', identifier: group.identifier }) -+ } -+ -+ for (const { item, matches } of items) { -+ flattenedRows.push({ kind: 'item', item, matches }) -+ } -+ } -+ -+ let selectedRow = -1 -+ const selectedItem = props.selectedItem -+ if (selectedItem) { -+ selectedRow = flattenedRows.findIndex( -+ i => i.kind === 'item' && i.item.id === selectedItem.id -+ ) -+ } -+ -+ if (selectedRow < 0 && filter.length) { -+ // If the selected item isn't in the list (e.g., filtered out), then -+ // select the first visible item. -+ selectedRow = flattenedRows.findIndex(i => i.kind === 'item') -+ } -+ -+ return { rows: flattenedRows, selectedRow } -+} -+ -+function getItemFromRowIndex<T extends IFilterListItem>( -+ items: ReadonlyArray<IFilterListRow<T>>, -+ index: number -+): T | null { -+ if (index >= 0 && index < items.length) { -+ const row = items[index] -+ -+ if (row.kind === 'item') { -+ return row.item -+ } -+ } -+ -+ return null -+} -+ -+function getItemIdFromRowIndex<T extends IFilterListItem>( -+ items: ReadonlyArray<IFilterListRow<T>>, -+ index: number -+): string | null { -+ const item = getItemFromRowIndex(items, index) -+ return item ? item.id : null -+} -added in remote - their 100644 d666cd5c14b87ffda942cd0f3e61275231162d0a app/src/ui/lib/list/filter-results.tsx -@@ -0,0 +1,115 @@ -+import * as React from 'react' -+ -+import { List, findNextSelectableRow, SelectionSource } from '../../lib/list' -+ -+interface IFilterResultProps { -+ /** The number of rows in the current filtered list */ -+ readonly rowCount: number -+ -+ /** The set of selected rows in the current filtered list */ -+ readonly selectedRows: ReadonlyArray<number> -+ -+ /** Callback to fire to render an element in the lists */ -+ readonly renderRow: (index: number) => JSX.Element | null -+ -+ /** Optional callback to render something when no items are available */ -+ readonly renderNoItems?: () => JSX.Element | null -+ -+ /** The height of each row in the list. */ -+ readonly rowHeight: number -+ -+ /** Any props which should cause a re-render if they change. */ -+ readonly invalidationProps: any -+ -+ /** Callback to fire when the selected row changes */ -+ readonly onSelectedRowChanged?: ( -+ index: number, -+ source: SelectionSource -+ ) => void -+ -+ /** -+ * Function to validate if the given row can be selected by the user -+ */ -+ readonly canSelectRow: (index: number) => boolean -+ -+ /** -+ * Callback to the parent component that it should focus on the filter text box -+ */ -+ readonly onFocusTextBox: (event: React.KeyboardEvent<any>) => void -+} -+ -+export class FilterResults extends React.Component<IFilterResultProps, {}> { -+ private list: List | null = null -+ -+ public render() { -+ if (this.props.rowCount === 0 && this.props.renderNoItems) { -+ return this.props.renderNoItems() -+ } else { -+ return ( -+ <List -+ ref={this.onListRef} -+ rowCount={this.props.rowCount} -+ rowRenderer={this.props.renderRow} -+ rowHeight={this.props.rowHeight} -+ selectedRows={this.props.selectedRows} -+ onSelectedRowChanged={this.props.onSelectedRowChanged} -+ onRowClick={this.onRowClick} -+ onRowKeyDown={this.onRowKeyDown} -+ canSelectRow={this.props.canSelectRow} -+ invalidationProps={{ -+ ...this.props, -+ ...this.props.invalidationProps, -+ }} -+ /> -+ ) -+ } -+ } -+ -+ private onListRef = (instance: List | null) => { -+ this.list = instance -+ } -+ -+ public focus() { -+ if (this.list != null) { -+ this.list.focus() -+ } -+ } -+ -+ private onRowClick = (row: number, source: SelectionSource) => { -+ if (this.props.onSelectedRowChanged) { -+ this.props.onSelectedRowChanged(row, source) -+ } -+ } -+ -+ private onRowKeyDown = (row: number, event: React.KeyboardEvent<any>) => { -+ const list = this.list -+ if (!list) { -+ return -+ } -+ -+ const rowCount = this.props.rowCount -+ -+ const firstSelectableRow = findNextSelectableRow( -+ rowCount, -+ { direction: 'down', row: -1 }, -+ this.props.canSelectRow -+ ) -+ const lastSelectableRow = findNextSelectableRow( -+ rowCount, -+ { direction: 'up', row: 0 }, -+ this.props.canSelectRow -+ ) -+ -+ let shouldFocus = false -+ -+ if (event.key === 'ArrowUp' && row === firstSelectableRow) { -+ shouldFocus = true -+ } else if (event.key === 'ArrowDown' && row === lastSelectableRow) { -+ shouldFocus = true -+ } -+ -+ if (shouldFocus) { -+ this.props.onFocusTextBox(event) -+ } -+ } -+} -added in remote - their 100644 ab64cc861dda12b34a24844da30a659e17092457 app/src/ui/lib/list/filter-text-box.tsx -@@ -0,0 +1,124 @@ -+import * as React from 'react' -+ -+import { TextBox } from '../../lib/text-box' -+ -+import { SelectionDirection } from '../../lib/list' -+ -+interface IFilterTextBoxProps { -+ /** The number of rows in the current filtered list */ -+ readonly rowCount: number -+ -+ /** The current filter text to use in the form */ -+ readonly filterText?: string -+ -+ /** Called when the filter text is changed by the user */ -+ readonly onFilterTextChanged?: (text: string) => void -+ -+ /** -+ * Called when a key down happens in the filter text input. Users have a -+ * chance to respond or cancel the default behavior by calling -+ * `preventDefault()`. -+ */ -+ readonly onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void -+ -+ /** -+ * Whether or not the filter list should allow selection -+ * and filtering. Defaults to false. -+ */ -+ readonly disabled?: boolean -+ -+ /** Called when an item should be focused in the filtered list. */ -+ readonly onMoveToRow: ( -+ direction: SelectionDirection, -+ currentRow: number -+ ) => void -+ -+ /** Called when the parent component should choose the default entry in the filtered list. */ -+ readonly onSelectFirstRow: () => void -+} -+ -+/** A List which includes the ability to filter based on its contents. */ -+export class FilterTextBox extends React.Component<IFilterTextBoxProps, {}> { -+ private textBoxRef: TextBox | null = null -+ -+ public render() { -+ return ( -+ <TextBox -+ ref={this.onTextBoxRef} -+ type="search" -+ autoFocus={true} -+ placeholder="Filter" -+ className="filter-list-filter-field" -+ onValueChanged={this.onFilterValueChanged} -+ onKeyDown={this.onKeyDown} -+ value={this.props.filterText} -+ disabled={this.props.disabled} -+ /> -+ ) -+ } -+ -+ public focus() { -+ if (this.textBoxRef != null) { -+ this.textBoxRef.focus() -+ } -+ } -+ -+ public selectAll() { -+ if (this.textBoxRef != null) { -+ this.textBoxRef.selectAll() -+ } -+ } -+ -+ private onTextBoxRef = (textBox: TextBox | null) => { -+ this.textBoxRef = textBox -+ } -+ -+ private onFilterValueChanged = (text: string) => { -+ if (this.props.onFilterTextChanged) { -+ this.props.onFilterTextChanged(text) -+ } -+ } -+ -+ private onKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => { -+ const key = event.key -+ -+ if (this.props.onKeyDown) { -+ this.props.onKeyDown(event) -+ } -+ -+ if (event.defaultPrevented) { -+ return -+ } -+ -+ const rowCount = this.props.rowCount -+ -+ if (key === 'ArrowDown') { -+ if (rowCount > 0) { -+ this.props.onMoveToRow('down', -1) -+ } -+ -+ event.preventDefault() -+ } else if (key === 'ArrowUp') { -+ if (rowCount > 0) { -+ this.props.onMoveToRow('up', 0) -+ } -+ -+ event.preventDefault() -+ } else if (key === 'Enter') { -+ // no repositories currently displayed, bail out -+ if (rowCount === 0) { -+ return event.preventDefault() -+ } -+ -+ const filterText = this.props.filterText -+ -+ if (filterText !== undefined && !/\S/.test(filterText)) { -+ return event.preventDefault() -+ } -+ -+ if (this.props.onSelectFirstRow) { -+ this.props.onSelectFirstRow() -+ } -+ } -+ } -+} -changed in both - base 100644 72a36afa71949e6a0a3d2550c9bcf5a07b731868 app/src/ui/lib/list/list.tsx - our 100644 e534ebfd72eb9026d47bcdcd9e3077b295db520a app/src/ui/lib/list/list.tsx - their 100644 92779478b46a6e660a1cac230900cbfdd9faac78 app/src/ui/lib/list/list.tsx -@@ -465,7 +465,11 @@ - - const newRow = findNextSelectableRow( - this.props.rowCount, -+<<<<<<< .our - { direction, row: lastSelection, wrap: false }, -+======= -+ { direction, row: lastSelection }, -+>>>>>>> .their - this.canSelectRow - ) - -@@ -500,7 +504,11 @@ - - const newRow = findNextSelectableRow( - this.props.rowCount, -+<<<<<<< .our - { direction, row: lastSelection }, -+======= -+ { direction, row: lastSelection, wrap: false }, -+>>>>>>> .their - this.canSelectRow - ) - -added in both - our 100644 e508ad7bd721169b3f96558a76f7e5a32bcf8a71 app/src/ui/lib/list/selection.ts - their 100644 fc006b23b096e3dd5a3d40d1c4b6b20ee553a387 app/src/ui/lib/list/selection.ts -@@ -100,6 +100,7 @@ - let currentRow = - row < 0 || row >= rowCount ? (direction === 'up' ? rowCount - 1 : 0) : row - -+<<<<<<< .our - // handle specific case from switching from filter text to list - // - // locking currentRow to [0,rowCount) above means that the below loops -@@ -108,6 +109,8 @@ - currentRow = -1 - } - -+======= -+>>>>>>> .their - const delta = direction === 'up' ? -1 : 1 - - // Iterate through all rows (starting offset from the diff --git a/app/test/fixtures/merge-parser/desktop/merge-remove-remote-with-caution-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-remove-remote-with-caution-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 704326701fc..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-remove-remote-with-caution-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,288 +0,0 @@ -changed in both - base 100644 f90c946fa2c439ffe576db4820b3768a65a1b08e app/src/lib/dispatcher/dispatcher.ts - our 100644 5e56c00e713342e76f5ccba040062e322e8c90cb app/src/lib/dispatcher/dispatcher.ts - their 100644 16fc744a17f351d7db2bb1e7ae547fe77d3742ff app/src/lib/dispatcher/dispatcher.ts -@@ -583,6 +583,11 @@ - return this.appStore._reportStats() - } - -+ /** Removes the given remote for the repository */ -+ public removeRemote(repository: Repository, name: string): Promise<void> { -+ return this.appStore._removeRemote(repository, name) -+ } -+ - /** Changes the URL for the remote that matches the given name */ - public setRemoteURL( - repository: Repository, -changed in both - base 100644 35616ea966ef4ad7549bac1421f71090fbe1d3e6 app/src/lib/stores/app-store.ts - our 100644 1a4e387e4d192d34abfd0621b4b5ebe8cc34d8d1 app/src/lib/stores/app-store.ts - their 100644 15cd235220c186f54795bca0d0d2cf8d7cd03cf7 app/src/lib/stores/app-store.ts -@@ -3067,6 +3067,12 @@ - } - - /** This shouldn't be called directly. See `Dispatcher`. */ -+ public _removeRemote(repository: Repository, name: string): Promise<void> { -+ const gitStore = this.getGitStore(repository) -+ return gitStore.removeRemote(name) -+ } -+ -+ /** This shouldn't be called directly. See `Dispatcher`. */ - public _setRemoteURL( - repository: Repository, - name: string, -changed in both - base 100644 cc8f049009ace9094a0307160770ffdcd0217554 app/src/lib/stores/git-store.ts - our 100644 f8eedeb9d958345be59538b82b1b69cd4326d73b app/src/lib/stores/git-store.ts - their 100644 b431d751c1c7cf6ea3f671d2ea8f28bc3c4a7d35 app/src/lib/stores/git-store.ts -@@ -31,6 +31,7 @@ - deleteRef, - getCommits, - merge, -+ removeRemote, - setRemoteURL, - getStatus, - IStatusResult, -@@ -1110,6 +1111,18 @@ - }) - } - -+ /** Remove the given remote from the given repository */ -+ public async removeRemote(name: string): Promise<void> { -+ await this.performFailableOperation(() => -+ removeRemote(this.repository, name) -+ ) -+ -+ this._remote = null -+ await this.loadCurrentRemote() -+ -+ this.emitUpdate() -+ } -+ - /** Changes the URL for the remote that matches the given name */ - public async setRemoteURL(name: string, url: string): Promise<void> { - await this.performFailableOperation(() => -merged - result 100644 3208900a9b6bad0f92a9c552289c43ae750e809a app/src/ui/repository-settings/remote.tsx - our 100644 5c8ba70c0b00b68c877c28f5786d6f96fbb9532a app/src/ui/repository-settings/remote.tsx -@@ -1,6 +1,9 @@ - import * as React from 'react' - import { IRemote } from '../../models/remote' -+import { Row } from '../lib/row' - import { TextBox } from '../lib/text-box' -+import { LinkButton } from '../lib/link-button' -+import { Octicon, OcticonSymbol } from '../octicons' - import { DialogContent } from '../dialog' - - interface IRemoteProps { -@@ -9,21 +12,73 @@ - - /** The function to call when the remote URL is changed by the user. */ - readonly onRemoteUrlChanged: (url: string) => void -+ -+ /** The function to call when the user marks the repository for removal */ -+ readonly onRemoteRemoved: () => void -+ -+ /** A flag to confirm the remote will be removed when saving changes */ -+ readonly remoteDeleted: boolean - } - - /** The Remote component. */ - export class Remote extends React.Component<IRemoteProps, {}> { - public render() { - const remote = this.props.remote -+ -+ if (this.props.remoteDeleted) { -+ return ( -+ <DialogContent> -+ <Row className="warning-helper-text"> -+ <Octicon symbol={OcticonSymbol.alert} /> -+ <p> -+ Removing the <strong>{remote.name}</strong> remote will affect -+ publishing the repository to your remote server. Press{' '} -+ <strong>Save</strong> to confirm this change. -+ </p> -+ </Row> -+ </DialogContent> -+ ) -+ } -+ -+ const title = `Remove the ${remote.name} remote from this repository` - return ( - <DialogContent> -- <div>Primary remote repository ({remote.name})</div> -- <TextBox -- placeholder="Remote URL" -- value={remote.url} -- onValueChanged={this.props.onRemoteUrlChanged} -- /> -+ <Row> -+ <div>Primary remote repository ({remote.name})</div> -+ </Row> -+ <Row> -+ <TextBox -+ placeholder="Remote URL" -+ value={remote.url} -+ onValueChanged={this.props.onRemoteUrlChanged} -+ /> -+ <LinkButton onClick={this.removeRemote} title={title}> -+ <Octicon symbol={OcticonSymbol.trashcan} /> -+ </LinkButton> -+ </Row> -+ -+ {this.renderInvalidUrlWarning()} - </DialogContent> - ) - } -+ -+ private renderInvalidUrlWarning() { -+ const isValidPath = this.props.remote.url.length > 0 -+ -+ if (isValidPath) { -+ return null -+ } -+ -+ return ( -+ <Row className="error-helper-text"> -+ <Octicon symbol={OcticonSymbol.x} /> -+ <p>You cannot create an empty remote URL.</p> -+ </Row> -+ ) -+ } -+ -+ private removeRemote = () => { -+ // TODO: propagate this up the chain -+ this.props.onRemoteRemoved() -+ } - } -changed in both - base 100644 ad68721a27fd17b357977ad754663df39fa337ab app/src/ui/repository-settings/repository-settings.tsx - our 100644 df6e4cf60b4e535a69c9fc0a585902ada9e70fbb app/src/ui/repository-settings/repository-settings.tsx - their 100644 fc03bb01f366eb3490f84ba88db8f0d3dcb6be1b app/src/ui/repository-settings/repository-settings.tsx -@@ -27,6 +27,7 @@ - interface IRepositorySettingsState { - readonly selectedTab: RepositorySettingsTab - readonly remote: IRemote | null -+ readonly remoteDeleted: boolean - readonly ignoreText: string | null - readonly ignoreTextHasChanged: boolean - readonly disabled: boolean -@@ -43,6 +44,7 @@ - this.state = { - selectedTab: RepositorySettingsTab.Remote, - remote: props.remote, -+ remoteDeleted: false, - ignoreText: null, - ignoreTextHasChanged: false, - disabled: false, -@@ -106,15 +108,23 @@ - - private renderFooter() { - const tab = this.state.selectedTab -+ if (tab !== RepositorySettingsTab.Remote) { -+ return null -+ } -+ - const remote = this.state.remote -- if (tab === RepositorySettingsTab.Remote && !remote) { -+ if (!remote) { - return null - } - -+ const disabled = remote.url.length === 0 -+ - return ( - <DialogFooter> - <ButtonGroup> -- <Button type="submit">Save</Button> -+ <Button type="submit" disabled={disabled}> -+ Save -+ </Button> - <Button onClick={this.props.onDismissed}>Cancel</Button> - </ButtonGroup> - </DialogFooter> -@@ -131,6 +141,8 @@ - <Remote - remote={remote} - onRemoteUrlChanged={this.onRemoteUrlChanged} -+ onRemoteRemoved={this.onRemoteRemoved} -+ remoteDeleted={this.state.remoteDeleted} - /> - ) - } else { -@@ -167,21 +179,42 @@ - const errors = new Array<JSX.Element | string>() - - if (this.state.remote && this.props.remote) { -- if (this.state.remote.url !== this.props.remote.url) { -+ if (this.state.remoteDeleted) { - try { -- await this.props.dispatcher.setRemoteURL( -+ await this.props.dispatcher.removeRemote( - this.props.repository, -- this.props.remote.name, -- this.state.remote.url -+ this.props.remote.name - ) - } catch (e) { - log.error( -+<<<<<<< .our - `RepositorySettings: unable to set remote URL at ${ - this.props.repository.path - }`, -+======= -+ `RepositorySettings: unable to remove remote at ${this.props -+ .repository.path}`, -+>>>>>>> .their - e - ) -- errors.push(`Failed setting the remote URL: ${e}`) -+ errors.push(`Failed removing the remote: ${e}`) -+ } -+ } else { -+ if (this.state.remote.url !== this.props.remote.url) { -+ try { -+ await this.props.dispatcher.setRemoteURL( -+ this.props.repository, -+ this.props.remote.name, -+ this.state.remote.url -+ ) -+ } catch (e) { -+ log.error( -+ `RepositorySettings: unable to set remote URL at ${this.props -+ .repository.path}`, -+ e -+ ) -+ errors.push(`Failed setting the remote URL: ${e}`) -+ } - } - } - } -@@ -221,6 +254,10 @@ - this.setState({ remote: newRemote }) - } - -+ private onRemoteRemoved = () => { -+ this.setState({ remoteDeleted: true }) -+ } -+ - private onIgnoreTextChanged = (text: string) => { - this.setState({ ignoreText: text, ignoreTextHasChanged: true }) - } -changed in both - base 100644 8452efb173e669e14878c01f74896e865306cda9 app/styles/ui/_dialog.scss - our 100644 94b86d54fb9b0314deb1ef48cc9e1466578ed390 app/styles/ui/_dialog.scss - their 100644 9cf3db7cc7ea8b2e7116074e23a87ebdc17fd27e app/styles/ui/_dialog.scss -@@ -362,3 +362,12 @@ - margin-right: var(--spacing-half); - } - } -+ -+.error-helper-text { -+ font-size: var(--font-size-sm); -+ -+ .octicon { -+ fill: var(--dialog-error-color); -+ margin-right: var(--spacing-half); -+ } -+} diff --git a/app/test/fixtures/merge-parser/desktop/merge-reproduce-minification-issue-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-reproduce-minification-issue-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 9ce270a5084..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-reproduce-minification-issue-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,305 +0,0 @@ -merged - result 100644 f4900c37ac00d3742e619feca84299314005c1e5 .gitignore - our 100644 63a2cc1a341c354faf7c4979d2fffb86d5e93501 .gitignore -@@ -1,4 +1,5 @@ - out/ -+out-repro/ - dist/ - node_modules/ - npm-debug.log -merged - result 100644 8f351133737a768c028df6b9274441ba702cf011 .prettierignore - our 100644 d247d9a68070ec5848c5feb83bddbfab02adbb6c .prettierignore -@@ -1,4 +1,5 @@ - out/ -+out-repro/ - dist/ - node_modules/ - npm-debug.log -added in remote - their 100644 ff5f95e7e6aef0d6f48b7d95d4559da0a46a3ded app/webpack.repro.js -@@ -0,0 +1,27 @@ -+'use strict' -+ -+const path = require('path') -+const webpack = require('webpack') -+const MinifyPlugin = require('babel-minify-webpack-plugin') -+ -+module.exports = { -+ mode: 'none', -+ plugins: [ -+ new MinifyPlugin(), -+ new webpack.DefinePlugin({ -+ 'process.env.NODE_ENV': JSON.stringify('production'), -+ }), -+ new webpack.optimize.ModuleConcatenationPlugin(), -+ new webpack.NoEmitOnErrorsPlugin(), -+ ], -+ entry: './out-repro/ui/lib/author-input.js', -+ target: 'electron-renderer', -+ output: { -+ path: path.resolve(__dirname, '..', 'dist'), -+ filename: 'author-input.bundle.js', -+ }, -+ resolve: { -+ extensions: ['.js', '.ts', '.tsx'], -+ modules: [path.resolve(__dirname, 'node_modules/')], -+ }, -+} -changed in both - base 100644 b4df82455d0dcd44363b8ebb6b2c1d5fc4891d44 package.json - our 100644 2006bfb748810f6ea8bdbd26edf7c09524a1388a package.json - their 100644 02a214a6ad80830c93c0f9878ebd15f965b6d786 package.json -@@ -38,7 +38,10 @@ - "rebuild-hard:prod": "yarn clean-slate && yarn build:prod", - "changelog": "ts-node script/changelog/index.ts", - "draft-release": "ts-node script/draft-release/index.ts", -- "validate-changelog": "ts-node script/validate-changelog.ts" -+ "validate-changelog": "ts-node script/validate-changelog.ts", -+ "build:repro": "tsc -p tsconfig-repro.json", -+ "bundle:repro": "webpack --config app/webpack.repro.js", -+ "minify:repro": "uglifyjs --compress --mangle -o ./out-repro/ui/lib/author-input-after.js -- ./out-repro/ui/lib/author-input.js" - }, - "author": { - "name": "GitHub, Inc.", -@@ -155,7 +158,13 @@ - "electron": "2.0.5", - "electron-builder": "20.27.1", - "electron-mocha": "^6.0.1", -+<<<<<<< .our - "electron-packager": "^12.0.0", - "electron-winstaller": "2.5.2" -+======= -+ "electron-packager": "^11.0.0", -+ "electron-winstaller": "2.5.2", -+ "webpack-cli": "^3.0.2" -+>>>>>>> .their - } - } -added in remote - their 100644 a06dcb5a88dce3efb3c8bd9731550e3c536b863d tsconfig-repro.json -@@ -0,0 +1,26 @@ -+{ -+ "compilerOptions": { -+ "module": "commonjs", -+ "moduleResolution": "node", -+ "target": "es2017", -+ "noImplicitReturns": true, -+ "noFallthroughCasesInSwitch": true, -+ "noUnusedLocals": true, -+ "sourceMap": true, -+ "jsx": "react", -+ "strict": true, -+ "outDir": "./out-repro" -+ }, -+ "include": [ -+ "app/src/lib/globals.d.ts", -+ "app/src/ui/lib/author-input.tsx" -+ ], -+ "exclude": [ -+ "node_modules", -+ "app/node_modules", -+ "dist", -+ "out", -+ "app/src/highlighter" -+ ], -+ "compileOnSave": false -+} -changed in both - base 100644 96d27900c243924d7f9aa7f6ef5b348dcea93af4 yarn.lock - our 100644 45ddb8bf6902bbb22708d844324093dccda26c79 yarn.lock - their 100644 161de194f715ee122925a08b8c35349cd250029d yarn.lock -@@ -218,6 +218,7 @@ - "@types/prop-types" "*" - "@types/react" "*" - -+<<<<<<< .our - "@types/react@*", "@types/react@^16.3.16": - version "16.3.16" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.3.16.tgz#78fc44a90b45701f50c8a7008f733680ba51fc86" -@@ -231,6 +232,11 @@ - "@types/request@^2.0.9": - version "2.0.9" - resolved "https://registry.yarnpkg.com/@types/request/-/request-2.0.9.tgz#125b8a60d8a439e8d87e6d1335c61cccdc18343a" -+======= -+"@types/react@*", "@types/react@16.3.14": -+ version "16.3.14" -+ resolved "https://registry.yarnpkg.com/@types/react/-/react-16.3.14.tgz#f90ac6834de172e13ecca430dcb6814744225d36" -+>>>>>>> .their - dependencies: - "@types/form-data" "*" - "@types/node" "*" -@@ -3582,9 +3588,19 @@ - dependencies: - ini "^1.3.4" - -+<<<<<<< .our - globals@^11.7.0: - version "11.7.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673" -+======= -+global-modules-path@^2.1.0: -+ version "2.1.0" -+ resolved "https://registry.yarnpkg.com/global-modules-path/-/global-modules-path-2.1.0.tgz#923ec524e8726bb0c1a4ed4b8e21e1ff80c88bbb" -+ -+globals@^11.0.1: -+ version "11.0.1" -+ resolved "https://registry.yarnpkg.com/globals/-/globals-11.0.1.tgz#12a87bb010e5154396acc535e1e43fc753b0e5e8" -+>>>>>>> .their - - globals@^9.18.0: - version "9.18.0" -@@ -3949,6 +3965,13 @@ - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" - -+import-local@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" -+ dependencies: -+ pkg-dir "^2.0.0" -+ resolve-cwd "^2.0.0" -+ - imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" -@@ -4008,6 +4031,24 @@ - strip-ansi "^4.0.0" - through "^2.3.6" - -+inquirer@^5.2.0: -+ version "5.2.0" -+ resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-5.2.0.tgz#db350c2b73daca77ff1243962e9f22f099685726" -+ dependencies: -+ ansi-escapes "^3.0.0" -+ chalk "^2.0.0" -+ cli-cursor "^2.1.0" -+ cli-width "^2.0.0" -+ external-editor "^2.1.0" -+ figures "^2.0.0" -+ lodash "^4.3.0" -+ mute-stream "0.0.7" -+ run-async "^2.2.0" -+ rxjs "^5.5.2" -+ string-width "^2.1.0" -+ strip-ansi "^4.0.0" -+ through "^2.3.6" -+ - inquirer@~3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.0.6.tgz#e04aaa9d05b7a3cb9b0f407d04375f0447190347" -@@ -4030,6 +4071,10 @@ - version "1.0.4" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.4.tgz#820cdd588b868ffb191a809506d6c9c8f212b1b0" - -+interpret@^1.1.0: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" -+ - invariant@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" -@@ -6501,10 +6546,20 @@ - version "1.1.0" - resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.1.0.tgz#e5404b81557ef75db6e49c5a72004893fe03e162" - -+resolve-cwd@^2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" -+ dependencies: -+ resolve-from "^3.0.0" -+ - resolve-from@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" - -+resolve-from@^3.0.0: -+ version "3.0.0" -+ resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" -+ - resolve-url@^0.2.1, resolve-url@~0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" -@@ -7178,7 +7233,7 @@ - dependencies: - has-flag "^2.0.0" - --supports-color@^5.3.0: -+supports-color@^5.3.0, supports-color@^5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" - dependencies: -@@ -7200,9 +7255,15 @@ - version "1.0.1" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" - -+<<<<<<< .our - table@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc" -+======= -+table@4.0.2: -+ version "4.0.2" -+ resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" -+>>>>>>> .their - dependencies: - ajv "^6.0.1" - ajv-keywords "^3.0.0" -@@ -7752,6 +7813,10 @@ - version "3.1.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" - -+v8-compile-cache@^2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.0.tgz#526492e35fc616864284700b7043e01baee09f0a" -+ - validate-npm-package-license@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" -@@ -7855,6 +7920,22 @@ - opener "^1.4.3" - ws "^4.0.0" - -+webpack-cli@^3.0.2: -+ version "3.0.2" -+ resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.0.2.tgz#e48c5662aff8ed5aac3db5f82f51d7f32e50459e" -+ dependencies: -+ chalk "^2.4.1" -+ cross-spawn "^6.0.5" -+ enhanced-resolve "^4.0.0" -+ global-modules-path "^2.1.0" -+ import-local "^1.0.0" -+ inquirer "^5.2.0" -+ interpret "^1.1.0" -+ loader-utils "^1.1.0" -+ supports-color "^5.4.0" -+ v8-compile-cache "^2.0.0" -+ yargs "^11.1.0" -+ - webpack-dev-middleware@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.1.3.tgz#8b32aa43da9ae79368c1bf1183f2b6cf5e1f39ed" -@@ -8146,6 +8227,23 @@ - y18n "^3.2.1 || ^4.0.0" - yargs-parser "^10.1.0" - -+yargs@^11.1.0: -+ version "11.1.0" -+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" -+ dependencies: -+ cliui "^4.0.0" -+ decamelize "^1.1.1" -+ find-up "^2.1.0" -+ get-caller-file "^1.0.1" -+ os-locale "^2.0.0" -+ require-directory "^2.1.1" -+ require-main-filename "^1.0.1" -+ set-blocking "^2.0.0" -+ string-width "^2.0.0" -+ which-module "^2.0.0" -+ y18n "^3.2.1" -+ yargs-parser "^9.0.2" -+ - yargs@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" diff --git a/app/test/fixtures/merge-parser/desktop/merge-rework-state-for-repositories-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-rework-state-for-repositories-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 6d4081d7673..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-rework-state-for-repositories-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,886 +0,0 @@ -changed in both - base 100644 0f1f72f03c916f554505d816f73ec3f336ff874a app/src/lib/app-state.ts - our 100644 b30f0fe080d909b81d2fb683ceb8deb365fb0191 app/src/lib/app-state.ts - their 100644 a1faa806de3876ec375b913d275e231a2cbfae41 app/src/lib/app-state.ts -@@ -1,7 +1,11 @@ - import { Account } from '../models/account' - import { CommitIdentity } from '../models/commit-identity' - import { IDiff } from '../models/diff' -+<<<<<<< .our - import { Repository, ILocalRepositoryState } from '../models/repository' -+======= -+import { Repository, IRepositoryListItem } from '../models/repository' -+>>>>>>> .their - - import { Branch, IAheadBehind } from '../models/branch' - import { Tip } from '../models/tip' -@@ -52,6 +56,10 @@ - Difference, - } - -+export interface IRepositoryListState { -+ readonly repositories: ReadonlyArray<IRepositoryListItem> -+} -+ - export type PossibleSelections = - | { - type: SelectionType.Repository -@@ -68,10 +76,15 @@ - /** All of the shared app state. */ - export interface IAppState { - readonly accounts: ReadonlyArray<Account> -+<<<<<<< .our - /** - * The current list of repositories tracked in the application - */ - readonly repositories: ReadonlyArray<Repository | CloningRepository> -+======= -+ -+ readonly repositoryList: IRepositoryListState -+>>>>>>> .their - - /** - * A cache of the latest repository state values, keyed by the repository id -changed in both - base 100644 f7a2f33b4a3e4787f6446ec13c490c0519671b8c app/src/lib/dispatcher/dispatcher.ts - our 100644 5e56c00e713342e76f5ccba040062e322e8c90cb app/src/lib/dispatcher/dispatcher.ts - their 100644 8ff1e93a00d8036ddc4cdfa83b00ac8c15a1d595 app/src/lib/dispatcher/dispatcher.ts -@@ -863,7 +863,7 @@ - const path = (await validatedRepositoryPath(action.path)) || action.path - const state = this.appStore.getState() - let existingRepository = matchExistingRepository( -- state.repositories, -+ state.repositoryList.repositories, - path - ) - -@@ -969,7 +969,7 @@ - branch: string | null - ): Promise<Repository | null> { - const state = this.appStore.getState() -- const repositories = state.repositories -+ const repositories = state.repositoryList.repositories.map(r => r.source) - const existingRepository = repositories.find(r => { - if (r instanceof Repository) { - const gitHubRepository = r.gitHubRepository -changed in both - base 100644 7ade1dfc6be6bbfd8149dfb41a77caded99e26c0 app/src/lib/fuzzy-find.ts - our 100644 fe445459765dc96bdabb09ac7dea1feccc473728 app/src/lib/fuzzy-find.ts - their 100644 b1df8e63b1639dcbfbf7ff42604f96cf5ffa64f7 app/src/lib/fuzzy-find.ts -@@ -1,23 +1,12 @@ - import * as fuzzAldrin from 'fuzzaldrin-plus' - - import { compareDescending } from './compare' -+import { IMatch } from '../models/filter-list' - - function score(str: string, query: string, maxScore: number) { - return fuzzAldrin.score(str, query) / maxScore - } - --export interface IMatches { -- readonly title: ReadonlyArray<number> -- readonly subtitle: ReadonlyArray<number> --} -- --export interface IMatch<T> { -- /** `0 <= score <= 1` */ -- score: number -- item: T -- matches: IMatches --} -- - export type KeyFunction<T> = (item: T) => ReadonlyArray<string> - - export function match<T, _K extends keyof T>( -added in remote - their 100644 6047ec0bc933c874c56ec75db9a2eb0ac54d086f app/src/lib/group-repositories.ts -@@ -0,0 +1,79 @@ -+import { Repository } from '../models/repository' -+import { CloningRepository } from '../models/cloning-repository' -+import { getDotComAPIEndpoint } from './api' -+import { caseInsensitiveCompare } from './compare' -+import { IFilterListGroup, IFilterListItem } from '../models/filter-list' -+ -+export type RepositoryGroupIdentifier = 'github' | 'enterprise' | 'other' -+ -+export type Repositoryish = Repository | CloningRepository -+ -+export interface IRepositoryListItem extends IFilterListItem { -+ readonly text: ReadonlyArray<string> -+ readonly id: string -+ readonly repository: Repositoryish -+ readonly needsDisambiguation: boolean -+} -+ -+export function groupRepositories( -+ repositories: ReadonlyArray<Repositoryish> -+): ReadonlyArray<IFilterListGroup<IRepositoryListItem>> { -+ const grouped = new Map<RepositoryGroupIdentifier, Repositoryish[]>() -+ for (const repository of repositories) { -+ const gitHubRepository = -+ repository instanceof Repository ? repository.gitHubRepository : null -+ let group: RepositoryGroupIdentifier = 'other' -+ if (gitHubRepository) { -+ if (gitHubRepository.endpoint === getDotComAPIEndpoint()) { -+ group = 'github' -+ } else { -+ group = 'enterprise' -+ } -+ } else { -+ group = 'other' -+ } -+ -+ let repositories = grouped.get(group) -+ if (!repositories) { -+ repositories = new Array<Repository>() -+ grouped.set(group, repositories) -+ } -+ -+ repositories.push(repository) -+ } -+ -+ const groups = new Array<IFilterListGroup<IRepositoryListItem>>() -+ -+ const addGroup = (identifier: RepositoryGroupIdentifier) => { -+ const repositories = grouped.get(identifier) -+ if (!repositories || repositories.length === 0) { -+ return -+ } -+ -+ const names = new Map<string, number>() -+ for (const repository of repositories) { -+ const existingCount = names.get(repository.name) || 0 -+ names.set(repository.name, existingCount + 1) -+ } -+ -+ repositories.sort((x, y) => caseInsensitiveCompare(x.name, y.name)) -+ const items: ReadonlyArray<IRepositoryListItem> = repositories.map(r => { -+ const nameCount = names.get(r.name) || 0 -+ return { -+ text: [r.name], -+ id: r.id.toString(), -+ repository: r, -+ needsDisambiguation: nameCount > 1, -+ } -+ }) -+ -+ groups.push({ identifier, items }) -+ } -+ -+ // NB: This ordering reflects the order in the repositories sidebar. -+ addGroup('github') -+ addGroup('enterprise') -+ addGroup('other') -+ -+ return groups -+} -merged - result 100644 cfbc4c3fb41fb4d678e3752e33737434470f4387 app/src/lib/repository-matching.ts - our 100644 320c31614eb7012348f2ae7877bfb5a0b11cf5af app/src/lib/repository-matching.ts -@@ -2,7 +2,7 @@ - import * as Path from 'path' - - import { CloningRepository } from '../models/cloning-repository' --import { Repository } from '../models/repository' -+import { Repository, IRepositoryListItem } from '../models/repository' - import { Account } from '../models/account' - import { IRemote } from '../models/remote' - import { getHTMLURL } from './api' -@@ -77,11 +77,11 @@ - * @param path The path on disk which might be a repository - */ - export function matchExistingRepository( -- repositories: ReadonlyArray<Repository | CloningRepository>, -+ repositories: ReadonlyArray<IRepositoryListItem>, - path: string - ): Repository | CloningRepository | null { - return ( -- repositories.find(r => { -+ repositories.map(r => r.source).find(r => { - if (__WIN32__) { - // Windows is guaranteed to be case-insensitive so we can be a - // bit more accepting. -changed in both - base 100644 cef55da5f79cf3f422447bb55cb4b9e55162076a app/src/lib/stores/app-store.ts - our 100644 1a4e387e4d192d34abfd0621b4b5ebe8cc34d8d1 app/src/lib/stores/app-store.ts - their 100644 26c65eda55acf194df477bfa99e8897daa8eadcf app/src/lib/stores/app-store.ts -@@ -24,7 +24,11 @@ - IDisplayHistory, - ICompareBranch, - ICompareFormUpdate, -+<<<<<<< .our - ICompareToBranch, -+======= -+ IRepositoryListState, -+>>>>>>> .their - } from '../app-state' - import { Account } from '../../models/account' - import { -@@ -544,6 +548,19 @@ - }) - } - -+ private getRepositoryListState(): IRepositoryListState { -+ const allRepos = [ -+ ...this.repositories, -+ ...this.cloningRepositoriesStore.repositories, -+ ] -+ -+ return { -+ repositories: allRepos.map(source => ({ -+ source, -+ })), -+ } -+ } -+ - private getSelectedState(): PossibleSelections | null { - const repository = this.selectedRepository - if (!repository) { -@@ -582,11 +599,15 @@ - public getState(): IAppState { - return { - accounts: this.accounts, -+<<<<<<< .our - repositories: [ - ...this.repositories, - ...this.cloningRepositoriesStore.repositories, - ], - localRepositoryStateLookup: this.localRepositoryStateLookup, -+======= -+ repositoryList: this.getRepositoryListState(), -+>>>>>>> .their - windowState: this.windowState, - windowZoomFactor: this.windowZoomFactor, - appIsFocused: this.appIsFocused, -added in remote - their 100644 471a2bbf7f0b40cfb77f041a5adabb83303b1b51 app/src/models/filter-list.ts -@@ -0,0 +1,41 @@ -+export interface IMatches { -+ readonly title: ReadonlyArray<number> -+ readonly subtitle: ReadonlyArray<number> -+} -+ -+export interface IMatch<T> { -+ /** `0 <= score <= 1` */ -+ score: number -+ item: T -+ matches: IMatches -+} -+ -+/** An item in the filter list. */ -+export interface IFilterListItem { -+ /** The text which represents the item. This is used for filtering. */ -+ readonly text: ReadonlyArray<string> -+ -+ /** A unique identifier for the item. */ -+ readonly id: string -+} -+ -+/** A group of items in the list. */ -+export interface IFilterListGroup<T extends IFilterListItem> { -+ /** The identifier for this group. */ -+ readonly identifier: string -+ -+ /** The items in the group. */ -+ readonly items: ReadonlyArray<T> -+} -+ -+export interface IFlattenedGroup { -+ readonly kind: 'group' -+ readonly identifier: string -+} -+ -+export interface IFlattenedItem<T extends IFilterListItem> { -+ readonly kind: 'item' -+ readonly item: T -+ /** Array of indexes in `item.text` that should be highlighted */ -+ readonly matches: IMatches -+} -changed in both - base 100644 0602a86788419c4d0be13a0de4f8c5ac6b37a368 app/src/models/repository.ts - our 100644 4eb1a58be5e5e17b1a8714be9248b2d332f526e4 app/src/models/repository.ts - their 100644 8593e8a9bf907314361c6157df2fc9fa6f253a45 app/src/models/repository.ts -@@ -1,6 +1,7 @@ - import * as Path from 'path' - - import { GitHubRepository } from './github-repository' -+<<<<<<< .our - import { IAheadBehind } from './branch' - - function getBaseName(path: string): string { -@@ -14,6 +15,9 @@ - - return baseName - } -+======= -+import { CloningRepository } from './cloning-repository' -+>>>>>>> .their - - /** A local repository. */ - export class Repository { -@@ -53,6 +57,7 @@ - } - } - -+<<<<<<< .our - /** - * A snapshot for the local state for a given repository - */ -@@ -76,4 +81,10 @@ - const { gitHubRepository } = repository - - return gitHubRepository !== null ? gitHubRepository.fullName : repository.name -+======= -+export type Repositoryish = Repository | CloningRepository -+ -+export interface IRepositoryListItem { -+ readonly source: Repositoryish -+>>>>>>> .their - } -changed in both - base 100644 dbc99e8d5c3c6d7dd14ee7ba7539b1e57f05757a app/src/ui/app.tsx - our 100644 c38c806e36c237ea70f3cdeee739941530c0c7cd app/src/ui/app.tsx - their 100644 4922d8b238e8e14e03a3228b9f734b88e614dc51 app/src/ui/app.tsx -@@ -87,10 +87,14 @@ - import { UpstreamAlreadyExists } from './upstream-already-exists' - import { DeletePullRequest } from './delete-branch/delete-pull-request-dialog' - import { MergeConflictsWarning } from './merge-conflicts' -+<<<<<<< .our - import { AppTheme } from './app-theme' - import { ApplicationTheme } from './lib/application-theme' - - const MinuteInMilliseconds = 1000 * 60 -+======= -+import { groupRepositories } from '../lib/group-repositories' -+>>>>>>> .their - - /** The interval at which we should check for updates. */ - const UpdateCheckInterval = 1000 * 60 * 60 * 4 -@@ -751,7 +755,7 @@ - const path = (await validatedRepositoryPath(first)) || first - - const existingRepository = matchExistingRepository( -- this.state.repositories, -+ this.state.repositoryList.repositories, - path - ) - -@@ -1412,17 +1416,26 @@ - const externalEditorLabel = this.state.selectedExternalEditor - const shellLabel = this.state.selectedShell - const filterText = this.state.repositoryFilterText -+ -+ const groups = groupRepositories( -+ this.state.repositoryList.repositories.map(r => r.source) -+ ) -+ - return ( - <RepositoriesList - filterText={filterText} - onFilterTextChanged={this.onRepositoryFilterTextChanged} - selectedRepository={selectedRepository} - onSelectionChanged={this.onSelectionChanged} -+<<<<<<< .our - repositories={this.state.repositories} - localRepositoryStateLookup={this.state.localRepositoryStateLookup} - askForConfirmationOnRemoveRepository={ - this.state.askForConfirmationOnRepositoryRemoval - } -+======= -+ groups={groups} -+>>>>>>> .their - onRemoveRepository={this.removeRepository} - onOpenInShell={this.openInShell} - onShowRepository={this.showRepository} -@@ -1482,7 +1495,7 @@ - if (repository) { - icon = iconForRepository(repository) - title = repository.name -- } else if (this.state.repositories.length > 0) { -+ } else if (this.state.repositoryList.repositories.length > 0) { - icon = OcticonSymbol.repo - title = __DARWIN__ ? 'Select a Repository' : 'Select a repository' - } else { -@@ -1668,7 +1681,7 @@ - - private renderRepository() { - const state = this.state -- if (state.repositories.length < 1) { -+ if (state.repositoryList.repositories.length < 1) { - return ( - <BlankSlateView - onCreate={this.showCreateRepository} -merged - result 100644 4dc52d68274ce071386cb34dda8a2f6f17119962 app/src/ui/branches/branch-list-item.tsx - our 100644 474f18ccb67239743953eda7f33488769a615c05 app/src/ui/branches/branch-list-item.tsx -@@ -1,7 +1,7 @@ - import * as React from 'react' - import * as moment from 'moment' - --import { IMatches } from '../../lib/fuzzy-find' -+import { IMatches } from '../../models/filter-list' - - import { Octicon, OcticonSymbol } from '../octicons' - import { HighlightText } from '../lib/highlight-text' -changed in both - base 100644 c6fd907ca55c1ee3575c15a64b60ef898d259ae9 app/src/ui/branches/branch-list.tsx - our 100644 f996cca6bcc1348eedd5f3c852bf8652b60f95aa app/src/ui/branches/branch-list.tsx - their 100644 f7ba834036a39cfdffd1b87d044ee03b0e2e5d1d app/src/ui/branches/branch-list.tsx -@@ -4,12 +4,9 @@ - - import { assertNever } from '../../lib/fatal-error' - --import { -- FilterList, -- IFilterListGroup, -- SelectionSource, --} from '../lib/filter-list' --import { IMatches } from '../../lib/fuzzy-find' -+import { IFilterListGroup, IMatches } from '../../models/filter-list' -+ -+import { FilterList, SelectionSource } from '../lib/filter-list' - import { Button } from '../lib/button' - import { TextBox } from '../lib/text-box' - -merged - result 100644 6da41ab3f7da5b855ce59e6054c4f82b0ae450ae app/src/ui/branches/branch-renderer.tsx - our 100644 dd27f7b0f40a3be55aa8a51cd83f116cf289c7e6 app/src/ui/branches/branch-renderer.tsx -@@ -1,10 +1,10 @@ - import * as React from 'react' - - import { Branch } from '../../models/branch' -+import { IMatches } from '../../models/filter-list' - - import { IBranchListItem } from './group-branches' - import { BranchListItem } from './branch-list-item' --import { IMatches } from '../../lib/fuzzy-find' - - export function renderDefaultBranch( - item: IBranchListItem, -changed in both - base 100644 13f691705648f0b7a0f7303372de8f2db79f3d76 app/src/ui/branches/branches-container.tsx - our 100644 6a5612ae608b20b3a486f139daf4063209bca568 app/src/ui/branches/branches-container.tsx - their 100644 247643b0608b2ae041337ad2e4c558dfc4c49043 app/src/ui/branches/branches-container.tsx -@@ -5,6 +5,7 @@ - import { Repository, nameOf } from '../../models/repository' - import { Branch } from '../../models/branch' - import { BranchesTab } from '../../models/branches-tab' -+import { IMatches } from '../../models/filter-list' - - import { Dispatcher } from '../../lib/dispatcher' - import { FoldoutType, PopupType } from '../../lib/app-state' -@@ -17,7 +18,6 @@ - import { PullRequestsLoading } from './pull-requests-loading' - import { IBranchListItem } from './group-branches' - import { renderDefaultBranch } from './branch-renderer' --import { IMatches } from '../../lib/fuzzy-find' - - const PullRequestsLoadingCrossFadeInTimeout = 300 - const PullRequestsLoadingCrossFadeOutTimeout = 200 -merged - result 100644 2ecee9b32490089b39f44642ef6fca16b7b3ab56 app/src/ui/branches/group-branches.ts - our 100644 f4953500cb984957451e61da094929c0254c811d app/src/ui/branches/group-branches.ts -@@ -1,5 +1,5 @@ - import { Branch } from '../../models/branch' --import { IFilterListGroup, IFilterListItem } from '../lib/filter-list' -+import { IFilterListGroup, IFilterListItem } from '../../models/filter-list' - - export type BranchGroupIdentifier = 'default' | 'recent' | 'other' - -merged - result 100644 4be30f2736a9018e19fc2b105b3514cabc524c6b app/src/ui/branches/pull-request-list-item.tsx - our 100644 075b2904f501296734519cbb19ed658a9f168a05 app/src/ui/branches/pull-request-list-item.tsx -@@ -5,7 +5,7 @@ - import { CIStatus } from './ci-status' - import { PullRequestStatus } from '../../models/pull-request' - import { HighlightText } from '../lib/highlight-text' --import { IMatches } from '../../lib/fuzzy-find' -+import { IMatches } from '../../models/filter-list' - - export interface IPullRequestListItemProps { - /** The title. */ -changed in both - base 100644 ec5384d11e1ccc41654a814bf95443c8159d7c17 app/src/ui/branches/pull-request-list.tsx - our 100644 484112784b83cd0d9be46284b3a1fb1b877894b2 app/src/ui/branches/pull-request-list.tsx - their 100644 d0cb65d04b4ee72da49baed09c132b059f4af620 app/src/ui/branches/pull-request-list.tsx -@@ -1,15 +1,15 @@ - import * as React from 'react' - import * as moment from 'moment' -+ - import { -- FilterList, -+ IMatches, - IFilterListGroup, - IFilterListItem, -- SelectionSource, --} from '../lib/filter-list' -+} from '../../models/filter-list' -+import { FilterList, SelectionSource } from '../lib/filter-list' - import { PullRequestListItem } from './pull-request-list-item' - import { PullRequest, PullRequestStatus } from '../../models/pull-request' - import { NoPullRequests } from './no-pull-requests' --import { IMatches } from '../../lib/fuzzy-find' - - interface IPullRequestListItem extends IFilterListItem { - readonly id: string -changed in both - base 100644 bd003b8166b0069ee40ffc86f2ea9593db202001 app/src/ui/branches/pull-requests-loading.tsx - our 100644 6965fcba858e40dc9bebce9bd3f18f369bde8ae3 app/src/ui/branches/pull-requests-loading.tsx - their 100644 413230dc687126b2536a2c67a32082eda7e06d68 app/src/ui/branches/pull-requests-loading.tsx -@@ -1,5 +1,6 @@ - import * as React from 'react' --import { FilterList, IFilterListItem } from '../lib/filter-list' -+import { IFilterListItem } from '../../models/filter-list' -+import { FilterList } from '../lib/filter-list' - import { - PullRequestListItem, - IPullRequestListItemProps, -merged - result 100644 025849db4722f41ecb84201c726a3cd4986d0235 app/src/ui/clone-repository/clone-github-repository.tsx - our 100644 81bb2d3dc71f42c419af98460238b7063d80badd app/src/ui/clone-repository/clone-github-repository.tsx -@@ -1,6 +1,7 @@ - import * as React from 'react' - - import { Account } from '../../models/account' -+import { IFilterListGroup, IMatches } from '../../models/filter-list' - import { DialogContent } from '../dialog' - import { TextBox } from '../lib/text-box' - import { Row } from '../lib/row' -@@ -9,8 +10,6 @@ - import { Octicon } from '../octicons' - import { FilterList } from '../lib/filter-list' - import { API } from '../../lib/api' --import { IFilterListGroup } from '../lib/filter-list' --import { IMatches } from '../../lib/fuzzy-find' - import { - ICloneableRepositoryListItem, - groupRepositories, -merged - result 100644 409a64070c8e30188cda16fff34d038ffb51b8af app/src/ui/clone-repository/group-repositories.ts - our 100644 b7412f2d5dd94cba15f7a987e719915969a75f6e app/src/ui/clone-repository/group-repositories.ts -@@ -1,5 +1,6 @@ -+import { IFilterListGroup, IFilterListItem } from '../../models/filter-list' -+ - import { IAPIRepository } from '../../lib/api' --import { IFilterListGroup, IFilterListItem } from '../lib/filter-list' - import { caseInsensitiveCompare } from '../../lib/compare' - import { OcticonSymbol } from '../octicons' - -merged - result 100644 314c4e3f15fbb4c493a948f1cc22fcf9a3749879 app/src/ui/history/compare-branch-list-item.tsx - our 100644 16d4efb540d90ba9514f7b5da356f9fa5372e2f6 app/src/ui/history/compare-branch-list-item.tsx -@@ -3,7 +3,7 @@ - import { Octicon, OcticonSymbol } from '../octicons' - import { HighlightText } from '../lib/highlight-text' - import { Branch, IAheadBehind } from '../../models/branch' --import { IMatches } from '../../lib/fuzzy-find' -+import { IMatches } from '../../models/filter-list' - - interface ICompareBranchListItemProps { - readonly branch: Branch -changed in both - base 100644 502863ec0901ae8ebc62d75cd84ee11869f5c653 app/src/ui/history/compare.tsx - our 100644 c0be0e26ce79b9a590edfa3a9fd3718fa58782d4 app/src/ui/history/compare.tsx - their 100644 c5431287ccbdbd63877c1207dc5aad90dedded2b app/src/ui/history/compare.tsx -@@ -3,6 +3,7 @@ - - import { IGitHubUser } from '../../lib/databases' - import { Commit } from '../../models/commit' -+import { IMatches } from '../../models/filter-list' - import { - ComparisonView, - ICompareState, -@@ -22,7 +23,7 @@ - import { FancyTextBox } from '../lib/fancy-text-box' - import { OcticonSymbol } from '../octicons' - import { SelectionSource } from '../lib/filter-list' --import { IMatches } from '../../lib/fuzzy-find' -+ - import { Ref } from '../lib/ref' - import { - NewCommitsBanner, -changed in both - base 100644 c845440dc0449aaf6b81f86a7a77eb0d3d8d1a8f app/src/ui/lib/filter-list.tsx - our 100644 a625bab6249781a07060095fe6306dfd832f032f app/src/ui/lib/filter-list.tsx - their 100644 3646e167d967db370f232beec160c6d9213dafb0 app/src/ui/lib/filter-list.tsx -@@ -8,38 +8,15 @@ - } from '../lib/list' - import { TextBox } from '../lib/text-box' - import { Row } from '../lib/row' -- --import { match, IMatch, IMatches } from '../../lib/fuzzy-find' -- --/** An item in the filter list. */ --export interface IFilterListItem { -- /** The text which represents the item. This is used for filtering. */ -- readonly text: ReadonlyArray<string> -- -- /** A unique identifier for the item. */ -- readonly id: string --} -- --/** A group of items in the list. */ --export interface IFilterListGroup<T extends IFilterListItem> { -- /** The identifier for this group. */ -- readonly identifier: string -- -- /** The items in the group. */ -- readonly items: ReadonlyArray<T> --} -- --interface IFlattenedGroup { -- readonly kind: 'group' -- readonly identifier: string --} -- --interface IFlattenedItem<T extends IFilterListItem> { -- readonly kind: 'item' -- readonly item: T -- /** Array of indexes in `item.text` that should be highlighted */ -- readonly matches: IMatches --} -+import { -+ IFilterListItem, -+ IFlattenedGroup, -+ IFlattenedItem, -+ IFilterListGroup, -+ IMatches, -+ IMatch, -+} from '../../models/filter-list' -+import { match } from '../../lib/fuzzy-find' - - /** - * A row in the list. This is used internally after the user-provided groups are -changed in both - base 100644 b86b84acd2592be32e1e96ba15a6e1c4baa01c61 app/src/ui/merge-branch/merge.tsx - our 100644 6a7e6976257ec16e58a7331db61b40096a9bde08 app/src/ui/merge-branch/merge.tsx - their 100644 1e2ae1fa7934c87eabfdd36fc7ea54af92ba8edf app/src/ui/merge-branch/merge.tsx -@@ -5,6 +5,7 @@ - - import { Branch } from '../../models/branch' - import { Repository } from '../../models/repository' -+import { IMatches } from '../../models/filter-list' - - import { Button } from '../lib/button' - import { ButtonGroup } from '../lib/button-group' -@@ -12,7 +13,6 @@ - import { Dialog, DialogContent, DialogFooter } from '../dialog' - import { BranchList, IBranchListItem, renderDefaultBranch } from '../branches' - import { revSymmetricDifference } from '../../lib/git' --import { IMatches } from '../../lib/fuzzy-find' - - interface IMergeProps { - readonly dispatcher: Dispatcher -removed in remote - base 100644 7d155f75357c2b37aaf547a4502c6db165116cae app/src/ui/repositories-list/group-repositories.ts - our 100644 9e6e38681ef352ce76fa65fea817492a6aef088f app/src/ui/repositories-list/group-repositories.ts -@@ -1,92 +0,0 @@ --import { Repository, ILocalRepositoryState } from '../../models/repository' --import { CloningRepository } from '../../models/cloning-repository' --import { getDotComAPIEndpoint } from '../../lib/api' --import { caseInsensitiveCompare } from '../../lib/compare' --import { IFilterListGroup, IFilterListItem } from '../lib/filter-list' --import { IAheadBehind } from '../../models/branch' -- --export type RepositoryGroupIdentifier = 'github' | 'enterprise' | 'other' -- --export type Repositoryish = Repository | CloningRepository -- --export interface IRepositoryListItem extends IFilterListItem { -- readonly text: ReadonlyArray<string> -- readonly id: string -- readonly repository: Repositoryish -- readonly needsDisambiguation: boolean -- readonly aheadBehind: IAheadBehind | null -- readonly changedFilesCount: number --} -- --const fallbackValue = { -- changedFilesCount: 0, -- aheadBehind: null, --} -- --export function groupRepositories( -- repositories: ReadonlyArray<Repositoryish>, -- localRepositoryStateLookup: Map<number, ILocalRepositoryState> --): ReadonlyArray<IFilterListGroup<IRepositoryListItem>> { -- const grouped = new Map<RepositoryGroupIdentifier, Repositoryish[]>() -- for (const repository of repositories) { -- const gitHubRepository = -- repository instanceof Repository ? repository.gitHubRepository : null -- let group: RepositoryGroupIdentifier = 'other' -- if (gitHubRepository) { -- if (gitHubRepository.endpoint === getDotComAPIEndpoint()) { -- group = 'github' -- } else { -- group = 'enterprise' -- } -- } else { -- group = 'other' -- } -- -- let repositories = grouped.get(group) -- if (!repositories) { -- repositories = new Array<Repository>() -- grouped.set(group, repositories) -- } -- -- repositories.push(repository) -- } -- -- const groups = new Array<IFilterListGroup<IRepositoryListItem>>() -- -- const addGroup = (identifier: RepositoryGroupIdentifier) => { -- const repositories = grouped.get(identifier) -- if (!repositories || repositories.length === 0) { -- return -- } -- -- const names = new Map<string, number>() -- for (const repository of repositories) { -- const existingCount = names.get(repository.name) || 0 -- names.set(repository.name, existingCount + 1) -- } -- -- repositories.sort((x, y) => caseInsensitiveCompare(x.name, y.name)) -- const items: ReadonlyArray<IRepositoryListItem> = repositories.map(r => { -- const nameCount = names.get(r.name) || 0 -- const { aheadBehind, changedFilesCount } = -- localRepositoryStateLookup.get(r.id) || fallbackValue -- return { -- text: [r.name], -- id: r.id.toString(), -- repository: r, -- needsDisambiguation: nameCount > 1, -- aheadBehind, -- changedFilesCount, -- } -- }) -- -- groups.push({ identifier, items }) -- } -- -- // NB: This ordering reflects the order in the repositories sidebar. -- addGroup('github') -- addGroup('enterprise') -- addGroup('other') -- -- return groups --} -changed in both - base 100644 099975495f19aeb0f19adfcacf11a6f51bc6c4d6 app/src/ui/repositories-list/repositories-list.tsx - our 100644 e4ca588b503842ff6df4517d209f5fc5537d4a11 app/src/ui/repositories-list/repositories-list.tsx - their 100644 980b0c986ac78fdb0d6ed17f44fb5bb5ee148d8a app/src/ui/repositories-list/repositories-list.tsx -@@ -1,14 +1,13 @@ - import * as React from 'react' - - import { RepositoryListItem } from './repository-list-item' -+import { Repositoryish } from '../../models/repository' - import { -- groupRepositories, - IRepositoryListItem, -- Repositoryish, - RepositoryGroupIdentifier, --} from './group-repositories' -+} from '../../lib/group-repositories' -+import { IFilterListGroup, IMatches } from '../../models/filter-list' - import { FilterList } from '../lib/filter-list' --import { IMatches } from '../../lib/fuzzy-find' - import { assertNever } from '../../lib/fatal-error' - import { ILocalRepositoryState } from '../../models/repository' - import { enableRepoInfoIndicators } from '../../lib/feature-flag' -@@ -16,7 +15,9 @@ - - interface IRepositoriesListProps { - readonly selectedRepository: Repositoryish | null -- readonly repositories: ReadonlyArray<Repositoryish> -+ -+ /** The grouped repositories to display in the list */ -+ readonly groups: ReadonlyArray<IFilterListGroup<IRepositoryListItem>> - - /** A cache of the latest repository state values, keyed by the repository id */ - readonly localRepositoryStateLookup: Map<number, ILocalRepositoryState> -@@ -119,19 +120,26 @@ - } - - public render() { -- if (this.props.repositories.length < 1) { -+ const repositoryCount = this.props.groups -+ .map(g => g.items.length) -+ .reduce((prev, current) => prev + current) -+ -+ if (repositoryCount < 1) { - return this.noRepositories() - } - -+<<<<<<< .our - const groups = groupRepositories( - this.props.repositories, - this.props.localRepositoryStateLookup - ) - -+======= -+>>>>>>> .their - let selectedItem: IRepositoryListItem | null = null - const selectedRepository = this.props.selectedRepository - if (selectedRepository) { -- for (const group of groups) { -+ for (const group of this.props.groups) { - selectedItem = - group.items.find(i => { - const repository = i.repository -@@ -154,9 +162,9 @@ - renderItem={this.renderItem} - renderGroupHeader={this.renderGroupHeader} - onItemClick={this.onItemClick} -- groups={groups} -+ groups={this.props.groups} - invalidationProps={{ -- repositories: this.props.repositories, -+ groups: this.props.groups, - filterText: this.props.filterText, - }} - /> -changed in both - base 100644 4d6d2718f07e7136c8197bc1c47a8d2bfe8b2d38 app/src/ui/repositories-list/repository-list-item.tsx - our 100644 6ca3c771c795eba242cc4b795e3a3b0bbb4c7488 app/src/ui/repositories-list/repository-list-item.tsx - their 100644 e4a3aa331427b2bbfcb8b6c4f320e528747277c8 app/src/ui/repositories-list/repository-list-item.tsx -@@ -1,12 +1,20 @@ - import * as React from 'react' -+<<<<<<< .our - import { Repository } from '../../models/repository' - import { Octicon, iconForRepository, OcticonSymbol } from '../octicons' -+======= -+import { Repository, Repositoryish } from '../../models/repository' -+import { Octicon, iconForRepository } from '../octicons' -+>>>>>>> .their - import { showContextualMenu } from '../main-process-proxy' --import { Repositoryish } from './group-repositories' - import { IMenuItem } from '../../lib/menu-item' - import { HighlightText } from '../lib/highlight-text' -+<<<<<<< .our - import { IMatches } from '../../lib/fuzzy-find' - import { IAheadBehind } from '../../models/branch' -+======= -+import { IMatches } from '../../models/filter-list' -+>>>>>>> .their - - const defaultEditorLabel = __DARWIN__ - ? 'Open in External Editor' -changed in both - base 100644 bf18722fdca8c3cfe0ee6e56f94440876e888175 app/test/unit/repositories-list-grouping-test.ts - our 100644 8c3c9ac4c1b7875569c8d7d44dec79ca7047423d app/test/unit/repositories-list-grouping-test.ts - their 100644 c01b5360134d88f9326a915d704d5d3ceaef0562 app/test/unit/repositories-list-grouping-test.ts -@@ -1,7 +1,12 @@ - import { expect } from 'chai' - -+<<<<<<< .our - import { groupRepositories } from '../../src/ui/repositories-list/group-repositories' - import { Repository, ILocalRepositoryState } from '../../src/models/repository' -+======= -+import { groupRepositories } from '../../src/lib/group-repositories' -+import { Repository } from '../../src/models/repository' -+>>>>>>> .their - import { GitHubRepository } from '../../src/models/github-repository' - import { Owner } from '../../src/models/owner' - import { getDotComAPIEndpoint } from '../../src/lib/api' diff --git a/app/test/fixtures/merge-parser/desktop/merge-selected-compare-commit-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-selected-compare-commit-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index 7bae36146f4..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-selected-compare-commit-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,402 +0,0 @@ -changed in both - base 100644 86b3c6de0194dc7492ad693937f515e539e85002 app/src/lib/app-state.ts - our 100644 b30f0fe080d909b81d2fb683ceb8deb365fb0191 app/src/lib/app-state.ts - their 100644 3e0e9a02ae5c99656f88283a2e811b94e86d5960 app/src/lib/app-state.ts -@@ -564,8 +564,17 @@ - export interface ICommitSelection { - /** The commit currently selected in the app */ - readonly sha: string | null -+<<<<<<< .our - - /** The list of files associated with the current commit */ -+======= -+ readonly file: CommittedFileChange | null -+} -+ -+export interface IHistoryState { -+ readonly selection: IHistorySelection -+ -+>>>>>>> .their - readonly changedFiles: ReadonlyArray<CommittedFileChange> - - /** The selected file inside the selected commit */ -@@ -623,6 +632,11 @@ - */ - export interface IDisplayHistory { - readonly kind: ComparisonView.None -+ -+ readonly selectedCommitSHA: string | null -+ -+ /** The SHAs of commits to render in the list */ -+ readonly commitSHAs: ReadonlyArray<string> - } - - /** -@@ -638,12 +652,18 @@ - - /** The number of commits the selected branch is ahead/behind the current branch */ - readonly aheadBehind: IAheadBehind -+ -+ readonly selectedCommitSHA: string | null -+ -+ /** The SHAs of commits to render in the list */ -+ readonly commitSHAs: ReadonlyArray<string> - } - - export interface ICompareState { - /** The current state of the compare form, based on user input */ - readonly formState: IDisplayHistory | ICompareBranch - -+<<<<<<< .our - /** Whether the branch list should be expanded or hidden */ - readonly showBranchList: boolean - -@@ -653,6 +673,8 @@ - /** The SHAs of commits to render in the compare list */ - readonly commitSHAs: ReadonlyArray<string> - -+======= -+>>>>>>> .their - /** A list of all branches (remote and local) currently in the repository. */ - readonly allBranches: ReadonlyArray<Branch> - -changed in both - base 100644 7660f27c9fa483bd947f1ffde2576ef075b5cf1b app/src/lib/dispatcher/dispatcher.ts - our 100644 5e56c00e713342e76f5ccba040062e322e8c90cb app/src/lib/dispatcher/dispatcher.ts - their 100644 69eeff384875a8663ab57a5a84ebdb207b5f7795 app/src/lib/dispatcher/dispatcher.ts -@@ -148,6 +148,13 @@ - return this.appStore._changeCommitSelection(repository, sha) - } - -+ public changeCompareCommitSelection( -+ repository: Repository, -+ sha: string -+ ): Promise<void> { -+ return this.appStore._changeCompareCommitSelection(repository, sha) -+ } -+ - /** - * Change the selected changed file in the history view. - * -changed in both - base 100644 913f0d9877d9d1681da13a02004091689e826c67 app/src/lib/stores/app-store.ts - our 100644 1a4e387e4d192d34abfd0621b4b5ebe8cc34d8d1 app/src/lib/stores/app-store.ts - their 100644 b6383b0080b772a8e9b61fe679fdbe0912f9e93b app/src/lib/stores/app-store.ts -@@ -461,10 +461,18 @@ - isLoadingPullRequests: false, - }, - compareState: { -+<<<<<<< .our - formState: { kind: ComparisonView.None }, - showBranchList: false, - filterText: '', - commitSHAs: [], -+======= -+ formState: { -+ kind: ComparisonView.None, -+ selectedCommitSHA: null, -+ commitSHAs: [], -+ }, -+>>>>>>> .their - aheadBehindCache: new ComparisonCache(), - allBranches: new Array<Branch>(), - recentBranches: new Array<Branch>(), -@@ -617,6 +625,21 @@ - } - - private onGitStoreUpdated(repository: Repository, gitStore: GitStore) { -+<<<<<<< .our -+======= -+ this.updateCompareState(repository, state => { -+ if (state.formState.kind === ComparisonView.None) { -+ return { -+ formState: { ...state.formState, commitSHAs: gitStore.history }, -+ } -+ } -+ -+ // TODO: This is a workaround for Pick<T> expecting at least one -+ // property, it's ugly and there has to be a workaround for it. -+ return { formState: state.formState } -+ }) -+ -+>>>>>>> .their - this.updateBranchesState(repository, state => ({ - tip: gitStore.tip, - defaultBranch: gitStore.defaultBranch, -@@ -700,6 +723,7 @@ - } - - /** This shouldn't be called directly. See `Dispatcher`. */ -+<<<<<<< .our - public async _changeCommitSelection( - repository: Repository, - sha: string -@@ -730,12 +754,35 @@ - // -> clear the selection in the app state - selectedSHA = null - this.clearSelectedCommit(repository) -+======= -+ public async _loadHistory(repository: Repository): Promise<void> { -+ const gitStore = this.getGitStore(repository) -+ await gitStore.loadHistory() -+ -+ const state = this.getRepositoryState(repository).compareState -+ -+ if (state.formState.kind === ComparisonView.None) { -+ const { commitSHAs } = state.formState -+ let selectedSHA = state.formState.selectedCommitSHA -+ if (selectedSHA) { -+ const index = commitSHAs.findIndex(sha => sha === selectedSHA) -+ // Our selected SHA disappeared, so clear the selection. -+ if (index < 0) { -+ selectedSHA = null -+ } -+>>>>>>> .their - } -- } - -+<<<<<<< .our - if (selectedSHA == null && commitSHAs.length > 0) { - this._changeCommitSelection(repository, commitSHAs[0]) - this._loadChangedFilesForCurrentSelection(repository) -+======= -+ if (selectedSHA === null && commitSHAs.length > 0) { -+ this._changeHistoryCommitSelection(repository, commitSHAs[0]) -+ this._loadChangedFilesForCurrentSelection(repository) -+ } -+>>>>>>> .their - } - } - -@@ -871,20 +918,30 @@ - const kind = action.kind - - if (action.kind === CompareActionKind.History) { -+<<<<<<< .our - // load initial group of commits for current branch - const commits = await gitStore.loadCommitBatch('HEAD') - - if (commits === null) { - return - } -+======= -+ await gitStore.loadHistory() -+ const commits = gitStore.history -+>>>>>>> .their - - this.updateCompareState(repository, () => ({ - formState: { - kind: ComparisonView.None, -+ selectedCommitSHA: commits.length ? commits[0] : null, -+ commitSHAs: commits, - }, -+<<<<<<< .our - commitSHAs: commits, - filterText: '', - showBranchList: false, -+======= -+>>>>>>> .their - })) - this.updateOrSelectFirstCommit(repository, commits) - -@@ -939,7 +996,21 @@ - commitSHAs, - })) - -+<<<<<<< .our - const tip = gitStore.tip -+======= -+ if (compare !== null) { -+ const commits = compare.commits.map(commit => commit.sha) -+ this.updateCompareState(repository, s => ({ -+ formState: { -+ comparisonBranch, -+ kind: action.mode, -+ selectedCommitSHA: commits.length ? commits[0] : null, -+ aheadBehind: { ahead: compare.ahead, behind: compare.behind }, -+ commitSHAs: commits, -+ }, -+ })) -+>>>>>>> .their - - let currentSha: string | null = null - -@@ -1079,6 +1150,40 @@ - } - - /** This shouldn't be called directly. See `Dispatcher`. */ -+<<<<<<< .our -+======= -+ public async _changeHistoryCommitSelection( -+ repository: Repository, -+ sha: string -+ ): Promise<void> { -+ this.updateHistoryState(repository, state => { -+ const commitChanged = state.selection.sha !== sha -+ const changedFiles = commitChanged -+ ? new Array<CommittedFileChange>() -+ : state.changedFiles -+ const file = commitChanged ? null : state.selection.file -+ const selection = { sha, file } -+ const diff = null -+ -+ return { selection, changedFiles, diff } -+ }) -+ this.emitUpdate() -+ } -+ -+ /** This shouldn't be called directly. See `Dispatcher`. */ -+ public async _changeCompareCommitSelection( -+ repository: Repository, -+ sha: string -+ ): Promise<void> { -+ this.updateCompareState(repository, state => { -+ const newFormState = { ...state.formState, selectedCommitSHA: sha } -+ return { formState: newFormState } -+ }) -+ this.emitUpdate() -+ } -+ -+ /** This shouldn't be called directly. See `Dispatcher`. */ -+>>>>>>> .their - public async _setRepositoryFilterText(text: string): Promise<void> { - this.repositoryFilterText = text - this.emitUpdate() -changed in both - base 100644 2bb0d1e69b6e6acc7bc7b9b7b8cd79ba486625a8 app/src/ui/history/compare.tsx - our 100644 c0be0e26ce79b9a590edfa3a9fd3718fa58782d4 app/src/ui/history/compare.tsx - their 100644 cc767f0ad425e2a97efa57513e52ccda7536bd31 app/src/ui/history/compare.tsx -@@ -53,12 +53,17 @@ - * For all other cases, use the prop - */ - readonly focusedBranch: Branch | null -+<<<<<<< .our - - /** - * Flag that tracks whether the user interacted with one of the notification's - * "call to action" buttons - */ - readonly hasConsumedNotification: boolean -+======= -+ readonly filterText: string -+ readonly showBranchList: boolean -+>>>>>>> .their - } - - /** If we're within this many rows from the bottom, load the next history batch. */ -@@ -79,7 +84,12 @@ - - this.state = { - focusedBranch: null, -+<<<<<<< .our - hasConsumedNotification: false, -+======= -+ filterText: '', -+ showBranchList: false, -+>>>>>>> .their - } - } - -@@ -238,7 +248,13 @@ - } - - private renderCommitList() { -+<<<<<<< .our - const { formState, commitSHAs } = this.props.compareState -+======= -+ const compareState = this.props.compareState -+ const { formState } = compareState -+ const { commitSHAs, selectedCommitSHA } = formState -+>>>>>>> .their - - let emptyListMessage: string | JSX.Element - if (formState.kind === ComparisonView.None) { -@@ -265,7 +281,11 @@ - gitHubRepository={this.props.repository.gitHubRepository} - commitLookup={this.props.commitLookup} - commitSHAs={commitSHAs} -+<<<<<<< .our - selectedSHA={this.props.selectedCommitSha} -+======= -+ selectedSHA={selectedCommitSHA} -+>>>>>>> .their - gitHubUsers={this.props.gitHubUsers} - localCommitSHAs={this.props.localCommitSHAs} - emoji={this.props.emoji} -@@ -447,6 +467,11 @@ - commit.sha - ) - -+ this.props.dispatcher.changeCompareCommitSelection( -+ this.props.repository, -+ commit.sha -+ ) -+ - this.loadChangedFilesScheduler.queue(() => { - this.props.dispatcher.loadChangedFilesForCurrentSelection( - this.props.repository -@@ -464,7 +489,7 @@ - return - } - -- const commits = compareState.commitSHAs -+ const commits = compareState.formState.commitSHAs - if (commits.length - end <= CloseToBottomThreshold) { - if (this.loadingMoreCommitsPromise != null) { - // as this callback fires for any scroll event we need to guard -removed in local - base 100644 0f7ba2c51eb72711ce866811c1cdf6ec2a641439 app/src/ui/history/sidebar.tsx - their 100644 0dde562e164abfa27a4dd7bf40a08af7f7a4eb54 app/src/ui/history/sidebar.tsx -changed in both - base 100644 2fe9280cbce5add68c32917de0f29293a5c1f684 app/src/ui/repository.tsx - our 100644 efb00423012b8da0dfa5e8897acacaeb0a5e648a app/src/ui/repository.tsx - their 100644 9d3ba9d30a822ca2f1cd262769b0e7e7af5e34a1 app/src/ui/repository.tsx -@@ -14,6 +14,7 @@ - IRepositoryState, - RepositorySectionTab, - ImageDiffType, -+ ComparisonView, - } from '../lib/app-state' - import { Dispatcher } from '../lib/dispatcher' - import { IssuesStore, GitHubUserStore } from '../lib/stores' -@@ -156,6 +157,31 @@ - ) - } - -+<<<<<<< .our -+======= -+ private renderHistorySidebar(): JSX.Element | null { -+ const formState = this.props.state.compareState.formState -+ -+ if (formState.kind !== ComparisonView.None) { -+ return null -+ } -+ -+ return ( -+ <HistorySidebar -+ repository={this.props.repository} -+ dispatcher={this.props.dispatcher} -+ history={formState} -+ gitHubUsers={this.props.state.gitHubUsers} -+ emoji={this.props.emoji} -+ commitLookup={this.props.state.commitLookup} -+ localCommitSHAs={this.props.state.localCommitSHAs} -+ onRevertCommit={this.onRevertCommit} -+ onViewCommitOnGitHub={this.props.onViewCommitOnGitHub} -+ /> -+ ) -+ } -+ -+>>>>>>> .their - private renderCompareSidebar(): JSX.Element { - const tip = this.props.state.branchesState.tip - const currentBranch = tip.kind === TipState.Valid ? tip.branch : null -@@ -180,7 +206,7 @@ - ) - } - -- private renderSidebarContents(): JSX.Element { -+ private renderSidebarContents(): JSX.Element | null { - const selectedSection = this.props.state.selectedSection - - if (selectedSection === RepositorySectionTab.Changes) { diff --git a/app/test/fixtures/merge-parser/desktop/merge-selenium-desktop-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-selenium-desktop-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index de24eaa4779..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-selenium-desktop-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,894 +0,0 @@ -removed in local - base 100644 5602d04593bc047d4920549bc1db59981d58b263 .github/ISSUE_TEMPLATE/feature_request.md - their 100644 9ac98a9ec52032212c8b2611bbcb688d0f7e6e58 .github/ISSUE_TEMPLATE/feature_request.md -added in remote - their 100644 d8f838babad858136432a79366d352f0613ee017 app/test/integration/selenium-launch.ts -@@ -0,0 +1,73 @@ -+import { expect } from 'chai' -+ -+import * as webdriver from 'selenium-webdriver' -+const { findElement, getText, click } = require('selenium-adapter') -+ -+// SETUP -+// 0. yarn install -+// 1. find your desktop binary and update variable below (const DESKTOP_BINARY_LOCATION, ~L22) -+// 2. change the test's `expect` to equal the name of your first repo in the repo list dropdown (~L53) -+// 3. make sure you're not running Desktop any more -+// 4. run: `$ yarn test:selenium` -+ -+// NOTE -+// * i might migrate to puppeteer for fun -+// * selenium-adapter is from a friend's repo (vinsonchuong on github), not needed but it's nice to have around -+ -+const WAIT_BEFORE_OPEN = 1 // will not scale well! we should do a wait until for a title to appear -+const WAIT_BEFORE_CLOSE = 0 // in case you want to inspect as you're testing before you lose your spot -+ -+// NOTE!!! you must locate your desktop app's binary that you want to use. eventually we'll have URL -+// from central to download, setup, and run tests on (especially if we want this in CI) -+const DESKTOP_BINARY_LOCATION = -+ '/Applications/GitHub Desktop.app/Contents/MacOS/GitHub Desktop' // change this according to your machine -+ -+async function openDesktop() { -+ const driver = await new webdriver.Builder() -+ .usingServer('http://localhost:9515') -+ .withCapabilities({ -+ chromeOptions: { binary: DESKTOP_BINARY_LOCATION }, -+ }) -+ .forBrowser('electron') -+ .build() -+ -+ await driver.sleep(WAIT_BEFORE_OPEN * 1000) -+ return driver -+} -+ -+async function closeDesktop(driver: webdriver.WebDriver) { -+ await driver.sleep(WAIT_BEFORE_CLOSE * 1000) -+ await driver.quit() -+} -+ -+describe('Repository Dropdown', () => { -+ it('can show repository names', async () => { -+ // BEFORE EACH (eventually pull out to actual `beforeEach`) -+ // note: challenge is getting the driver and passing it into each test; especially if we paralellize -+ const driver = await openDesktop() -+ -+ // TEST -+ await openDropdown(driver) -+ const repositoryItemText = await getFirstRepository(driver) -+ -+ expect(repositoryItemText).to.equal('adacats') // customized to first repo on *my computer* -+ -+ // AFTER EACH (eventually pull out to actual `afterEach`) -+ await closeDesktop(driver) -+ }) -+}) -+ -+async function openDropdown(driver: webdriver.WebDriver) { -+ const repositoryDropdown = await findElement(driver, '.button-component') -+ await click(repositoryDropdown) -+ -+ await driver.sleep(WAIT_BEFORE_OPEN * 1000) // hacky fix. needs better solution. will not work well on CI -+} -+ -+async function getFirstRepository(driver: webdriver.WebDriver) { -+ const repositoryDropdownElement = await findElement( -+ driver, -+ '.repository-list-item' -+ ) -+ return await getText(repositoryDropdownElement) -+} -changed in both - base 100644 25df97959715b124e8108bef0b086939d7e328c9 package.json - our 100644 2006bfb748810f6ea8bdbd26edf7c09524a1388a package.json - their 100644 878c5eae6149d86b6e830469f870b352f98b4861 package.json -@@ -5,7 +5,12 @@ - }, - "description": "GitHub Desktop build dependencies", - "scripts": { -+<<<<<<< .our - "cli": "ts-node --require ./app/test/globals.ts --require ./app/src/cli/dev-commands-global.ts app/src/cli/main.ts", -+======= -+ "cli": "ts-node --require ./app/test/globals.ts --require ./app/src/cli/dev-commands-global.js app/src/cli/main.ts", -+ "test:selenium": "./node_modules/.bin/chromedriver & yarn mocha -t 30000 --require ts-node/register app/test/integration/selenium-launch.ts", -+>>>>>>> .their - "test:integration": "cross-env TEST_ENV=1 ELECTRON_NO_ATTACH_CONSOLE=1 xvfb-maybe --auto-servernum -- mocha -t 30000 --require ts-node/register app/test/integration/*.ts", - "test:unit": "ts-node script/unit-tests.ts", - "test:script": "mocha -t 10000 --require ts-node/register script/changelog/test/*.ts", -@@ -136,7 +141,11 @@ - "@types/react-dom": "^16.0.5", - "@types/react-transition-group": "1.1.1", - "@types/react-virtualized": "^9.7.12", -+<<<<<<< .our - "@types/request": "^2.0.9", -+======= -+ "@types/selenium-webdriver": "^3.0.8", -+>>>>>>> .their - "@types/semver": "^5.5.0", - "@types/strip-ansi": "^3.0.0", - "@types/temp": "^0.8.29", -@@ -152,10 +161,21 @@ - "@types/webpack-merge": "^4.1.3", - "@types/winston": "^2.2.0", - "@types/xml2js": "^0.4.0", -+<<<<<<< .our - "electron": "2.0.5", - "electron-builder": "20.27.1", - "electron-mocha": "^6.0.1", - "electron-packager": "^12.0.0", - "electron-winstaller": "2.5.2" -+======= -+ "electron": "1.8.3", -+ "electron-builder": "20.2.0", -+ "electron-chromedriver": "^2.0.0", -+ "electron-mocha": "^6.0.1", -+ "electron-packager": "^11.0.0", -+ "electron-winstaller": "2.5.2", -+ "selenium-adapter": "^0.2.7", -+ "selenium-webdriver": "^4.0.0-alpha.1" -+>>>>>>> .their - } - } -changed in both - base 100644 3a75632078d5f75640a371d3287e6a15a9e8f3ac yarn.lock - our 100644 45ddb8bf6902bbb22708d844324093dccda26c79 yarn.lock - their 100644 b2869f6a4030fa90f7e8d13b345a0842fa9824b9 yarn.lock -@@ -235,6 +235,10 @@ - "@types/form-data" "*" - "@types/node" "*" - -+"@types/selenium-webdriver@^3.0.8": -+ version "3.0.8" -+ resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-3.0.8.tgz#83de9dd7aaf25f7fbd967c0d4fcc8112746dbf31" -+ - "@types/semver@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45" -@@ -499,9 +503,23 @@ - version "5.5.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" - -+<<<<<<< .our - ajv-keywords@^3.0.0, ajv-keywords@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" -+======= -+adm-zip@0.4.7: -+ version "0.4.7" -+ resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.7.tgz#8606c2cbf1c426ce8c8ec00174447fd49b6eafc1" -+ -+ajv-keywords@^1.1.1: -+ version "1.5.1" -+ resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" -+ -+ajv-keywords@^2.0.0, ajv-keywords@^2.1.0: -+ version "2.1.1" -+ resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" -+>>>>>>> .their - - ajv-keywords@^3.1.0: - version "3.1.0" -@@ -1293,7 +1311,15 @@ - dependencies: - bluebird "^3.5.1" - -+<<<<<<< .our - bluebird@^3.0.6, bluebird@^3.1.1, bluebird@^3.3.4, bluebird@^3.5.0, bluebird@^3.5.1: -+======= -+bluebird@3.4.6: -+ version "3.4.6" -+ resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.6.tgz#01da8d821d87813d158967e743d5fe6c62cf8c0f" -+ -+bluebird@^3.0.6, bluebird@^3.1.1, bluebird@^3.3.4, bluebird@^3.4.7, bluebird@^3.5.0, bluebird@^3.5.1: -+>>>>>>> .their - version "3.5.1" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" - -@@ -1301,6 +1327,10 @@ - version "4.11.8" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" - -+bo-selector@0.0.10: -+ version "0.0.10" -+ resolved "https://registry.yarnpkg.com/bo-selector/-/bo-selector-0.0.10.tgz#9816dcb00adf374ea87941a863b2acfc026afa3e" -+ - body-parser@1.18.2: - version "1.18.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454" -@@ -1724,6 +1754,20 @@ - version "0.1.3" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-0.1.3.tgz#d395af2d31c87b90a716c831fe326f69768ec084" - -+chownr@^1.0.1: -+ version "1.0.1" -+ resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" -+ -+chromedriver@^2.32.3: -+ version "2.38.3" -+ resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-2.38.3.tgz#a432a254bc9ed1faa6edfa67cf5d1135aa2468d6" -+ dependencies: -+ del "^3.0.0" -+ extract-zip "^1.6.6" -+ kew "^0.7.0" -+ mkdirp "^0.5.1" -+ request "^2.85.0" -+ - chromium-pickle-js@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/chromium-pickle-js/-/chromium-pickle-js-0.1.0.tgz#1d48b107d82126a2f3e211c2ea25f803ba551b21" -@@ -2018,6 +2062,10 @@ - version "2.5.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" - -+core-js@~2.3.0: -+ version "2.3.0" -+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.3.0.tgz#fab83fbb0b2d8dc85fa636c4b9d34c75420c6d65" -+ - core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" -@@ -2040,7 +2088,7 @@ - bn.js "^4.1.0" - elliptic "^6.0.0" - --create-error-class@^3.0.0: -+create-error-class@^3.0.0, create-error-class@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" - dependencies: -@@ -2179,6 +2227,13 @@ - fastparse "^1.1.1" - regexpu-core "^1.0.0" - -+css-to-xpath@^0.1.0: -+ version "0.1.0" -+ resolved "https://registry.yarnpkg.com/css-to-xpath/-/css-to-xpath-0.1.0.tgz#ac0d1c26cef023f7bd8cf2e1fc1f77134bc70c47" -+ dependencies: -+ bo-selector "0.0.10" -+ xpath-builder "0.0.7" -+ - css-value@~0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/css-value/-/css-value-0.0.1.tgz#5efd6c2eea5ea1fd6b6ac57ec0427b18452424ea" -@@ -2378,6 +2433,17 @@ - pinkie-promise "^2.0.0" - rimraf "^2.2.8" - -+del@^3.0.0: -+ version "3.0.0" -+ resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5" -+ dependencies: -+ globby "^6.1.0" -+ is-path-cwd "^1.0.0" -+ is-path-in-cwd "^1.0.0" -+ p-map "^1.1.1" -+ pify "^3.0.0" -+ rimraf "^2.2.8" -+ - delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" -@@ -2525,6 +2591,12 @@ - version "6.0.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.0.0.tgz#24e37c041741c5f4b25324958ebbc34bca965935" - -+duplexer2@^0.1.4: -+ version "0.1.4" -+ resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" -+ dependencies: -+ readable-stream "^2.0.2" -+ - duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" -@@ -2582,6 +2654,13 @@ - update-notifier "^2.5.0" - yargs "^12.0.1" - -+electron-chromedriver@^2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/electron-chromedriver/-/electron-chromedriver-2.0.0.tgz#e63d7f53716e15a5861d691ace522b5c82c186b0" -+ dependencies: -+ electron-download "^4.1.0" -+ extract-zip "^1.6.5" -+ - electron-chromedriver@~1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/electron-chromedriver/-/electron-chromedriver-1.8.0.tgz#901714133cf6f6093d365e1f44a52d99624d8241" -@@ -2818,10 +2897,47 @@ - version "4.2.4" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29" - -+es6-promise@^4.0.3: -+ version "4.2.4" -+ resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29" -+ - es6-promise@^4.0.5: - version "4.1.1" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.1.1.tgz#8811e90915d9a0dba36274f0b242dbda78f9c92a" - -+<<<<<<< .our -+======= -+es6-promise@~3.0.2: -+ version "3.0.2" -+ resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.0.2.tgz#010d5858423a5f118979665f46486a95c6ee2bb6" -+ -+es6-set@~0.1.5: -+ version "0.1.5" -+ resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" -+ dependencies: -+ d "1" -+ es5-ext "~0.10.14" -+ es6-iterator "~2.0.1" -+ es6-symbol "3.1.1" -+ event-emitter "~0.3.5" -+ -+es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1: -+ version "3.1.1" -+ resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" -+ dependencies: -+ d "1" -+ es5-ext "~0.10.14" -+ -+es6-weak-map@^2.0.1: -+ version "2.0.2" -+ resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" -+ dependencies: -+ d "1" -+ es5-ext "^0.10.14" -+ es6-iterator "^2.0.1" -+ es6-symbol "^3.1.1" -+ -+>>>>>>> .their - escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" -@@ -3139,7 +3255,20 @@ - snapdragon "^0.8.1" - to-regex "^3.0.1" - -+<<<<<<< .our - extract-zip@^1.0.3, extract-zip@^1.6.5: -+======= -+extract-text-webpack-plugin@^3.0.0: -+ version "3.0.2" -+ resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz#5f043eaa02f9750a9258b78c0a6e0dc1408fb2f7" -+ dependencies: -+ async "^2.4.1" -+ loader-utils "^1.1.0" -+ schema-utils "^0.3.0" -+ webpack-sources "^1.0.1" -+ -+extract-zip@^1.0.3, extract-zip@^1.6.5, extract-zip@^1.6.6: -+>>>>>>> .their - version "1.6.6" - resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.6.tgz#1290ede8d20d0872b429fd3f351ca128ec5ef85c" - dependencies: -@@ -3499,6 +3628,15 @@ - dependencies: - globule "^1.0.0" - -+geckodriver@^1.9.0: -+ version "1.11.0" -+ resolved "https://registry.yarnpkg.com/geckodriver/-/geckodriver-1.11.0.tgz#2853ccd4f420d347c61542daeed782c87a718687" -+ dependencies: -+ adm-zip "0.4.7" -+ bluebird "3.4.6" -+ got "5.6.0" -+ tar "4.0.2" -+ - generate-function@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" -@@ -3601,6 +3739,16 @@ - pify "^2.0.0" - pinkie-promise "^2.0.0" - -+globby@^6.1.0: -+ version "6.1.0" -+ resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" -+ dependencies: -+ array-union "^1.0.1" -+ glob "^7.0.3" -+ object-assign "^4.0.1" -+ pify "^2.0.0" -+ pinkie-promise "^2.0.0" -+ - globule@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.0.tgz#1dc49c6822dd9e8a2fa00ba2a295006e8664bd09" -@@ -3609,6 +3757,27 @@ - lodash "~4.17.4" - minimatch "~3.0.2" - -+got@5.6.0: -+ version "5.6.0" -+ resolved "https://registry.yarnpkg.com/got/-/got-5.6.0.tgz#bb1d7ee163b78082bbc8eb836f3f395004ea6fbf" -+ dependencies: -+ create-error-class "^3.0.1" -+ duplexer2 "^0.1.4" -+ is-plain-obj "^1.0.0" -+ is-redirect "^1.0.0" -+ is-retry-allowed "^1.0.0" -+ is-stream "^1.0.0" -+ lowercase-keys "^1.0.0" -+ node-status-codes "^1.0.0" -+ object-assign "^4.0.1" -+ parse-json "^2.1.0" -+ pinkie-promise "^2.0.0" -+ read-all-stream "^3.0.0" -+ readable-stream "^2.0.5" -+ timed-out "^2.0.0" -+ unzip-response "^1.0.0" -+ url-parse-lax "^1.0.0" -+ - got@^6.7.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" -@@ -3763,7 +3932,11 @@ - is-stream "^1.0.1" - pinkie-promise "^2.0.0" - -+<<<<<<< .our - hawk@~3.1.3: -+======= -+hawk@3.1.3, hawk@~3.1.3: -+>>>>>>> .their - version "3.1.3" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" - dependencies: -@@ -3945,6 +4118,10 @@ - version "4.0.3" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.3.tgz#e2d58c9654d75b542529fa28d80ac95b29e4f467" - -+immediate@~3.0.5: -+ version "3.0.6" -+ resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" -+ - import-lazy@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" -@@ -4508,10 +4685,32 @@ - dependencies: - array-includes "^3.0.3" - -+<<<<<<< .our -+kew@^0.7.0: -+ version "0.7.0" -+ resolved "https://registry.yarnpkg.com/kew/-/kew-0.7.0.tgz#79d93d2d33363d6fdd2970b335d9141ad591d79b" -+======= -+jszip@^3.1.3: -+ version "3.1.5" -+ resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.1.5.tgz#e3c2a6c6d706ac6e603314036d43cd40beefdf37" -+ dependencies: -+ core-js "~2.3.0" -+ es6-promise "~3.0.2" -+ lie "~3.1.0" -+ pako "~1.0.2" -+ readable-stream "~2.0.6" -+ - kew@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/kew/-/kew-0.7.0.tgz#79d93d2d33363d6fdd2970b335d9141ad591d79b" - -+kind-of@^2.0.1: -+ version "2.0.1" -+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-2.0.1.tgz#018ec7a4ce7e3a86cb9141be519d24c8faa981b5" -+ dependencies: -+ is-buffer "^1.0.2" -+>>>>>>> .their -+ - kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" -@@ -4594,6 +4793,12 @@ - prelude-ls "~1.1.2" - type-check "~0.3.2" - -+lie@~3.1.0: -+ version "3.1.1" -+ resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" -+ dependencies: -+ immediate "~3.0.5" -+ - load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" -@@ -4947,19 +5152,30 @@ - version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - -+<<<<<<< .our - minipass@^2.2.1, minipass@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.2.4.tgz#03c824d84551ec38a8d1bb5bc350a5a30a354a40" -+======= -+minipass@^2.2.1: -+ version "2.3.0" -+ resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.0.tgz#2e11b1c46df7fe7f1afbe9a490280add21ffe384" -+>>>>>>> .their - dependencies: - safe-buffer "^5.1.1" - yallist "^3.0.0" - -+<<<<<<< .our - minizlib@^1.1.0: -+======= -+minizlib@^1.0.4: -+>>>>>>> .their - version "1.1.0" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" - dependencies: - minipass "^2.2.1" - -+<<<<<<< .our - mississippi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-2.0.0.tgz#3442a508fafc28500486feea99409676e4ee5a6f" -@@ -4975,6 +5191,8 @@ - stream-each "^1.1.0" - through2 "^2.0.0" - -+======= -+>>>>>>> .their - mixin-deep@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.2.0.tgz#d02b8c6f8b6d4b8f5982d3fd009c4919851c3fe2" -@@ -5201,6 +5419,10 @@ - stdout-stream "^1.4.0" - "true-case-path" "^1.0.2" - -+node-status-codes@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/node-status-codes/-/node-status-codes-1.0.0.tgz#5ae5541d024645d32a58fcddc9ceecea7ae3ac2f" -+ - nodeify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/nodeify/-/nodeify-1.0.1.tgz#64ab69a7bdbaf03ce107b4f0335c87c0b9e91b1d" -@@ -5453,6 +5675,7 @@ - dependencies: - p-limit "^1.1.0" - -+<<<<<<< .our - p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" -@@ -5462,6 +5685,11 @@ - p-try@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" -+======= -+p-map@^1.1.1: -+ version "1.2.0" -+ resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" -+>>>>>>> .their - - package-json@^4.0.0: - version "4.0.1" -@@ -5476,6 +5704,7 @@ - version "0.2.9" - resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" - -+<<<<<<< .our - parallel-transform@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" -@@ -5487,6 +5716,15 @@ - parallel-webpack@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/parallel-webpack/-/parallel-webpack-2.3.0.tgz#a614625e25647cea9655918cb80cf829fa674ff8" -+======= -+pako@~1.0.2: -+ version "1.0.6" -+ resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" -+ -+parallel-webpack@^2.1.0: -+ version "2.2.0" -+ resolved "https://registry.yarnpkg.com/parallel-webpack/-/parallel-webpack-2.2.0.tgz#7171440b684444610ba890d32439a33666ab46cb" -+>>>>>>> .their - dependencies: - ajv "^4.9.2" - bluebird "^3.0.6" -@@ -5529,7 +5767,20 @@ - dependencies: - color-convert "~0.5.0" - -+<<<<<<< .our - parse-json@^2.2.0: -+======= -+parse-glob@^3.0.4: -+ version "3.0.4" -+ resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" -+ dependencies: -+ glob-base "^0.3.0" -+ is-dotfile "^1.0.0" -+ is-extglob "^1.0.0" -+ is-glob "^2.0.0" -+ -+parse-json@^2.1.0, parse-json@^2.2.0: -+>>>>>>> .their - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - dependencies: -@@ -5621,6 +5872,7 @@ - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - -+<<<<<<< .our - phantom@~4.0.1: - version "4.0.12" - resolved "https://registry.yarnpkg.com/phantom/-/phantom-4.0.12.tgz#78d18cf3f2a76fea4909f6160fcabf2742d7dbf0" -@@ -5630,6 +5882,9 @@ - winston "^2.4.0" - - phantomjs-prebuilt@^2.1.16, phantomjs-prebuilt@~2.1.7: -+======= -+phantomjs-prebuilt@^2.1.15: -+>>>>>>> .their - version "2.1.16" - resolved "https://registry.yarnpkg.com/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz#efd212a4a3966d3647684ea8ba788549be2aefef" - dependencies: -@@ -6141,9 +6396,22 @@ - version "1.0.0" - resolved "https://registry.yarnpkg.com/rcedit/-/rcedit-1.0.0.tgz#43309ecbc8814f3582fca6b751748cfad66a16a2" - -+<<<<<<< .our - read-config-file@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/read-config-file/-/read-config-file-3.1.0.tgz#d433283c76f32204d6995542e4a04723db9e8308" -+======= -+read-all-stream@^3.0.0: -+ version "3.1.0" -+ resolved "https://registry.yarnpkg.com/read-all-stream/-/read-all-stream-3.1.0.tgz#35c3e177f2078ef789ee4bfafa4373074eaef4fa" -+ dependencies: -+ pinkie-promise "^2.0.0" -+ readable-stream "^2.0.0" -+ -+read-config-file@3.0.0: -+ version "3.0.0" -+ resolved "https://registry.yarnpkg.com/read-config-file/-/read-config-file-3.0.0.tgz#771def5184a7f76abaf6b2c82f20cb983775b8ea" -+>>>>>>> .their - dependencies: - ajv "^6.5.2" - ajv-keywords "^3.2.0" -@@ -6260,6 +6528,17 @@ - string_decoder "~1.0.3" - util-deprecate "~1.0.1" - -+readable-stream@~2.0.6: -+ version "2.0.6" -+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" -+ dependencies: -+ core-util-is "~1.0.0" -+ inherits "~2.0.1" -+ isarray "~1.0.0" -+ process-nextick-args "~1.0.6" -+ string_decoder "~0.10.x" -+ util-deprecate "~1.0.1" -+ - readdir-scoped-modules@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz#9fafa37d286be5d92cbaebdee030dc9b5f406747" -@@ -6455,9 +6734,42 @@ - tunnel-agent "~0.4.1" - uuid "^3.0.0" - -+<<<<<<< .our - request@~2.81.0: - version "2.81.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" -+======= -+request@^2.85.0: -+ version "2.85.0" -+ resolved "https://registry.yarnpkg.com/request/-/request-2.85.0.tgz#5a03615a47c61420b3eb99b7dba204f83603e1fa" -+ dependencies: -+ aws-sign2 "~0.7.0" -+ aws4 "^1.6.0" -+ caseless "~0.12.0" -+ combined-stream "~1.0.5" -+ extend "~3.0.1" -+ forever-agent "~0.6.1" -+ form-data "~2.3.1" -+ har-validator "~5.0.3" -+ hawk "~6.0.2" -+ http-signature "~1.2.0" -+ is-typedarray "~1.0.0" -+ isstream "~0.1.2" -+ json-stringify-safe "~5.0.1" -+ mime-types "~2.1.17" -+ oauth-sign "~0.8.2" -+ performance-now "^2.1.0" -+ qs "~6.5.1" -+ safe-buffer "^5.1.1" -+ stringstream "~0.0.5" -+ tough-cookie "~2.3.3" -+ tunnel-agent "^0.6.0" -+ uuid "^3.1.0" -+ -+request@~2.79.0: -+ version "2.79.0" -+ resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" -+>>>>>>> .their - dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" -@@ -6530,7 +6842,17 @@ - version "0.1.0" - resolved "https://registry.yarnpkg.com/rgb2hex/-/rgb2hex-0.1.0.tgz#ccd55f860ae0c5c4ea37504b958e442d8d12325b" - -+<<<<<<< .our - rimraf@2, rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: -+======= -+right-align@^0.1.1: -+ version "0.1.3" -+ resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" -+ dependencies: -+ align-text "^0.1.1" -+ -+rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.1: -+>>>>>>> .their - version "2.6.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - dependencies: -@@ -6638,6 +6960,34 @@ - js-base64 "^2.1.8" - source-map "^0.4.2" - -+selenium-adapter@^0.2.7: -+ version "0.2.7" -+ resolved "https://registry.yarnpkg.com/selenium-adapter/-/selenium-adapter-0.2.7.tgz#0f1af0a11d920d416c6eb5f2a8cb27a3142b3b7c" -+ dependencies: -+ chromedriver "^2.32.3" -+ css-to-xpath "^0.1.0" -+ geckodriver "^1.9.0" -+ phantomjs-prebuilt "^2.1.15" -+ selenium-webdriver "^3.5.0" -+ -+selenium-webdriver@^3.5.0: -+ version "3.6.0" -+ resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz#2ba87a1662c020b8988c981ae62cb2a01298eafc" -+ dependencies: -+ jszip "^3.1.3" -+ rimraf "^2.5.4" -+ tmp "0.0.30" -+ xml2js "^0.4.17" -+ -+selenium-webdriver@^4.0.0-alpha.1: -+ version "4.0.0-alpha.1" -+ resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.0.0-alpha.1.tgz#cc93415e21d2dc1dfd85dfc5f6b55f3ac53933b1" -+ dependencies: -+ jszip "^3.1.3" -+ rimraf "^2.5.4" -+ tmp "0.0.30" -+ xml2js "^0.4.17" -+ - semver-diff@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" -@@ -7224,7 +7574,21 @@ - readable-stream "^2.0.0" - xtend "^4.0.0" - -+<<<<<<< .our - tar@^2.0.0: -+======= -+tar@4.0.2: -+ version "4.0.2" -+ resolved "https://registry.yarnpkg.com/tar/-/tar-4.0.2.tgz#e8e22bf3eec330e5c616d415a698395e294e8fad" -+ dependencies: -+ chownr "^1.0.1" -+ minipass "^2.2.1" -+ minizlib "^1.0.4" -+ mkdirp "^0.5.0" -+ yallist "^3.0.2" -+ -+tar@^2.0.0, tar@^2.2.1: -+>>>>>>> .their - version "2.2.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" - dependencies: -@@ -7278,6 +7642,7 @@ - version "1.0.0" - resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" - -+<<<<<<< .our - through2@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" -@@ -7285,6 +7650,8 @@ - readable-stream "^2.1.5" - xtend "~4.0.1" - -+======= -+>>>>>>> .their - through2@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/through2/-/through2-0.2.3.tgz#eb3284da4ea311b6cc8ace3653748a52abf25a3f" -@@ -7296,6 +7663,10 @@ - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - -+timed-out@^2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-2.0.0.tgz#f38b0ae81d3747d628001f41dafc652ace671c0a" -+ - timed-out@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" -@@ -7312,6 +7683,12 @@ - dependencies: - os-tmpdir "~1.0.1" - -+tmp@0.0.30: -+ version "0.0.30" -+ resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.30.tgz#72419d4a8be7d6ce75148fd8b324e593a711c2ed" -+ dependencies: -+ os-tmpdir "~1.0.1" -+ - tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" -@@ -7636,6 +8013,10 @@ - has-value "^0.3.1" - isobject "^3.0.0" - -+unzip-response@^1.0.0: -+ version "1.0.2" -+ resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-1.0.2.tgz#b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe" -+ - unzip-response@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" -@@ -7948,7 +8329,7 @@ - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - --which@1, which@^1.2.4, which@^1.2.9, which@^1.3.0: -+which@1, which@^1.2.10, which@^1.2.4, which@^1.2.9, which@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" - dependencies: -@@ -8051,7 +8432,7 @@ - sax ">=0.6.0" - xmlbuilder "^4.1.0" - --xml2js@^0.4.16: -+xml2js@^0.4.16, xml2js@^0.4.17: - version "0.4.19" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" - dependencies: -@@ -8080,11 +8461,19 @@ - version "0.1.27" - resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" - -+<<<<<<< .our - xregexp@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020" - - xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: -+======= -+xpath-builder@0.0.7: -+ version "0.0.7" -+ resolved "https://registry.yarnpkg.com/xpath-builder/-/xpath-builder-0.0.7.tgz#67d6bbc3f6a320ec317e3e6368c5706b6111deec" -+ -+xtend@^4.0.0, xtend@^4.0.1: -+>>>>>>> .their - version "4.0.1" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - -@@ -8117,9 +8506,15 @@ - version "3.0.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" - -+<<<<<<< .our - yargs-parser@^10.0.0, yargs-parser@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" -+======= -+yargs-parser@^4.2.0: -+ version "4.2.1" -+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" -+>>>>>>> .their - dependencies: - camelcase "^4.1.0" - diff --git a/app/test/fixtures/merge-parser/desktop/merge-shiftkey-yarn-bump-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-shiftkey-yarn-bump-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index e789331fd3f..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-shiftkey-yarn-bump-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,98 +0,0 @@ -changed in both - base 100644 fde223649b6eef6edf60d8726f22ddd799873819 .travis.yml - our 100644 7e0e74ba2993836baa0a7461123da84818d6a990 .travis.yml - their 100644 df10666f88d7c94e6f08caad298af5b6f2ad5d31 .travis.yml -@@ -48,6 +48,13 @@ - - .eslintcache - - $HOME/.cache/electron-builder - -+<<<<<<< .our -+======= -+before_install: -+ - curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.7.0 -+ - export PATH=$HOME/.yarn/bin:$PATH -+ -+>>>>>>> .their - install: - - yarn install --offline - -removed in local - base 100644 19865d13f3ab50d13c233da23115035bf423212e circle.yml - their 100644 2f7175ea65c162d0a071a6e84a3993a2f30ff480 circle.yml -changed in both - base 100644 1f98235d11d633403ddaa711926d2a73f53456e0 vsts.yml - our 100644 dcf24cca01f5cd69beee03d16eb12c73081b9793 vsts.yml - their 100644 8a07441df176251ae82204268f07997e7310cb3e vsts.yml -@@ -1,4 +1,5 @@ - phases: -+<<<<<<< .our - - phase: Windows - queue: Hosted VS2017 - steps: -@@ -57,3 +58,66 @@ - - script: | - yarn test:setup && yarn test - name: Test -+======= -+- phase: Windows -+ queue: Hosted VS2017 -+ steps: -+ - task: NodeTool@0 -+ inputs: -+ versionSpec: "8.11.1" -+ - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 -+ inputs: -+ versionSpec: "1.7.0" -+ - script: | -+ yarn install --force -+ name: Install -+ - script: | -+ yarn lint && yarn build:prod -+ name: Build -+ - script: | -+ yarn test:setup && yarn test -+ name: Test -+ -+- phase: Linux -+ queue: Hosted Linux Preview -+ steps: -+ - script: | -+ apt-get update -+ apt-get install -y --no-install-recommends libsecret-1-dev xvfb fakeroot dpkg rpm xz-utils xorriso zsync libxss1 libgconf2-4 libgtk-3-0 -+ - task: NodeTool@0 -+ inputs: -+ versionSpec: "8.11.1" -+ - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 -+ inputs: -+ versionSpec: "1.7.0" -+ - script: | -+ yarn install --force -+ name: Install -+ - script: | -+ yarn lint && yarn build:prod -+ name: Build -+ - script: | -+ export DISPLAY=':99.0' -+ Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & -+ yarn test:setup && yarn test -+ name: Test -+ -+- phase: macOS -+ queue: Hosted macOS Preview -+ steps: -+ - task: NodeTool@0 -+ inputs: -+ versionSpec: "8.11.1" -+ - task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 -+ inputs: -+ versionSpec: "1.7.0" -+ - script: | -+ yarn install --force -+ name: Install -+ - script: | -+ yarn lint && yarn build:prod -+ name: Build -+ - script: | -+ yarn test:setup && yarn test -+ name: Test -+>>>>>>> .their diff --git a/app/test/fixtures/merge-parser/desktop/merge-sms-send-help-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-sms-send-help-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index b0c1916e65a..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-sms-send-help-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,241 +0,0 @@ -changed in both - base 100644 d2d4fe241dd73c289adf5eafe191299a25144a88 app/src/ui/dialog/error.tsx - our 100644 744a786b47398054587a2eb3c35460ee471cc51f app/src/ui/dialog/error.tsx - their 100644 4279d8bada629e97486dbbcef1cbc5c5166cb4f1 app/src/ui/dialog/error.tsx -@@ -1,7 +1,24 @@ - import * as React from 'react' - import { Octicon, OcticonSymbol } from '../octicons' -+import * as classNames from 'classnames' - -+<<<<<<< .our - interface IDialogErrorProps {} -+======= -+interface IDialogErrorProps { -+ readonly children?: ReadonlyArray<JSX.Element> -+ -+ /** -+ * An optional type for the banner displayed. -+ * -+ * When passed 'warning', the error message will render with a yellow -+ * background, black text, and an alert icon. -+ * -+ * Defaults to 'error' -+ */ -+ readonly bannertype?: 'error' | 'warning' -+} -+>>>>>>> .their - - /** - * A component used for displaying short error messages inline -@@ -16,10 +33,24 @@ - */ - export class DialogError extends React.Component<IDialogErrorProps, {}> { - public render() { -+<<<<<<< .our - return ( - <div className="dialog-error"> - <Octicon symbol={OcticonSymbol.stop} /> - <div>{this.props.children}</div> -+======= -+ const classname = classNames('dialog-error', { -+ 'dialog-warning': this.props.bannertype === 'warning', -+ }) -+ const octicon = this.props.bannertype === 'warning' ? OcticonSymbol.alert : OcticonSymbol.stop -+ -+ return ( -+ <div className={classname}> -+ <Octicon symbol={octicon} /> -+ <div> -+ {this.props.children} -+ </div> -+>>>>>>> .their - </div> - ) - } -changed in both - base 100644 29139bdcd2057b471360a3dd21a47b12fbfb13e1 app/src/ui/sign-in/sign-in.tsx - our 100644 e4ee46a6fe80cf3c36db4a62459618eadc3fee7e app/src/ui/sign-in/sign-in.tsx - their 100644 8af4667dda19e15010f8fe8684cea73ee7df2c85 app/src/ui/sign-in/sign-in.tsx -@@ -16,7 +16,14 @@ - import { ButtonGroup } from '../lib/button-group' - import { Dialog, DialogError, DialogContent, DialogFooter } from '../dialog' - -+<<<<<<< .our - import { getWelcomeMessage } from '../../lib/2fa' -+======= -+import { -+ AuthenticationMode, -+ getWelcomeMessage, -+ } from '../../lib/2fa' -+>>>>>>> .their - - interface ISignInProps { - readonly dispatcher: Dispatcher -@@ -232,12 +239,28 @@ - ) - } - -+<<<<<<< .our - private renderTwoFactorAuthenticationStep( - state: ITwoFactorAuthenticationState - ) { - return ( - <DialogContent> - <p>{getWelcomeMessage(state.type)}</p> -+======= -+ private renderTwoFactorAuthenticationStep(state: ITwoFactorAuthenticationState) { -+ let resendLink = null -+ -+ if (state.type === AuthenticationMode.Sms) { -+ resendLink = <LinkButton className='resend-sms-link'>Resend SMS Code</LinkButton> -+ } -+ -+ return ( -+ <DialogContent> -+ <p> -+ { getWelcomeMessage(state.type) } -+ </p> -+ -+>>>>>>> .their - <Row> - <TextBox - label="Authentication code" -@@ -248,6 +271,10 @@ - autoFocus={true} - /> - </Row> -+ -+ <Row className='resend-sms-link-row'> -+ {resendLink} -+ </Row> - </DialogContent> - ) - } -changed in both - base 100644 61ce0352a8d13a4b2c8d3df20f73809bf4b04d7b app/styles/_variables.scss - our 100644 6c89a529c5a8dbfefb127f171468af9ae5651141 app/styles/_variables.scss - their 100644 985dff91b66b71b39c825292712c3db339b117bd app/styles/_variables.scss -@@ -5,11 +5,36 @@ - // Primer colors, see https://github.com/primer/primer-css/blob/master/modules/primer-support/lib/variables/color-system.scss - @import '~primer-support/lib/variables/color-system.scss'; - -+<<<<<<< .our - // Extracted as a SCSS variable so that we can define the --overlay-background-color - // on both the :root and the ::backdrop scope. The ::backdrop pseudo-element - // doesn't inherit :root, see - // https://bugs.chromium.org/p/chromium/issues/detail?id=594096 - $overlay-background-color: rgba(0, 0, 0, 0.4); -+======= -+ // Colors -+ // -+ // These are declared here to let us avoid duplicating color constants -+ // in variables. It also makes it easier to read and understand what -+ // color is being used. Note that these variables should _never_ be -+ // used outside of this scope. -+ $darkBlue: #005CC5; -+ $blue: #0366d6; -+ $yellow: #ffd33d; -+ $darkYellow: #745d00; -+ $lightYellow: #fff5b1; -+ $red: #d73a49; -+ $lightRed: #f04747; -+ $green: #28a745; -+ $orange: #f66a0a; -+ $black: #24292e; -+ $darkerGray: #6a737d; -+ $darkGray: #959da5; -+ $gray: #E1E4E8; -+ $lightGray: #F6F8FA; -+ $lighterGray: #fafbfc; -+ $white: #fff; -+>>>>>>> .their - - :root { - --color-new: $green; -@@ -370,6 +395,10 @@ - /** Overlay is used as a background for both modals and foldouts */ - --overlay-background-color: $overlay-background-color; - -+ // Colors for form warnings -+ --warning-color: $darkYellow; -+ --form-warning-background: $lightYellow; -+ - /** Dialog */ - --dialog-warning-color: $yellow-600; - --dialog-error-color: $red; -changed in both - base 100644 58f4e9d43bed5cda813e1b05c87b7bc5e1fed407 app/styles/ui/_dialog.scss - our 100644 94b86d54fb9b0314deb1ef48cc9e1466578ed390 app/styles/ui/_dialog.scss - their 100644 583b976db4e4d400fe15666cd1447c0b0d16d824 app/styles/ui/_dialog.scss -@@ -97,8 +97,26 @@ - - .dialog-header { - height: 50px; -+<<<<<<< .our - border-bottom: var(--base-border); - -+======= -+ box-shadow: 0 1px 0 rgba(#000, 0.1); -+ position: relative; -+ -+ // There's at most three elements in the header, -+ // 1. The icon (optional, only for errors, warnings, etc) -+ // 2. The title, a h1 element which is always present if the -+ // header element is visible -+ // 3. The close button (optional, hidden when dialog isn't dismissable). -+ // -+ // In order to correctly center the title in all scenarios we lay out the -+ // children in a flexbox but we position the icon and close button -+ // absolutely to the left and right side leaving the h1 all available -+ // width. We then add a 40px margin on each side of the h1 ensuring that -+ // even in the scenario where only one of the two optional elements is -+ // visible the h1 stays centered horizontally. -+>>>>>>> .their - display: flex; - flex-direction: row; - align-items: center; -@@ -260,14 +278,24 @@ - white-space: pre-wrap; - - background: var(--form-error-background); -+<<<<<<< .our - border-bottom: 1px solid var(--form-error-border-color); - color: var(--form-error-text-color); -+======= -+ box-shadow: inset 0 -1px 0 rgba(#000, 0.1); -+ color: var(--error-color); -+>>>>>>> .their - - > .octicon { - flex-grow: 0; - flex-shrink: 0; - margin-right: var(--spacing); - } -+ -+ &.dialog-warning { -+ background: var(--form-warning-background); -+ color: var(--warning-color); -+ } - } - - &#app-error { -@@ -336,6 +364,7 @@ - justify-content: flex-end; - } - -+<<<<<<< .our - .forgot-password-link-sign-in { - margin-left: auto; - } -@@ -351,6 +380,11 @@ - - &#lfs-attribute-mismatch { - width: 400px; -+======= -+ .resend-sms-link-row { -+ margin-top: calc(var(--spacing-half) * -1); -+ } -+>>>>>>> .their - } - } - diff --git a/app/test/fixtures/merge-parser/desktop/merge-spike-primer-utility-classes-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-spike-primer-utility-classes-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index a0d2ae2266f..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-spike-primer-utility-classes-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,573 +0,0 @@ -changed in both - base 100644 c748c3e92b4e28df2e4f2141eef417fd2d016a31 app/src/ui/changes/changed-file.tsx - our 100644 e68da78b55ca434ace46ff94982da3e9897bfb4c app/src/ui/changes/changed-file.tsx - their 100644 a2387ab1b092f4e8ea1c43ead1574161d611047d app/src/ui/changes/changed-file.tsx -@@ -58,6 +58,7 @@ - statusWidth - - return ( -+<<<<<<< .our - <div className="file" onContextMenu={this.onContextMenu}> - <Checkbox - // The checkbox doesn't need to be tab reachable since we emulate -@@ -81,6 +82,16 @@ - className={'status status-' + fileStatus.toLowerCase()} - title={fileStatus} - /> -+======= -+ <div className='changed-file'> -+ <input -+ type='checkbox' -+ checked={this.props.include} -+ onChange={event => this.handleChange(event)} -+ /> -+ <span className='path'>{this.props.path}</span> -+ <span className='ml-3'>{ChangedFile.mapStatus(this.props.status)}</span> -+>>>>>>> .their - </div> - ) - } -changed in both - base 100644 d7585ab50b37f653dbf7b9228f853679547641a7 app/src/ui/changes/changes-list.tsx - our 100644 f785abb2624c245a3387a304168d5fc629e1430e app/src/ui/changes/changes-list.tsx - their 100644 a95d566a006d39cd1bc6a21cb13d25e7628af080 app/src/ui/changes/changes-list.tsx -@@ -32,7 +32,11 @@ - - const RowHeight = 29 - -+<<<<<<< .our - const GitIgnoreFileName = '.gitignore' -+======= -+const RowHeight = 30 -+>>>>>>> .their - - interface IChangesListProps { - readonly repository: Repository -@@ -371,6 +375,7 @@ - fileCount > 0 && this.includeAllValue !== CheckboxValue.Off - - return ( -+<<<<<<< .our - <div className="changes-list-container file-list"> - <div className="header" onContextMenu={this.onContextMenu}> - <Checkbox -@@ -379,6 +384,23 @@ - onChange={this.onIncludeAllChanged} - disabled={fileCount === 0 || this.props.isCommitting} - /> -+======= -+ <div className='panel border-right border-top' id='changes-list'> -+ <div className='border-bottom px-3 py-2 shrink-0' id='select-all'> -+ <label> -+ <input -+ type='checkbox' -+ checked={includeAll} -+ onChange={event => this.handleOnChangeEvent(event) } -+ ref={function(input) { -+ if (input != null) { -+ input.indeterminate = (includeAll === null) -+ } -+ }} /> -+ -+ Select all changes -+ </label> -+>>>>>>> .their - </div> - - <List -changed in both - base 100644 3a5879808cb9de866276a6714a2577045245416d app/src/ui/changes/commit-message.tsx - our 100644 0a0e18fc9f4c8956a648726827dc496f3d5f98db app/src/ui/changes/commit-message.tsx - their 100644 4a09a41b5a733400fbb48c0245dd498bd1ba8719 app/src/ui/changes/commit-message.tsx -@@ -483,6 +483,7 @@ - }) - - return ( -+<<<<<<< .our - <div - id="commit-message" - role="group" -@@ -538,6 +539,18 @@ - </span> - </Button> - </div> -+======= -+ <form className='commit-form border-top bg-alt p-3 shrink-0' onSubmit={event => event.stopPropagation()}> -+ <input type='text' -+ placeholder='Commit summary' -+ value={this.state.title} -+ onChange={event => this.handleTitleChange(event) } /> -+ -+ <button onClick={event => this.handleSubmit(event)}> -+ Commit Changes -+ </button> -+ </form> -+>>>>>>> .their - ) - } - } -removed in local - base 100644 48580b1b4f4897f71599ed209bbaf00c3fb3ef91 app/src/ui/changes/index.tsx - their 100644 00da4b52bddb7dc3aa4a1f54ea44d049c24aa437 app/src/ui/changes/index.tsx -removed in local - base 100644 a10ad562938ab69d9877cd497352ba81e3fdebe4 app/src/ui/comparison-graph.tsx - their 100644 061f3f0d4f8fc6c90518923cf685c4508d806ebb app/src/ui/comparison-graph.tsx -removed in local - base 100644 0419a26350b7b95a59fd487eb60da8e79dada934 app/src/ui/file-diff.tsx - their 100644 8fa328fd68b1dd8526497368522ed9fb5c29d805 app/src/ui/file-diff.tsx -changed in both - base 100644 42899f7977a36794572305edc1de3cc2049055f1 app/src/ui/history/commit-list.tsx - our 100644 3e0e90eccd5a8894b7cce153c15009fe732a39cc app/src/ui/history/commit-list.tsx - their 100644 10f1ad904ed78aad40e155fbe9ae6ddd12c395a9 app/src/ui/history/commit-list.tsx -@@ -108,6 +108,7 @@ - } - - return ( -+<<<<<<< .our - <div id="commit-list"> - <List - rowCount={this.props.commitSHAs.length} -@@ -121,6 +122,14 @@ - gitHubUsers: this.props.gitHubUsers, - }} - /> -+======= -+ <div className='panel border-top border-right' id='commit-list'> -+ <List itemCount={this.props.commits.length} -+ itemHeight={68} -+ selectedRow={this.rowForCommit(this.props.selectedCommit)} -+ renderItem={row => this.renderCommit(row)} -+ onSelectionChanged={row => this.onSelectionChanged(row)}/> -+>>>>>>> .their - </div> - ) - } -removed in local - base 100644 ca6496326f249e933ab558fabe31121a9728607a app/src/ui/history/commit-summary-container.tsx - their 100644 3fbd2f352aec0e23c82ab9c9ab5be68a771f3350 app/src/ui/history/commit-summary-container.tsx -changed in both - base 100644 301bc111fef978a96656f45084a79d7da4964be9 app/src/ui/history/commit-summary.tsx - our 100644 94bcb37b5e8ed8a8b4b2819e8ee9f0336b1ba0c6 app/src/ui/history/commit-summary.tsx - their 100644 3bcc694706ba81ad5b8c0659d3abbbb1860a91c2 app/src/ui/history/commit-summary.tsx -@@ -283,6 +283,7 @@ - }) - - return ( -+<<<<<<< .our - <div id="commit-summary" className={className}> - <div className="commit-summary-header"> - <RichText -@@ -319,6 +320,19 @@ - {filesDescription} - </li> - </ul> -+======= -+ <div className='panel'> -+ <div className='f3-light border-bottom p-3'>{this.props.summary}</div> -+ <div className='ff-monospace border-bottom p-3 hide-when-empty'> -+ {this.props.body} -+ </div> -+ <div className='files'> -+ <List renderItem={row => this.renderFile(row)} -+ itemCount={this.props.files.length} -+ itemHeight={30} -+ selectedRow={this.rowForFile(this.props.selectedFile)} -+ onSelectionChanged={row => this.onSelectionChanged(row)}/> -+>>>>>>> .their - </div> - - {this.renderDescription()} -removed in local - base 100644 ec707aa2b8fa810e44c97cb96a92be0c06f4f608 app/src/ui/history/index.tsx - their 100644 9dbac19a0eeecff3b5f16f4da5f8ca6d02cc684b app/src/ui/history/index.tsx -removed in local - base 100644 76210097d11622b60cb03493f6d798f9c1892fda app/src/ui/list.tsx - their 100644 97a93276ea7985df54399734e2e2b8e0352043b6 app/src/ui/list.tsx -removed in local - base 100644 f834f529d76df02393f51f230fa36eeedd41329f app/src/ui/repositories-list/index.tsx - their 100644 7332f7bfa29e3774c98aa8e75cb0b7b1b2dc65e6 app/src/ui/repositories-list/index.tsx -changed in both - base 100644 5cf59add65285cfea3a285539fadbc54eadd8cdd app/src/ui/repositories-list/repository-list-item.tsx - our 100644 6ca3c771c795eba242cc4b795e3a3b0bbb4c7488 app/src/ui/repositories-list/repository-list-item.tsx - their 100644 2ae63d5c33a26b08f571c7978dcdf8df702961f6 app/src/ui/repositories-list/repository-list-item.tsx -@@ -99,6 +99,7 @@ - } - - return ( -+<<<<<<< .our - <div onContextMenu={this.onContextMenu} className="repository-list-item"> - <div - className="change-indicator-wrapper" -@@ -113,6 +114,9 @@ - /> - ) : null} - </div> -+======= -+ <div className='repository-list-item pl-3' title={tooltip}> -+>>>>>>> .their - <Octicon symbol={iconForRepository(repository)} /> - <div className="name" title={repoTooltip}> - {prefix ? <span className="prefix">{prefix}</span> : null} -changed in both - base 100644 3cb96ddf5cdb4d58761c9eab3241d5e6116a3063 app/src/ui/repository.tsx - our 100644 efb00423012b8da0dfa5e8897acacaeb0a5e648a app/src/ui/repository.tsx - their 100644 5d3ab7ec90a61ff5dae0e4a6cad00f5d0a3a38b7 app/src/ui/repository.tsx -@@ -132,6 +132,7 @@ - const availableWidth = this.props.sidebarWidth - 1 - - return ( -+<<<<<<< .our - <ChangesSidebar - repository={this.props.repository} - dispatcher={this.props.dispatcher} -@@ -153,6 +154,11 @@ - externalEditorLabel={this.props.externalEditorLabel} - onOpenInExternalEditor={this.props.onOpenInExternalEditor} - /> -+======= -+ <div className='blankslate bg-alt'> -+ <p className='f3-light'>No repo selected!</p> -+ </div> -+>>>>>>> .their - ) - } - -changed in both - base 100644 ce026cf68ce6abe09e1d2401eefa066b4482f7b3 app/styles/_globals.scss - our 100644 b1af174b6d02934b6e9b5f29051ccc89c28454ad app/styles/_globals.scss - their 100644 fbd2446a05a95168f36d8bc0aa0dc668c4962d5e app/styles/_globals.scss -@@ -107,6 +107,7 @@ - width: 100%; - } - -+<<<<<<< .our - .blankslate { - background: var(--box-alt-background-color); - color: var(--text-secondary-color); -@@ -159,4 +160,24 @@ - - .brutalism { - background: salmon; -+======= -+.shrink-0 { -+ flex-shrink: 0 !important; -+} -+ -+.hide-when-empty:empty { -+ display: none !important; -+} -+ -+.bg-alt { -+ background-color: var(--box-alt-background-color) !important; -+} -+ -+.blankslate { -+ display: flex; -+ flex: 1; -+ align-items: center; -+ justify-content: center; -+ text-align: center; -+>>>>>>> .their - } -added in remote - their 100644 2a5c09a88668942f9c392b29a55fa6a003985836 app/styles/_primer-helpers.scss -@@ -0,0 +1,34 @@ -+@import "~primer-support/index.scss"; -+ -+// We need to import each utility file manually since webpack breaks when -+// trying to use `@import "~primer-utilities/index.scss";` because the import -+// statement doesn't know where `"primer-utilities/index.scss"` exists. -+// -+// https://github.com/primer/utilities/blob/master/index.scss -+// https://github.com/jtangelder/sass-loader#imports -+ -+@import "~primer-utilities/lib/border.scss"; -+@import "~primer-utilities/lib/colors.scss"; -+@import "~primer-utilities/lib/layout.scss"; -+@import "~primer-utilities/lib/margin.scss"; -+@import "~primer-utilities/lib/padding.scss"; -+@import "~primer-utilities/lib/typography.scss"; -+ -+// TODO: Remove when the next version of primer is released -+// -+// Porting utilities these font-weigth utilties until primer gets updated -+// https://github.com/primer/utilities/blob/master/lib/typography.scss -+// -+// load missing variables -+// https://github.com/primer/support/blob/master/lib/variables.scss#L122 -+$h00-size: 48px !default; -+$h0-size: 40px !default; -+$font-weight-light: 300 !default; -+// -+// Type utils with light weight that match type scale -+.f00-light { font-size: $h00-size !important; font-weight: $font-weight-light !important; } -+.f0-light { font-size: $h0-size !important; font-weight: $font-weight-light !important; } -+.f1-light { font-size: $h1-size !important; font-weight: $font-weight-light !important; } -+.f2-light { font-size: $h2-size !important; font-weight: $font-weight-light !important; } -+// Same size and weight as .lead but without color property -+.f3-light { font-size: $h3-size !important; font-weight: $font-weight-light !important; } -changed in both - base 100644 bfc830f7d9ff507f9e18a4b808ad29c6819b0402 app/styles/_type.scss - our 100644 e603c67be24cd76693db032111917284a78939cb app/styles/_type.scss - their 100644 bb30ff8c8c109b086e7ee4470a945fc4ab639cc4 app/styles/_type.scss -@@ -2,7 +2,12 @@ - // Typography - // - -+<<<<<<< .our - .byline { - font-size: var(--font-size-sm); - color: var(--text-secondary-color); -+======= -+.ff-monospace { -+ font-family: var(--font-family-monospace) !important; -+>>>>>>> .their - } -changed in both - base 100644 9ae4fd4799e3c721661ffb503a9ec256cebfb39a app/styles/_ui.scss - our 100644 fe75df3631a5a6b0a4f5c1fc08ec016a19917524 app/styles/_ui.scss - their 100644 4d82345499983ab5cd78f698b15feac9226554eb app/styles/_ui.scss -@@ -1,3 +1,4 @@ -+<<<<<<< .our - @import 'ui/app'; - @import 'ui/app-menu'; - @import 'ui/scroll'; -@@ -66,3 +67,24 @@ - @import 'ui/commit-attribution'; - @import 'ui/fancy-text-box'; - @import 'ui/notification-banner'; -+======= -+@import "ui/app"; -+@import "ui/forms"; -+@import "ui/buttons"; -+@import "ui/scroll"; -+@import "ui/window/title-bar"; -+@import "ui/octicons"; -+@import "ui/sidebar"; -+@import "ui/list"; -+@import "ui/repository-list"; -+@import "ui/changes-list"; -+@import "ui/commit-summary"; -+@import "ui/commit-list"; -+@import "ui/commit-message"; -+@import "ui/comparison-graph"; -+@import "ui/file-diff"; -+@import "ui/repository"; -+@import "ui/toolbar"; -+@import "ui/segmented-control"; -+@import "ui/panel"; -+>>>>>>> .their -changed in both - base 100644 567d939074cd222abd2c789dcb514c742f4929ed app/styles/_variables.scss - our 100644 6c89a529c5a8dbfefb127f171468af9ae5651141 app/styles/_variables.scss - their 100644 25bf8afb64f2143ab89c337ab59bea34596eb1f2 app/styles/_variables.scss -@@ -18,8 +18,26 @@ - --color-renamed: $blue; - --color-conflicted: $orange; - -+<<<<<<< .our - --text-color: $gray-900; - --text-secondary-color: $gray-500; -+======= -+ // Colors -+ // -+ // These are declared here to let us avoid duplicating color constants -+ // in variables. It also makes it easier to read and understand what -+ // color is being used. Note that these variables should _never_ be -+ // used outside of this scope. -+ $blue: #4ca6eb; -+ $darkGray: #5f717f; -+ $orange: #c9510c; -+ $gray: #C6CACC; -+ $lightGray: #E3E7E9; -+ $lighterGray: #f9f9f9; -+ $white: #fff; -+ -+ --text-color: $darkGray; -+>>>>>>> .their - --background-color: $white; - - --button-height: 25px; -@@ -33,11 +51,17 @@ - --link-button-color: $blue; - --link-button-hover-color: $blue-600; - -+<<<<<<< .our - --secondary-button-background: $gray-000; - --secondary-button-hover-background: $white; - --secondary-button-text-color: var(--text-color); - --secondary-button-focus-shadow-color: rgba($gray-200, 0.75); - --secondary-button-focus-border-color: $gray-300; -+======= -+ --button-border-color: $gray; -+ --button-background: $white; -+ --button-hover-background: $white; -+>>>>>>> .their - - // Typography - // -@@ -101,7 +125,11 @@ - /** - * Border color for boxes. - */ -+<<<<<<< .our - --box-border-color: $gray-200; -+======= -+ --box-border-color: $lightGray; -+>>>>>>> .their - --box-border-accent-color: $blue; - - /** -changed in both - base 100644 dec2cc2936adb4bc212b670bb0abe7bd49076e61 app/styles/desktop.scss - our 100644 3a8c3b0ce9abb4b883fdc4f28ada9ac3a70b2f2e app/styles/desktop.scss - their 100644 a6fa210cec9f0541b6c674e6598af150cd41bc16 app/styles/desktop.scss -@@ -1,7 +1,16 @@ -+<<<<<<< .our - @import 'vendor'; - - @import 'variables'; - @import 'themes/dark'; -+======= -+@import "variables"; -+@import "primer-helpers"; -+@import "mixins"; -+ -+@import "globals"; -+@import "type"; -+>>>>>>> .their - - @import 'mixins'; - -removed in local - base 100644 e032ce4f42477c866af6cadaf6c5b9951a8f0ac9 app/styles/ui/_buttons.scss - their 100644 2e7abff7c6c41966c0933caed30e9104f3a0adc4 app/styles/ui/_buttons.scss -removed in local - base 100644 a081b438b5478c014c51324d3c8c47785f375046 app/styles/ui/_changes-list.scss - their 100644 a2850081288ebf3331f33450e2a2db1f49c19d03 app/styles/ui/_changes-list.scss -removed in remote - base 100644 1087e76feb599ac50ddd50838c820c78517255a5 app/styles/ui/_changes.scss - our 100644 de2ffe80b995654b81e8336fd2535bac0fb67820 app/styles/ui/_changes.scss -@@ -1,6 +0,0 @@ --@import 'changes/commit-message'; --@import 'changes/changes-list'; --@import 'changes/sidebar'; --@import 'changes/undo-commit'; --@import 'changes/changes-view'; --@import 'changes/no-changes'; -removed in local - base 100644 59ab5270f83362169e656c4181e89d3e4e8063aa app/styles/ui/_commit-list.scss - their 100644 a394b502004840b6fb5af75e4604a1b45c93099f app/styles/ui/_commit-list.scss -removed in local - base 100644 e435a162aff1d73e9fa1bb92e695e700b1a7a1a3 app/styles/ui/_commit-message.scss - their 100644 ef9ae4430409bd16b91944ae498d7dd2c1a693c1 app/styles/ui/_commit-message.scss -removed in local - base 100644 73a3547e959414f490cd1c7de0c3d454bc469c12 app/styles/ui/_commit-summary.scss - their 100644 b5be34b04a1733b21ab828fde60a7f529c458df9 app/styles/ui/_commit-summary.scss -removed in local - base 100644 2a7fead7d16da6f69892f5358b3f0784a7121090 app/styles/ui/_comparison-graph.scss - their 100644 6847ae73aca6f83c1c72b58e27a6c38acf637599 app/styles/ui/_comparison-graph.scss -removed in local - base 100644 ad8fb1f792dee66e0dcd90f0f81fd6ead395c090 app/styles/ui/_file-diff.scss - their 100644 c3cde7598ff4ef66603593d7eb473cc991fc9b58 app/styles/ui/_file-diff.scss -removed in remote - base 100644 d621b3b1bd9bac193c06757e568cfbcc78e25707 app/styles/ui/_history.scss - our 100644 3be2e7a8361b043848a95566478c6416c8a4516d app/styles/ui/_history.scss -@@ -1,4 +0,0 @@ --@import 'history/history'; --@import 'history/commit-list'; --@import 'history/commit-summary'; --@import 'history/file-list'; -added in both - our 100644 e19b802ece2262b43808c25e54eb70fde647626a app/styles/ui/_panel.scss - their 100644 3b010cc7d21173271ec7090025c66ffa3daa8f37 app/styles/ui/_panel.scss -@@ -3,3 +3,12 @@ - flex-direction: column; - flex: 1; - } -+<<<<<<< .our -+======= -+ -+.panel-container { -+ display: flex; -+ flex-direction: row; -+ flex: 1; -+} -+>>>>>>> .their -changed in both - base 100644 489625412bf51611a04eebc31c8e758b0f0517e4 app/styles/ui/_repository-list.scss - our 100644 157e36f8a6d1951007c2c6c8f17b69d30f96b0c7 app/styles/ui/_repository-list.scss - their 100644 48a6e62b75f58f0f1bcb419bc708a11b394fe7ad app/styles/ui/_repository-list.scss -@@ -21,7 +21,10 @@ - * and one <div class='name'> holding the repository name. - */ - .repository-list-item { -+<<<<<<< .our - padding: 0 var(--spacing); -+======= -+>>>>>>> .their - - // Layout the icon and repository name horizontally - display: flex; -@@ -119,6 +122,7 @@ - } - } - } -+<<<<<<< .our - - &.focus-within { - /** Ahead/behind badge colors when list item is selected and focused */ -@@ -135,4 +139,6 @@ - color: var(--text-color); - } - } -+======= -+>>>>>>> .their - } -changed in both - base 100644 e0c7b8a4bbc131e2b4b4ef9e1871d345acffd302 package.json - our 100644 2006bfb748810f6ea8bdbd26edf7c09524a1388a package.json - their 100644 51fb2bbe6a0a92d6c3c9b207281e1d5e0a349d25 package.json -@@ -51,6 +51,7 @@ - "yarn": ">= 1.9" - }, - "dependencies": { -+<<<<<<< .our - "ajv": "^6.4.0", - "awesome-node-loader": "^1.1.0", - "awesome-typescript-loader": "^5.0.0", -@@ -86,6 +87,34 @@ - "octicons": "^7.0.1", - "parallel-webpack": "^2.3.0", - "prettier": "^1.14.2", -+======= -+ "aws-sdk": "^2.3.15", -+ "babel-core": "^6.7.6", -+ "babel-loader": "^6.2.4", -+ "babel-plugin-react-transform": "^2.0.2", -+ "babel-plugin-transform-runtime": "^6.8.0", -+ "babel-preset-es2015": "^6.6.0", -+ "babel-preset-react": "^6.5.0", -+ "babel-preset-react-hmre": "^1.1.1", -+ "babel-preset-stage-0": "^6.5.0", -+ "chai": "^3.5.0", -+ "cross-env": "^1.0.8", -+ "css-loader": "^0.23.1", -+ "electron-mocha": "2.1.0", -+ "electron-packager": "^7.2.0", -+ "electron-prebuilt": "1.3.1", -+ "electron-winstaller": "^2.3.0", -+ "express": "^4.13.4", -+ "extract-text-webpack-plugin": "^1.0.1", -+ "fs-extra": "^0.30.0", -+ "got": "^6.3.0", -+ "html-webpack-plugin": "^2.21.0", -+ "mocha": "^2.4.5", -+ "node-sass": "^3.7.0", -+ "primer-support": "^0.5.0", -+ "primer-utilities": "^0.5.0", -+ "react-transform-hmr": "^1.0.4", -+>>>>>>> .their - "request": "^2.72.0", - "rimraf": "^2.5.2", - "sass-loader": "^7.0.1", diff --git a/app/test/fixtures/merge-parser/desktop/merge-submodule-diff-on-top-of-diff-changes-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-submodule-diff-on-top-of-diff-changes-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index ea66036dec6..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-submodule-diff-on-top-of-diff-changes-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,1664 +0,0 @@ -changed in both - base 100644 595c4ccc42a67e036909be3572ab1131e6cd1935 app/src/lib/app-state.ts - our 100644 b30f0fe080d909b81d2fb683ceb8deb365fb0191 app/src/lib/app-state.ts - their 100644 4601ec5e4074819945b51b57518f924111e115a5 app/src/lib/app-state.ts -@@ -1,10 +1,16 @@ - import { Account } from '../models/account' - import { CommitIdentity } from '../models/commit-identity' - import { IDiff } from '../models/diff' -+<<<<<<< .our - import { Repository, ILocalRepositoryState } from '../models/repository' - - import { Branch, IAheadBehind } from '../models/branch' - import { Tip } from '../models/tip' -+======= -+import { Repository } from '../models/repository' -+import { IAheadBehind } from './git' -+import { Branch } from '../models/branch' -+>>>>>>> .their - import { Commit } from '../models/commit' - import { - CommittedFileChange, -@@ -571,12 +577,20 @@ - /** The selected file inside the selected commit */ - readonly file: CommittedFileChange | null - -+<<<<<<< .our - /** The diff of the currently-selected file */ -+======= -+>>>>>>> .their - readonly diff: IDiff | null - } - - export interface IChangesState { - readonly workingDirectory: WorkingDirectoryStatus -+<<<<<<< .our -+======= -+ readonly selectedFile: WorkingDirectoryFileChange | null -+ readonly diff: IDiff | null -+>>>>>>> .their - - /** - * The ID of the selected files. The files themselves can be looked up in -changed in both - base 100644 5681db4dacf0b40c8272b8e9e5dd06ebc239cd60 app/src/lib/diff-parser.ts - our 100644 d8312b68a2839cd36ba6507b023bede53368a654 app/src/lib/diff-parser.ts - their 100644 8e3ebe94815c40ea4c1f6fd46b6b3f9c1f1e0990 app/src/lib/diff-parser.ts -@@ -1,3 +1,4 @@ -+<<<<<<< .our - import { - IRawDiff, - DiffHunk, -@@ -5,6 +6,9 @@ - DiffLine, - DiffLineType, - } from '../models/diff' -+======= -+import { IRawDiff, DiffHunk, DiffHunkHeader, DiffLine, DiffLineType } from '../models/diff' -+>>>>>>> .their - import { assertNever } from '../lib/fatal-error' - - // https://en.wikipedia.org/wiki/Diff_utility -@@ -373,6 +377,10 @@ - * diffs. - */ - public parse(text: string): IRawDiff { -+<<<<<<< .our -+======= -+ -+>>>>>>> .their - this.text = text - - try { -@@ -383,11 +391,25 @@ - - // empty diff - if (!headerInfo) { -+<<<<<<< .our - return { header, contents: '', hunks: [], isBinary: false } - } - - if (headerInfo.isBinary) { - return { header, contents: '', hunks: [], isBinary: true } -+======= -+ return { -+ hunks: [], -+ isBinary: false, -+ } -+ } -+ -+ if (headerInfo.isBinary) { -+ return { -+ hunks: [], -+ isBinary: true, -+ } -+>>>>>>> .their - } - - const hunks = new Array<DiffHunk>() -@@ -399,6 +421,7 @@ - linesConsumed += hunk.lines.length - } while (this.peek()) - -+<<<<<<< .our - const contents = this.text - .substring(headerEnd + 1, this.le) - // Note that this simply returns a reference to the -@@ -407,6 +430,12 @@ - .replace(/\n\\ No newline at end of file/g, '') - - return { header, contents, hunks, isBinary: headerInfo.isBinary } -+======= -+ return { -+ hunks, -+ isBinary: headerInfo.isBinary, -+ } -+>>>>>>> .their - } finally { - this.reset() - } -removed in local - base 100644 4844d41b832a89c74a083b9503a1bad1329bc7d8 app/src/lib/dispatcher/app-store.ts - their 100644 2e2358a1d3b3a91ac26d1e83a9ea37b5a9babdbc app/src/lib/dispatcher/app-store.ts -changed in both - base 100644 fcdf978c8b65d7d75655455af3799fd77e894bd4 app/src/lib/git/apply.ts - our 100644 57f2df6dd951c6129d9da4ea5809b3e26b6a764c app/src/lib/git/apply.ts - their 100644 99472b37aff6fd6ef970be7d22ff1e5369074d05 app/src/lib/git/apply.ts -@@ -1,5 +1,9 @@ - import { git } from './core' -+<<<<<<< .our - import { AppFileStatus, WorkingDirectoryFileChange } from '../../models/status' -+======= -+import { FileStatus, WorkingDirectoryFileChange } from '../../models/status' -+>>>>>>> .their - import { DiffType } from '../../models/diff' - import { Repository } from '../../models/repository' - import { getWorkingDirectoryDiff } from './diff' -changed in both - base 100644 ae50139e7823fd04a2e47f11d0ae428a959fd93a app/src/lib/git/diff.ts - our 100644 c7b70925514f334e2076ddb67f208c2f3f12672f app/src/lib/git/diff.ts - their 100644 5d54e2ba1a5b991dd4f4edabdbb064c5c15c4d3c app/src/lib/git/diff.ts -@@ -4,6 +4,7 @@ - import { getBlobContents } from './show' - - import { Repository } from '../../models/repository' -+<<<<<<< .our - import { - WorkingDirectoryFileChange, - FileChange, -@@ -22,6 +23,12 @@ - } from '../../models/diff' - - import { spawnAndComplete } from './spawn' -+======= -+import { WorkingDirectoryFileChange, FileChange, FileStatus } from '../../models/status' -+import { DiffType, IRawDiff, IDiff, IImageDiff, Image, FileSummary, DiffHunk } from '../../models/diff' -+ -+import { getSubmoduleDetails } from '../../lib/git/submodule' -+>>>>>>> .their - - import { DiffParser } from '../diff-parser' - -@@ -93,6 +100,7 @@ - * @param commitish A commit SHA or some other identifier that ultimately dereferences - * to a commit. - */ -+<<<<<<< .our - export async function getCommitDiff( - repository: Repository, - file: FileChange, -@@ -114,6 +122,9 @@ - if (file.oldPath != null) { - args.push(file.oldPath) - } -+======= -+export function getCommitDiff(repository: Repository, file: FileChange, commitish: string): Promise<IDiff> { -+>>>>>>> .their - - const { output } = await spawnAndComplete( - args, -@@ -121,7 +132,13 @@ - 'getCommitDiff' - ) - -+<<<<<<< .our - return buildDiff(output, repository, file, commitish) -+======= -+ return git(args, repository.path, 'getCommitDiff') -+ .then(value => diffFromRawDiffOutput(value.stdout)) -+ .then(diff => convertDiff(repository, file, diff, commitish)) -+>>>>>>> .their - } - - /** -@@ -129,11 +146,17 @@ - * compared against HEAD if it's tracked, if not it'll be compared to an empty file meaning - * that all content in the file will be treated as additions. - */ -+<<<<<<< .our - export async function getWorkingDirectoryDiff( - repository: Repository, - file: WorkingDirectoryFileChange - ): Promise<IDiff> { - let successExitCodes: Set<number> | undefined -+======= -+export function getWorkingDirectoryDiff(repository: Repository, file: WorkingDirectoryFileChange): Promise<IDiff> { -+ -+ let opts: IGitExecutionOptions | undefined -+>>>>>>> .their - let args: Array<string> - - // `--no-ext-diff` should be provided wherever we invoke `git diff` so that any -@@ -180,6 +203,7 @@ - file.path, - ] - } else { -+<<<<<<< .our - args = [ - 'diff', - 'HEAD', -@@ -208,6 +232,17 @@ - file: FileChange, - commitish: string - ): Promise<IImageDiff> { -+======= -+ args = [ 'diff', 'HEAD', '--patch-with-raw', '-z', '--', file.path ] -+ } -+ -+ return git(args, repository.path, 'getWorkingDirectoryDiff', opts) -+ .then(value => diffFromRawDiffOutput(value.stdout)) -+ .then(diff => convertDiff(repository, file, diff, 'HEAD')) -+} -+ -+async function getImageDiff(repository: Repository, file: FileChange, commitish: string): Promise<IImageDiff> { -+>>>>>>> .their - let current: Image | undefined = undefined - let previous: Image | undefined = undefined - -@@ -216,7 +251,11 @@ - // No idea what to do about this, a conflicted binary (presumably) file. - // Ideally we'd show all three versions and let the user pick but that's - // a bit out of scope for now. -+<<<<<<< .our - if (file.status === AppFileStatus.Conflicted) { -+======= -+ if (file.status === FileStatus.Conflicted) { -+>>>>>>> .their - return { kind: DiffType.Image } - } - -@@ -261,6 +300,7 @@ - } - } - -+<<<<<<< .our - export async function convertDiff( - repository: Repository, - file: FileChange, -@@ -271,6 +311,37 @@ - const extension = Path.extname(file.path).toLowerCase() - - if (diff.isBinary) { -+======= -+/** -+ * normalize the line endings in the diff so that the CodeMirror editor -+ * will display the unified diff correctly -+ */ -+function formatLineEnding(text: string): string { -+ if (text.endsWith('\n')) { -+ return text -+ } else if (text.endsWith('\r')) { -+ return text + '\n' -+ } else { -+ return text + '\r\n' -+ } -+} -+ -+function diffMatchesSubmoduleChange(hunk: DiffHunk): boolean { -+ // for any sort of submodule change, the first line should match this format -+ const line = hunk.lines[1] -+ const match = /[\+\-]Subproject commit ([a-z0-9]{40})/.exec(line.text) -+ // no need to look at the found hash, just looking for the equivalent format -+ if (match) { -+ return true -+ } -+ return false -+} -+ -+export async function convertDiff(repository: Repository, file: FileChange, diff: IRawDiff, commitish: string): Promise<IDiff> { -+ if (diff.isBinary) { -+ const extension = Path.extname(file.path) -+ -+>>>>>>> .their - // some extension we don't know how to parse, never mind - if (!imageFileExtensions.has(extension)) { - return { -@@ -281,11 +352,59 @@ - } - } - -+<<<<<<< .our - return { - kind: DiffType.Text, - text: diff.contents, - hunks: diff.hunks, - lineEndingsChange, -+======= -+ if (diff.hunks.length === 1) { -+ -+ const hunk = diff.hunks[0] -+ -+ if (hunk.lines.length <= 3) { -+ -+ const maybeSubmodule = diffMatchesSubmoduleChange(hunk) -+ -+ if (maybeSubmodule) { -+ -+ // TODO: what about renaming a submodule? Would that be handled here? -+ const result = await getSubmoduleDetails(repository, file, commitish) -+ -+ if (result) { -+ const name = Path.basename(file.path) -+ const type = result.type -+ const from = result.from -+ const to = result.to -+ -+ const changes = from && to -+ ? await getSubmoduleDiff(repository, file, from, to) -+ : undefined -+ -+ return { -+ kind: DiffType.Submodule, -+ type, -+ from, -+ to, -+ name, -+ changes, -+ } -+ } -+ } -+ } -+ } -+ -+ let diffText = '' -+ diff.hunks.forEach(hunk => { -+ hunk.lines.forEach(l => diffText += formatLineEnding(l.text)) -+ }) -+ -+ return { -+ kind: DiffType.Text, -+ text: diffText, -+ hunks: diff.hunks, -+>>>>>>> .their - } - } - -@@ -352,11 +471,15 @@ - * - * Parses the output from a diff-like command that uses `--path-with-raw` - */ -+<<<<<<< .our - function diffFromRawDiffOutput(output: Buffer): IRawDiff { - // for now we just assume the diff is UTF-8, but given we have the raw buffer - // we can try and convert this into other encodings in the future - const result = output.toString('utf-8') - -+======= -+function diffFromRawDiffOutput(result: string): IRawDiff { -+>>>>>>> .their - const pieces = result.split('\0') - const parser = new DiffParser() - return parser.parse(pieces[pieces.length - 1]) -@@ -393,6 +516,38 @@ - return convertDiff(repository, file, diff, commitish, lineEndingsChange) - } - -+function tryParseInt(text: string): number | undefined { -+ const value = parseInt(text, 10) -+ return isNaN(value) ? undefined : value -+} -+ -+export async function getSubmoduleDiff(repository: Repository, file: FileChange, from: string, to: string): Promise<ReadonlyArray<FileSummary>> { -+ const args = [ 'diff', '--numstat', '-z', `${from}..${to}` ] -+ const submodulePath = Path.join(repository.path, file.path) -+ -+ const diffStats = await git(args, submodulePath, 'getSubmoduleDiff') -+ const output = diffStats.stdout -+ -+ const results: Array<FileSummary> = [ ] -+ -+ const lines = output.split('\0') -+ -+ for (let i = 0; i < lines.length; i++) { -+ const line = lines[i] -+ const entries = line.split('\t') -+ -+ if (entries.length === 3) { -+ const added = tryParseInt(entries[0]) -+ const removed = tryParseInt(entries[1]) -+ const path = entries[2].trim().replace('\0', '') -+ -+ results.push(new FileSummary(path, added, removed)) -+ } -+ } -+ -+ return results -+} -+ - /** - * Retrieve the binary contents of a blob from the object database - * -added in both - our 100644 497889aae05c2de60409b2354678563f32994314 app/src/lib/git/submodule.ts - their 100644 efb0efe2bbb460832f610eb016e05f58b3c68bda app/src/lib/git/submodule.ts -@@ -1,4 +1,5 @@ - import * as Path from 'path' -+<<<<<<< .our - import { pathExists } from 'fs-extra' - - import { git } from './core' -@@ -88,3 +89,130 @@ - ) - } - } -+======= -+ -+import { git } from './core' -+import { Repository } from '../../models/repository' -+import { FileStatus, FileChange, WorkingDirectoryFileChange } from '../../models/status' -+import { mapStatus } from './status' -+ -+// TODO: docs -+ -+export class SubmoduleChange { -+ -+ public readonly path: string -+ -+ public readonly from?: string -+ -+ public readonly to?: string -+ -+ public readonly type: FileStatus -+} -+ -+const zeroSha = /0{7,40}/ -+const submoduleMode = '160000' -+ -+// NOTE: -+// as of Git 2.11, abbreviated SHAs may be more than 7 characters -+// we probably need to revisit some places where we do this trimming -+// ourselves - e.g. `commit-summary.tsx` -+function formatSha(text: string): string { -+ return text.slice(0, 7) -+} -+ -+/** -+ * Map the found identifier to a object id in the Git database -+ * -+ * @returns the 40-character OID if the object exists, or undefined if the -+ * found input is '0000000000000000000000000000000000000000' which -+ * represents a non-existent object. -+ */ -+function getIdentifier(input: string): string | undefined { -+ if (zeroSha.test(input)) { -+ return undefined -+ } -+ return formatSha(input) -+} -+ -+const submoduleEntryRegex = /Submodule .* ([a-z0-9]{7,40})..([a-z0-9]{7,40})\:/ -+ -+async function getSubmoduleDetailsWorkingDirectory(repository: Repository, file: WorkingDirectoryFileChange): Promise<SubmoduleChange | null> { -+ -+ if (file.status === FileStatus.New) { -+ // if the submodule has not been staged elsewhere, it's not going to appear -+ // in any of the `git submodule summary` calls - so let's poke at it here -+ const submodulePath = Path.join(repository.path, file.path) -+ -+ const result = await git([ 'show-ref', 'HEAD' ], submodulePath, 'submodule-workdir-untracked') -+ -+ const output = result.stdout -+ const tokens = output.split(' ') -+ -+ const tip = tokens[0] -+ -+ const path = file.path -+ const type = file.status -+ const from = undefined -+ const to = tip -+ return { path, from, to, type } -+ } else { -+ const result = await git([ 'diff', '--submodule', '-z', '--', file.path ], repository.path, 'submodule-workdir-tracked') -+ -+ const match = submoduleEntryRegex.exec(result.stdout) -+ if (match) { -+ const path = file.path -+ const type = file.status -+ const from = getIdentifier(match[1]) -+ const to = getIdentifier(match[2]) -+ return { path, from, to, type } -+ } -+ -+ return null -+ } -+} -+ -+async function getSubmoduleDetailsHistory(repository: Repository, file: FileChange, committish: string): Promise<SubmoduleChange | null> { -+ -+ const range = `${committish}~1..${committish}` -+ // TODO: control formatting betterer here? -+ const result = await git([ 'diff-tree', '--raw', '-z', range, '--', file.path ], repository.path, 'submodule-history') -+ -+ // the expected format here is a row like this: -+ // :000000 160000 0000000000000000000000000000000000000000 f1a74d299b28b4278d6127fbb3e9cc7aeedc153f A friendly-bassoon -+ // -+ // index 0 is the empty string before the first semi-colon, skip it -+ const line = result.stdout.substr(1) -+ // \0 separates path from diff stats -+ const tokens = line.split('\0') -+ const inputs = tokens[0].split(' ') -+ const path = tokens[1] -+ -+ // the first two values are the mode for the change -+ // if either of these values is 160000, we have a submodule change -+ if (inputs[0] === submoduleMode || inputs[1] === submoduleMode) { -+ const from = getIdentifier(inputs[2]) -+ const to = getIdentifier(inputs[3]) -+ const type = mapStatus(inputs[4]) -+ return { path, from, to, type } -+ } -+ -+ return null -+} -+ -+/** -+ * Retrieve the submodule list for the current repository. -+ * -+ * For historical commits, use `git diff-tree` as this works independent of the -+ * .gitmodules state. -+ * -+ * For working directory changes, use `git submodule summary` as the .gitmodules -+ * state can be relied on for tracking changes. -+ */ -+export async function getSubmoduleDetails(repository: Repository, file: FileChange, committish: string): Promise<SubmoduleChange | null> { -+ if (file instanceof WorkingDirectoryFileChange) { -+ return getSubmoduleDetailsWorkingDirectory(repository, file) -+ } else { -+ return getSubmoduleDetailsHistory(repository, file, committish) -+ } -+} -+>>>>>>> .their -changed in both - base 100644 89bc05d61dc8e935503d1c57fd962a7edd5654de app/src/lib/patch-formatter.ts - our 100644 07394cb099e9aa88821fa27c76986f91e7c86007 app/src/lib/patch-formatter.ts - their 100644 15945ecc933d4f324d7231f625b341b1675e2fb4 app/src/lib/patch-formatter.ts -@@ -1,5 +1,9 @@ - import { assertNever } from '../lib/fatal-error' -+<<<<<<< .our - import { WorkingDirectoryFileChange, AppFileStatus } from '../models/status' -+======= -+import { WorkingDirectoryFileChange, FileStatus } from '../models/status' -+>>>>>>> .their - import { DiffLineType, ITextDiff } from '../models/diff' - - /** -@@ -114,10 +118,14 @@ - * - * @param diff The source diff - */ -+<<<<<<< .our - export function formatPatch( - file: WorkingDirectoryFileChange, - diff: ITextDiff - ): string { -+======= -+export function formatPatch(file: WorkingDirectoryFileChange, diff: ITextDiff): string { -+>>>>>>> .their - let patch = '' - - diff.hunks.forEach((hunk, hunkIndex) => { -removed in local - base 100644 8e1278e78e0dfe9067cfa506261d342c74ae94f8 app/src/models/diff.ts - their 100644 d6f40a61ae4fae061485ecc00454a87ee3bc52cf app/src/models/diff.ts -added in both - our 100644 dc40c8309be3d5fb88ce7c549d18e0a218138062 app/src/ui/diff/diff-explorer.ts - their 100644 15fc1c1dbbc1f6745f8449df16b05a354e842cb0 app/src/ui/diff/diff-explorer.ts -@@ -1,13 +1,22 @@ -+<<<<<<< .our - import { DiffLine, DiffHunk } from '../../models/diff' -+======= -+import { DiffLine, DiffHunk, ITextDiff } from '../../models/diff' -+>>>>>>> .their - - /** - * Locate the diff hunk for the given (absolute) line number in the diff. - */ -+<<<<<<< .our - export function diffHunkForIndex( - hunks: ReadonlyArray<DiffHunk>, - index: number - ): DiffHunk | null { - const hunk = hunks.find(h => { -+======= -+export function diffHunkForIndex(diff: ITextDiff, index: number): DiffHunk | null { -+ const hunk = diff.hunks.find(h => { -+>>>>>>> .their - return index >= h.unifiedDiffStart && index <= h.unifiedDiffEnd - }) - return hunk || null -@@ -16,6 +25,7 @@ - /** - * Locate the diff line for the given (absolute) line number in the diff. - */ -+<<<<<<< .our - export function diffLineForIndex( - hunks: ReadonlyArray<DiffHunk>, - index: number -@@ -92,3 +102,11 @@ - - return { start, end } - } -+======= -+export function diffLineForIndex(diff: ITextDiff, index: number): DiffLine | null { -+ const hunk = diffHunkForIndex(diff, index) -+ if (!hunk) { return null } -+ -+ return hunk.lines[index - hunk.unifiedDiffStart] || null -+} -+>>>>>>> .their -changed in both - base 100644 3e516b6d4f3d61bfd9ee4f1cf169b1f7daaf8527 app/src/ui/diff/diff-line-gutter.tsx - our 100644 de4e6d59229013efd700fa8ab59fdabd09a5054b app/src/ui/diff/diff-line-gutter.tsx - their 100644 9dc3b00bbe2647df1093590982d14f7b730e6a37 app/src/ui/diff/diff-line-gutter.tsx -@@ -1,6 +1,11 @@ - import * as React from 'react' -+<<<<<<< .our - import { DiffHunk, DiffLine, DiffLineType } from '../../models/diff' - import { diffHunkForIndex, findInteractiveDiffRange } from './diff-explorer' -+======= -+import { ITextDiff, DiffHunk, DiffLine, DiffLineType } from '../../models/diff' -+import { diffHunkForIndex } from './diff-explorer' -+>>>>>>> .their - import { hoverCssClass, selectedLineClass } from './selection/selection' - import { assertNever } from '../../lib/fatal-error' - import * as classNames from 'classnames' -@@ -30,7 +35,11 @@ - /** - * The diff currently displayed in the app - */ -+<<<<<<< .our - readonly hunks: ReadonlyArray<DiffHunk> -+======= -+ readonly diff: ITextDiff -+>>>>>>> .their - - /** - * Callback to apply hover effect to specific lines in the diff -@@ -203,14 +212,37 @@ - - private mouseLeaveHandler = (ev: MouseEvent) => { - ev.preventDefault() -+<<<<<<< .our - const isRangeSelection = isMouseCursorNearEdge(ev) - this.updateHoverState(isRangeSelection, false) -+======= -+ -+ const isHunkSelection = isMouseInHunkSelectionZone(ev) -+ this.updateHoverState(isHunkSelection, false) -+ } -+ -+ private updateHoverState(isHunkSelection: boolean, isActive: boolean) { -+ if (isHunkSelection) { -+ const hunk = diffHunkForIndex(this.props.diff, this.props.index) -+ if (!hunk) { -+ console.error('unable to find hunk for given line in diff') -+ return -+ } -+ this.props.updateHunkHoverState(hunk, isActive) -+ } else { -+ this.setHover(isActive) -+ } -+>>>>>>> .their - } - - private mouseMoveHandler = (ev: MouseEvent) => { - ev.preventDefault() - -+<<<<<<< .our - const hunk = diffHunkForIndex(this.props.hunks, this.props.index) -+======= -+ const hunk = diffHunkForIndex(this.props.diff, this.props.index) -+>>>>>>> .their - if (!hunk) { - console.error('unable to find hunk for given line in diff') - return -changed in both - base 100644 611f7bbe5cd13b46da78feabc6c1f0264266862a app/src/ui/diff/index.tsx - our 100644 8695c640dc0a5184c74a112f131a2e2a07ef572d app/src/ui/diff/index.tsx - their 100644 279bcb59b65d4b90754eb67db81a79729f423f37 app/src/ui/diff/index.tsx -@@ -1,6 +1,19 @@ - import * as React from 'react' -+<<<<<<< .our -+======= -+import * as ReactDOM from 'react-dom' -+import { Disposable } from 'event-kit' -+ -+import { NewImageDiff } from './new-image-diff' -+import { ModifiedImageDiff } from './modified-image-diff' -+import { DeletedImageDiff } from './deleted-image-diff' -+import { BinaryFile } from './binary-file' -+import { SubmoduleDiff } from './submodule-diff' -+ -+>>>>>>> .their - import { Editor } from 'codemirror' - -+<<<<<<< .our - import { assertNever } from '../../lib/fatal-error' - import { encodePathAsUrl } from '../../lib/path' - import { ImageDiffType } from '../../lib/app-state' -@@ -30,17 +43,27 @@ - } from './image-diffs' - import { BinaryFile } from './binary-file' - import { diffLineForIndex } from './diff-explorer' -+======= -+import { FileChange, WorkingDirectoryFileChange, FileStatus } from '../../models/status' -+import { DiffHunk, DiffSelection, DiffType, IDiff, IImageDiff, ITextDiff, ISubmoduleDiff } from '../../models/diff' -+import { Dispatcher } from '../../lib/dispatcher/dispatcher' -+ -+import { diffLineForIndex, diffHunkForIndex } from './diff-explorer' -+>>>>>>> .their - import { DiffLineGutter } from './diff-line-gutter' - import { DiffSyntaxMode } from './diff-syntax-mode' - - import { ISelectionStrategy } from './selection/selection-strategy' - import { TextDiff } from './text-diff' - -+<<<<<<< .our - // image used when no diff is displayed - const NoDiffImage = encodePathAsUrl(__dirname, 'static/ufo-alert.svg') - - type ChangedFile = WorkingDirectoryFileChange | CommittedFileChange - -+======= -+>>>>>>> .their - /** The props for the Diff component. */ - interface IDiffProps { - readonly repository: Repository -@@ -129,7 +152,11 @@ - } - - if (diff.kind === DiffType.Text) { -+<<<<<<< .our - const line = diffLineForIndex(diff.hunks, index) -+======= -+ const line = diffLineForIndex(diff, index) -+>>>>>>> .their - const isIncludable = line ? line.isIncludeableLine() : false - const isSelected = selection.isSelected(index) && isIncludable - element.setSelected(isSelected) -@@ -190,8 +217,42 @@ - this.selection = null - } - -+<<<<<<< .our - private onChangeImageDiffType = (type: ImageDiffType) => { - this.props.dispatcher.changeImageDiffType(type) -+======= -+ private onMouseDown = (index: number, isHunkSelection: boolean) => { -+ if (!(this.props.file instanceof WorkingDirectoryFileChange)) { -+ fatalError('must not start selection when selected file is not a WorkingDirectoryFileChange') -+ return -+ } -+ -+ const diff = this.props.diff -+ if (diff.kind !== DiffType.Text) { -+ // text diffs are the only ones that can handle selection -+ return -+ } -+ -+ const snapshot = this.props.file.selection -+ const selected = snapshot.isSelected(index) -+ const desiredSelection = !selected -+ -+ if (isHunkSelection) { -+ const hunk = diffHunkForIndex(diff, index) -+ if (!hunk) { -+ console.error('unable to find hunk for given line in diff') -+ return -+ } -+ -+ const start = hunk.unifiedDiffStart -+ const end = hunk.unifiedDiffEnd -+ this.selection = new HunkSelection(start, end, desiredSelection, snapshot) -+ } else { -+ this.selection = new DragDropSelection(index, desiredSelection, snapshot) -+ } -+ -+ this.selection.paint(this.cachedGutterElements) -+>>>>>>> .their - } - - private renderImage(imageDiff: IImageDiff) { -@@ -210,11 +271,96 @@ - return <NewImageDiff current={imageDiff.current} /> - } - -+<<<<<<< .our - if ( - imageDiff.previous && - this.props.file.status === AppFileStatus.Deleted - ) { - return <DeletedImageDiff previous={imageDiff.previous} /> -+======= -+ const diff = this.props.diff -+ if (diff.kind !== DiffType.Text) { -+ return -+ } -+ -+ const index = instance.getLineNumber(line) as number -+ const hunk = diffHunkForIndex(diff, index) -+ if (hunk) { -+ const relativeIndex = index - hunk.unifiedDiffStart -+ const diffLine = hunk.lines[relativeIndex] -+ if (diffLine) { -+ const diffLineElement = element.children[0] as HTMLSpanElement -+ -+ const reactContainer = document.createElement('span') -+ -+ let isIncluded = false -+ if (this.props.file instanceof WorkingDirectoryFileChange) { -+ isIncluded = this.props.file.selection.isSelected(index) -+ } -+ -+ const cache = this.cachedGutterElements -+ -+ ReactDOM.render( -+ <DiffLineGutter -+ line={diffLine} -+ isIncluded={isIncluded} -+ index={index} -+ readOnly={this.props.readOnly} -+ diff={diff} -+ updateHunkHoverState={this.updateHunkHoverState} -+ isSelectionEnabled={this.isSelectionEnabled} -+ onMouseUp={this.onMouseUp} -+ onMouseDown={this.onMouseDown} -+ onMouseMove={this.onMouseMove} />, -+ reactContainer, -+ function (this: DiffLineGutter) { -+ if (this !== undefined) { -+ cache.set(index, this) -+ } -+ } -+ ) -+ -+ element.insertBefore(reactContainer, diffLineElement) -+ -+ // Hack(ish?). In order to be a real good citizen we need to unsubscribe from -+ // the line delete event once we've been called once or the component has been -+ // unmounted. In the latter case it's _probably_ not strictly necessary since -+ // the only thing gc rooted by the event should be isolated and eligble for -+ // collection. But let's be extra cautious I guess. -+ // -+ // The only way to unsubscribe is to pass the exact same function given to the -+ // 'on' function to the 'off' so we need a reference to ourselves, basically. -+ let deleteHandler: () => void -+ -+ // Since we manually render a react component we have to take care of unmounting -+ // it or else we'll leak memory. This disposable will unmount the component. -+ // -+ // See https://facebook.github.io/react/blog/2015/10/01/react-render-and-top-level-api.html -+ const gutterCleanup = new Disposable(() => { -+ this.cachedGutterElements.delete(index) -+ -+ ReactDOM.unmountComponentAtNode(reactContainer) -+ -+ line.off('delete', deleteHandler) -+ }) -+ -+ // Add the cleanup disposable to our list of disposables so that we clean up when -+ // this component is unmounted or when the line is re-rendered. When either of that -+ // happens the line 'delete' event doesn't fire. -+ this.lineCleanup.set(line, gutterCleanup) -+ -+ // If the line delete event fires we dispose of the disposable (disposing is -+ // idempotent) -+ deleteHandler = () => { -+ const disp = this.lineCleanup.get(line) -+ if (disp) { -+ this.lineCleanup.delete(line) -+ disp.dispose() -+ } -+ } -+ line.on('delete', deleteHandler) -+ } -+>>>>>>> .their - } - - return null -@@ -246,6 +392,7 @@ - ) - } - -+<<<<<<< .our - private renderLargeText(diff: ILargeTextDiff) { - // guaranteed to be set since this function won't be called if text or hunks are null - const textDiff: ITextDiff = { -@@ -253,11 +400,27 @@ - hunks: diff.hunks, - kind: DiffType.Text, - lineEndingsChange: diff.lineEndingsChange, -+======= -+ private renderImage(imageDiff: IImageDiff) { -+ if (imageDiff.current && imageDiff.previous) { -+ return <ModifiedImageDiff -+ current={imageDiff.current} -+ previous={imageDiff.previous} /> -+ } -+ -+ if (imageDiff.current && this.props.file.status === FileStatus.New) { -+ return <NewImageDiff current={imageDiff.current} /> -+ } -+ -+ if (imageDiff.previous && this.props.file.status === FileStatus.Deleted) { -+ return <DeletedImageDiff previous={imageDiff.previous} /> -+>>>>>>> .their - } - - return this.renderTextDiff(textDiff) - } - -+<<<<<<< .our - private renderText(diff: ITextDiff) { - if (diff.hunks.length === 0) { - if (this.props.file.status === AppFileStatus.New) { -@@ -299,6 +462,72 @@ - hunks={diff.hunks} - /> - ) -+======= -+ private renderBinaryFile() { -+ return <BinaryFile path={this.props.file.path} -+ repository={this.props.repository} -+ dispatcher={this.props.dispatcher} /> -+ } -+ -+ private renderSubmoduleDiff(diff: ISubmoduleDiff) { -+ return <SubmoduleDiff name={diff.name} -+ type={diff.type} -+ from={diff.from} -+ to={diff.to} -+ changes={diff.changes} /> -+ } -+ -+ private renderTextDiff(diff: ITextDiff) { -+ const options: IEditorConfigurationExtra = { -+ lineNumbers: false, -+ readOnly: true, -+ showCursorWhenSelecting: false, -+ cursorBlinkRate: -1, -+ lineWrapping: localStorage.getItem('soft-wrap-is-best-wrap') ? true : false, -+ // Make sure CodeMirror doesn't capture Tab and thus destroy tab navigation -+ extraKeys: { Tab: false }, -+ scrollbarStyle: __DARWIN__ ? 'simple' : 'native', -+ mode: getDiffMode(), -+ } -+ -+ return ( -+ <CodeMirrorHost -+ className='diff-code-mirror' -+ value={diff.text} -+ options={options} -+ isSelectionEnabled={this.isSelectionEnabled} -+ onChanges={this.onChanges} -+ onRenderLine={this.renderLine} -+ ref={this.getAndStoreCodeMirrorInstance} -+ /> -+ ) -+ } -+ -+ private getAndStoreCodeMirrorInstance = (cmh: CodeMirrorHost) => { -+ this.codeMirror = cmh === null ? null : cmh.getEditor() -+ } -+ -+ public render() { -+ const diff = this.props.diff -+ -+ if (diff.kind === DiffType.Image) { -+ return this.renderImage(diff) -+ } -+ -+ if (diff.kind === DiffType.Binary) { -+ return this.renderBinaryFile() -+ } -+ -+ if (diff.kind === DiffType.Text) { -+ return this.renderTextDiff(diff) -+ } -+ -+ if (diff.kind === DiffType.Submodule) { -+ return this.renderSubmoduleDiff(diff) -+ } -+ -+ return null -+>>>>>>> .their - } - - private showLargeDiff = () => { -added in remote - their 100644 3ec848da728a2dd4ce1688ceae1f87cb00aa29d8 app/src/ui/diff/submodule-diff.tsx -@@ -0,0 +1,68 @@ -+import * as React from 'react' -+ -+import { Octicon, OcticonSymbol } from '../octicons' -+import { FileSummary } from '../../models/diff' -+import { FileStatus } from '../../models/status' -+ -+interface ISubmoduleDiffProps { -+ readonly changes?: ReadonlyArray<FileSummary> -+ readonly name: string -+ readonly type: FileStatus -+ readonly from?: string -+ readonly to?: string -+} -+ -+/** A component to render when a new image has been added to the repository */ -+export class SubmoduleDiff extends React.Component<ISubmoduleDiffProps, void> { -+ -+ public render() { -+ -+ if (this.props.type === FileStatus.New || this.props.type === FileStatus.Deleted) { -+ const action = this.props.type === FileStatus.New -+ ? 'added at' -+ : 'removed from' -+ -+ // when removing or adding a submodule, only one SHA is available -+ const sha = this.props.type === FileStatus.New -+ ? this.props.to -+ : this.props.from -+ -+ if (!sha) { -+ console.error('the submodule diff should have specified a SHA but it didn\'t, look into this') -+ } -+ -+ return <div className='panel' id='diff'> -+ <div className='submodule-header'> -+ <Octicon symbol={OcticonSymbol.fileSubmodule} /> Submodule {this.props.name} {action} {sha} -+ </div> -+ </div> -+ } -+ -+ const message = this.props.changes -+ ? `${this.props.changes.length} ${this.props.changes.length > 1 ? 'files' : 'file'}` -+ : `from ${this.props.from} to ${this.props.to}` -+ -+ const changes = this.props.changes || [ ] -+ -+ return <div className='panel' id='diff'> -+ <div className='submodule-header'> -+ <Octicon symbol={OcticonSymbol.fileSubmodule} /> Submodule {this.props.name} updated {message} -+ </div> -+ -+ <table className='submodule-changes'> -+ <tbody> -+ {changes.map(f => -+ <tr className='entry' key={f.id}> -+ <td className='stats'> -+ <span className='added'>+{f.added}</span> -+ <span className='removed'> -{f.removed}</span> -+ </td> -+ <td className='icon'><Octicon symbol={OcticonSymbol.diffModified} /></td> -+ <td className='path'>{f.path}</td> -+ </tr> -+ )} -+ </tbody> -+ </table> -+ </div> -+ } -+} -changed in both - base 100644 e6c3b8f49a2b24e7478e4fbf5c6ebc507f5279be app/styles/_variables.scss - our 100644 6c89a529c5a8dbfefb127f171468af9ae5651141 app/styles/_variables.scss - their 100644 a11f9adbcecf5e114799353a54e7a7339e18128b app/styles/_variables.scss -@@ -333,6 +333,7 @@ - --diff-hover-gutter-color: $blue-400; - --diff-hover-text-color: var(--background-color); - -+<<<<<<< .our - --diff-add-hover-background-color: $green-300; - --diff-add-hover-border-color: $green-400; - --diff-add-hover-gutter-color: $green-400; -@@ -356,6 +357,10 @@ - --syntax-attribute-color: #6f42c1; - --syntax-link-color: #032f62; - --syntax-header-color: #0000ff; -+======= -+ --diff-submodule-add-text-color: #55a532; -+ --diff-submodule-remove-text-color: #bd2c00; -+>>>>>>> .their - - // Note that this duration *must* match the `UndoCommitAnimationTimeout` - // specified in `changes/index.tsx`. -changed in both - base 100644 fe2b84bd34f381a033b197d20aaefa97e9bf8487 app/styles/ui/_diff.scss - our 100644 372c4e6b8d6af44922f648559b128e98c085134d app/styles/ui/_diff.scss - their 100644 963a4fa2f1f92344c241f4fc9085833ac3feaa45 app/styles/ui/_diff.scss -@@ -565,3 +565,38 @@ - } - } - } -+// *************************************************************************************************************************** -+ -+#diff .submodule-header { -+ margin: var(--spacing-half) var(--spacing); -+ -+ .octicon { -+ vertical-align: text-top; -+ } -+} -+ -+#diff .submodule-changes { -+ margin: 0px var(--spacing-triple); -+ -+ .stats { -+ text-align: right; -+ padding-right: var(--spacing); -+ box-sizing: border-box -+ } -+ -+ .added { -+ color: var(--diff-submodule-add-text-color); -+ } -+ -+ .removed { -+ color: var(--diff-submodule-remove-text-color); -+ } -+ -+ .icon { -+ color: var(--color-modified); -+ -+ .octicon { -+ vertical-align: text-top; -+ } -+ } -+} -\ No newline at end of file -removed in local - base 100644 54351aef2f622a952d5f9e76430fdd381745ed60 app/test/fixture-helper.ts - their 100644 d5b53ec32b23c5dea5e84be3fdad21dfa582062d app/test/fixture-helper.ts -added in remote - their 100644 a681274e61ddc6f5ce99462d47db6f334b2ef804 app/test/fixtures/repository-with-submodule-change/.gitmodules -@@ -0,0 +1,3 @@ -+[submodule "friendly-bassoon"] -+ path = friendly-bassoon -+ url = https://github.com/shiftkey/friendly-bassoon.git -added in remote - their 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 app/test/fixtures/repository-with-submodule-change/README.md -added in remote - their 100644 099b35e7ee7aee17705fe449b5479a80de42a46b app/test/fixtures/repository-with-submodule-change/_git/COMMIT_EDITMSG -@@ -0,0 +1 @@ -+added submodule -added in remote - their 100644 cb089cd89a7d7686d284d8761201649346b5aa1c app/test/fixtures/repository-with-submodule-change/_git/HEAD -@@ -0,0 +1 @@ -+ref: refs/heads/master -added in remote - their 100644 638e1db7272faf93c1dbe1d5601211df798235e6 app/test/fixtures/repository-with-submodule-change/_git/config -@@ -0,0 +1,9 @@ -+[core] -+ repositoryformatversion = 0 -+ filemode = true -+ bare = false -+ logallrefupdates = true -+ ignorecase = true -+ precomposeunicode = true -+[submodule "friendly-bassoon"] -+ url = https://github.com/shiftkey/friendly-bassoon.git -added in remote - their 100644 498b267a8c7812490d6479839c5577eaaec79d62 app/test/fixtures/repository-with-submodule-change/_git/description -@@ -0,0 +1 @@ -+Unnamed repository; edit this file 'description' to name the repository. -added in remote - their 100644 002b960c2105f2920e2e4d36638eaca5736a09e9 app/test/fixtures/repository-with-submodule-change/_git/index -@@ -0,0 +1,2 @@ -+DIRC+�/���ŭ�?)-O�����fW�+M����W��%���� ��8� -\ No newline at end of file -added in remote - their 100644 a5196d1be8fb59edf8062bef36d3a602e0812139 app/test/fixtures/repository-with-submodule-change/_git/info/exclude -@@ -0,0 +1,6 @@ -+# git ls-files --others --exclude-from=.git/info/exclude -+# Lines that start with '#' are comments. -+# For a project mostly in C, the following would be a good set of -+# exclude patterns (uncomment them if you want to use them): -+# *.[oa] -+# *~ -added in remote - their 100644 9ea85a1ed5c989f698dc54d47e9b1f629ef6c352 app/test/fixtures/repository-with-submodule-change/_git/logs/HEAD -@@ -0,0 +1,2 @@ -+0000000000000000000000000000000000000000 3d86799509ebef82896e96bf175cc2aa22b5c3cc Brendan Forster <brendan@github.com> 1480641798 +1100 commit (initial): create empty file -+3d86799509ebef82896e96bf175cc2aa22b5c3cc 2b0eed7db3ab39050a3bc71888b2ed3fe77802e2 Brendan Forster <brendan@github.com> 1480641906 +1100 commit: added submodule -added in remote - their 100644 9ea85a1ed5c989f698dc54d47e9b1f629ef6c352 app/test/fixtures/repository-with-submodule-change/_git/logs/refs/heads/master -@@ -0,0 +1,2 @@ -+0000000000000000000000000000000000000000 3d86799509ebef82896e96bf175cc2aa22b5c3cc Brendan Forster <brendan@github.com> 1480641798 +1100 commit (initial): create empty file -+3d86799509ebef82896e96bf175cc2aa22b5c3cc 2b0eed7db3ab39050a3bc71888b2ed3fe77802e2 Brendan Forster <brendan@github.com> 1480641906 +1100 commit: added submodule -added in remote - their 100644 d9060fa013fa103fcc4f2f723f8360dbe08e9415 app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/FETCH_HEAD -@@ -0,0 +1 @@ -+f1a74d299b28b4278d6127fbb3e9cc7aeedc153f branch 'master' of https://github.com/shiftkey/friendly-bassoon -added in remote - their 100644 cb089cd89a7d7686d284d8761201649346b5aa1c app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/HEAD -@@ -0,0 +1 @@ -+ref: refs/heads/master -added in remote - their 100644 fbf6dff08db39d3e3a25baa082900310039533e9 app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/ORIG_HEAD -@@ -0,0 +1 @@ -+ba7ba0bfa67c309b09835bd9b96198b5b19a5b16 -added in remote - their 100644 f042bd0069421510841216504515b990f41c559f app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/config -@@ -0,0 +1,14 @@ -+[core] -+ repositoryformatversion = 0 -+ filemode = true -+ bare = false -+ logallrefupdates = true -+ worktree = ../../../friendly-bassoon -+ ignorecase = true -+ precomposeunicode = true -+[remote "origin"] -+ url = https://github.com/shiftkey/friendly-bassoon.git -+ fetch = +refs/heads/*:refs/remotes/origin/* -+[branch "master"] -+ remote = origin -+ merge = refs/heads/master -added in remote - their 100644 498b267a8c7812490d6479839c5577eaaec79d62 app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/description -@@ -0,0 +1 @@ -+Unnamed repository; edit this file 'description' to name the repository. -added in remote - their 100644 639854c84156b7f99a172c48178aa1da16fd804e app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/index -@@ -0,0 +1,3 @@ -+DIRC+.gitignore+�E6 �XY[KU ��N�;�CS�F������|�� �,� -\ No newline at end of file -added in remote - their 100644 a5196d1be8fb59edf8062bef36d3a602e0812139 app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/info/exclude -@@ -0,0 +1,6 @@ -+# git ls-files --others --exclude-from=.git/info/exclude -+# Lines that start with '#' are comments. -+# For a project mostly in C, the following would be a good set of -+# exclude patterns (uncomment them if you want to use them): -+# *.[oa] -+# *~ -added in remote - their 100644 27de224e90d50b4e2e3018258f09645377548292 app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/logs/HEAD -@@ -0,0 +1,2 @@ -+0000000000000000000000000000000000000000 ba7ba0bfa67c309b09835bd9b96198b5b19a5b16 Brendan Forster <brendan@github.com> 1480641858 +1100 clone: from https://github.com/shiftkey/friendly-bassoon.git -+ba7ba0bfa67c309b09835bd9b96198b5b19a5b16 f1a74d299b28b4278d6127fbb3e9cc7aeedc153f Brendan Forster <brendan@github.com> 1480642009 +1100 pull: Fast-forward -added in remote - their 100644 27de224e90d50b4e2e3018258f09645377548292 app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/logs/refs/heads/master -@@ -0,0 +1,2 @@ -+0000000000000000000000000000000000000000 ba7ba0bfa67c309b09835bd9b96198b5b19a5b16 Brendan Forster <brendan@github.com> 1480641858 +1100 clone: from https://github.com/shiftkey/friendly-bassoon.git -+ba7ba0bfa67c309b09835bd9b96198b5b19a5b16 f1a74d299b28b4278d6127fbb3e9cc7aeedc153f Brendan Forster <brendan@github.com> 1480642009 +1100 pull: Fast-forward -added in remote - their 100644 2305d374cbaafed2ce6e898c1c7407f0516fea18 app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/logs/refs/remotes/origin/HEAD -@@ -0,0 +1 @@ -+0000000000000000000000000000000000000000 ba7ba0bfa67c309b09835bd9b96198b5b19a5b16 Brendan Forster <brendan@github.com> 1480641858 +1100 clone: from https://github.com/shiftkey/friendly-bassoon.git -added in remote - their 100644 b89ad60ec3fc350b6af7909cc3289b7bae40b432 app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/logs/refs/remotes/origin/master -@@ -0,0 +1 @@ -+ba7ba0bfa67c309b09835bd9b96198b5b19a5b16 f1a74d299b28b4278d6127fbb3e9cc7aeedc153f Brendan Forster <brendan@github.com> 1480642001 +1100 fetch: fast-forward -added in remote - their 100644 f61734b707b45193a84dd0793677a2bc965a3a27 app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/objects/0b/a8a7e4e260ae93d17a2178a906663faccc712b -@@ -0,0 +1 @@ -+x+)JMU044`040031Q�K�,�L��/Je���B��핢l[�+N�}��������/ؕaU�ݚG-2�������r���� WG_W���m:w�k4�P������)��k���0q -\ No newline at end of file -added in remote - their 100644 0cc886813b8b1769630710cb632ca43fae648143 app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/objects/0f/91ecbd640e30969a56cefde559edeba9e11bed -@@ -0,0 +1 @@ -+xK��OR05bPVH+�L�Kɩ�MJ,.������M���KW(��MUH�H�KO-V(�W(�HUH��I� -\ No newline at end of file -added in remote - their 100644 6c4a10db08799ff493a350f72e1d5a1c9066590d app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/objects/aa/83dd7cfec538e10256998af78d4550a9a543a0 -@@ -0,0 +1,3 @@ -+x]RK��0�ٿb��VB��=�Ro��U�8����WG�i���c�l�JH���5nF���ӷ�O[.!ӭ��"$6�w������3�<=��USWO�뼲��ʞ�s�L� ʪ������"�R`zh��U�@=��YY����t�Z�"���q����*l�vδ�F<�L;���k�z=*~P��n�� I��� �ܯ��`fV9ou0"�S;�]�p��I����#�|v� ��d:݇�Zl��f�n�����=v�P\����/ƂS�HA����_uKO��A�[D.T.�9��D;��vBJ ;:��-��T�C%(��8�K�֚�����N�ī�1������x��Ľ,`q���� �8B�n�!/Ƌ�;�nn����z��� ��6�à*R������OX+Z�y���M������+4?��'���`U� |[f�a��q�Kx� -+k�� |��2��� �3�Ka�D�Ad������\�3-P(��<�eT@�eQ1�O6�y*��mY.�k��� -\ No newline at end of file -added in remote - their 100644 4c692a070a3f7a99d6b73253857afb98dc47e07d app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/objects/b6/2cddc72880f8275efd8ae2d931ca13e55bad8b -@@ -0,0 +1 @@ -+xK��OR0�`PVH+�L�Kɩ�MJ,.��� -\ No newline at end of file -added in remote - their 100644 2219f006c10506658c5f5de1e78059036ad9fda4 app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/objects/ba/7ba0bfa67c309b09835bd9b96198b5b19a5b16 -@@ -0,0 +1,3 @@ -+x��A -+�0E]��d& �Dą�1&�h6����Jo�����.K�@���F �թe���X�AFd��))%O6Y�\ܚ�I -+�k�tmp�;��r��xJu� -\ No newline at end of file -added in remote - their 100644 5adaa29679d1f16b2af71ed877d6ab1251deaad6 app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/objects/d6/4508360b9d58595b4b550c9b06bf4eb53b1eb6 -@@ -0,0 +1 @@ -+x+)JMU044`040031Q�K�,�L��/Je���B��핢l[�+N�}��������/ؕaU�ݚG-2�������r���� WG_W����o���L�v���ȷ�W>�~ -\ No newline at end of file -added in remote - their 100644 d3f7260795dd57806098295aeba31896553d5f2a app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/objects/f1/a74d299b28b4278d6127fbb3e9cc7aeedc153f -@@ -0,0 +1,2 @@ -+x}�Aj�0E��)f�X�H`B��5�Il���Ȅ�>*�w����yY�Jǣ�բJ�Ya�;FH�%,Dx `��UH�p�#]+!���Nc�� -+����L��۸.nuʅ>[��J_�<��>ns�6Ƽ��X�ζ�������׿��{ k.�����u�\ғn�&-�{TGJ -\ No newline at end of file -added in remote - their 100644 f9f31686ca7aba1cdc075b687cb2b7a634d0017a app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/objects/f8/05e810e5c6e087791506b4e721958de3574ae4 -@@ -0,0 +1,2 @@ -+x=���0�=�M�(�F����&�'ӟ���"��SL<��Mwf�� -+��o1�����*m�GIjQ� -\ No newline at end of file -added in remote - their 100644 2908b3e468a38f1099d3772d58d7bf4bd860938f app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/packed-refs -@@ -0,0 +1,2 @@ -+# pack-refs with: peeled fully-peeled -+ba7ba0bfa67c309b09835bd9b96198b5b19a5b16 refs/remotes/origin/master -added in remote - their 100644 b15db3b0fa3e514577be6ee9d422d2640602f09e app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/refs/heads/master -@@ -0,0 +1 @@ -+f1a74d299b28b4278d6127fbb3e9cc7aeedc153f -added in remote - their 100644 6efe28fff834a94fbc20cac51fe9cd65ecc78d43 app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/refs/remotes/origin/HEAD -@@ -0,0 +1 @@ -+ref: refs/remotes/origin/master -added in remote - their 100644 b15db3b0fa3e514577be6ee9d422d2640602f09e app/test/fixtures/repository-with-submodule-change/_git/modules/friendly-bassoon/refs/remotes/origin/master -@@ -0,0 +1 @@ -+f1a74d299b28b4278d6127fbb3e9cc7aeedc153f -added in remote - their 100644 095a034a4f32bf06147462f1cba9372b0ee00f41 app/test/fixtures/repository-with-submodule-change/_git/objects/2b/0eed7db3ab39050a3bc71888b2ed3fe77802e2 -@@ -0,0 +1 @@ -+x��Aj�0 -\ No newline at end of file -added in remote - their 100644 8a65b437fe5091113b67449b099cc0a13cf73c19 app/test/fixtures/repository-with-submodule-change/_git/objects/3d/86799509ebef82896e96bf175cc2aa22b5c3cc -@@ -0,0 +1,3 @@ -+x��A -+�0+�U��H����v�m �G��8� ��َ}L�7�K�k�u�n��T* �.�E�-�R�g �s�G"D�������M��* ��o�����>� -\ No newline at end of file -added in remote - their 100644 6a2e3bd70bd0a3a591a81f554af268c9df0e3ac6 app/test/fixtures/repository-with-submodule-change/_git/objects/96/2f9afa84c5adb23f292d4ffac8f5ebce6657e6 -@@ -0,0 +1 @@ -+x+)JMU042`040031Q�K�,��O)�I-fX֨�x���s3�t�o�{��`�* rut�u��Max6���M�9{wk�+��q�IO�DC3 PH+�L�Kɩ�MJ,.���c�U�`���ٜ��7w&�غqV� -\ No newline at end of file -added in remote - their 100644 0c1dd4b0f7faec0d272efa31b733251d93418df0 app/test/fixtures/repository-with-submodule-change/_git/objects/a6/81274e61ddc6f5ce99462d47db6f334b2ef804 -@@ -0,0 +1,2 @@ -+x]�;� @]��] �&��8X!�%� �^g��������� -+�hKr��ot�Mu����7)��A-�UR�7�<0g��>#�ぷ�=_����H~��*� -\ No newline at end of file -added in remote - their 100644 711223894375fe1186ac5bfffdc48fb1fa1e65cc app/test/fixtures/repository-with-submodule-change/_git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 -@@ -0,0 +1 @@ -+xK��OR0` -\ No newline at end of file -added in remote - their 100644 91fccd447fe1ae44bda5ac217479c40ea5879984 app/test/fixtures/repository-with-submodule-change/_git/objects/f9/3e3a1a1525fb5b91020da86e44810c87a2d7bc -@@ -0,0 +1 @@ -+x+)JMU06g040031Qrut�u��Max6���M�9{wk�+��q�IO�D -\ No newline at end of file -added in remote - their 100644 c8ac18d211a6983ed81b0e01e3ee099eb3bcea13 app/test/fixtures/repository-with-submodule-change/_git/refs/heads/master -@@ -0,0 +1 @@ -+2b0eed7db3ab39050a3bc71888b2ed3fe77802e2 -added in remote - their 100644 f805e810e5c6e087791506b4e721958de3574ae4 app/test/fixtures/repository-with-submodule-change/friendly-bassoon/.gitignore -@@ -0,0 +1,33 @@ -+# Object files -+*.o -+*.ko -+*.obj -+*.elf -+ -+# Precompiled Headers -+*.gch -+*.pch -+ -+# Libraries -+*.lib -+*.a -+*.la -+*.lo -+ -+# Shared objects (inc. Windows DLLs) -+*.dll -+*.so -+*.so.* -+*.dylib -+ -+# Executables -+*.exe -+*.out -+*.app -+*.i*86 -+*.x86_64 -+*.hex -+ -+# Debug files -+*.dSYM/ -+*.su -added in remote - their 100644 aa83dd7cfec538e10256998af78d4550a9a543a0 app/test/fixtures/repository-with-submodule-change/friendly-bassoon/LICENSE -@@ -0,0 +1,21 @@ -+MIT License -+ -+Copyright (c) 2016 Brendan Forster -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in all -+copies or substantial portions of the Software. -+ -+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -+SOFTWARE. -added in remote - their 100644 0f91ecbd640e30969a56cefde559edeba9e11bed app/test/fixtures/repository-with-submodule-change/friendly-bassoon/README.md -@@ -0,0 +1,3 @@ -+# friendly-bassoon -+ -+making some changes to the file -added in remote - their 100644 605d03273508c7eea710bdd641f902153da0082c app/test/fixtures/repository-with-submodule-change/friendly-bassoon/_git -@@ -0,0 +1 @@ -+gitdir: ../.git/modules/friendly-bassoon -changed in both - base 100644 d00f5af6dd1e2536018d5d11e4ae8396320e30e8 app/test/unit/git/commit-test.ts - our 100644 82db4554497e52551ddf6d5f89e004c8bd81738f app/test/unit/git/commit-test.ts - their 100644 977e497505ea4ba2da8c13e9dbcef446e84323fa app/test/unit/git/commit-test.ts -@@ -12,11 +12,18 @@ - getWorkingDirectoryDiff, - } from '../../../src/lib/git' - -+<<<<<<< .our - import { - setupFixtureRepository, - setupEmptyRepository, - setupConflictedRepo, - } from '../../helpers/repositories' -+======= -+import { setupFixtureRepository, setupEmptyRepository } from '../../fixture-helper' -+import { GitProcess } from 'git-kitchen-sink' -+import { FileStatus, WorkingDirectoryFileChange } from '../../../src/models/status' -+import { DiffSelectionType, DiffSelection, ITextDiff, DiffType } from '../../../src/models/diff' -+>>>>>>> .their - - import { GitProcess } from 'dugite' - import { -@@ -40,6 +47,12 @@ - return diff as ITextDiff - } - -+async function getTextDiff(repo: Repository, file: WorkingDirectoryFileChange): Promise<ITextDiff> { -+ const diff = await getWorkingDirectoryDiff(repo, file) -+ expect(diff.kind === DiffType.Text) -+ return diff as ITextDiff -+} -+ - describe('git/commit', () => { - let repository: Repository | null = null - -@@ -201,6 +214,7 @@ - - const modifiedFile = 'modified-file.md' - -+<<<<<<< .our - const unselectedFile = DiffSelection.fromInitialSelection( - DiffSelectionType.None - ) -@@ -219,6 +233,16 @@ - diff.hunks[0].unifiedDiffEnd - diff.hunks[0].unifiedDiffStart, - false - ) -+======= -+ const unselectedFile = DiffSelection.fromInitialSelection(DiffSelectionType.None) -+ const file = new WorkingDirectoryFileChange(modifiedFile, FileStatus.Modified, unselectedFile) -+ -+ const diff = await getTextDiff(repository!, file) -+ -+ const selection = DiffSelection -+ .fromInitialSelection(DiffSelectionType.All) -+ .withRangeSelection(diff.hunks[0].unifiedDiffStart, diff.hunks[0].unifiedDiffEnd - diff.hunks[0].unifiedDiffStart, false) -+>>>>>>> .their - - const updatedFile = file.withSelection(selection) - -@@ -294,6 +318,7 @@ - - const modifiedFile = 'modified-file.md' - -+<<<<<<< .our - const unselectedFile = DiffSelection.fromInitialSelection( - DiffSelectionType.None - ) -@@ -318,6 +343,18 @@ - AppFileStatus.Modified, - selection - ) -+======= -+ const unselectedFile = DiffSelection.fromInitialSelection(DiffSelectionType.None) -+ const file = new WorkingDirectoryFileChange(modifiedFile, FileStatus.Modified, unselectedFile) -+ -+ const diff = await getTextDiff(repository!, file) -+ -+ const selection = DiffSelection -+ .fromInitialSelection(DiffSelectionType.All) -+ .withRangeSelection(diff.hunks[1].unifiedDiffStart, diff.hunks[1].unifiedDiffEnd - diff.hunks[1].unifiedDiffStart, false) -+ -+ const updatedFile = new WorkingDirectoryFileChange(modifiedFile, FileStatus.Modified, selection) -+>>>>>>> .their - - // commit just this change, ignore everything else - await createCommit(repository!, 'title', [updatedFile]) -@@ -442,10 +479,14 @@ - - expect(statusAfter.workingDirectory.files.length).to.equal(1) - -+<<<<<<< .our - const diff = await getTextDiff( - repo, - statusAfter.workingDirectory.files[0] - ) -+======= -+ const diff = await getTextDiff(repo, statusAfter.workingDirectory.files[0]) -+>>>>>>> .their - - expect(diff.hunks.length).to.equal(1) - expect(diff.hunks[0].lines.length).to.equal(4) -removed in local - base 100644 f85846560a0779faeac9def00f4fa86c4f519306 app/test/unit/git/git-diff-tests.ts - their 100644 f52b530461f4813e99a271848f4de7cd38f09ca1 app/test/unit/git/git-diff-tests.ts -changed in both - base 100644 0214e9738c4d7118d5371bd86da609fffcda67c7 app/test/unit/patch-formatter-test.ts - our 100644 c0b463a119f370007a15b53596eef661434e881a app/test/unit/patch-formatter-test.ts - their 100644 9b89c3124c8aba3e6fc5491408fe3823919994a2 app/test/unit/patch-formatter-test.ts -@@ -4,6 +4,7 @@ - import * as FSE from 'fs-extra' - - import { Repository } from '../../src/models/repository' -+<<<<<<< .our - import { - WorkingDirectoryFileChange, - FileChange, -@@ -25,6 +26,20 @@ - const rawDiff = parser.parse(diff) - const repository = new Repository('', -1, null, false) - const fileChange = new FileChange('file.txt', AppFileStatus.Modified) -+======= -+import { WorkingDirectoryFileChange, FileChange, FileStatus } from '../../src/models/status' -+import { DiffSelection, DiffSelectionType, ITextDiff, DiffType } from '../../src/models/diff' -+import { DiffParser } from '../../src/lib/diff-parser' -+import { formatPatch } from '../../src/lib/patch-formatter' -+import { getWorkingDirectoryDiff, convertDiff } from '../../src/lib/git' -+import { setupFixtureRepository } from '../fixture-helper' -+ -+async function parseDiff(diff: string): Promise<ITextDiff> { -+ const parser = new DiffParser() -+ const rawDiff = parser.parse(diff) -+ const repository = new Repository('', -1) -+ const fileChange = new FileChange('file.txt', FileStatus.Modified) -+>>>>>>> .their - const output = await convertDiff(repository, fileChange, rawDiff, 'HEAD') - expect(output.kind === DiffType.Text) - return output as ITextDiff -@@ -58,6 +73,7 @@ - const textDiff = diff as ITextDiff - const second = textDiff.hunks[1] - -+<<<<<<< .our - const selection = DiffSelection.fromInitialSelection( - DiffSelectionType.All - ).withRangeSelection( -@@ -65,6 +81,11 @@ - second.unifiedDiffEnd - second.unifiedDiffStart, - false - ) -+======= -+ const selection = DiffSelection -+ .fromInitialSelection(DiffSelectionType.All) -+ .withRangeSelection(second.unifiedDiffStart, second.unifiedDiffEnd - second.unifiedDiffStart, false) -+>>>>>>> .their - - const updatedFile = new WorkingDirectoryFileChange( - modifiedFile, -@@ -96,6 +117,13 @@ - - const textDiff = diff as ITextDiff - const first = textDiff.hunks[0] -+<<<<<<< .our -+======= -+ -+ const selection = DiffSelection -+ .fromInitialSelection(DiffSelectionType.All) -+ .withRangeSelection(first.unifiedDiffStart, first.unifiedDiffEnd - first.unifiedDiffStart, false) -+>>>>>>> .their - - const selection = DiffSelection.fromInitialSelection( - DiffSelectionType.All -@@ -105,12 +133,15 @@ - false - ) - -+<<<<<<< .our - const updatedFile = new WorkingDirectoryFileChange( - modifiedFile, - AppFileStatus.Modified, - selection - ) - -+======= -+>>>>>>> .their - const patch = formatPatch(updatedFile, textDiff) - - expect(patch).to.have.string('--- a/modified-file.md\n') -@@ -133,6 +164,7 @@ - const diff = await getWorkingDirectoryDiff(repository!, file) - - expect(diff.kind === DiffType.Text) -+<<<<<<< .our - - const textDiff = diff as ITextDiff - const second = textDiff.hunks[1] -@@ -150,6 +182,17 @@ - selection - ) - -+======= -+ -+ const textDiff = diff as ITextDiff -+ const second = textDiff.hunks[1] -+ -+ const selection = DiffSelection -+ .fromInitialSelection(DiffSelectionType.All) -+ .withRangeSelection(second.unifiedDiffStart, second.unifiedDiffEnd - second.unifiedDiffStart, false) -+ const updatedFile = new WorkingDirectoryFileChange(modifiedFile, FileStatus.Modified, selection) -+ -+>>>>>>> .their - const patch = formatPatch(updatedFile, textDiff) - - expect(patch).to.have.string('--- a/modified-file.md\n') -@@ -235,7 +278,11 @@ - expect(patch).to.equal(expectedPatch) - }) - -+<<<<<<< .our - it("doesn't include unselected added lines as context", async () => { -+======= -+ it('doesn\'t include unselected added lines as context', async () => { -+>>>>>>> .their - const rawDiff = [ - '--- a/file.md', - '+++ b/file.md', diff --git a/app/test/fixtures/merge-parser/desktop/merge-vanilla-mocha-into-offline-mode-y-u-no-work.txt b/app/test/fixtures/merge-parser/desktop/merge-vanilla-mocha-into-offline-mode-y-u-no-work.txt deleted file mode 100644 index d001298d0a6..00000000000 --- a/app/test/fixtures/merge-parser/desktop/merge-vanilla-mocha-into-offline-mode-y-u-no-work.txt +++ /dev/null @@ -1,1169 +0,0 @@ -added in remote - their 100644 e84ab4e6f3cb9a03e6c851fd2150d898345e7a71 app/test/helpers/fake-electron.ts -@@ -0,0 +1,8 @@ -+import * as sinon from 'sinon' -+ -+export const shell = sinon.fake() -+export const remote = { -+ autoUpdater: { -+ on: sinon.fake(), -+ }, -+} -added in remote - their 100644 fff0e4201755967df54676c30db37ad0f7546e90 app/test/helpers/mocking.ts -@@ -0,0 +1,20 @@ -+import * as sinon from 'sinon' -+import rewiremock from 'rewiremock/node' -+ -+import 'core-js' -+ -+require('jsdom-global')() -+ -+rewiremock('electron').by('./fake-electron.ts') -+rewiremock.enable() -+ -+import { Headers, Request, Response, FetchError } from 'node-fetch' -+ -+global.Headers = Headers -+global.Request = Request -+global.Response = Response -+global.FetchError = FetchError -+ -+global.localStorage = { -+ getItem: sinon.fake(), -+} -merged - result 100644 f4438719674cc3795be74665efb7671892aa92ef app/yarn.lock - our 100644 cd6294bb698115d3ff652d361f00efbf85c1e781 app/yarn.lock -@@ -223,8 +223,8 @@ - humanize-plus "^1.8.1" - - dexie@^2.0.0: -- version "2.0.0" -- resolved "https://registry.yarnpkg.com/dexie/-/dexie-2.0.0.tgz#d3ad7b7aa29e8de82ea4a8e09a4ccbfa80213f0d" -+ version "2.0.4" -+ resolved "https://registry.yarnpkg.com/dexie/-/dexie-2.0.4.tgz#6027a5e05879424e8f9979d8c14e7420f27e3a11" - - dom-classlist@^1.0.1: - version "1.0.1" -changed in both - base 100644 8db07d17ce96651a9515f2c1aea7ca9f02a20c6d package.json - our 100644 2006bfb748810f6ea8bdbd26edf7c09524a1388a package.json - their 100644 43ed8db007e7545e74497f30e42ae197d42183f9 package.json -@@ -7,8 +7,8 @@ - "scripts": { - "cli": "ts-node --require ./app/test/globals.ts --require ./app/src/cli/dev-commands-global.ts app/src/cli/main.ts", - "test:integration": "cross-env TEST_ENV=1 ELECTRON_NO_ATTACH_CONSOLE=1 xvfb-maybe --auto-servernum -- mocha -t 30000 --require ts-node/register app/test/integration/*.ts", -- "test:unit": "ts-node script/unit-tests.ts", -- "test:script": "mocha -t 10000 --require ts-node/register script/changelog/test/*.ts", -+ "test:unit": "yarn cross-env TEST_ENV=1 ts-mocha -t 1000 -r app/test/globals.ts -r app/test/helpers/mocking.ts 'app/test/unit/**/*.ts{,x}'", -+ "test:script": "mocha -P ./tsonfig.json -t 10000 --require ts-node/register script/changelog/test/*.ts", - "test": "yarn test:unit && yarn test:script && yarn test:integration", - "test:setup": "ts-node -P script/tsconfig.json script/test-setup.ts", - "test:review": "ts-node -P script/tsconfig.json script/test-review.ts", -@@ -138,6 +138,7 @@ - "@types/react-virtualized": "^9.7.12", - "@types/request": "^2.0.9", - "@types/semver": "^5.5.0", -+ "@types/sinon": "^5.0.1", - "@types/strip-ansi": "^3.0.0", - "@types/temp": "^0.8.29", - "@types/textarea-caret": "^3.0.0", -@@ -152,10 +153,17 @@ - "@types/webpack-merge": "^4.1.3", - "@types/winston": "^2.2.0", - "@types/xml2js": "^0.4.0", -+ "core-js": "^2.5.7", - "electron": "2.0.5", - "electron-builder": "20.27.1", - "electron-mocha": "^6.0.1", - "electron-packager": "^12.0.0", -- "electron-winstaller": "2.5.2" -+ "electron-winstaller": "2.5.2", -+ "jsdom": "^11.12.0", -+ "jsdom-global": "^3.0.2", -+ "node-fetch": "^2.2.0", -+ "rewiremock": "^3.7.7", -+ "sinon": "^6.1.5", -+ "ts-mocha": "^2.0.0" - } - } -changed in both - base 100644 f882d0c97d785b6cdbe161e15e6951c7d010ecc9 yarn.lock - our 100644 45ddb8bf6902bbb22708d844324093dccda26c79 yarn.lock - their 100644 51e3b8cf296c315d74bf16f35dbc9ced276ea67b yarn.lock -@@ -6,6 +6,22 @@ - version "4.0.2" - resolved "https://registry.yarnpkg.com/7zip-bin/-/7zip-bin-4.0.2.tgz#6abbdc22f33cab742053777a26db2e25ca527179" - -+"@sinonjs/commons@^1.0.1": -+ version "1.0.2" -+ resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.0.2.tgz#3e0ac737781627b8844257fadc3d803997d0526e" -+ dependencies: -+ type-detect "4.0.8" -+ -+"@sinonjs/formatio@^2.0.0": -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-2.0.0.tgz#84db7e9eb5531df18a8c5e0bfb6e449e55e654b2" -+ dependencies: -+ samsam "1.3.0" -+ -+"@sinonjs/samsam@^2.0.0": -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-2.0.0.tgz#9163742ac35c12d3602dece74317643b35db6a80" -+ - "@types/body-parser@*": - version "1.16.8" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.16.8.tgz#687ec34140624a3bec2b1a8ea9268478ae8f3be3" -@@ -142,6 +158,10 @@ - "@types/html-minifier" "*" - "@types/webpack" "*" - -+"@types/json5@^0.0.29": -+ version "0.0.29" -+ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" -+ - "@types/keytar@^4.0.0": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/keytar/-/keytar-4.0.1.tgz#e2cf6405dc33861424e59b67516c66d2cf7bc21b" -@@ -246,6 +266,10 @@ - "@types/express-serve-static-core" "*" - "@types/mime" "*" - -+"@types/sinon@^5.0.1": -+ version "5.0.1" -+ resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-5.0.1.tgz#a15b36ec42f1f53166617491feabd1734cb03e21" -+ - "@types/source-map@*": - version "0.5.1" - resolved "https://registry.yarnpkg.com/@types/source-map/-/source-map-0.5.1.tgz#7e74db5d06ab373a712356eebfaea2fad0ea2367" -@@ -457,6 +481,14 @@ - "@webassemblyjs/wast-parser" "1.4.3" - long "^3.2.0" - -+abab@^1.0.4: -+ version "1.0.4" -+ resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" -+ -+abab@^2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f" -+ - abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" -@@ -481,6 +513,12 @@ - dependencies: - acorn "^5.0.0" - -+acorn-globals@^4.1.0: -+ version "4.1.0" -+ resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.1.0.tgz#ab716025dbe17c54d3ef81d32ece2b2d99fe2538" -+ dependencies: -+ acorn "^5.0.0" -+ - acorn-jsx@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-4.1.1.tgz#e8e41e48ea2fe0c896740610ab6a4ffd8add225e" -@@ -491,7 +529,7 @@ - version "5.2.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7" - --acorn@^5.0.3, acorn@^5.6.0: -+acorn@^5.0.3, acorn@^5.5.3, acorn@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8" - -@@ -523,7 +561,20 @@ - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" - -+<<<<<<< .our - ajv@^6.0.1, ajv@^6.5.0, ajv@^6.5.2: -+======= -+ajv@^5.3.0: -+ version "5.5.2" -+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" -+ dependencies: -+ co "^4.6.0" -+ fast-deep-equal "^1.0.0" -+ fast-json-stable-stringify "^2.0.0" -+ json-schema-traverse "^0.3.0" -+ -+ajv@^6.0.1, ajv@^6.5.0, ajv@^6.5.1: -+>>>>>>> .their - version "6.5.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.2.tgz#678495f9b82f7cca6be248dd92f59bff5e1f4360" - dependencies: -@@ -694,6 +745,10 @@ - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - -+array-equal@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" -+ - array-find-index@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" -@@ -888,6 +943,10 @@ - version "1.6.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" - -+aws4@^1.8.0: -+ version "1.8.0" -+ resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" -+ - babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" -@@ -1392,6 +1451,10 @@ - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - -+browser-process-hrtime@^0.1.2: -+ version "0.1.2" -+ resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz#425d68a58d3447f02a04aa894187fce8af8b7b8e" -+ - browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" -@@ -1448,6 +1511,12 @@ - dependencies: - pako "~0.2.0" - -+browserify-zlib@^0.2.0: -+ version "0.2.0" -+ resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" -+ dependencies: -+ pako "~1.0.5" -+ - browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: - version "1.7.7" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9" -@@ -1890,6 +1959,12 @@ - version "1.1.2" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" - -+combined-stream@1.0.6, combined-stream@~1.0.6: -+ version "1.0.6" -+ resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" -+ dependencies: -+ delayed-stream "~1.0.0" -+ - combined-stream@^1.0.5, combined-stream@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" -@@ -1912,6 +1987,10 @@ - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - -+compare-module-exports@^2.0.0: -+ version "2.0.1" -+ resolved "https://registry.yarnpkg.com/compare-module-exports/-/compare-module-exports-2.0.1.tgz#0f733a8407554a512fb10e4a0aceec6787df4696" -+ - compare-version@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/compare-version/-/compare-version-0.1.2.tgz#0162ec2d9351f5ddd59a9202cba935366a725080" -@@ -2018,6 +2097,10 @@ - version "2.5.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" - -+core-js@^2.5.7: -+ version "2.5.7" -+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" -+ - core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" -@@ -2244,6 +2327,16 @@ - clap "^1.0.9" - source-map "^0.5.3" - -+cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": -+ version "0.3.4" -+ resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.4.tgz#8cd52e8a3acfd68d3aed38ee0a640177d2f9d797" -+ -+cssstyle@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.0.0.tgz#79b16d51ec5591faec60e688891f15d2a5705129" -+ dependencies: -+ cssom "0.3.x" -+ - csstype@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.3.0.tgz#062e141c78345cf814da0e0b716ad777931b08af" -@@ -2272,6 +2365,14 @@ - dependencies: - assert-plus "^1.0.0" - -+data-urls@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.0.0.tgz#24802de4e81c298ea8a9388bb0d8e461c774684f" -+ dependencies: -+ abab "^1.0.4" -+ whatwg-mimetype "^2.0.0" -+ whatwg-url "^6.4.0" -+ - date-now@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" -@@ -2332,6 +2433,10 @@ - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - -+deepmerge@^2.0.1: -+ version "2.1.1" -+ resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.1.1.tgz#e862b4e45ea0555072bf51e7fd0d9845170ae768" -+ - deepmerge@~1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-1.3.2.tgz#1663691629d4dbfe364fa12a2a4f0aa86aa3a050" -@@ -2426,7 +2531,7 @@ - asap "^2.0.0" - wrappy "1" - --diff@3.5.0: -+diff@3.5.0, diff@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - -@@ -2486,6 +2591,12 @@ - version "1.1.3" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" - -+domexception@^1.0.1: -+ version "1.0.1" -+ resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" -+ dependencies: -+ webidl-conversions "^4.0.2" -+ - domhandler@2.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.1.0.tgz#d2646f5e57f6c3bab11cf6cb05d3c0acf7412594" -@@ -2830,6 +2941,17 @@ - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - -+escodegen@^1.9.1: -+ version "1.11.0" -+ resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.0.tgz#b27a9389481d5bfd5bec76f7bb1eb3f8f4556589" -+ dependencies: -+ esprima "^3.1.3" -+ estraverse "^4.2.0" -+ esutils "^2.0.2" -+ optionator "^0.8.1" -+ optionalDependencies: -+ source-map "~0.6.1" -+ - eslint-config-prettier@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-2.9.0.tgz#5ecd65174d486c22dff389fe036febf502d468a3" -@@ -2951,6 +3073,10 @@ - version "2.7.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" - -+esprima@^3.1.3: -+ version "3.1.3" -+ resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" -+ - esprima@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" -@@ -2968,7 +3094,7 @@ - estraverse "^4.1.0" - object-assign "^4.0.1" - --estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: -+estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - -@@ -3110,6 +3236,10 @@ - version "3.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" - -+extend@~3.0.2: -+ version "3.0.2" -+ resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" -+ - external-editor@^2.0.1: - version "2.0.5" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.0.5.tgz#52c249a3981b9ba187c7cacf5beb50bf1d91a6bc" -@@ -3328,6 +3458,14 @@ - combined-stream "^1.0.5" - mime-types "^2.1.12" - -+form-data@~2.3.2: -+ version "2.3.2" -+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099" -+ dependencies: -+ asynckit "^0.4.0" -+ combined-stream "1.0.6" -+ mime-types "^2.1.12" -+ - forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" -@@ -3671,6 +3809,13 @@ - ajv "^5.1.0" - har-schema "^2.0.0" - -+har-validator@~5.1.0: -+ version "5.1.0" -+ resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.0.tgz#44657f5688a22cfd4b72486e81b3a3fb11742c29" -+ dependencies: -+ ajv "^5.3.0" -+ har-schema "^2.0.0" -+ - has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" -@@ -3824,6 +3969,12 @@ - version "1.1.1" - resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.1.tgz#668b93776eaae55ebde8f3ad464b307a4963625e" - -+html-encoding-sniffer@^1.0.2: -+ version "1.0.2" -+ resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" -+ dependencies: -+ whatwg-encoding "^1.0.1" -+ - html-entities@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" -@@ -3901,11 +4052,15 @@ - version "0.0.1" - resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82" - -+https-browserify@^1.0.0: -+ version "1.0.0" -+ resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" -+ - iconv-lite@0.4.19, iconv-lite@^0.4.17: - version "0.4.19" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" - --iconv-lite@^0.4.23: -+iconv-lite@0.4.23, iconv-lite@^0.4.23: - version "0.4.23" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" - dependencies: -@@ -4404,6 +4559,41 @@ - version "1.6.0" - resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.6.0.tgz#c7d1a71edcff2839db2f9ec30fc5d5ebd3c1a678" - -+jsdom-global@^3.0.2: -+ version "3.0.2" -+ resolved "https://registry.yarnpkg.com/jsdom-global/-/jsdom-global-3.0.2.tgz#6bd299c13b0c4626b2da2c0393cd4385d606acb9" -+ -+jsdom@^11.12.0: -+ version "11.12.0" -+ resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" -+ dependencies: -+ abab "^2.0.0" -+ acorn "^5.5.3" -+ acorn-globals "^4.1.0" -+ array-equal "^1.0.0" -+ cssom ">= 0.3.2 < 0.4.0" -+ cssstyle "^1.0.0" -+ data-urls "^1.0.0" -+ domexception "^1.0.1" -+ escodegen "^1.9.1" -+ html-encoding-sniffer "^1.0.2" -+ left-pad "^1.3.0" -+ nwsapi "^2.0.7" -+ parse5 "4.0.0" -+ pn "^1.1.0" -+ request "^2.87.0" -+ request-promise-native "^1.0.5" -+ sax "^1.2.4" -+ symbol-tree "^3.2.2" -+ tough-cookie "^2.3.4" -+ w3c-hr-time "^1.0.1" -+ webidl-conversions "^4.0.2" -+ whatwg-encoding "^1.0.3" -+ whatwg-mimetype "^2.1.0" -+ whatwg-url "^6.4.1" -+ ws "^5.2.0" -+ xml-name-validator "^3.0.0" -+ - jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" -@@ -4508,6 +4698,10 @@ - dependencies: - array-includes "^3.0.3" - -+just-extend@^1.1.27: -+ version "1.1.27" -+ resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-1.1.27.tgz#ec6e79410ff914e472652abfa0e603c03d60e905" -+ - kew@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/kew/-/kew-0.7.0.tgz#79d93d2d33363d6fdd2970b335d9141ad591d79b" -@@ -4580,6 +4774,10 @@ - version "0.3.0" - resolved "https://registry.yarnpkg.com/leb/-/leb-0.3.0.tgz#32bee9fad168328d6aea8522d833f4180eed1da3" - -+left-pad@^1.3.0: -+ version "1.3.0" -+ resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" -+ - legal-eagle@0.16.0: - version "0.16.0" - resolved "https://registry.yarnpkg.com/legal-eagle/-/legal-eagle-0.16.0.tgz#bd3d136dd1b761a540bad898ace68f4009412575" -@@ -4672,7 +4870,7 @@ - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" - --lodash.get@^4.0.0: -+lodash.get@^4.0.0, lodash.get@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" - -@@ -4692,11 +4890,15 @@ - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" - -+lodash.sortby@^4.7.0: -+ version "4.7.0" -+ resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" -+ - lodash.tail@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.tail/-/lodash.tail-4.1.1.tgz#d2333a36d9e7717c8ad2f7cacafec7c32b444664" - --lodash.template@^4.2.2: -+lodash.template@^4.2.2, lodash.template@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" - dependencies: -@@ -4721,7 +4923,7 @@ - version "4.17.4" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" - --lodash@^4.17.5, lodash@~4.17.10: -+lodash@^4.13.1, lodash@^4.17.5, lodash@~4.17.10: - version "4.17.10" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" - -@@ -4735,6 +4937,10 @@ - version "1.0.1" - resolved "https://registry.yarnpkg.com/loglevelnext/-/loglevelnext-1.0.1.tgz#8b17b5a43395338a96c67911a962c44af466d1c8" - -+lolex@^2.3.2, lolex@^2.7.1: -+ version "2.7.1" -+ resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.7.1.tgz#e40a8c4d1f14b536aa03e42a537c7adbaf0c20be" -+ - long@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" -@@ -4886,6 +5092,10 @@ - version "1.33.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" - -+mime-db@~1.35.0: -+ version "1.35.0" -+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.35.0.tgz#0569d657466491283709663ad379a99b90d9ab47" -+ - mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.16, mime-types@~2.1.17, mime-types@~2.1.7: - version "2.1.17" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" -@@ -4898,6 +5108,12 @@ - dependencies: - mime-db "~1.33.0" - -+mime-types@~2.1.19: -+ version "2.1.19" -+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.19.tgz#71e464537a7ef81c15f2db9d97e913fc0ff606f0" -+ dependencies: -+ mime-db "~1.35.0" -+ - mime@1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" -@@ -5102,12 +5318,26 @@ - version "1.0.4" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4" - -+nise@^1.4.2: -+ version "1.4.2" -+ resolved "https://registry.yarnpkg.com/nise/-/nise-1.4.2.tgz#a9a3800e3994994af9e452333d549d60f72b8e8c" -+ dependencies: -+ "@sinonjs/formatio" "^2.0.0" -+ just-extend "^1.1.27" -+ lolex "^2.3.2" -+ path-to-regexp "^1.7.0" -+ text-encoding "^0.6.4" -+ - no-case@^2.2.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" - dependencies: - lower-case "^1.1.1" - -+node-fetch@^2.2.0: -+ version "2.2.0" -+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.2.0.tgz#4ee79bde909262f9775f731e3656d0db55ced5b5" -+ - node-gyp@^3.3.1: - version "3.6.2" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.6.2.tgz#9bfbe54562286284838e750eac05295853fa1c60" -@@ -5162,6 +5392,34 @@ - util "^0.10.3" - vm-browserify "0.0.4" - -+node-libs-browser@^2.1.0: -+ version "2.1.0" -+ resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" -+ dependencies: -+ assert "^1.1.1" -+ browserify-zlib "^0.2.0" -+ buffer "^4.3.0" -+ console-browserify "^1.1.0" -+ constants-browserify "^1.0.0" -+ crypto-browserify "^3.11.0" -+ domain-browser "^1.1.1" -+ events "^1.0.0" -+ https-browserify "^1.0.0" -+ os-browserify "^0.3.0" -+ path-browserify "0.0.0" -+ process "^0.11.10" -+ punycode "^1.2.4" -+ querystring-es3 "^0.2.0" -+ readable-stream "^2.3.3" -+ stream-browserify "^2.0.1" -+ stream-http "^2.7.2" -+ string_decoder "^1.0.0" -+ timers-browserify "^2.0.4" -+ tty-browserify "0.0.0" -+ url "^0.11.0" -+ util "^0.10.3" -+ vm-browserify "0.0.4" -+ - node-pre-gyp@^0.9.0: - version "0.9.1" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.9.1.tgz#f11c07516dd92f87199dbc7e1838eab7cd56c9e0" -@@ -5311,10 +5569,18 @@ - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - -+nwsapi@^2.0.7: -+ version "2.0.8" -+ resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.0.8.tgz#e3603579b7e162b3dbedae4fb24e46f771d8fa24" -+ - oauth-sign@~0.8.1, oauth-sign@~0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" - -+oauth-sign@~0.9.0: -+ version "0.9.0" -+ resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" -+ - object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" -@@ -5389,7 +5655,7 @@ - minimist "~0.0.1" - wordwrap "~0.0.2" - --optionator@^0.8.2: -+optionator@^0.8.1, optionator@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" - dependencies: -@@ -5404,6 +5670,10 @@ - version "0.2.1" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.2.1.tgz#63fc4ccee5d2d7763d26bbf8601078e6c2e0044f" - -+os-browserify@^0.3.0: -+ version "0.3.0" -+ resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" -+ - os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" -@@ -5476,6 +5746,10 @@ - version "0.2.9" - resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" - -+pako@~1.0.5: -+ version "1.0.6" -+ resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" -+ - parallel-transform@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" -@@ -5535,6 +5809,10 @@ - dependencies: - error-ex "^1.2.0" - -+parse5@4.0.0: -+ version "4.0.0" -+ resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" -+ - parseurl@~1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" -@@ -5581,6 +5859,12 @@ - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - -+path-to-regexp@^1.7.0: -+ version "1.7.0" -+ resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" -+ dependencies: -+ isarray "0.0.1" -+ - path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" -@@ -5691,6 +5975,10 @@ - version "7.0.0" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" - -+pn@^1.1.0: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" -+ - posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" -@@ -5979,7 +6267,7 @@ - version "2.0.0" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" - --process@^0.11.0: -+process@^0.11.0, process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - -@@ -6041,6 +6329,10 @@ - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - -+psl@^1.1.24: -+ version "1.1.29" -+ resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" -+ - public-encrypt@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.0.tgz#39f699f3a46560dd5ebacbca693caf7c65c18cc6" -@@ -6094,6 +6386,10 @@ - version "6.4.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" - -+qs@~6.5.2: -+ version "6.5.2" -+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" -+ - query-string@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" -@@ -6209,7 +6505,7 @@ - normalize-package-data "^2.3.2" - path-type "^2.0.0" - --"readable-stream@1 || 2", readable-stream@^2.0.4, readable-stream@^2.1.5: -+"readable-stream@1 || 2", readable-stream@^2.0.4, readable-stream@^2.1.5, readable-stream@^2.3.3, readable-stream@^2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - dependencies: -@@ -6403,6 +6699,20 @@ - dependencies: - throttleit "^1.0.0" - -+request-promise-core@1.1.1: -+ version "1.1.1" -+ resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" -+ dependencies: -+ lodash "^4.13.1" -+ -+request-promise-native@^1.0.5: -+ version "1.0.5" -+ resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5" -+ dependencies: -+ request-promise-core "1.1.1" -+ stealthy-require "^1.1.0" -+ tough-cookie ">=2.3.3" -+ - request@2, request@^2.45.0, request@^2.72.0, request@^2.79.0, request@^2.81.0: - version "2.83.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" -@@ -6430,6 +6740,31 @@ - tunnel-agent "^0.6.0" - uuid "^3.1.0" - -+request@^2.87.0: -+ version "2.88.0" -+ resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" -+ dependencies: -+ aws-sign2 "~0.7.0" -+ aws4 "^1.8.0" -+ caseless "~0.12.0" -+ combined-stream "~1.0.6" -+ extend "~3.0.2" -+ forever-agent "~0.6.1" -+ form-data "~2.3.2" -+ har-validator "~5.1.0" -+ http-signature "~1.2.0" -+ is-typedarray "~1.0.0" -+ isstream "~0.1.2" -+ json-stringify-safe "~5.0.1" -+ mime-types "~2.1.19" -+ oauth-sign "~0.9.0" -+ performance-now "^2.1.0" -+ qs "~6.5.2" -+ safe-buffer "^5.1.2" -+ tough-cookie "~2.4.3" -+ tunnel-agent "^0.6.0" -+ uuid "^3.3.2" -+ - request@~2.79.0: - version "2.79.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" -@@ -6526,6 +6861,18 @@ - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - -+rewiremock@^3.7.7: -+ version "3.7.7" -+ resolved "https://registry.yarnpkg.com/rewiremock/-/rewiremock-3.7.7.tgz#a3ce37f9cd8131329e3ddf9f7708147d5cb86524" -+ dependencies: -+ compare-module-exports "^2.0.0" -+ lodash.some "^4.6.0" -+ lodash.template "^4.4.0" -+ node-libs-browser "^2.1.0" -+ path-parse "^1.0.5" -+ wipe-node-cache "^1.1.0" -+ wipe-webpack-cache "^1.0.3" -+ - rgb2hex@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/rgb2hex/-/rgb2hex-0.1.0.tgz#ccd55f860ae0c5c4ea37504b958e442d8d12325b" -@@ -6591,6 +6938,10 @@ - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - -+samsam@1.3.0: -+ version "1.3.0" -+ resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50" -+ - sanitize-filename@^1.6.0, sanitize-filename@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.1.tgz#612da1c96473fa02dccda92dcd5b4ab164a6772a" -@@ -6797,6 +7148,20 @@ - dependencies: - string-width "^1.0.1" - -+sinon@^6.1.5: -+ version "6.1.5" -+ resolved "https://registry.yarnpkg.com/sinon/-/sinon-6.1.5.tgz#41451502d43cd5ffb9d051fbf507952400e81d09" -+ dependencies: -+ "@sinonjs/commons" "^1.0.1" -+ "@sinonjs/formatio" "^2.0.0" -+ "@sinonjs/samsam" "^2.0.0" -+ diff "^3.5.0" -+ lodash.get "^4.4.2" -+ lolex "^2.7.1" -+ nise "^1.4.2" -+ supports-color "^5.4.0" -+ type-detect "^4.0.8" -+ - slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" -@@ -7019,6 +7384,10 @@ - dependencies: - readable-stream "^2.0.1" - -+stealthy-require@^1.1.0: -+ version "1.1.1" -+ resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" -+ - stream-browserify@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" -@@ -7043,6 +7412,25 @@ - to-arraybuffer "^1.0.0" - xtend "^4.0.0" - -+<<<<<<< .our -+======= -+stream-http@^2.7.2: -+ version "2.8.3" -+ resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" -+ dependencies: -+ builtin-status-codes "^3.0.0" -+ inherits "^2.0.1" -+ readable-stream "^2.3.6" -+ to-arraybuffer "^1.0.0" -+ xtend "^4.0.0" -+ -+stream-json@^1.1.0: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/stream-json/-/stream-json-1.1.0.tgz#0a91e84e3cfb017f2446d9023025694982c99e89" -+ dependencies: -+ stream-chain "^2.0.3" -+ -+>>>>>>> .their - stream-shift@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" -@@ -7080,15 +7468,15 @@ - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - --string_decoder@~1.0.3: -- version "1.0.3" -- resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" -+string_decoder@^1.0.0, string_decoder@~1.1.1: -+ version "1.1.1" -+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - dependencies: - safe-buffer "~5.1.0" - --string_decoder@~1.1.1: -- version "1.1.1" -- resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" -+string_decoder@~1.0.3: -+ version "1.0.3" -+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" - dependencies: - safe-buffer "~5.1.0" - -@@ -7178,7 +7566,7 @@ - dependencies: - has-flag "^2.0.0" - --supports-color@^5.3.0: -+supports-color@^5.3.0, supports-color@^5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" - dependencies: -@@ -7200,6 +7588,10 @@ - version "1.0.1" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" - -+symbol-tree@^3.2.2: -+ version "3.2.2" -+ resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" -+ - table@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc" -@@ -7266,6 +7658,10 @@ - dependencies: - execa "^0.7.0" - -+text-encoding@^0.6.4: -+ version "0.6.4" -+ resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" -+ - text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" -@@ -7306,6 +7702,12 @@ - dependencies: - setimmediate "^1.0.4" - -+timers-browserify@^2.0.4: -+ version "2.0.10" -+ resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" -+ dependencies: -+ setimmediate "^1.0.4" -+ - tmp@0.0.28: - version "0.0.28" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.28.tgz#172735b7f614ea7af39664fa84cf0de4e515d120" -@@ -7382,12 +7784,25 @@ - dependencies: - nopt "~1.0.10" - -+tough-cookie@>=2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.4.3: -+ version "2.4.3" -+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" -+ dependencies: -+ psl "^1.1.24" -+ punycode "^1.4.1" -+ - tough-cookie@~2.3.0, tough-cookie@~2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" - dependencies: - punycode "^1.4.1" - -+tr46@^1.0.1: -+ version "1.0.1" -+ resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" -+ dependencies: -+ punycode "^2.1.0" -+ - "traverse@>=0.3.0 <0.4": - version "0.3.9" - resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" -@@ -7416,9 +7831,36 @@ - version "1.0.0" - resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.0.tgz#027b69fa823225e551cace3ef03b11f6ab37c1d7" - -+<<<<<<< .our - ts-node@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.0.tgz#a94a13c75e5e1aa6b82814b84c68deb339ba7bff" -+======= -+ts-mocha@^2.0.0: -+ version "2.0.0" -+ resolved "https://registry.yarnpkg.com/ts-mocha/-/ts-mocha-2.0.0.tgz#0dbd3cd04671df9933b9303b4aa46347573c5635" -+ dependencies: -+ ts-node "7.0.0" -+ optionalDependencies: -+ tsconfig-paths "^3.5.0" -+ -+ts-node@7.0.0: -+ version "7.0.0" -+ resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.0.tgz#a94a13c75e5e1aa6b82814b84c68deb339ba7bff" -+ dependencies: -+ arrify "^1.0.0" -+ buffer-from "^1.1.0" -+ diff "^3.1.0" -+ make-error "^1.1.1" -+ minimist "^1.2.0" -+ mkdirp "^0.5.1" -+ source-map-support "^0.5.6" -+ yn "^2.0.0" -+ -+ts-node@^5.0.1: -+ version "5.0.1" -+ resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-5.0.1.tgz#78e5d1cb3f704de1b641e43b76be2d4094f06f81" -+>>>>>>> .their - dependencies: - arrify "^1.0.0" - buffer-from "^1.1.0" -@@ -7429,6 +7871,16 @@ - source-map-support "^0.5.6" - yn "^2.0.0" - -+tsconfig-paths@^3.5.0: -+ version "3.5.0" -+ resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.5.0.tgz#a447c7721e49281af97343d9a850864e949a0b51" -+ dependencies: -+ "@types/json5" "^0.0.29" -+ deepmerge "^2.0.1" -+ json5 "^1.0.1" -+ minimist "^1.2.0" -+ strip-bom "^3.0.0" -+ - tslib@^1.7.1: - version "1.8.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.8.0.tgz#dc604ebad64bcbf696d613da6c954aa0e7ea1eb6" -@@ -7512,6 +7964,10 @@ - dependencies: - prelude-ls "~1.1.2" - -+type-detect@4.0.8, type-detect@^4.0.8: -+ version "4.0.8" -+ resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" -+ - type-detect@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.3.tgz#0e3f2670b44099b0b46c284d136a7ef49c74c2ea" -@@ -7752,6 +8208,10 @@ - version "3.1.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" - -+uuid@^3.3.2: -+ version "3.3.2" -+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" -+ - validate-npm-package-license@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" -@@ -7785,6 +8245,12 @@ - dependencies: - indexof "0.0.1" - -+w3c-hr-time@^1.0.1: -+ version "1.0.1" -+ resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" -+ dependencies: -+ browser-process-hrtime "^0.1.2" -+ - walkdir@^0.0.11: - version "0.0.11" - resolved "https://registry.yarnpkg.com/walkdir/-/walkdir-0.0.11.tgz#a16d025eb931bd03b52f308caed0f40fcebe9532" -@@ -7838,6 +8304,10 @@ - wdio-dot-reporter "~0.0.8" - wgxpath "~1.0.0" - -+webidl-conversions@^4.0.2: -+ version "4.0.2" -+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" -+ - webpack-bundle-analyzer@^2.13.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.13.0.tgz#8d7db44c3d4844bc911890998e1110514cf12264" -@@ -7936,6 +8406,24 @@ - version "1.0.0" - resolved "https://registry.yarnpkg.com/wgxpath/-/wgxpath-1.0.0.tgz#eef8a4b9d558cc495ad3a9a2b751597ecd9af690" - -+whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: -+ version "1.0.4" -+ resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.4.tgz#63fb016b7435b795d9025632c086a5209dbd2621" -+ dependencies: -+ iconv-lite "0.4.23" -+ -+whatwg-mimetype@^2.0.0, whatwg-mimetype@^2.1.0: -+ version "2.1.0" -+ resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.1.0.tgz#f0f21d76cbba72362eb609dbed2a30cd17fcc7d4" -+ -+whatwg-url@^6.4.0, whatwg-url@^6.4.1: -+ version "6.5.0" -+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" -+ dependencies: -+ lodash.sortby "^4.7.0" -+ tr46 "^1.0.1" -+ webidl-conversions "^4.0.2" -+ - whet.extend@~0.9.9: - version "0.9.9" - resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" -@@ -7983,6 +8471,14 @@ - isstream "0.1.x" - stack-trace "0.0.x" - -+wipe-node-cache@^1.1.0: -+ version "1.1.0" -+ resolved "https://registry.yarnpkg.com/wipe-node-cache/-/wipe-node-cache-1.1.0.tgz#cd407904d81f0a76e536a9376ed1b82800dc837c" -+ -+wipe-webpack-cache@^1.0.3: -+ version "1.0.3" -+ resolved "https://registry.yarnpkg.com/wipe-webpack-cache/-/wipe-webpack-cache-1.0.3.tgz#cac81dbba9223d14b46fb88e5e56f5eaa70a8776" -+ - wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" -@@ -8036,6 +8532,12 @@ - async-limiter "~1.0.0" - safe-buffer "~5.1.0" - -+ws@^5.2.0: -+ version "5.2.2" -+ resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" -+ dependencies: -+ async-limiter "~1.0.0" -+ - xdg-basedir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" -@@ -8044,6 +8546,10 @@ - version "1.0.0" - resolved "https://registry.yarnpkg.com/xml-char-classes/-/xml-char-classes-1.0.0.tgz#64657848a20ffc5df583a42ad8a277b4512bbc4d" - -+xml-name-validator@^3.0.0: -+ version "3.0.0" -+ resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" -+ - xml2js@0.4.17: - version "0.4.17" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.17.tgz#17be93eaae3f3b779359c795b419705a8817e868" diff --git a/app/test/fixtures/merge-parser/desktop/valid-merge-master-into-script-upgrade.txt b/app/test/fixtures/merge-parser/desktop/valid-merge-master-into-script-upgrade.txt deleted file mode 100644 index 682e9872f4f..00000000000 --- a/app/test/fixtures/merge-parser/desktop/valid-merge-master-into-script-upgrade.txt +++ /dev/null @@ -1,903 +0,0 @@ -merged - result 100644 b5349c7c5e60dd396af3a4977b0684bcd69d7cfe app/package.json - our 100644 530138f765a7c89ac3e0b31cc78047926364323a app/package.json -@@ -3,7 +3,7 @@ - "productName": "GitHub Desktop", - "bundleID": "com.github.GitHubClient", - "companyName": "GitHub, Inc.", -- "version": "1.1.2-beta6", -+ "version": "1.1.2-beta7", - "main": "./main.js", - "repository": { - "type": "git", -merged - result 100644 2f9cf6d58beb7abf74b241c52c4deed1155c7e98 app/src/lib/app-state.ts - our 100644 5382e869682845ac92aee17c4ebcb0609749ab88 app/src/lib/app-state.ts -@@ -318,11 +318,18 @@ - | { type: FoldoutType.AddMenu } - | AppMenuFoldout - --export enum RepositorySection { -+export enum RepositorySectionTab { - Changes, - History, - } - -+export type RepositorySection = -+ | { selectedTab: RepositorySectionTab.Changes } -+ | { -+ selectedTab: RepositorySectionTab.History -+ shouldFocusBranchList?: boolean -+ } -+ - export interface IRepositoryState { - readonly historyState: IHistoryState - readonly changesState: IChangesState -merged - result 100644 22b6ea7eef95cb48385e88add7643839925d07c4 app/src/lib/menu-update.ts - our 100644 3db472be9c029edd019dbe29d8dfebda25fdb6e3 app/src/lib/menu-update.ts -@@ -104,7 +104,7 @@ - 'update-branch', - 'merge-branch', - 'view-repository-on-github', -- 'compare-branch', -+ 'compare-on-github', - 'open-in-shell', - 'push', - 'pull', -@@ -200,6 +200,7 @@ - 'show-history', - 'show-branches-list', - 'open-external-editor', -+ 'compare-to-branch', - ] - - const menuStateBuilder = new MenuStateBuilder() -@@ -227,7 +228,7 @@ - ) - menuStateBuilder.setEnabled('merge-branch', onBranch) - menuStateBuilder.setEnabled( -- 'compare-branch', -+ 'compare-on-github', - isHostedOnGitHub && hasPublishedBranch - ) - -@@ -278,10 +279,10 @@ - menuStateBuilder.disable('delete-branch') - menuStateBuilder.disable('update-branch') - menuStateBuilder.disable('merge-branch') -- menuStateBuilder.disable('compare-branch') - - menuStateBuilder.disable('push') - menuStateBuilder.disable('pull') -+ menuStateBuilder.disable('compare-to-branch') - } - return menuStateBuilder - } -merged - result 100644 4cee841bc4c314fa326fcd00d2a037b661073822 app/src/lib/stores/app-store.ts - our 100644 3664497681402ef660531130f999ac3e39892b4d app/src/lib/stores/app-store.ts -@@ -3,7 +3,7 @@ - IRepositoryState, - IHistoryState, - IAppState, -- RepositorySection, -+ RepositorySectionTab, - IChangesState, - Popup, - PopupType, -@@ -23,6 +23,7 @@ - CompareActionKind, - IDisplayHistory, - ICompareBranch, -+ RepositorySection, - } from '../app-state' - import { Account } from '../../models/account' - import { Repository } from '../../models/repository' -@@ -421,7 +422,7 @@ - coAuthors: [], - showCoAuthoredBy: false, - }, -- selectedSection: RepositorySection.Changes, -+ selectedSection: { selectedTab: RepositorySectionTab.Changes }, - branchesState: { - tip: { kind: TipState.Unknown }, - defaultBranch: null, -@@ -1486,9 +1487,9 @@ - this.updateRepositoryState(repository, state => ({ selectedSection })) - this.emitUpdate() - -- if (selectedSection === RepositorySection.History) { -+ if (selectedSection.selectedTab === RepositorySectionTab.History) { - return this.refreshHistorySection(repository) -- } else if (selectedSection === RepositorySection.Changes) { -+ } else if (selectedSection.selectedTab === RepositorySectionTab.Changes) { - return this.refreshChangesSection(repository, { - includingStatus: true, - clearPartialState: false, -@@ -1728,9 +1729,9 @@ - const section = state.selectedSection - let refreshSectionPromise: Promise<void> - -- if (section === RepositorySection.History) { -+ if (section.selectedTab === RepositorySectionTab.History) { - refreshSectionPromise = this.refreshHistorySection(repository) -- } else if (section === RepositorySection.Changes) { -+ } else if (section.selectedTab === RepositorySectionTab.Changes) { - refreshSectionPromise = this.refreshChangesSection(repository, { - includingStatus: false, - clearPartialState: false, -merged - result 100644 dff54e1df436eca06f803e56a2c700192a68c1cf app/src/main-process/menu/build-default-menu.ts - our 100644 f73c46b1ab5a571eba85dca0885ad2caf0d05e0d app/src/main-process/menu/build-default-menu.ts -@@ -6,6 +6,7 @@ - - import { log } from '../log' - import { openDirectorySafe } from '../shell' -+import { enableCompareSidebar } from '../../lib/feature-flag' - - const defaultEditorLabel = __DARWIN__ - ? 'Open in External Editor' -@@ -289,6 +290,13 @@ - click: emit('update-branch'), - }, - { -+ label: __DARWIN__ ? 'Compare to Branch' : '&Compare to branch', -+ id: 'compare-to-branch', -+ accelerator: 'CmdOrCtrl+Shift+B', -+ click: emit('compare-to-branch'), -+ visible: enableCompareSidebar(), -+ }, -+ { - label: __DARWIN__ - ? 'Merge Into Current Branch…' - : '&Merge into current branch…', -@@ -298,10 +306,10 @@ - }, - separator, - { -- label: __DARWIN__ ? 'Compare on GitHub' : '&Compare on GitHub', -- id: 'compare-branch', -+ label: __DARWIN__ ? 'Compare on GitHub' : 'Compare on &GitHub', -+ id: 'compare-on-github', - accelerator: 'CmdOrCtrl+Shift+C', -- click: emit('compare-branch'), -+ click: emit('compare-on-github'), - }, - { - label: pullRequestLabel, -merged - result 100644 8cc13deea5f3f8d74873101c9081ecbe276096a8 app/src/main-process/menu/menu-event.ts - our 100644 8e175de4d092b861c197b0cc4ac15be0e32a406f app/src/main-process/menu/menu-event.ts -@@ -14,10 +14,11 @@ - | 'choose-repository' - | 'open-working-directory' - | 'update-branch' -+ | 'compare-to-branch' - | 'merge-branch' - | 'show-repository-settings' - | 'open-in-shell' -- | 'compare-branch' -+ | 'compare-on-github' - | 'view-repository-on-github' - | 'clone-repository' - | 'show-about' -merged - result 100644 b920b03154f5bd06aee18172e0dcdb18d5bfe473 app/src/main-process/menu/menu-ids.ts - our 100644 5b579fb99a93d40f063d3a027effd7171e24584d app/src/main-process/menu/menu-ids.ts -@@ -5,7 +5,7 @@ - | 'update-branch' - | 'merge-branch' - | 'view-repository-on-github' -- | 'compare-branch' -+ | 'compare-on-github' - | 'open-in-shell' - | 'push' - | 'pull' -@@ -25,3 +25,4 @@ - | 'clone-repository' - | 'about' - | 'create-pull-request' -+ | 'compare-to-branch' -merged - result 100644 f16d51fe525218882768fff0889dc5f8079e04b3 app/src/ui/app.tsx - our 100644 c80c3d7daa71f7643b743afb65e5d6fa4297adfe app/src/ui/app.tsx -@@ -4,7 +4,7 @@ - - import { - IAppState, -- RepositorySection, -+ RepositorySectionTab, - Popup, - PopupType, - FoldoutType, -@@ -270,6 +270,9 @@ - this.props.dispatcher.recordMenuInitiatedUpdate() - return this.updateBranch() - } -+ case 'compare-to-branch': { -+ return this.showHistory(true) -+ } - case 'merge-branch': { - this.props.dispatcher.recordMenuInitiatedMerge() - return this.mergeBranch() -@@ -278,8 +281,8 @@ - return this.showRepositorySettings() - case 'view-repository-on-github': - return this.viewRepositoryOnGitHub() -- case 'compare-branch': -- return this.compareBranch() -+ case 'compare-on-github': -+ return this.compareBranchOnDotcom() - case 'open-in-shell': - return this.openCurrentRepositoryInShell() - case 'clone-repository': -@@ -385,7 +388,7 @@ - }) - } - -- private compareBranch() { -+ private compareBranchOnDotcom() { - const htmlURL = this.getCurrentRepositoryGitHubURL() - if (!htmlURL) { - return -@@ -486,30 +489,30 @@ - this.props.dispatcher.showPopup({ type: PopupType.About }) - } - -- private createCommit() { -+ private showHistory(shouldFocusBranchList: boolean = false) { - const state = this.state.selectedState - if (state == null || state.type !== SelectionType.Repository) { - return - } - - this.props.dispatcher.closeCurrentFoldout() -- this.props.dispatcher.changeRepositorySection( -- state.repository, -- RepositorySection.Changes -- ) -+ -+ this.props.dispatcher.changeRepositorySection(state.repository, { -+ selectedTab: RepositorySectionTab.History, -+ shouldFocusBranchList, -+ }) - } - -- private showHistory() { -+ private createCommit() { - const state = this.state.selectedState - if (state == null || state.type !== SelectionType.Repository) { - return - } - - this.props.dispatcher.closeCurrentFoldout() -- this.props.dispatcher.changeRepositorySection( -- state.repository, -- RepositorySection.History -- ) -+ this.props.dispatcher.changeRepositorySection(state.repository, { -+ selectedTab: RepositorySectionTab.Changes, -+ }) - } - - private chooseRepository() { -merged - result 100644 5767695ddcbb64acdff6868a158f8ee6f1ae7795 app/src/ui/branches/branch-list-item.tsx - our 100644 5ce11ddd900487909cec10cb7abff7d498a3ecac app/src/ui/branches/branch-list-item.tsx -@@ -1,12 +1,19 @@ - import * as React from 'react' - import * as moment from 'moment' -+import * as classNames from 'classnames' - --import { Octicon, OcticonSymbol } from '../octicons' -+import { Branch } from '../../models/branch' -+ -+import { IMenuItem } from '../../lib/menu-item' - import { HighlightText } from '../lib/highlight-text' - -+import { showContextualMenu } from '../main-process-proxy' -+import { Octicon, OcticonSymbol } from '../octicons' -+import { enableCompareSidebar } from '../../lib/feature-flag' -+ - interface IBranchListItemProps { - /** The name of the branch */ -- readonly name: string -+ readonly branch: Branch - - /** Specifies whether this item is currently selected */ - readonly isCurrentBranch: boolean -@@ -16,29 +23,84 @@ - - /** The characters in the branch name to highlight */ - readonly matches: ReadonlyArray<number> --} - -+ /** -+ * Callback to fire when the user wants to compare to this branch. -+ * -+ * If this is not specified, kebab element will not be rendered. -+ */ -+ readonly onCompareToBranch?: (branch: Branch) => void -+} - /** The branch component. */ - export class BranchListItem extends React.Component<IBranchListItemProps, {}> { -+ private onContextMenu = (event: React.MouseEvent<any>) => { -+ event.preventDefault() -+ event.stopPropagation() -+ -+ const items: IMenuItem[] = [ -+ { -+ label: 'Compare to this branch', -+ action: () => { -+ if (this.props.onCompareToBranch) { -+ this.props.onCompareToBranch(this.props.branch) -+ } -+ }, -+ }, -+ ] -+ -+ showContextualMenu(items) -+ } -+ -+ private renderKebab = (lastCommitDate: Date | null, infoTitle: string) => { -+ if (this.props.onCompareToBranch == null) { -+ return null -+ } -+ -+ if (!enableCompareSidebar()) { -+ return null -+ } -+ -+ return ( -+ <div className="branches-list-item-menu" title={infoTitle}> -+ <div className="branch-menu-wrapper" onClick={this.onContextMenu}> -+ <Octicon symbol={OcticonSymbol.kebabHorizontal} /> -+ </div> -+ </div> -+ ) -+ } -+ - public render() { - const lastCommitDate = this.props.lastCommitDate - const isCurrentBranch = this.props.isCurrentBranch -- const name = this.props.name -+ const name = this.props.branch.name - - const date = lastCommitDate ? moment(lastCommitDate).fromNow() : '' - const icon = isCurrentBranch ? OcticonSymbol.check : OcticonSymbol.gitBranch - const infoTitle = isCurrentBranch - ? 'Current branch' - : lastCommitDate ? lastCommitDate.toString() : '' -+ -+ const enableKebabEffect = -+ enableCompareSidebar() && -+ !isCurrentBranch && -+ this.props.onCompareToBranch != null -+ -+ const className = classNames('branches-list-item', { -+ 'kebab-effect': enableKebabEffect, -+ }) -+ - return ( -- <div className="branches-list-item"> -+ <div className={className}> - <Octicon className="icon" symbol={icon} /> - <div className="name" title={name}> - <HighlightText text={name} highlight={this.props.matches} /> - </div> -+ - <div className="description" title={infoTitle}> - {date} - </div> -+ -+ {this.renderKebab(lastCommitDate, infoTitle)} - </div> - ) - } -merged - result 100644 292ba973e860f3355a07d5e065c48375de1c310b app/src/ui/branches/branch-renderer.tsx - our 100644 f42659ed79888d2c70f22251464d169c46333d83 app/src/ui/branches/branch-renderer.tsx -@@ -8,17 +8,19 @@ - export function renderDefaultBranch( - item: IBranchListItem, - matches: ReadonlyArray<number>, -- currentBranch: Branch | null -+ currentBranch: Branch | null, -+ onCompareToBranch?: (branch: Branch) => void - ): JSX.Element { - const branch = item.branch - const commit = branch.tip - const currentBranchName = currentBranch ? currentBranch.name : null - return ( - <BranchListItem -- name={branch.name} -+ branch={branch} - isCurrentBranch={branch.name === currentBranchName} - lastCommitDate={commit ? commit.author.date : null} - matches={matches} -+ onCompareToBranch={onCompareToBranch} - /> - ) - } -merged - result 100644 5d911045738fda18f7ba387bee8506a1636956bc app/src/ui/branches/branches-container.tsx - our 100644 f08de18102ffb24add928e0ce726b0a8fdd7457b app/src/ui/branches/branches-container.tsx -@@ -7,7 +7,13 @@ - import { BranchesTab } from '../../models/branches-tab' - - import { Dispatcher } from '../../lib/dispatcher' --import { FoldoutType, PopupType } from '../../lib/app-state' -+import { -+ FoldoutType, -+ PopupType, -+ CompareActionKind, -+ ComparisonView, -+ RepositorySectionTab, -+} from '../../lib/app-state' - import { assertNever } from '../../lib/fatal-error' - - import { TabBar } from '../tab-bar' -@@ -97,11 +103,28 @@ - ) - } - -+ private onCompareToBranch = async (branch: Branch) => { -+ await this.props.dispatcher.initializeCompare(this.props.repository, { -+ kind: CompareActionKind.Branch, -+ branch, -+ mode: ComparisonView.Behind, -+ }) -+ await this.props.dispatcher.changeRepositorySection(this.props.repository, { -+ selectedTab: RepositorySectionTab.History, -+ }) -+ await this.props.dispatcher.closeFoldout(FoldoutType.Branch) -+ } -+ - private renderBranch = ( - item: IBranchListItem, - matches: ReadonlyArray<number> - ) => { -- return renderDefaultBranch(item, matches, this.props.currentBranch) -+ return renderDefaultBranch( -+ item, -+ matches, -+ this.props.currentBranch, -+ this.onCompareToBranch -+ ) - } - - private renderSelectedTab() { -merged - result 100644 7847e0708feff2e0a3104e0f98840da2944919df app/src/ui/history/compare.tsx - our 100644 353aec44fd01563221794684d9c30fa54019686d app/src/ui/history/compare.tsx -@@ -33,6 +33,11 @@ - readonly dispatcher: Dispatcher - readonly currentBranch: Branch | null - readonly sidebarHasFocusWithin: boolean -+ -+ /** -+ * Shows the branch list when the component is loaded -+ */ -+ readonly initialShowBranchList: boolean - readonly onRevertCommit: (commit: Commit) => void - readonly onViewCommitOnGitHub: (sha: string) => void - } -@@ -63,10 +68,17 @@ - public constructor(props: ICompareSidebarProps) { - super(props) - -+ const formState = props.compareState.formState -+ -+ const filterText = -+ formState.kind === ComparisonView.None -+ ? '' -+ : formState.comparisonBranch.name -+ - this.state = { - focusedBranch: null, -- filterText: '', -- showBranchList: false, -+ filterText, -+ showBranchList: props.initialShowBranchList, - selectedCommit: null, - } - } -@@ -84,7 +96,7 @@ - return - } - -- if (!hasFormStateChanged && newFormState.kind !== ComparisonView.None) { -+ if (newFormState.kind !== ComparisonView.None) { - // ensure the filter text is in sync with the comparison branch - const branch = newFormState.comparisonBranch - -@@ -132,6 +144,7 @@ - onRef={this.onTextBoxRef} - onValueChanged={this.onBranchFilterTextChanged} - onKeyDown={this.onBranchFilterKeyDown} -+ onSearchCleared={this.onSearchCleared} - /> - </div> - -@@ -142,6 +155,10 @@ - ) - } - -+ private onSearchCleared = () => { -+ this.handleEscape() -+ } -+ - private onBranchesListRef = (branchList: BranchList | null) => { - this.branchList = branchList - } -@@ -273,7 +290,8 @@ - <div className="merge-message"> - This will merge - <strong>{` ${count} ${pluralized}`}</strong> -- {` `}from{` `} -+ <br /> -+ from{` `} - <strong>{branch.name}</strong> - {` `}into{` `} - <strong>{currentBranch.name}</strong> -merged - result 100644 ad88a9b7996ea014994a13b187e2752d883ef61a app/src/ui/index.tsx - our 100644 e09719d3d34c3169bd68c26a84f6b7040c4d34a1 app/src/ui/index.tsx -@@ -50,6 +50,7 @@ - enableSourceMaps, - withSourceMappedStack, - } from '../lib/source-map-support' -+import { enableCompareSidebar } from '../lib/feature-flag' - - if (__DEV__) { - installDevGlobals() -@@ -139,7 +140,9 @@ - dispatcher.registerErrorHandler(upstreamAlreadyExistsHandler) - dispatcher.registerErrorHandler(externalEditorErrorHandler) - dispatcher.registerErrorHandler(openShellErrorHandler) --dispatcher.registerErrorHandler(mergeConflictHandler) -+if (enableCompareSidebar()) { -+ dispatcher.registerErrorHandler(mergeConflictHandler) -+} - dispatcher.registerErrorHandler(lfsAttributeMismatchHandler) - dispatcher.registerErrorHandler(gitAuthenticationErrorHandler) - dispatcher.registerErrorHandler(pushNeedsPullHandler) -merged - result 100644 7e0e709f0e2c042f8e122480dc6f4a05460633d4 app/src/ui/lib/fancy-text-box.tsx - our 100644 6df9115db9a0aeacd505b2fb8240433391229e3c app/src/ui/lib/fancy-text-box.tsx -@@ -47,6 +47,7 @@ - placeholder={this.props.placeholder} - onKeyDown={this.props.onKeyDown} - onValueChanged={this.props.onValueChanged} -+ onSearchCleared={this.props.onSearchCleared} - tabIndex={this.props.tabIndex} - ref={this.props.onRef} - /> -merged - result 100644 a7340d5ff2ec3d5eb79dfe531a6dbce60eb7ab03 app/src/ui/lib/filter-list.tsx - our 100644 77cee6a28a6f7a75649844e1af52c5598547e633 app/src/ui/lib/filter-list.tsx -@@ -244,19 +244,25 @@ - } - - public selectFirstItem(focus: boolean = false) { -- if (this.list !== null) { -- const next = findNextSelectableRow(this.state.rows.length, { -+ if (this.list === null) { -+ return -+ } -+ -+ const next = findNextSelectableRow( -+ this.state.rows.length, -+ { - direction: 'down', - row: -1, -- }) -- -- if (next !== null) { -- this.setState({ selectedRow: next }) -- } -+ }, -+ this.canSelectRow -+ ) - -- if (focus) { -- this.list.focus() -- } -+ if (next !== null) { -+ this.setState({ selectedRow: next }, () => { -+ if (focus && this.list !== null) { -+ this.list.focus() -+ } -+ }) - } - } - -merged - result 100644 d99f339f0d967a2ba0f2d644345ead21bc38e5ba app/src/ui/lib/text-box.tsx - our 100644 66bfac13bd43aaa38cac461cd0a48bd47c66fa29 app/src/ui/lib/text-box.tsx -@@ -84,6 +84,11 @@ - * Callback used when the component loses focus. - */ - readonly onBlur?: () => void -+ -+ /** -+ * Callback used when the user has cleared the search text. -+ */ -+ readonly onSearchCleared?: () => void - } - - interface ITextBoxState { -@@ -162,8 +167,33 @@ - }) - } - -+ private onSearchTextCleared = () => { -+ if (this.props.onSearchCleared != null) { -+ this.props.onSearchCleared() -+ } -+ } -+ -+ /** -+ * The search event here is a Chrome and Safari specific event that is -+ * only reported for input[type=search] elements. -+ * -+ * Source: http://help.dottoro.com/ljdvxmhr.php -+ * -+ * TODO: can we hook into the warning API of React to report on incorrect usage -+ * when you set a `onSearchCleared` callback prop but don't use a `type=search` -+ * input - because this won't set an event handler. -+ * -+ */ - private onInputRef = (element: HTMLInputElement | null) => { -+ if (this.inputElement != null && this.props.type === 'search') { -+ this.inputElement.removeEventListener('search', this.onSearchTextCleared) -+ } -+ - this.inputElement = element -+ -+ if (this.inputElement != null && this.props.type === 'search') { -+ this.inputElement.addEventListener('search', this.onSearchTextCleared) -+ } - } - - private renderLabelLink() { -merged - result 100644 a3b6556013c00f4521932e03bf32044fc404eb9c app/src/ui/merge-conflicts/merge-conflicts-warning.tsx - our 100644 fc7cf8351657a4d7be73ce9248306c414d5ddbb3 app/src/ui/merge-conflicts/merge-conflicts-warning.tsx -@@ -3,7 +3,7 @@ - import { ButtonGroup } from '../lib/button-group' - import { Dialog, DialogContent, DialogFooter } from '../dialog' - import { Dispatcher } from '../../lib/dispatcher' --import { RepositorySection } from '../../lib/app-state' -+import { RepositorySectionTab } from '../../lib/app-state' - import { Repository } from '../../models/repository' - - interface IMergeConflictsWarningProps { -@@ -17,10 +17,9 @@ - {} - > { - private onSubmit = () => { -- this.props.dispatcher.changeRepositorySection( -- this.props.repository, -- RepositorySection.Changes -- ) -+ this.props.dispatcher.changeRepositorySection(this.props.repository, { -+ selectedTab: RepositorySectionTab.Changes, -+ }) - this.props.onDismissed() - } - -merged - result 100644 530e5ec3069faa47bceabedc36bce50656b2c4d3 app/src/ui/repository.tsx - our 100644 0148c3c16e7f2c3b26a1e7b674f3ceb6d438a34b app/src/ui/repository.tsx -@@ -11,8 +11,9 @@ - import { TabBar } from './tab-bar' - import { - IRepositoryState, -- RepositorySection, -+ RepositorySectionTab, - ImageDiffType, -+ RepositorySection, - } from '../lib/app-state' - import { Dispatcher } from '../lib/dispatcher' - import { IssuesStore, GitHubUserStore } from '../lib/stores' -@@ -76,7 +77,8 @@ - const hasChanges = - this.props.state.changesState.workingDirectory.files.length > 0 - const selectedTab = -- this.props.state.selectedSection === RepositorySection.Changes -+ this.props.state.selectedSection.selectedTab === -+ RepositorySectionTab.Changes - ? Tab.Changes - : Tab.History - -@@ -155,6 +157,11 @@ - private renderCompareSidebar(): JSX.Element { - const tip = this.props.state.branchesState.tip - const currentBranch = tip.kind === TipState.Valid ? tip.branch : null -+ const selectedSection = this.props.state.selectedSection -+ const focusBranchSelector = -+ selectedSection.selectedTab === RepositorySectionTab.History -+ ? selectedSection.shouldFocusBranchList || false -+ : false - - return ( - <CompareSidebar -@@ -169,6 +176,7 @@ - onRevertCommit={this.onRevertCommit} - onViewCommitOnGitHub={this.props.onViewCommitOnGitHub} - sidebarHasFocusWithin={this.state.sidebarHasFocusWithin} -+ initialShowBranchList={focusBranchSelector} - /> - ) - } -@@ -176,9 +184,9 @@ - private renderSidebarContents(): JSX.Element { - const selectedSection = this.props.state.selectedSection - -- if (selectedSection === RepositorySection.Changes) { -+ if (selectedSection.selectedTab === RepositorySectionTab.Changes) { - return this.renderChangesSidebar() -- } else if (selectedSection === RepositorySection.History) { -+ } else if (selectedSection.selectedTab === RepositorySectionTab.History) { - return enableCompareSidebar() - ? this.renderCompareSidebar() - : this.renderHistorySidebar() -@@ -220,7 +228,7 @@ - private renderContent(): JSX.Element | null { - const selectedSection = this.props.state.selectedSection - -- if (selectedSection === RepositorySection.Changes) { -+ if (selectedSection.selectedTab === RepositorySectionTab.Changes) { - const changesState = this.props.state.changesState - const selectedFileIDs = changesState.selectedFileIDs - -@@ -252,7 +260,7 @@ - /> - ) - } -- } else if (selectedSection === RepositorySection.History) { -+ } else if (selectedSection.selectedTab === RepositorySectionTab.History) { - return ( - <History - repository={this.props.repository} -@@ -290,10 +298,14 @@ - // about the shift key here, we can get away with that as long - // as there's only two tabs. - if (e.ctrlKey && e.key === 'Tab') { -- const section = -- this.props.state.selectedSection === RepositorySection.History -- ? RepositorySection.Changes -- : RepositorySection.History -+ const section: RepositorySection = -+ this.props.state.selectedSection.selectedTab === -+ RepositorySectionTab.History -+ ? { selectedTab: RepositorySectionTab.Changes } -+ : { -+ selectedTab: RepositorySectionTab.History, -+ shouldFocusBranchList: false, -+ } - - this.props.dispatcher.changeRepositorySection( - this.props.repository, -@@ -304,10 +316,14 @@ - } - - private onTabClicked = (tab: Tab) => { -- const section = -+ const section: RepositorySection = - tab === Tab.History -- ? RepositorySection.History -- : RepositorySection.Changes -+ ? { -+ selectedTab: RepositorySectionTab.History, -+ shouldFocusBranchList: false, -+ } -+ : { selectedTab: RepositorySectionTab.Changes } -+ - this.props.dispatcher.changeRepositorySection( - this.props.repository, - section -merged - result 100644 aa55a4afe2dbcf81388d5d4a68bbcef237edf516 app/styles/ui/_branches.scss - our 100644 8b437422d7971232a5209b075f6a7a4aac650780 app/styles/ui/_branches.scss -@@ -190,15 +190,12 @@ - - .branches-list { - &-item { -- padding: 0 var(--spacing); -- } -- -- &-item { - display: flex; - flex-direction: row; - min-width: 0; - flex-grow: 1; - align-items: center; -+ padding: 0 var(--spacing); - - .icon { - margin-right: var(--spacing-half); -@@ -221,6 +218,44 @@ - } - } - -+ .branches-list-item-menu { -+ display: none; -+ } -+ -+ &.kebab-effect:hover { -+ .description { -+ display: none; -+ } -+ -+ .branches-list-item-menu { -+ display: flex; -+ flex-grow: 1; -+ justify-content: flex-end; -+ } -+ -+ .branch-menu-wrapper { -+ display: flex; -+ margin: var(--spacing); -+ margin-right: 0; -+ padding: 0 var(--spacing); -+ border-radius: var(--border-radius); -+ transition: background 0.15s; -+ -+ .octicon { -+ fill: var(--text-secondary-color); -+ transition: fill 0.15s; -+ } -+ -+ &:hover { -+ background: rgba($gray-500, 0.2); -+ -+ .octicon { -+ fill: var(--text-color); -+ } -+ } -+ } -+ } -+ - .description { - margin-right: var(--spacing-half); - color: var(--text-secondary-color); -merged - result 100644 ef1599638c6d327a99a8043a83e57cd9d102d41b app/test/unit/app-store-test.ts - our 100644 11161765e2eda88e549efb9ec50be911f6c76442 app/test/unit/app-store-test.ts -@@ -28,7 +28,7 @@ - import { StatsStore } from '../../src/lib/stats' - - import { -- RepositorySection, -+ RepositorySectionTab, - SelectionType, - IRepositoryState, - } from '../../src/lib/app-state' -@@ -131,10 +131,9 @@ - - // select the repository and show the changes view - await appStore._selectRepository(repository) -- await appStore._changeRepositorySection( -- repository, -- RepositorySection.Changes -- ) -+ await appStore._changeRepositorySection(repository, { -+ selectedTab: RepositorySectionTab.Changes, -+ }) - - let state = getAppState(appStore) - expect(state.localCommitSHAs.length).to.equal(1) -merged - result 100644 c93e0568e69be37dc41420115d61f995f91b61ea changelog.json - our 100644 26d03c2e5abb64530a6274d877b1db7e9313236d changelog.json -@@ -1,5 +1,7 @@ - { - "releases": { -+ "1.1.2-beta7": [ -+ ], - "1.1.2-beta6": [ - "[Added] Add MacVim support for macOS - #4532. Thanks @johnelliott!", - "[Fixed] Open in Shell on Linux ensures Git is available on the user's PATH - #4619. Thanks @ziggy42!", diff --git a/app/test/fixtures/merge-parser/electron/merge-1-3-x-into-master.txt b/app/test/fixtures/merge-parser/electron/merge-1-3-x-into-master.txt deleted file mode 100644 index e70db3d1f9e..00000000000 --- a/app/test/fixtures/merge-parser/electron/merge-1-3-x-into-master.txt +++ /dev/null @@ -1,1599 +0,0 @@ -changed in both - base 100644 ef5ae30a840566e1f66ffb4e6e95b043275f95b3 atom/browser/native_window_views.cc - our 100644 0dba39942f92d54ba34db7709b73012055680d94 atom/browser/native_window_views.cc - their 100644 8e9e434d5a90dd446ec6615aaddc0ce2847a66ff atom/browser/native_window_views.cc -@@ -99,11 +99,36 @@ - - } // namespace - -+<<<<<<< .our - NativeWindowViews::NativeWindowViews(const mate::Dictionary& options, - NativeWindow* parent) - : NativeWindow(options, parent), - root_view_(new RootView(this)), - keyboard_event_handler_(new views::UnhandledKeyboardEventHandler) { -+======= -+NativeWindowViews::NativeWindowViews( -+ brightray::InspectableWebContents* web_contents, -+ const mate::Dictionary& options, -+ NativeWindow* parent) -+ : NativeWindow(web_contents, options, parent), -+ window_(new views::Widget), -+ web_view_(inspectable_web_contents()->GetView()->GetView()), -+ menu_bar_autohide_(false), -+ menu_bar_visible_(false), -+ menu_bar_alt_pressed_(false), -+#if defined(OS_WIN) -+ checked_for_a11y_support_(false), -+ thick_frame_(true), -+#endif -+ keyboard_event_handler_(new views::UnhandledKeyboardEventHandler), -+ disable_count_(0), -+ use_content_size_(false), -+ movable_(true), -+ resizable_(true), -+ maximizable_(true), -+ minimizable_(true), -+ fullscreenable_(true) { -+>>>>>>> .their - options.Get(options::kTitle, &title_); - - bool menu_bar_autohide; -changed in both - base 100644 d0d45fc53594e07521c2cd1f89cfc17e618707d7 atom/browser/native_window_views.h - our 100644 ef1e4413ca879980e46f301bccd6c8fe2b1a4611 atom/browser/native_window_views.h - their 100644 6118e2f9e3732cdb255554aa14a1de73950384e4 atom/browser/native_window_views.h -@@ -16,6 +16,8 @@ - #include "atom/browser/ui/win/message_handler_delegate.h" - #include "atom/browser/ui/win/taskbar_host.h" - #include "base/win/scoped_gdi_object.h" -+#include "ui/base/win/accessibility_misc_utils.h" -+#include <UIAutomationCoreApi.h> - #endif - - namespace views { -@@ -241,7 +243,11 @@ - TaskbarHost taskbar_host_; - - // Memoized version of a11y check -+<<<<<<< .our - bool checked_for_a11y_support_ = false; -+======= -+ bool checked_for_a11y_support_; -+>>>>>>> .their - - // Whether to show the WS_THICKFRAME style. - bool thick_frame_ = true; -changed in both - base 100644 bb6d9858f04555598df6a4001ecae26b52dbee1f atom/browser/native_window_views_win.cc - our 100644 0e61d18b915924eb3d3d14e40d1cbbd199631bed atom/browser/native_window_views_win.cc - their 100644 85230addb0c1d50f8223fa994ea0fe37268e856c atom/browser/native_window_views_win.cc -@@ -159,12 +159,20 @@ - // because we still want Chromium to handle returning the actual - // accessibility object. - case WM_GETOBJECT: { -+<<<<<<< .our - if (checked_for_a11y_support_) - return false; - - const DWORD obj_id = static_cast<DWORD>(l_param); - - if (obj_id != static_cast<DWORD>(OBJID_CLIENT)) { -+======= -+ if (checked_for_a11y_support_) return false; -+ -+ const DWORD obj_id = static_cast<DWORD>(l_param); -+ -+ if (obj_id != OBJID_CLIENT) { -+>>>>>>> .their - return false; - } - -@@ -174,7 +182,11 @@ - - checked_for_a11y_support_ = true; - -+<<<<<<< .our - auto* const axState = content::BrowserAccessibilityState::GetInstance(); -+======= -+ const auto axState = content::BrowserAccessibilityState::GetInstance(); -+>>>>>>> .their - if (axState && !axState->IsAccessibleBrowser()) { - axState->OnScreenReaderDetected(); - Browser::Get()->OnAccessibilitySupportChanged(); -changed in both - base 100644 bb9a9b5a6375fd5afd8df6df5be777437b43b59c atom/browser/resources/mac/Info.plist - our 100644 9094f0f7335edf833d51f688851e6a105de60433 atom/browser/resources/mac/Info.plist - their 100644 6c1509e3c0482ec44f943d7e2adea3826b1ad05b atom/browser/resources/mac/Info.plist -@@ -17,9 +17,15 @@ - <key>CFBundleIconFile</key> - <string>electron.icns</string> - <key>CFBundleVersion</key> -+<<<<<<< .our - <string>4.0.0</string> - <key>CFBundleShortVersionString</key> - <string>4.0.0</string> -+======= -+ <string>1.3.15</string> -+ <key>CFBundleShortVersionString</key> -+ <string>1.3.15</string> -+>>>>>>> .their - <key>LSApplicationCategoryType</key> - <string>public.app-category.developer-tools</string> - <key>LSMinimumSystemVersion</key> -changed in both - base 100644 599d8b694994ea399e991e7aa85150c84c079785 atom/browser/resources/win/atom.rc - our 100644 c0bd831e8bddf10180f75cd40694831e2e98622d atom/browser/resources/win/atom.rc - their 100644 8b925d8fe7bf1d0a746432bd240b0b447ab2c5be atom/browser/resources/win/atom.rc -@@ -56,8 +56,13 @@ - // - - VS_VERSION_INFO VERSIONINFO -+<<<<<<< .our - FILEVERSION 4,0,0,20180821 - PRODUCTVERSION 4,0,0,20180821 -+======= -+ FILEVERSION 1,3,15,0 -+ PRODUCTVERSION 1,3,15,0 -+>>>>>>> .their - FILEFLAGSMASK 0x3fL - #ifdef _DEBUG - FILEFLAGS 0x1L -@@ -74,12 +79,20 @@ - BEGIN - VALUE "CompanyName", "GitHub, Inc." - VALUE "FileDescription", "Electron" -+<<<<<<< .our - VALUE "FileVersion", "4.0.0" -+======= -+ VALUE "FileVersion", "1.3.15" -+>>>>>>> .their - VALUE "InternalName", "electron.exe" - VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." - VALUE "OriginalFilename", "electron.exe" - VALUE "ProductName", "Electron" -+<<<<<<< .our - VALUE "ProductVersion", "4.0.0" -+======= -+ VALUE "ProductVersion", "1.3.15" -+>>>>>>> .their - VALUE "SquirrelAwareVersion", "1" - END - END -changed in both - base 100644 7b7655c6cd2e0661a45968636737f5ab3b70467f atom/common/api/atom_api_v8_util.cc - our 100644 3d80db0c0a4cdbb4c7a78fa7e4266fc6fc87193f atom/common/api/atom_api_v8_util.cc - their 100644 ddb1075586c1eefaad73789b42e124f00548d939 atom/common/api/atom_api_v8_util.cc -@@ -94,6 +94,7 @@ - isolate->GetHeapProfiler()->TakeHeapSnapshot(); - } - -+<<<<<<< .our - void RequestGarbageCollectionForTesting(v8::Isolate* isolate) { - isolate->RequestGarbageCollectionForTesting( - v8::Isolate::GarbageCollectionType::kFullGarbageCollection); -@@ -107,6 +108,14 @@ - v8::Local<v8::Value> unused, - v8::Local<v8::Context> context, - void* priv) { -+======= -+bool IsSameOrigin(const GURL& l, const GURL& r) { -+ return url::Origin(l).IsSameOriginWith(url::Origin(r)); -+} -+ -+void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused, -+ v8::Local<v8::Context> context, void* priv) { -+>>>>>>> .their - mate::Dictionary dict(context->GetIsolate(), exports); - dict.SetMethod("getHiddenValue", &GetHiddenValue); - dict.SetMethod("setHiddenValue", &SetHiddenValue); -@@ -116,11 +125,16 @@ - dict.SetMethod("setRemoteCallbackFreer", &atom::RemoteCallbackFreer::BindTo); - dict.SetMethod("setRemoteObjectFreer", &atom::RemoteObjectFreer::BindTo); - dict.SetMethod("createIDWeakMap", &atom::api::KeyWeakMap<int32_t>::Create); -+<<<<<<< .our - dict.SetMethod( - "createDoubleIDWeakMap", - &atom::api::KeyWeakMap<std::pair<std::string, int32_t>>::Create); - dict.SetMethod("requestGarbageCollectionForTesting", - &RequestGarbageCollectionForTesting); -+======= -+ dict.SetMethod("createDoubleIDWeakMap", -+ &atom::api::KeyWeakMap<std::pair<int32_t, int32_t>>::Create); -+>>>>>>> .their - dict.SetMethod("isSameOrigin", &IsSameOrigin); - } - -changed in both - base 100644 a27cb04a4b137f053065b935eab3e1fa6f537d70 atom/common/atom_version.h - our 100644 65e7d19911559a40b1b258319df5fe0fa180354f atom/common/atom_version.h - their 100644 94554df10c372f62787e459f3cd451eff54cf561 atom/common/atom_version.h -@@ -5,10 +5,22 @@ - #ifndef ATOM_COMMON_ATOM_VERSION_H_ - #define ATOM_COMMON_ATOM_VERSION_H_ - -+<<<<<<< .our - #define ATOM_MAJOR_VERSION 4 - #define ATOM_MINOR_VERSION 0 - #define ATOM_PATCH_VERSION 0 - #define ATOM_PRE_RELEASE_VERSION -nightly.20180821 -+======= -+#define ATOM_MAJOR_VERSION 1 -+#define ATOM_MINOR_VERSION 3 -+#define ATOM_PATCH_VERSION 15 -+ -+#define ATOM_VERSION_IS_RELEASE 1 -+ -+#ifndef ATOM_TAG -+# define ATOM_TAG "" -+#endif -+>>>>>>> .their - - #ifndef ATOM_STRINGIFY - #define ATOM_STRINGIFY(n) ATOM_STRINGIFY_HELPER(n) -changed in both - base 100644 dd28ad7a97b3fc9d45428ca28b8c363d5d7b1339 atom/renderer/api/atom_api_web_frame.cc - our 100644 f0f7ef249d73876f7107d3d3865e8fc71ee33945 atom/renderer/api/atom_api_web_frame.cc - their 100644 8e6d1c15e1f35902963f0558d126077b15d272bf atom/renderer/api/atom_api_web_frame.cc -@@ -179,12 +179,26 @@ - } - - void WebFrame::SetVisualZoomLevelLimits(double min_level, double max_level) { -+<<<<<<< .our - web_frame_->View()->SetDefaultPageScaleLimits(min_level, max_level); - web_frame_->View()->SetIgnoreViewportTagScaleLimits(true); - } - - void WebFrame::SetLayoutZoomLevelLimits(double min_level, double max_level) { - web_frame_->View()->ZoomLimitsChanged(min_level, max_level); -+======= -+ web_frame_->view()->setDefaultPageScaleLimits(min_level, max_level); -+} -+ -+void WebFrame::SetLayoutZoomLevelLimits(double min_level, double max_level) { -+ web_frame_->view()->zoomLimitsChanged(min_level, max_level); -+} -+ -+v8::Local<v8::Value> WebFrame::RegisterEmbedderCustomElement( -+ const base::string16& name, v8::Local<v8::Object> options) { -+ blink::WebExceptionCode c = 0; -+ return web_frame_->document().registerEmbedderCustomElement(name, options, c); -+>>>>>>> .their - } - - v8::Local<v8::Value> WebFrame::RegisterEmbedderCustomElement( -@@ -510,6 +524,7 @@ - &WebFrame::SetIsolatedWorldHumanReadableName) - .SetMethod("getResourceUsage", &WebFrame::GetResourceUsage) - .SetMethod("clearCache", &WebFrame::ClearCache) -+<<<<<<< .our - .SetMethod("getFrameForSelector", &WebFrame::GetFrameForSelector) - .SetMethod("findFrameByName", &WebFrame::FindFrameByName) - .SetProperty("opener", &WebFrame::Opener) -@@ -519,6 +534,10 @@ - .SetProperty("nextSibling", &WebFrame::NextSibling) - .SetProperty("routingId", &WebFrame::RoutingId) - .SetMethod("findFrameByRoutingId", &WebFrame::FindFrameByRoutingId); -+======= -+ // TODO(kevinsawicki): Remove in 2.0, deprecate before then with warnings -+ .SetMethod("setZoomLevelLimits", &WebFrame::SetVisualZoomLevelLimits); -+>>>>>>> .their - } - - } // namespace api -changed in both - base 100644 7b2401dd4077b5e7a067b54dd2a4bead9f1d9ca3 atom/renderer/api/atom_api_web_frame.h - our 100644 4cc6386abcb41cfa29fdc002f6fb267329bb112d atom/renderer/api/atom_api_web_frame.h - their 100644 c2706708beab5bdc1fa5f98cfa11a306611100ad atom/renderer/api/atom_api_web_frame.h -changed in both - base 100644 52eba31d0aee456320d7e64bb1d0671fb97d02a1 common.gypi - our 100644 676d1e904127066e4a3d313106f15406fcbed8b6 common.gypi - their 100644 61946656dd8432f337fff7af308e672aaf815ae2 common.gypi -changed in both - base 100644 235c044c81e52314468ba1775f9fcaae7541962d docs/api/web-contents.md - our 100644 8990fe2e97ab62eafdd3f7a4eb8ee782415124c5 docs/api/web-contents.md - their 100644 016daa345fc636144eb830111ff499635d024c96 docs/api/web-contents.md -@@ -873,6 +873,17 @@ - * `minimumLevel` Number - * `maximumLevel` Number - -+<<<<<<< .our -+======= -+**Deprecated:** Call `setVisualZoomLevelLimits` instead to set the visual zoom -+level limits. This method will be removed in Electron 2.0. -+ -+#### `contents.setVisualZoomLevelLimits(minimumLevel, maximumLevel)` -+ -+* `minimumLevel` Number -+* `maximumLevel` Number -+ -+>>>>>>> .their - Sets the maximum and minimum pinch-to-zoom level. - - #### `contents.setLayoutZoomLevelLimits(minimumLevel, maximumLevel)` -changed in both - base 100644 8a0e1dd6a9b1b4f83b30701d3b8e05e049d6a56b docs/api/web-frame.md - our 100644 989060ef3e50c5d93db1a914997f1d190edf3cf5 docs/api/web-frame.md - their 100644 062c3310d5d1f879ee5ace8b0e672f8fb7910df5 docs/api/web-frame.md -@@ -55,6 +55,24 @@ - * `minimumLevel` Number - * `maximumLevel` Number - -+<<<<<<< .our -+======= -+**Deprecated:** Call `setVisualZoomLevelLimits` instead to set the visual zoom -+level limits. This method will be removed in Electron 2.0. -+ -+### `webFrame.setVisualZoomLevelLimits(minimumLevel, maximumLevel)` -+ -+* `minimumLevel` Number -+* `maximumLevel` Number -+ -+Sets the maximum and minimum pinch-to-zoom level. -+ -+### `webFrame.setLayoutZoomLevelLimits(minimumLevel, maximumLevel)` -+ -+* `minimumLevel` Number -+* `maximumLevel` Number -+ -+>>>>>>> .their - Sets the maximum and minimum layout-based (i.e. non-visual) zoom level. - - ### `webFrame.setSpellCheckProvider(language, autoCorrectWord, provider)` -removed in local - base 100644 896fd07000b38da3e7df62464670a8a65ac53868 docs/tutorial/planned-breaking-changes.md - their 100644 525ffecb81702a2fbd9d6152ba247decf85b39fe docs/tutorial/planned-breaking-changes.md -changed in both - base 100644 6cf495afbc1fde1ef313db9834170084c131b31d electron.gyp - our 100644 944ddab2a3fd879044e31677e4bac2843fffbdee electron.gyp - their 100644 26793815ace126ff4f0bef84af4c1c786b3cd8b3 electron.gyp -@@ -4,8 +4,12 @@ - 'product_name%': 'Electron', - 'company_name%': 'GitHub, Inc', - 'company_abbr%': 'github', -+<<<<<<< .our - 'version%': '4.0.0-nightly.20180821', - 'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c', -+======= -+ 'version%': '1.3.15', -+>>>>>>> .their - }, - 'includes': [ - 'features.gypi', -@@ -371,9 +375,13 @@ - '-lcomdlg32.lib', - '-lwininet.lib', - '-lwinmm.lib', -+<<<<<<< .our - '-lcrypt32.lib', - '-luiautomationcore.lib', - '-lPropsys.lib' -+======= -+ '-luiautomationcore.lib', -+>>>>>>> .their - ], - }, - 'dependencies': [ -changed in both - base 100644 c6ad57321baacf5277cfef75e7f1e5683dacbcc4 lib/browser/api/app.js - our 100644 66f6ae651acf10fb19b8ec068fc5280850dd3d91 lib/browser/api/app.js - their 100644 8e7760593bde28502b681a1f71703979098e2790 lib/browser/api/app.js -changed in both - base 100644 ecfdda05f8db327ffc7c846136126d072848a6eb lib/browser/api/browser-window.js - our 100644 cb523496d65c7018c30054621cfdeb1281f9db6a lib/browser/api/browser-window.js - their 100644 703fdcbfb450ce850e5ad8f7319eed355312e065 lib/browser/api/browser-window.js -@@ -217,9 +217,12 @@ - }, - capturePage (...args) { - return this.webContents.capturePage(...args) -+<<<<<<< .our - }, - setTouchBar (touchBar) { - electron.TouchBar._setOnWindow(touchBar, this) -+======= -+>>>>>>> .their - } - }) - -changed in both - base 100644 d24a1f98a7d8c27a9cec0c00d9fdb4553dd3d90f lib/browser/api/dialog.js - our 100644 d7545a7687a6c168a79c09c9e7866af05d336d12 lib/browser/api/dialog.js - their 100644 5002c18b150e0574d03215f331172e6d6609109b lib/browser/api/dialog.js -@@ -73,9 +73,13 @@ - module.exports = { - showOpenDialog: function (...args) { - checkAppInitialized() -+<<<<<<< .our - - let [window, options, callback] = parseArgs(...args) - -+======= -+ let [window, options, callback] = parseArgs(...args) -+>>>>>>> .their - if (options == null) { - options = { - title: 'Open', -@@ -136,9 +140,13 @@ - - showSaveDialog: function (...args) { - checkAppInitialized() -+<<<<<<< .our - - let [window, options, callback] = parseArgs(...args) - -+======= -+ let [window, options, callback] = parseArgs(...args) -+>>>>>>> .their - if (options == null) { - options = { - title: 'Save' -@@ -194,9 +202,13 @@ - - showMessageBox: function (...args) { - checkAppInitialized() -+<<<<<<< .our - - let [window, options, callback] = parseArgs(...args) - -+======= -+ let [window, options, callback] = parseArgs(...args) -+>>>>>>> .their - if (options == null) { - options = { - type: 'none' -@@ -281,6 +293,7 @@ - - showErrorBox: function (...args) { - return binding.showErrorBox(...args) -+<<<<<<< .our - }, - - showCertificateTrustDialog: function (...args) { -@@ -302,6 +315,8 @@ - } - - return binding.showCertificateTrustDialog(window, certificate, message, callback) -+======= -+>>>>>>> .their - } - } - -changed in both - base 100644 33ce779521fa4dd869872733405529662e1818c0 lib/browser/api/navigation-controller.js - our 100644 7eb21ddb3ea9c8bcec994e2fc8bcbcf6be4b82f0 lib/browser/api/navigation-controller.js - their 100644 0bccf0c6dcc5b70048566bf008fcfa41969f2610 lib/browser/api/navigation-controller.js -changed in both - base 100644 560b323d619bcdc9a8b842b4cd771125f0640d3a lib/browser/api/web-contents.js - our 100644 8f5bd037b14d05db7396bb8b5de1a29fdef167ae lib/browser/api/web-contents.js - their 100644 53c6c0f15ff9fad632dbe4bcbaa38b7ec52772c6 lib/browser/api/web-contents.js -@@ -109,7 +109,19 @@ - 'insertCSS', - 'insertText', - 'setLayoutZoomLevelLimits', -+<<<<<<< .our - 'setVisualZoomLevelLimits' -+======= -+ 'setVisualZoomLevelLimits', -+ 'setZoomFactor', -+ 'setZoomLevel', -+ // TODO(kevinsawicki): Remove in 2.0, deprecate before then with warnings -+ 'setZoomLevelLimits' -+] -+const webFrameMethodsWithResult = [ -+ 'getZoomFactor', -+ 'getZoomLevel' -+>>>>>>> .their - ] - const webFrameMethodsWithResult = [] - -@@ -313,6 +325,16 @@ - this.reload() - }) - -+<<<<<<< .our -+======= -+ // Delays the page-title-updated event to next tick. -+ this.on('-page-title-updated', function (...args) { -+ setImmediate(() => { -+ this.emit('page-title-updated', ...args) -+ }) -+ }) -+ -+>>>>>>> .their - app.emit('web-contents-created', {}, this) - } - -changed in both - base 100644 776ab91fec96619f04fbd4cff2d27a6dde736096 lib/browser/guest-window-manager.js - our 100644 7253c1942b0956ae6b9b0c80a23470fc26669b8a lib/browser/guest-window-manager.js - their 100644 7e8bf2e5652cf6c88e8d3d7e8b248f791b91009c lib/browser/guest-window-manager.js -@@ -2,7 +2,10 @@ - - const {BrowserWindow, ipcMain, webContents} = require('electron') - const {isSameOrigin} = process.atomBinding('v8_util') -+<<<<<<< .our - const parseFeaturesString = require('../common/parse-features-string') -+======= -+>>>>>>> .their - - const hasProp = {}.hasOwnProperty - const frameToGuest = new Map() -@@ -102,6 +105,7 @@ - return guestId - } - -+<<<<<<< .our - // Create a new guest created by |embedder| with |options|. - const createGuest = function (embedder, url, referrer, frameName, options, postData) { - let guest = frameToGuest.get(frameName) -@@ -158,6 +162,8 @@ - return setupGuest(embedder, frameName, guest, options) - } - -+======= -+>>>>>>> .their - const getGuestWindow = function (guestContents) { - let guestWindow = BrowserWindow.fromWebContents(guestContents) - if (guestWindow == null) { -@@ -180,6 +186,7 @@ - // The W3C does not have anything on this, but from my understanding of the - // security model of |window.opener|, this should be fine. - const canAccessWindow = function (sender, target) { -+<<<<<<< .our - return (target.getLastWebPreferences().openerId === sender.id) || - (sender.getLastWebPreferences().nodeIntegration === true) || - isSameOrigin(sender.getURL(), target.getURL()) -@@ -254,6 +261,15 @@ - ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', function (event, url, referrer, - frameName, disposition, options, - additionalFeatures, postData) { -+======= -+ return (target.getWebPreferences().openerId === sender.id) || -+ (sender.getWebPreferences().nodeIntegration === true) || -+ isSameOrigin(sender.getURL(), target.getURL()) -+} -+ -+// Routed window.open messages. -+ipcMain.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', function (event, url, frameName, disposition, options) { -+>>>>>>> .their - options = mergeBrowserWindowOptions(event.sender, options) - event.sender.emit('new-window', event, url, frameName, disposition, options, additionalFeatures, referrer) - const {newGuest} = event -@@ -318,7 +334,11 @@ - // The W3C does not seem to have word on how postMessage should work when the - // origins do not match, so we do not do |canAccessWindow| check here since - // postMessage across origins is useful and not harmful. -+<<<<<<< .our - if (targetOrigin === '*' || isSameOrigin(guestContents.getURL(), targetOrigin)) { -+======= -+ if (guestContents.getURL().indexOf(targetOrigin) === 0 || targetOrigin === '*') { -+>>>>>>> .their - const sourceId = event.sender.id - guestContents.send('ELECTRON_GUEST_WINDOW_POSTMESSAGE', sourceId, message, sourceOrigin) - } -changed in both - base 100644 fb1688d0cc74a75b3299768d79df625893591a24 lib/browser/init.js - our 100644 bed3d912ab8be3ca4f21de04e801bb42dc12a528 lib/browser/init.js - their 100644 56d4f0f7ae7599339ae979c5ad9231a5948b8e4d lib/browser/init.js -changed in both - base 100644 1917c65e655836872e72cf1588bbaeedf4b2a099 lib/browser/objects-registry.js - our 100644 f03a23d2f6910d6555bb9469180d1b60b94bc313 lib/browser/objects-registry.js - their 100644 b26374219f4530ad8d50ecc326b9d2ca5257900c lib/browser/objects-registry.js -@@ -26,11 +26,19 @@ - const id = this.saveToStorage(obj) - - // Add object to the set of referenced objects. -+<<<<<<< .our - const ownerKey = getOwnerKey(webContents, contextId) - let owner = this.owners[ownerKey] - if (!owner) { - owner = this.owners[ownerKey] = new Set() - this.registerDeleteListener(webContents, contextId) -+======= -+ const webContentsId = webContents.getId() -+ let owner = this.owners[webContentsId] -+ if (!owner) { -+ owner = this.owners[webContentsId] = new Set() -+ this.registerDeleteListener(webContents, webContentsId) -+>>>>>>> .their - } - if (!owner.has(id)) { - owner.add(id) -@@ -101,6 +109,7 @@ - } - } - -+<<<<<<< .our - // Private: Clear the storage when renderer process is destroyed. - registerDeleteListener (webContents, contextId) { - const processId = webContents.getProcessId() -@@ -108,6 +117,14 @@ - if (deletedProcessId === processId) { - webContents.removeListener('render-view-deleted', listener) - this.clear(webContents, contextId) -+======= -+ // Private: Clear the storage when webContents is reloaded/navigated. -+ registerDeleteListener (webContents, webContentsId) { -+ const listener = (event, deletedProcessId) => { -+ if (deletedProcessId === webContentsId) { -+ webContents.removeListener('render-view-deleted', listener) -+ this.clear(webContentsId) -+>>>>>>> .their - } - } - webContents.on('render-view-deleted', listener) -changed in both - base 100644 31e5a37732c709cf7843756b0f96d1d558a6babf lib/browser/rpc-server.js - our 100644 ff9f77321de3a4145946b67f3fe2a597f98e2510 lib/browser/rpc-server.js - their 100644 06e6f3be87c2b23bfd56d25022bd5814fa9e4b2c lib/browser/rpc-server.js -@@ -431,6 +431,7 @@ - } - }) - -+<<<<<<< .our - // Implements window.close() - ipcMain.on('ELECTRON_BROWSER_WINDOW_CLOSE', function (event) { - const window = event.sender.getOwnerBrowserWindow() -@@ -463,3 +464,35 @@ - } - } - }) -+======= -+// Implements window.alert(message, title) -+ipcMain.on('ELECTRON_BROWSER_WINDOW_ALERT', function (event, message, title) { -+ if (message == null) message = '' -+ if (title == null) title = '' -+ -+ event.returnValue = electron.dialog.showMessageBox(event.sender.getOwnerBrowserWindow(), { -+ message: `${message}`, -+ title: `${title}`, -+ buttons: ['OK'] -+ }) -+}) -+ -+// Implements window.confirm(message, title) -+ipcMain.on('ELECTRON_BROWSER_WINDOW_CONFIRM', function (event, message, title) { -+ if (message == null) message = '' -+ if (title == null) title = '' -+ -+ event.returnValue = !electron.dialog.showMessageBox(event.sender.getOwnerBrowserWindow(), { -+ message: `${message}`, -+ title: `${title}`, -+ buttons: ['OK', 'Cancel'], -+ cancelId: 1 -+ }) -+}) -+ -+// Implements window.close() -+ipcMain.on('ELECTRON_BROWSER_WINDOW_CLOSE', function (event) { -+ event.sender.getOwnerBrowserWindow().close() -+ event.returnValue = null -+}) -+>>>>>>> .their -changed in both - base 100644 459c392bc1888bda82a666eec21d0bb56162374a lib/common/api/callbacks-registry.js - our 100644 6a1c63b20413753eeb9c5f8d190a9f5d2f303d22 lib/common/api/callbacks-registry.js - their 100644 126694d154e47e848cb0783975272c912ea81537 lib/common/api/callbacks-registry.js -@@ -40,7 +40,12 @@ - } - - get (id) { -+<<<<<<< .our - return this.callbacks[id] || function () {} -+======= -+ var ref -+ return (ref = this.callbacks[id]) != null ? ref : function () {} -+>>>>>>> .their - } - - apply (id, ...args) { -changed in both - base 100644 0ffd97a7c53967ac8e2f547228b72a6a05f81d75 lib/common/init.js - our 100644 b424768414b857b485bd5e29bfce504de6f1d749 lib/common/init.js - their 100644 127e5e337eb0b41993df960346014fe9222cc894 lib/common/init.js -@@ -1,7 +1,21 @@ - const timers = require('timers') - const util = require('util') - -+<<<<<<< .our - process.atomBinding = require('./atom-binding-setup')(process.binding, process.type) -+======= -+const {binding} = process -+ -+process.atomBinding = function (name) { -+ try { -+ return binding('atom_' + process.type + '_' + name) -+ } catch (error) { -+ if (/No such module/.test(error.message)) { -+ return binding('atom_common_' + name) -+ } -+ } -+} -+>>>>>>> .their - - // setImmediate and process.nextTick makes use of uv_check and uv_prepare to - // run the callbacks, however since we only run uv loop on requests, the -changed in both - base 100644 a3a4443413d32d46a57f4a9667f7b5c0b86abcdb lib/renderer/api/remote.js - our 100644 59117f8f2dd977fc1817a6b1d540b616ddcb0dae lib/renderer/api/remote.js - their 100644 c3c8e3b89cd1458c6cfae6940bd9ff8ea54e3605 lib/renderer/api/remote.js -@@ -104,7 +104,11 @@ - // Populate object's members from descriptors. - // The |ref| will be kept referenced by |members|. - // This matches |getObjectMemebers| in rpc-server. -+<<<<<<< .our - function setObjectMembers (ref, object, metaId, members) { -+======= -+const setObjectMembers = function (ref, object, metaId, members) { -+>>>>>>> .their - if (!Array.isArray(members)) return - - for (let member of members) { -@@ -113,11 +117,22 @@ - let descriptor = { enumerable: member.enumerable } - if (member.type === 'method') { - const remoteMemberFunction = function (...args) { -+<<<<<<< .our - let command - if (this && this.constructor === remoteMemberFunction) { - command = 'ELECTRON_BROWSER_MEMBER_CONSTRUCTOR' - } else { - command = 'ELECTRON_BROWSER_MEMBER_CALL' -+======= -+ if (this && this.constructor === remoteMemberFunction) { -+ // Constructor call. -+ let ret = ipcRenderer.sendSync('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', metaId, member.name, wrapArgs(args)) -+ return metaToValue(ret) -+ } else { -+ // Call member function. -+ let ret = ipcRenderer.sendSync('ELECTRON_BROWSER_MEMBER_CALL', metaId, member.name, wrapArgs(args)) -+ return metaToValue(ret) -+>>>>>>> .their - } - const ret = ipcRenderer.sendSync(command, contextId, metaId, member.name, wrapArgs(args)) - return metaToValue(ret) -@@ -208,6 +223,7 @@ - } - - // Convert meta data from browser into real value. -+<<<<<<< .our - function metaToValue (meta) { - const types = { - value: () => meta.value, -@@ -218,6 +234,56 @@ - date: () => new Date(meta.value), - exception: () => { throw metaToException(meta) } - } -+======= -+const metaToValue = function (meta) { -+ var el, i, len, ref1, results, ret -+ switch (meta.type) { -+ case 'value': -+ return meta.value -+ case 'array': -+ ref1 = meta.members -+ results = [] -+ for (i = 0, len = ref1.length; i < len; i++) { -+ el = ref1[i] -+ results.push(metaToValue(el)) -+ } -+ return results -+ case 'buffer': -+ return Buffer.from(meta.value) -+ case 'promise': -+ return Promise.resolve({ -+ then: metaToValue(meta.then) -+ }) -+ case 'error': -+ return metaToPlainObject(meta) -+ case 'date': -+ return new Date(meta.value) -+ case 'exception': -+ throw new Error(meta.message + '\n' + meta.stack) -+ default: -+ if (remoteObjectCache.has(meta.id)) return remoteObjectCache.get(meta.id) -+ -+ if (meta.type === 'function') { -+ // A shadow class to represent the remote function object. -+ let remoteFunction = function (...args) { -+ if (this && this.constructor === remoteFunction) { -+ // Constructor call. -+ let obj = ipcRenderer.sendSync('ELECTRON_BROWSER_CONSTRUCTOR', meta.id, wrapArgs(args)) -+ // Returning object in constructor will replace constructed object -+ // with the returned object. -+ // http://stackoverflow.com/questions/1978049/what-values-can-a-constructor-return-to-avoid-returning-this -+ return metaToValue(obj) -+ } else { -+ // Function call. -+ let obj = ipcRenderer.sendSync('ELECTRON_BROWSER_FUNCTION_CALL', meta.id, wrapArgs(args)) -+ return metaToValue(obj) -+ } -+ } -+ ret = remoteFunction -+ } else { -+ ret = {} -+ } -+>>>>>>> .their - - if (meta.type in types) { - return types[meta.type]() -changed in both - base 100644 2356a81dda2ef366a22837825eb847aa8bcfdc3b lib/renderer/init.js - our 100644 2470a5e8be80e770b0c03f6a439a71e72ae12a1b lib/renderer/init.js - their 100644 5cee59059a2c1c9c736b77c55ecf0ebe772ff80b lib/renderer/init.js -@@ -26,6 +26,7 @@ - - // Use electron module after everything is ready. - -+<<<<<<< .our - const { - warnAboutNodeWithRemoteContent, - warnAboutDisabledWebSecurity, -@@ -39,6 +40,23 @@ - } = require('./security-warnings') - - require('./web-frame-init')() -+======= -+// Call webFrame method. -+electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', (event, method, args) => { -+ electron.webFrame[method](...args) -+}) -+ -+electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_SYNC_WEB_FRAME_METHOD', (event, requestId, method, args) => { -+ const result = electron.webFrame[method](...args) -+ event.sender.send(`ELECTRON_INTERNAL_BROWSER_SYNC_WEB_FRAME_RESPONSE_${requestId}`, result) -+}) -+ -+electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', (event, requestId, method, args) => { -+ electron.webFrame[method](...args, function (result) { -+ event.sender.send(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, result) -+ }) -+}) -+>>>>>>> .their - - // Process command line arguments. - let nodeIntegration = 'false' -changed in both - base 100644 29cf9f5acaec7093d4cdfb3987c0a892aa348ec6 lib/renderer/override.js - our 100644 fdeb6605a5cc5cae194ef9d31265b73b893822eb lib/renderer/override.js - their 100644 db35904f95236f7ece5bdafd8858eefd46a81ba1 lib/renderer/override.js -@@ -1,9 +1,251 @@ - 'use strict' - - const {ipcRenderer} = require('electron') -+<<<<<<< .our - - const {guestInstanceId, openerId} = process - const hiddenPage = process.argv.includes('--hidden-page') - const usesNativeWindowOpen = process.argv.includes('--native-window-open') - - require('./window-setup')(ipcRenderer, guestInstanceId, openerId, hiddenPage, usesNativeWindowOpen) -+======= -+ -+const {defineProperty} = Object -+ -+// Helper function to resolve relative url. -+const a = window.top.document.createElement('a') -+const resolveURL = function (url) { -+ a.href = url -+ return a.href -+} -+ -+// Window object returned by "window.open". -+const BrowserWindowProxy = (function () { -+ BrowserWindowProxy.proxies = {} -+ -+ BrowserWindowProxy.getOrCreate = function (guestId) { -+ let proxy = this.proxies[guestId] -+ if (proxy == null) { -+ proxy = new BrowserWindowProxy(guestId) -+ this.proxies[guestId] = proxy -+ } -+ return proxy -+ } -+ -+ BrowserWindowProxy.remove = function (guestId) { -+ delete this.proxies[guestId] -+ } -+ -+ function BrowserWindowProxy (guestId1) { -+ defineProperty(this, 'guestId', { -+ configurable: false, -+ enumerable: true, -+ writeable: false, -+ value: guestId1 -+ }) -+ -+ this.closed = false -+ ipcRenderer.once('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_' + this.guestId, () => { -+ BrowserWindowProxy.remove(this.guestId) -+ this.closed = true -+ }) -+ } -+ -+ BrowserWindowProxy.prototype.close = function () { -+ ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', this.guestId) -+ } -+ -+ BrowserWindowProxy.prototype.focus = function () { -+ ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'focus') -+ } -+ -+ BrowserWindowProxy.prototype.blur = function () { -+ ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'blur') -+ } -+ -+ BrowserWindowProxy.prototype.print = function () { -+ ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, 'print') -+ } -+ -+ defineProperty(BrowserWindowProxy.prototype, 'location', { -+ get: function () { -+ return ipcRenderer.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD_SYNC', this.guestId, 'getURL') -+ }, -+ set: function (url) { -+ url = resolveURL(url) -+ return ipcRenderer.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD_SYNC', this.guestId, 'loadURL', url) -+ } -+ }) -+ -+ BrowserWindowProxy.prototype.postMessage = function (message, targetOrigin) { -+ if (targetOrigin == null) { -+ targetOrigin = '*' -+ } -+ ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', this.guestId, message, targetOrigin, window.location.origin) -+ } -+ -+ BrowserWindowProxy.prototype['eval'] = function (...args) { -+ ipcRenderer.send('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, 'executeJavaScript', ...args) -+ } -+ -+ return BrowserWindowProxy -+})() -+ -+if (process.guestInstanceId == null) { -+ // Override default window.close. -+ window.close = function () { -+ ipcRenderer.sendSync('ELECTRON_BROWSER_WINDOW_CLOSE') -+ } -+} -+ -+// Make the browser window or guest view emit "new-window" event. -+window.open = function (url, frameName, features) { -+ var feature, guestId, i, j, len, len1, name, options, ref1, ref2, value -+ if (frameName == null) { -+ frameName = '' -+ } -+ if (features == null) { -+ features = '' -+ } -+ options = {} -+ -+ const ints = ['x', 'y', 'width', 'height', 'minWidth', 'maxWidth', 'minHeight', 'maxHeight', 'zoomFactor'] -+ const webPreferences = ['zoomFactor', 'nodeIntegration', 'preload'] -+ const disposition = 'new-window' -+ -+ // Make sure to get rid of excessive whitespace in the property name -+ ref1 = features.split(/,\s*/) -+ for (i = 0, len = ref1.length; i < len; i++) { -+ feature = ref1[i] -+ ref2 = feature.split(/\s*=/) -+ name = ref2[0] -+ value = ref2[1] -+ value = value === 'yes' || value === '1' ? true : value === 'no' || value === '0' ? false : value -+ if (webPreferences.includes(name)) { -+ if (options.webPreferences == null) { -+ options.webPreferences = {} -+ } -+ options.webPreferences[name] = value -+ } else { -+ options[name] = value -+ } -+ } -+ if (options.left) { -+ if (options.x == null) { -+ options.x = options.left -+ } -+ } -+ if (options.top) { -+ if (options.y == null) { -+ options.y = options.top -+ } -+ } -+ if (options.title == null) { -+ options.title = frameName -+ } -+ if (options.width == null) { -+ options.width = 800 -+ } -+ if (options.height == null) { -+ options.height = 600 -+ } -+ -+ // Resolve relative urls. -+ if (url == null || url === '') { -+ url = 'about:blank' -+ } else { -+ url = resolveURL(url) -+ } -+ for (j = 0, len1 = ints.length; j < len1; j++) { -+ name = ints[j] -+ if (options[name] != null) { -+ options[name] = parseInt(options[name], 10) -+ } -+ } -+ guestId = ipcRenderer.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', url, frameName, disposition, options) -+ if (guestId) { -+ return BrowserWindowProxy.getOrCreate(guestId) -+ } else { -+ return null -+ } -+} -+ -+window.alert = function (message, title) { -+ ipcRenderer.sendSync('ELECTRON_BROWSER_WINDOW_ALERT', message, title) -+} -+ -+window.confirm = function (message, title) { -+ return ipcRenderer.sendSync('ELECTRON_BROWSER_WINDOW_CONFIRM', message, title) -+} -+ -+// But we do not support prompt(). -+window.prompt = function () { -+ throw new Error('prompt() is and will not be supported.') -+} -+ -+if (process.openerId != null) { -+ window.opener = BrowserWindowProxy.getOrCreate(process.openerId) -+} -+ -+ipcRenderer.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (event, sourceId, message, sourceOrigin) { -+ // Manually dispatch event instead of using postMessage because we also need to -+ // set event.source. -+ event = document.createEvent('Event') -+ event.initEvent('message', false, false) -+ event.data = message -+ event.origin = sourceOrigin -+ event.source = BrowserWindowProxy.getOrCreate(sourceId) -+ window.dispatchEvent(event) -+}) -+ -+// Forward history operations to browser. -+var sendHistoryOperation = function (...args) { -+ ipcRenderer.send('ELECTRON_NAVIGATION_CONTROLLER', ...args) -+} -+ -+var getHistoryOperation = function (...args) { -+ return ipcRenderer.sendSync('ELECTRON_SYNC_NAVIGATION_CONTROLLER', ...args) -+} -+ -+window.history.back = function () { -+ sendHistoryOperation('goBack') -+} -+ -+window.history.forward = function () { -+ sendHistoryOperation('goForward') -+} -+ -+window.history.go = function (offset) { -+ sendHistoryOperation('goToOffset', offset) -+} -+ -+defineProperty(window.history, 'length', { -+ get: function () { -+ return getHistoryOperation('length') -+ } -+}) -+ -+// The initial visibilityState. -+let cachedVisibilityState = process.argv.includes('--hidden-page') ? 'hidden' : 'visible' -+ -+// Subscribe to visibilityState changes. -+ipcRenderer.on('ELECTRON_RENDERER_WINDOW_VISIBILITY_CHANGE', function (event, visibilityState) { -+ if (cachedVisibilityState !== visibilityState) { -+ cachedVisibilityState = visibilityState -+ document.dispatchEvent(new Event('visibilitychange')) -+ } -+}) -+ -+// Make document.hidden and document.visibilityState return the correct value. -+defineProperty(document, 'hidden', { -+ get: function () { -+ return cachedVisibilityState !== 'visible' -+ } -+}) -+ -+defineProperty(document, 'visibilityState', { -+ get: function () { -+ return cachedVisibilityState -+ } -+}) -+>>>>>>> .their -changed in both - base 100644 fed0275b90760d4bcdd58bee880f949e0f409528 lib/renderer/web-view/guest-view-internal.js - our 100644 6e42c769b70e5223fe97397f87144ec342882f8d lib/renderer/web-view/guest-view-internal.js - their 100644 f6eb244a6848825eed05100e62ca2477a178d222 lib/renderer/web-view/guest-view-internal.js -@@ -47,6 +47,15 @@ - const dispatchEvent = function (webView, eventName, eventKey, ...args) { - if (DEPRECATED_EVENTS[eventName] != null) { - dispatchEvent(webView, DEPRECATED_EVENTS[eventName], eventKey, ...args) -+<<<<<<< .our -+======= -+ } -+ domEvent = new Event(eventName) -+ ref1 = WEB_VIEW_EVENTS[eventKey] -+ for (i = j = 0, len = ref1.length; j < len; i = ++j) { -+ f = ref1[i] -+ domEvent[f] = args[i] -+>>>>>>> .their - } - const domEvent = new Event(eventName) - WEB_VIEW_EVENTS[eventKey].forEach((prop, index) => { -@@ -60,6 +69,7 @@ - - module.exports = { - registerEvents: function (webView, viewInstanceId) { -+<<<<<<< .our - ipcRenderer.on(`ELECTRON_GUEST_VIEW_INTERNAL_DESTROY_GUEST-${viewInstanceId}`, function () { - webView.guestInstanceId = undefined - webView.reset() -@@ -68,6 +78,9 @@ - }) - - ipcRenderer.on(`ELECTRON_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-${viewInstanceId}`, function (event, eventName, ...args) { -+======= -+ ipcRenderer.on('ELECTRON_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-' + viewInstanceId, function (event, eventName, ...args) { -+>>>>>>> .their - dispatchEvent(webView, eventName, eventName, ...args) - }) - -changed in both - base 100644 6e5e81798544104d9f46cd1e9d95e7bbff2da92c lib/renderer/web-view/web-view.js - our 100644 574a2b545597f9d1c05ec9b7147585063e90ae89 lib/renderer/web-view/web-view.js - their 100644 ab8d6996c8961aefec86c37387d635ccd3b8653b lib/renderer/web-view/web-view.js -@@ -319,7 +319,15 @@ - 'send', - 'sendInputEvent', - 'setLayoutZoomLevelLimits', -+<<<<<<< .our - 'setVisualZoomLevelLimits' -+======= -+ 'setVisualZoomLevelLimits', -+ 'setZoomFactor', -+ 'setZoomLevel', -+ // TODO(kevinsawicki): Remove in 2.0, deprecate before then with warnings -+ 'setZoomLevelLimits' -+>>>>>>> .their - ] - - // Forward proto.foo* method calls to WebViewImpl.foo*. -@@ -340,7 +348,11 @@ - const createNonBlockHandler = function (m) { - return function (...args) { - const internal = v8Util.getHiddenValue(this, 'internal') -+<<<<<<< .our - ipcRenderer.send('ELECTRON_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', contextId, null, internal.guestInstanceId, m, ...args) -+======= -+ return ipcRenderer.send('ELECTRON_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', null, internal.guestInstanceId, m, ...args) -+>>>>>>> .their - } - } - for (const method of nonblockMethods) { -changed in both - base 100644 bd7087e76707e1d1460a39917feba7bd0db74a4e package.json - our 100644 c081cd89450cd50efba1ec280ff1349a96ea3ce0 package.json - their 100644 a9e59235971454035fff313ee6a8cca91355966c package.json -@@ -1,8 +1,12 @@ - { - "name": "electron", -+<<<<<<< .our - "version": "4.0.0-nightly.20180821", - "repository": "https://github.com/electron/electron", - "description": "Build cross platform desktop apps with JavaScript, HTML, and CSS", -+======= -+ "version": "1.3.15", -+>>>>>>> .their - "devDependencies": { - "asar": "^0.11.0", - "browserify": "^13.1.0", -added in both - our 100755 0704b703fe1243fb4c8246cd09dcd209083a6fbf script/cibuild-linux - their 100755 22f15936ae34a5793754c071f9fe25b3d3ac5c5b script/cibuild-linux -@@ -5,12 +5,23 @@ - Bump* ) export ELECTRON_RELEASE=1 ;; - esac - -+<<<<<<< .our -+======= -+set +x -+ -+export ELECTRON_GITHUB_TOKEN="$BUILD_ELECTRON_ELECTRON_GITHUB_TOKEN" -+export ELECTRON_S3_BUCKET="$BUILD_ELECTRON_ELECTRON_S3_BUCKET" -+export ELECTRON_S3_ACCESS_KEY="$BUILD_ELECTRON_ELECTRON_S3_ACCESS_KEY" -+export ELECTRON_S3_SECRET_KEY="$BUILD_ELECTRON_ELECTRON_S3_SECRET_KEY" -+ -+>>>>>>> .their - if [[ -z "${ELECTRON_RELEASE}" ]]; then - echo "Generating Linux $TARGET_ARCH debug build" - else - echo "Generating Linux $TARGET_ARCH release build" - fi - -+<<<<<<< .our - set +x - set -e - set -o pipefail -@@ -35,3 +46,8 @@ - --volume "$PWD":/workspace/electron \ - --workdir /workspace/electron \ - electron-linux script/cibuild -+======= -+set -x -+ -+script/cibuild -+>>>>>>> .their -changed in both - base 100644 5ea60fcf539a6e0bcc534b1eee9efbe424bca5d3 script/lib/config.py - our 100644 9ad0fbc680e5ecdeb8c13d0f0d6678bbba7d9031 script/lib/config.py - their 100644 d2be141a0c0037cf3bde77a57cc3ceb5525b3448 script/lib/config.py -@@ -13,6 +13,11 @@ - - BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ - 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' -+<<<<<<< .our -+======= -+LIBCHROMIUMCONTENT_COMMIT = os.getenv('LIBCHROMIUMCONTENT_COMMIT') or \ -+ 'e93c6a82d7ab1e3b97a294200186d7254ad3f868' -+>>>>>>> .their - - PLATFORM = { - 'cygwin': 'win32', -removed in local - base 100644 ac5d06ad787a168824152c2a43b81cc447c1416d spec/api-ipc-spec.js - their 100644 22148c665732c074a8a435cf9edd81c196d2bf15 spec/api-ipc-spec.js -changed in both - base 100644 a41bc477018fbc4aa1c5b23ba9cdaf21e3837412 spec/api-web-frame-spec.js - our 100644 b8fd10b5d3f1319640fb209c707c758d0a0403d2 spec/api-web-frame-spec.js - their 100644 3d7a7d316f8bd4b8bfa53d84df2b77f6335c6991 spec/api-web-frame-spec.js -@@ -15,11 +15,14 @@ - - describe('webFrame module', function () { - var fixtures = path.resolve(__dirname, 'fixtures') -+<<<<<<< .our - var w = null - - afterEach(function () { - return closeWindow(w).then(function () { w = null }) - }) -+======= -+>>>>>>> .their - - describe('webFrame.registerURLSchemeAsPrivileged', function () { - it('supports fetch api by default', function (done) { -@@ -145,6 +148,7 @@ - }) - }) - -+<<<<<<< .our - it('calls a spellcheck provider', async () => { - w = new BrowserWindow({show: false}) - w.loadURL(`file://${fixtures}/pages/webframe-spell-check.html`) -@@ -157,5 +161,13 @@ - } - const [, text] = await spellCheckerFeedback - expect(text).to.equal(misspelledWord) -+======= -+ it('supports setting the visual and layout zoom level limits', function () { -+ assert.doesNotThrow(function () { -+ webFrame.setZoomLevelLimits(1, 100) -+ webFrame.setVisualZoomLevelLimits(1, 50) -+ webFrame.setLayoutZoomLevelLimits(0, 25) -+ }) -+>>>>>>> .their - }) - }) -changed in both - base 100644 e26cba87c38bf456925cb019452a5c43937b1c05 spec/chromium-spec.js - our 100644 d90269769d269e4054d25cba4b6c4ac8a1929aa6 spec/chromium-spec.js - their 100644 f4d8f4068b13aa8748e4fb640509889ce3ad1dc7 spec/chromium-spec.js -@@ -4,10 +4,17 @@ - const path = require('path') - const ws = require('ws') - const url = require('url') -+<<<<<<< .our - const ChildProcess = require('child_process') - const {ipcRenderer, remote} = require('electron') - const {closeWindow} = require('./window-helpers') - const {app, BrowserWindow, ipcMain, protocol, session, webContents} = remote -+======= -+const remote = require('electron').remote -+ -+const {BrowserWindow, protocol, session, webContents} = remote -+ -+>>>>>>> .their - const isCI = remote.getGlobal('isCi') - const features = process.atomBinding('features') - -@@ -103,8 +110,15 @@ - }) - }) - -+<<<<<<< .our - describe('navigator.mediaDevices', () => { - if (isCI) return -+======= -+ describe('navigator.mediaDevices', function () { -+ if (isCI) { -+ return -+ } -+>>>>>>> .their - - it('can return labels of enumerated devices', (done) => { - navigator.mediaDevices.enumerateDevices().then((devices) => { -@@ -478,6 +492,7 @@ - window.open('', {toString: null}) - }, /Cannot convert object to primitive value/) - -+<<<<<<< .our - assert.throws(() => { - window.open('', '', {toString: 3}) - }, /Cannot convert object to primitive value/) -@@ -491,6 +506,13 @@ - done() - }) - b = window.open('', 'hello') -+======= -+ let url = 'file://' + fixtures + '/pages/window-opener.html' -+ let w = null -+ -+ afterEach(function () { -+ if (w) w.destroy() -+>>>>>>> .their - }) - - it('does not throw an exception when the frameName is a built-in object property', (done) => { -@@ -524,9 +546,15 @@ - w.loadURL(url) - }) - -+<<<<<<< .our - it('is not null for window opened by window.open', (done) => { - let b - listener = (event) => { -+======= -+ it('is not null for window opened by window.open', function (done) { -+ let b -+ listener = function (event) { -+>>>>>>> .their - assert.equal(event.data, 'object') - b.close() - done() -@@ -536,11 +564,18 @@ - }) - }) - -+<<<<<<< .our - describe('window.opener access from BrowserWindow', () => { -+======= -+ describe('window.opener access from BrowserWindow', function () { -+ this.timeout(10000) -+ -+>>>>>>> .their - const scheme = 'other' - let url = `${scheme}://${fixtures}/pages/window-opener-location.html` - let w = null - -+<<<<<<< .our - before((done) => { - protocol.registerFileProtocol(scheme, (request, callback) => { - callback(`${fixtures}/pages/window-opener-location.html`) -@@ -557,24 +592,60 @@ - - it('does nothing when origin of current window does not match opener', (done) => { - listener = (event) => { -+======= -+ before(function (done) { -+ protocol.registerFileProtocol(scheme, function (request, callback) { -+ callback(`${fixtures}/pages/window-opener-location.html`) -+ }, function (error) { -+ done(error) -+ }) -+ }) -+ -+ after(function () { -+ protocol.unregisterProtocol(scheme) -+ }) -+ -+ afterEach(function () { -+ w.close() -+ }) -+ -+ it('does nothing when origin of current window does not match opener', function (done) { -+ listener = function (event) { -+>>>>>>> .their - assert.equal(event.data, undefined) - done() - } - window.addEventListener('message', listener) -+<<<<<<< .our - w = window.open(url, '', 'show=no,nodeIntegration=no') - }) - - it('works when origin matches', (done) => { - listener = (event) => { -+======= -+ w = window.open(url, '', 'show=no') -+ }) -+ -+ it('works when origin matches', function (done) { -+ listener = function (event) { -+>>>>>>> .their - assert.equal(event.data, location.href) - done() - } - window.addEventListener('message', listener) -+<<<<<<< .our - w = window.open(`file://${fixtures}/pages/window-opener-location.html`, '', 'show=no,nodeIntegration=no') - }) - - it('works when origin does not match opener but has node integration', (done) => { - listener = (event) => { -+======= -+ w = window.open(`file://${fixtures}/pages/window-opener-location.html`, '', 'show=no') -+ }) -+ -+ it('works when origin does not match opener but has node integration', function (done) { -+ listener = function (event) { -+>>>>>>> .their - assert.equal(event.data, location.href) - done() - } -@@ -583,12 +654,19 @@ - }) - }) - -+<<<<<<< .our - describe('window.opener access from <webview>', () => { -+======= -+ describe('window.opener access from <webview>', function () { -+ this.timeout(10000) -+ -+>>>>>>> .their - const scheme = 'other' - const srcPath = `${fixtures}/pages/webview-opener-postMessage.html` - const pageURL = `file://${fixtures}/pages/window-opener-location.html` - let webview = null - -+<<<<<<< .our - before((done) => { - protocol.registerFileProtocol(scheme, (request, callback) => { - callback(srcPath) -@@ -606,6 +684,27 @@ - it('does nothing when origin of webview src URL does not match opener', (done) => { - webview = new WebView() - webview.addEventListener('console-message', (e) => { -+======= -+ before(function (done) { -+ protocol.registerFileProtocol(scheme, function (request, callback) { -+ callback(srcPath) -+ }, function (error) { -+ done(error) -+ }) -+ }) -+ -+ after(function () { -+ protocol.unregisterProtocol(scheme) -+ }) -+ -+ afterEach(function () { -+ if (webview != null) webview.remove() -+ }) -+ -+ it('does nothing when origin of webview src URL does not match opener', function (done) { -+ webview = new WebView() -+ webview.addEventListener('console-message', function (e) { -+>>>>>>> .their - assert.equal(e.message, 'null') - done() - }) -@@ -621,9 +720,15 @@ - document.body.appendChild(webview) - }) - -+<<<<<<< .our - it('works when origin matches', (done) => { - webview = new WebView() - webview.addEventListener('console-message', (e) => { -+======= -+ it('works when origin matches', function (done) { -+ webview = new WebView() -+ webview.addEventListener('console-message', function (e) { -+>>>>>>> .their - assert.equal(e.message, webview.src) - done() - }) -@@ -639,9 +744,15 @@ - document.body.appendChild(webview) - }) - -+<<<<<<< .our - it('works when origin does not match opener but has node integration', (done) => { - webview = new WebView() - webview.addEventListener('console-message', (e) => { -+======= -+ it('works when origin does not match opener but has node integration', function (done) { -+ webview = new WebView() -+ webview.addEventListener('console-message', function (e) { -+>>>>>>> .their - webview.remove() - assert.equal(e.message, webview.src) - done() -@@ -660,10 +771,18 @@ - }) - }) - -+<<<<<<< .our - describe('window.postMessage', () => { - it('sets the source and origin correctly', (done) => { - let b - listener = (event) => { -+======= -+ describe('window.postMessage', function () { -+ it('sets the source and origin correctly', function (done) { -+ var b, sourceId -+ sourceId = remote.getCurrentWindow().id -+ listener = function (event) { -+>>>>>>> .their - window.removeEventListener('message', listener) - b.close() - const message = JSON.parse(event.data) -added in both - our 100644 bfc281eb4298c7df89b1dd379b9ac958efd20edd spec/fixtures/api/render-view-deleted.html - their 100644 5c996c1988ef60215784bab216801f7ecdff1393 spec/fixtures/api/render-view-deleted.html -@@ -17,7 +17,11 @@ - } - - // This should trigger a dereference and a remote getURL call should fail -+<<<<<<< .our - contents.emit('render-view-deleted', {}, contents.getProcessId()) -+======= -+ contents.emit('render-view-deleted', {}, contents.getId()) -+>>>>>>> .their - try { - contents.getURL() - ipcRenderer.send('error-message', 'No error thrown') -changed in both - base 100644 f2c45b0a71b4620d0665d956fd2311ebcba5ae5d spec/modules-spec.js - our 100644 b996b8f4839bff2160bffb69e55263b16a4178d7 spec/modules-spec.js - their 100644 601e40d050b8cd196be6c1c8f8936c67d518cad3 spec/modules-spec.js -@@ -90,6 +90,7 @@ - }) - }) - -+<<<<<<< .our - describe('Module._nodeModulePaths', () => { - describe('when the path is inside the resources path', () => { - it('does not include paths outside of the resources path', () => { -@@ -160,6 +161,15 @@ - const result = await w.webContents.executeJavaScript('typeof require("q").when') - assert.equal(result, 'function') - }) -+======= -+ describe('when the path is outside the resources path', function () { -+ it('includes paths outside of the resources path', function () { -+ let modulePath = path.resolve('/foo') -+ assert.deepEqual(Module._nodeModulePaths(modulePath), [ -+ path.join(modulePath, 'node_modules'), -+ path.resolve('/node_modules') -+ ]) -+>>>>>>> .their - }) - }) - }) -removed in local - base 160000 554946c7873bbc6930779c871fe230856575049a vendor/brightray - their 160000 ee26c5218eeec199c54c92a7517a72d2dbd0adbf vendor/brightray -changed in both - base 160000 ee8c429deaee0adeeef069c3ad34c0defe53a567 vendor/node - our 160000 ece0a06ac8147efb5b5af431c21f312f1884616e vendor/node - their 160000 c47e9bf9011de682d07c82f7f610a467f30cca60 vendor/node diff --git a/app/test/fixtures/merge-parser/electron/merge-1-4-x-into-master.txt b/app/test/fixtures/merge-parser/electron/merge-1-4-x-into-master.txt deleted file mode 100644 index 4772e171f6e..00000000000 --- a/app/test/fixtures/merge-parser/electron/merge-1-4-x-into-master.txt +++ /dev/null @@ -1,208 +0,0 @@ -changed in both - base 100644 f69fbc5c40409a1db7a3f8353bfffe46a21d6054 atom/browser/resources/mac/Info.plist - our 100644 9094f0f7335edf833d51f688851e6a105de60433 atom/browser/resources/mac/Info.plist - their 100644 2dd8bc646cff3869557549a39477e30022e6cfdd atom/browser/resources/mac/Info.plist -@@ -17,9 +17,15 @@ - <key>CFBundleIconFile</key> - <string>electron.icns</string> - <key>CFBundleVersion</key> -+<<<<<<< .our - <string>4.0.0</string> - <key>CFBundleShortVersionString</key> - <string>4.0.0</string> -+======= -+ <string>1.4.16</string> -+ <key>CFBundleShortVersionString</key> -+ <string>1.4.16</string> -+>>>>>>> .their - <key>LSApplicationCategoryType</key> - <string>public.app-category.developer-tools</string> - <key>LSMinimumSystemVersion</key> -changed in both - base 100644 c7a067984484d859db564046a9aba048b6979929 atom/browser/resources/win/atom.rc - our 100644 c0bd831e8bddf10180f75cd40694831e2e98622d atom/browser/resources/win/atom.rc - their 100644 f799ec4fe0defad29259d64ffdbe503bf768ef39 atom/browser/resources/win/atom.rc -@@ -56,8 +56,13 @@ - // - - VS_VERSION_INFO VERSIONINFO -+<<<<<<< .our - FILEVERSION 4,0,0,20180821 - PRODUCTVERSION 4,0,0,20180821 -+======= -+ FILEVERSION 1,4,16,0 -+ PRODUCTVERSION 1,4,16,0 -+>>>>>>> .their - FILEFLAGSMASK 0x3fL - #ifdef _DEBUG - FILEFLAGS 0x1L -@@ -74,12 +79,20 @@ - BEGIN - VALUE "CompanyName", "GitHub, Inc." - VALUE "FileDescription", "Electron" -+<<<<<<< .our - VALUE "FileVersion", "4.0.0" -+======= -+ VALUE "FileVersion", "1.4.16" -+>>>>>>> .their - VALUE "InternalName", "electron.exe" - VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." - VALUE "OriginalFilename", "electron.exe" - VALUE "ProductName", "Electron" -+<<<<<<< .our - VALUE "ProductVersion", "4.0.0" -+======= -+ VALUE "ProductVersion", "1.4.16" -+>>>>>>> .their - VALUE "SquirrelAwareVersion", "1" - END - END -changed in both - base 100644 f073afb5621ce56baa578a4f1737ebac7cc5389a atom/common/atom_version.h - our 100644 65e7d19911559a40b1b258319df5fe0fa180354f atom/common/atom_version.h - their 100644 c8e49bdb3cc7d395b80c8af73e901c4644645f0e atom/common/atom_version.h -@@ -5,10 +5,22 @@ - #ifndef ATOM_COMMON_ATOM_VERSION_H_ - #define ATOM_COMMON_ATOM_VERSION_H_ - -+<<<<<<< .our - #define ATOM_MAJOR_VERSION 4 - #define ATOM_MINOR_VERSION 0 - #define ATOM_PATCH_VERSION 0 - #define ATOM_PRE_RELEASE_VERSION -nightly.20180821 -+======= -+#define ATOM_MAJOR_VERSION 1 -+#define ATOM_MINOR_VERSION 4 -+#define ATOM_PATCH_VERSION 16 -+ -+#define ATOM_VERSION_IS_RELEASE 1 -+ -+#ifndef ATOM_TAG -+# define ATOM_TAG "" -+#endif -+>>>>>>> .their - - #ifndef ATOM_STRINGIFY - #define ATOM_STRINGIFY(n) ATOM_STRINGIFY_HELPER(n) -changed in both - base 100644 87971055e68f42b5d9dcc8fe035205531ba201ef chromium_src/chrome/browser/printing/print_job.cc - our 100644 80d9cc3c21a12b8256618405050f80bb6c2f08e4 chromium_src/chrome/browser/printing/print_job.cc - their 100644 15a618df428142b11c7127cece08b48da1465642 chromium_src/chrome/browser/printing/print_job.cc -@@ -282,6 +282,7 @@ - base::Bind(&PrintJob::OnPdfPageConverted, this)); - } - -+<<<<<<< .our - void PrintJob::OnPdfPageConverted(int page_number, - float scale_factor, - std::unique_ptr<MetafilePlayer> metafile) { -@@ -289,11 +290,21 @@ - if (!document_.get() || !metafile || page_number < 0 || - static_cast<size_t>(page_number) >= pdf_page_mapping_.size()) { - pdf_conversion_state_.reset(); -+======= -+void PrintJob::OnPdfToEmfPageConverted(int page_number, -+ float scale_factor, -+ std::unique_ptr<MetafilePlayer> emf) { -+ DCHECK(ptd_to_emf_state_); -+ if (!document_.get() || !emf || page_number < 0 || -+ static_cast<size_t>(page_number) >= pdf_page_mapping_.size()) { -+ ptd_to_emf_state_.reset(); -+>>>>>>> .their - Cancel(); - return; - } - - // Update the rendered document. It will send notifications to the listener. -+<<<<<<< .our - document_->SetPage(pdf_page_mapping_[page_number], std::move(metafile), - scale_factor, pdf_conversion_state_->page_size(), - pdf_conversion_state_->content_area()); -@@ -317,6 +328,16 @@ - : PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3); - pdf_conversion_state_->Start( - bytes, settings, base::Bind(&PrintJob::OnPdfConversionStarted, this)); -+======= -+ document_->SetPage(pdf_page_mapping_[page_number], -+ std::move(emf), -+ scale_factor, -+ ptd_to_emf_state_->page_size(), -+ ptd_to_emf_state_->content_area()); -+ -+ ptd_to_emf_state_->GetMorePages( -+ base::Bind(&PrintJob::OnPdfToEmfPageConverted, this)); -+>>>>>>> .their - } - - #endif // defined(OS_WIN) -changed in both - base 100644 420622a7e96861345b1cbffb54188bd8488e8ac6 chromium_src/chrome/browser/printing/print_job.h - our 100644 e5e5f44d6c50c6c7fd00591caec9cb4f8e1387dd chromium_src/chrome/browser/printing/print_job.h - their 100644 d4445e1bb1b87d965b64e411eb98702326fb9c86 chromium_src/chrome/browser/printing/print_job.h -@@ -96,7 +96,11 @@ - #if defined(OS_WIN) - // Let the PrintJob know the 0-based |page_number| of a given printed page. - void AppendPrintedPage(int page_number); -+<<<<<<< .our - -+======= -+ -+>>>>>>> .their - void StartPdfToEmfConversion( - const scoped_refptr<base::RefCountedMemory>& bytes, - const gfx::Size& page_size, -@@ -161,10 +165,17 @@ - bool is_canceling_; - - #if defined(OS_WIN) -+<<<<<<< .our - class PdfConversionState; - std::unique_ptr<PdfConversionState> pdf_conversion_state_; - std::vector<int> pdf_page_mapping_; - #endif // defined(OS_WIN) -+======= -+ class PdfToEmfState; -+ std::unique_ptr<PdfToEmfState> ptd_to_emf_state_; -+ std::vector<int> pdf_page_mapping_; -+#endif // OS_WIN -+>>>>>>> .their - - // Used at shutdown so that we can quit a nested message loop. - base::WeakPtrFactory<PrintJob> quit_factory_; -changed in both - base 100644 0638bd5c4d445e21c9678d47a949f1fa1b0480fe chromium_src/chrome/browser/printing/print_view_manager_base.cc - our 100644 3c7055a6f4c0f411049aebcf66ff9fba196d8b9f chromium_src/chrome/browser/printing/print_view_manager_base.cc - their 100644 df52e206e1ee7ba05552e054e26871ecc0da8b38 chromium_src/chrome/browser/printing/print_view_manager_base.cc -changed in both - base 100644 f9a3bf75766c25ee01e831dec59586913ada9ce6 electron.gyp - our 100644 944ddab2a3fd879044e31677e4bac2843fffbdee electron.gyp - their 100644 a26fa80cd496b553a045c557d669a77f2702dda7 electron.gyp -@@ -4,7 +4,11 @@ - 'product_name%': 'Electron', - 'company_name%': 'GitHub, Inc', - 'company_abbr%': 'github', -+<<<<<<< .our - 'version%': '4.0.0-nightly.20180821', -+======= -+ 'version%': '1.4.16', -+>>>>>>> .their - 'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c', - }, - 'includes': [ -changed in both - base 100644 e090c24befb0bc19711d7a37719de7102f1d5033 package.json - our 100644 c081cd89450cd50efba1ec280ff1349a96ea3ce0 package.json - their 100644 b1ce03d92ee6b4a0dd88b8b4ebad41dcc4e68938 package.json -@@ -1,8 +1,12 @@ - { - "name": "electron", -+<<<<<<< .our - "version": "4.0.0-nightly.20180821", - "repository": "https://github.com/electron/electron", - "description": "Build cross platform desktop apps with JavaScript, HTML, and CSS", -+======= -+ "version": "1.4.16", -+>>>>>>> .their - "devDependencies": { - "asar": "^0.11.0", - "browserify": "^13.1.0", diff --git a/app/test/fixtures/merge-parser/electron/merge-1-6-x-into-master.txt b/app/test/fixtures/merge-parser/electron/merge-1-6-x-into-master.txt deleted file mode 100644 index b1e72fd6c91..00000000000 --- a/app/test/fixtures/merge-parser/electron/merge-1-6-x-into-master.txt +++ /dev/null @@ -1,4383 +0,0 @@ -added in both - our 100644 6d44d618aabcce04c60344f2274dec5b0c2a1f68 .circleci/config.yml - their 100644 ab085246d001aa13fbfb587c63bd64c63b7ca1ce .circleci/config.yml -@@ -1,3 +1,4 @@ -+<<<<<<< .our - notify-slack-failure: ¬ify-slack-failure - run: - name: Send a slack notification on failure -@@ -348,10 +349,13 @@ - docker: - - image: electronbuilds/electron:0.0.8 - <<: *build-steps -+======= -+>>>>>>> .their - - version: 2 - jobs: - electron-linux-arm: -+<<<<<<< .our - environment: - TARGET_ARCH: arm - <<: *build-defaults -@@ -668,12 +672,211 @@ - GN_EXTRA_ARGS: 'is_mas_build = true' - <<: *gn-mac-build-machine - <<: *gn-mac-build-steps -+======= -+ docker: -+ - image: electronbuilds/electron:0.0.4 -+ environment: -+ TARGET_ARCH: arm -+ resource_class: 2xlarge -+ steps: -+ - checkout -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ electron-linux-ia32: -+ docker: -+ - image: electronbuilds/electron:0.0.4 -+ environment: -+ TARGET_ARCH: ia32 -+ resource_class: xlarge -+ steps: -+ - checkout -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ electron-linux-x64: -+ docker: -+ - image: electronbuilds/electron:0.0.4 -+ environment: -+ TARGET_ARCH: x64 -+ DISPLAY: ':99.0' -+ resource_class: xlarge -+ steps: -+ - checkout -+ - run: -+ name: Setup for headless testing -+ command: sh -e /etc/init.d/xvfb start -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Test -+ environment: -+ MOCHA_FILE: junit/test-results.xml -+ MOCHA_REPORTER: mocha-junit-reporter -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Testing Electron debug build' -+ mkdir junit -+ script/test.py --ci --rebuild_native_modules -+ else -+ echo 'Skipping testing on release build' -+ fi -+ - run: -+ name: Verify FFmpeg -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Verifying ffmpeg on debug build' -+ script/verify-ffmpeg.py -+ else -+ echo 'Skipping verify ffmpeg on release build' -+ fi -+>>>>>>> .their - - workflows: - version: 2 - build-arm: - jobs: - - electron-linux-arm -+<<<<<<< .our - - electron-linux-arm-test: - requires: - - electron-linux-arm -@@ -683,12 +886,15 @@ - - electron-linux-arm64-test: - requires: - - electron-linux-arm64 -+======= -+>>>>>>> .their - build-ia32: - jobs: - - electron-linux-ia32 - build-x64: - jobs: - - electron-linux-x64 -+<<<<<<< .our - build-osx-x64: - jobs: - - electron-osx-x64 -@@ -745,3 +951,5 @@ - - electron-gn-linux-arm64-release-fyi - - electron-gn-mas-release-fyi - - electron-gn-osx-release-fyi -+======= -+>>>>>>> .their -removed in remote - base 100644 b093d2a2126ea5e5a74712c103159f14f20e0ca2 appveyor.yml - our 100644 67a2b2124619d866f67d849f57f3548ba28be26a appveyor.yml -@@ -1,73 +0,0 @@ --version: 1.0.{build} --branches: -- except: -- - /^release$|^release-\d-\d-x$/ --build_cloud: electron-16 --image: electron-16-vs2017-15.4.5 --environment: -- DISABLE_CRASH_REPORTER_TESTS: true --build_script: --- ps: >- -- if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) { -- Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild -- } else { -- Add-Path "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64" -- $env:path = "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64;$env:path" -- if($env:APPVEYOR_SCHEDULED_BUILD -eq 'True') { -- $env:RUN_RELEASE_BUILD = "1" -- } -- $Message = (git log --format=%B -n 1 HEAD) | Out-String -- if ((Test-Path Env:\RUN_RELEASE_BUILD)) { -- $env:ELECTRON_RELEASE = '1' -- Write-Output "release build triggered from api" -- } -- if ((Test-Path Env:\ELECTRON_RELEASE)) { -- Write-Output "Running release build" -- python script\bootstrap.py --target_arch=$env:TARGET_ARCH -- python script\build.py -c R -- python script\create-dist.py -- } else { -- Write-Output "Running debug build" -- python script\bootstrap.py --target_arch=$env:TARGET_ARCH --dev -- python script\build.py -c D -- } -- if ($? -ne 'True') { -- throw "Build failed with exit code $?" -- } else { -- "Build succeeded." -- } -- Push-AppveyorArtifact out -- } --test_script: --- ps: >- -- if (Test-Path Env:\ELECTRON_RELEASE) { -- Write-Output "Skipping tests for release build" -- } else { -- Write-Output "Running tests for debug build" -- python script\test.py --ci --rebuild_native_modules -- if ($LASTEXITCODE -ne '0') { -- throw "Tests failed with exit code $LASTEXITCODE" -- } else { -- Write-Output "Tests succeeded." -- } -- python script\verify-ffmpeg.py -- if ($LASTEXITCODE -ne '0') { -- throw "Verify ffmpeg failed with exit code $LASTEXITCODE" -- } else { -- "Verify ffmpeg succeeded." -- } -- } --artifacts: --- path: test-results.xml -- name: test-results.xml --deploy_script: --- ps: >- -- if (Test-Path Env:\ELECTRON_RELEASE) { -- if (Test-Path Env:\RUN_RELEASE_BUILD) { -- Write-Output "Uploading Electron release distribution to s3" -- & python script\upload.py --upload_to_s3 -- } else { -- Write-Output "Uploading Electron release distribution to github releases" -- & python script\upload.py -- } -- } -changed in both - base 100644 e1603fa5942f7b000c3385648530255032e775a2 atom/app/atom_library_main.h - our 100644 2c7a27caa20a411558010c3c58bd78e7850c0737 atom/app/atom_library_main.h - their 100644 63d285bb5e4838578d23505d7738c9ac88575df1 atom/app/atom_library_main.h -@@ -9,7 +9,12 @@ - - #if defined(OS_MACOSX) - extern "C" { -+<<<<<<< .our - __attribute__((visibility("default"))) int AtomMain(int argc, char* argv[]); -+======= -+__attribute__((visibility("default"))) -+int AtomMain(int argc, char* argv[]); -+>>>>>>> .their - - #ifdef ENABLE_RUN_AS_NODE - __attribute__((visibility("default"))) int AtomInitializeICUandStartNode( -changed in both - base 100644 7ee7522934689937f7be7b0f866134bf611c7d69 atom/app/atom_library_main.mm - our 100644 57a519fcd0db28548ea75034cf92191161183385 atom/app/atom_library_main.mm - their 100644 ae096acd4a931d397e285643d36580625dde14bf atom/app/atom_library_main.mm -@@ -14,6 +14,10 @@ - #include "brightray/common/mac/main_application_bundle.h" - #include "content/public/app/content_main.h" - -+<<<<<<< .our -+======= -+#if defined(OS_MACOSX) -+>>>>>>> .their - int AtomMain(int argc, char* argv[]) { - atom::AtomMainDelegate delegate; - content::ContentMainParams params(&delegate); -changed in both - base 100644 9c255db5fb278c21a4e657513e6d9a3d53d397da atom/app/atom_main.cc - our 100644 fc77100d9acb58221c35f364c4db7866a44d347d atom/app/atom_main.cc - their 100644 59cd6801e52aebcd81959df7ed2f4eccdc555f30 atom/app/atom_main.cc -@@ -71,7 +71,11 @@ - - #ifdef _DEBUG - // Don't display assert dialog boxes in CI test runs -+<<<<<<< .our - static const char* kCI = "ELECTRON_CI"; -+======= -+ static const auto kCI = "ELECTRON_CI"; -+>>>>>>> .their - bool is_ci = IsEnvSet(kCI); - if (!is_ci) { - for (int i = 0; i < arguments.argc; ++i) { -@@ -88,6 +92,13 @@ - - _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE); - _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); -+<<<<<<< .our -+======= -+ -+ _set_error_mode(_OUT_TO_STDERR); -+ } -+#endif -+>>>>>>> .their - - _set_error_mode(_OUT_TO_STDERR); - } -@@ -103,6 +114,7 @@ - if (run_as_node || !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE")) - base::RouteStdioToConsole(false); - -+<<<<<<< .our - #ifndef DEBUG - // Chromium has its own TLS subsystem which supports automatic destruction - // of thread-local data, and also depends on memory allocation routines -@@ -121,6 +133,8 @@ - #endif - - #ifdef ENABLE_RUN_AS_NODE -+======= -+>>>>>>> .their - if (run_as_node) { - std::vector<char*> argv(arguments.argc); - std::transform( -@@ -132,10 +146,14 @@ - auto ret = atom::NodeMain(argv.size(), argv.data()); - std::for_each(argv.begin(), argv.end(), free); - return ret; -+<<<<<<< .our - } - #endif - - if (IsEnvSet("ELECTRON_INTERNAL_CRASH_SERVICE")) { -+======= -+ } else if (IsEnvSet("ELECTRON_INTERNAL_CRASH_SERVICE")) { -+>>>>>>> .their - return crash_service::Main(cmd); - } - -@@ -156,7 +174,10 @@ - #elif defined(OS_LINUX) // defined(OS_WIN) - - int main(int argc, char* argv[]) { -+<<<<<<< .our - #ifdef ENABLE_RUN_AS_NODE -+======= -+>>>>>>> .their - if (IsEnvSet(kRunAsNode)) { - base::i18n::InitializeICU(); - base::AtExitManager atexit_manager; -@@ -175,7 +196,10 @@ - #else // defined(OS_LINUX) - - int main(int argc, char* argv[]) { -+<<<<<<< .our - #ifdef ENABLE_RUN_AS_NODE -+======= -+>>>>>>> .their - if (IsEnvSet(kRunAsNode)) { - return AtomInitializeICUandStartNode(argc, argv); - } -added in both - our 100644 23e870cf4a32aecfc246a81edad46971b4456a55 atom/app/command_line_args.cc - their 100644 1cd98bb5f1acf24a7a00ffd264d7e1551d6a7c90 atom/app/command_line_args.cc -@@ -2,15 +2,30 @@ - // Use of this source code is governed by the MIT license that can be - // found in the LICENSE file. - -+<<<<<<< .our - #include "atom/app/command_line_args.h" - -+======= -+#include <string> -+ -+#include "atom/app/command_line_args.h" -+ -+#include "base/strings/string_util.h" -+#include "base/strings/utf_string_conversions.h" -+#include "content/public/common/content_switches.h" -+ -+>>>>>>> .their - namespace { - - bool IsUrlArg(const base::CommandLine::CharType* arg) { - // the first character must be a letter for this to be a URL - auto c = *arg; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) { -+<<<<<<< .our - for (auto* p = arg + 1; *p; ++p) { -+======= -+ for (auto p = arg + 1; *p; ++p) { -+>>>>>>> .their - c = *p; - - // colon indicates that the argument starts with a URI scheme -@@ -31,12 +46,1368 @@ - return false; - } - -+<<<<<<< .our -+======= -+const char* blacklist[] = { -+ // node -+ "inspect", -+ "inspect-brk", -+ -+ // chromium switches: -+ // find ./ -name "*switches.cc" \ -+ // | xargs grep -P --no-filename "\"\S+\";" \ -+ // | perl -pe 's|^.*?"(\S+)";| "$1",|' \ -+ // | sort | uniq -+ "?", -+ "0", -+ "accept-resource-provider", -+ "account-consistency", -+ "adaboost", -+ "aec-refined-adaptive-filter", -+ "agc-startup-min-volume", -+ "aggressive", -+ "aggressive-cache-discard", -+ "aggressive-tab-discard", -+ "all", -+ "allarticles", -+ "allow-cross-origin-auth-prompt", -+ "allow-external-pages", -+ "allow-failed-policy-fetch-for-test", -+ "allow-file-access-from-files", -+ "allow-hidden-media-playback", -+ "allow-http-background-page", -+ "allow-http-screen-capture", -+ "allow-insecure-localhost", -+ "allow-legacy-extension-manifests", -+ "allow-loopback-in-peer-connection", -+ "allow-nacl-crxfs-api", -+ "allow-nacl-file-handle-api", -+ "allow-nacl-socket-api", -+ "allow-no-sandbox-job", -+ "allow-outdated-plugins", -+ "allow-ra-in-dev-mode", -+ "allow-running-insecure-content", -+ "allow-sandbox-debugging", -+ "allow-silent-push", -+ "all-toolchains", -+ "alsa-check-close-timeout", -+ "alsa-enable-upsampling", -+ "alsa-fixed-output-sample-rate", -+ "alsa-input-device", -+ "alsa-mute-device-name", -+ "alsa-mute-element-name", -+ "alsa-output-avail-min", -+ "alsa-output-buffer-size", -+ "alsa-output-device", -+ "alsa-output-period-size", -+ "alsa-output-start-threshold", -+ "alsa-volume-device-name", -+ "alsa-volume-element-name", -+ "also-emit-success-logs", -+ "alternative", -+ "always-authorize-plugins", -+ "always-on", -+ "alwaystrue", -+ "always-use-complex-text", -+ "amd-switchable", -+ "android-fonts-path", -+ "android-stderr-port", -+ "android-stdin-port", -+ "android-stdout-port", -+ "angle", -+ "app", -+ "app-auto-launched", -+ "app-id", -+ "apple", -+ "app-mode-auth-code", -+ "app-mode-oauth-token", -+ "app-mode-oem-manifest", -+ "apps-gallery-download-url", -+ "apps-gallery-update-url", -+ "apps-gallery-url", -+ "app-shell-allow-roaming", -+ "app-shell-host-window-size", -+ "app-shell-preferred-network", -+ "app-shell-refresh-token", -+ "app-shell-user", -+ "apps-keep-chrome-alive-in-tests", -+ "arc-availability", -+ "arc-available", -+ "arc-start-mode", -+ "arc-transition-migration-required", -+ "args", -+ "artifacts-dir", -+ "ash-constrain-pointer-to-root", -+ "ash-debug-shortcuts", -+ "ash-dev-shortcuts", -+ "ash-disable-smooth-screen-rotation", -+ "ash-disable-tablet-autohide-titlebars", -+ "ash-disable-touch-exploration-mode", -+ "ash-enable-magnifier-key-scroller", -+ "ash-enable-mirrored-screen", -+ "ash-enable-night-light", -+ "ash-enable-palette-on-all-displays", -+ "ash-enable-scale-settings-tray", -+ "ash-enable-software-mirroring", -+ "ash-enable-unified-desktop", -+ "ash-estimated-presentation-delay", -+ "ash-hide-notifications-for-factory", -+ "ash-host-window-bounds", -+ "ash-shelf-color", -+ "ash-shelf-color-scheme", -+ "ash-touch-hud", -+ "ash-webui-init", -+ "attestation-server", -+ "audio-buffer-size", -+ "audio-output-channels", -+ "aura-legacy-power-button", -+ "auth-ext-path", -+ "auth-server-whitelist", -+ "auth-spnego-account-type", -+ "auto", -+ "auto-open-devtools-for-tabs", -+ "autoplay-policy", -+ "auto-select-desktop-capture-source", -+ "blink-settings", -+ "bootstrap", -+ "browser", -+ "browser-startup-dialog", -+ "browser-subprocess-path", -+ "browser-test", -+ "bwsi", -+ "bypass-app-banner-engagement-checks", -+ "canvas-msaa-sample-count", -+ "cast-initial-screen-height", -+ "cast-initial-screen-width", -+ "cc-layer-tree-test-long-timeout", -+ "cc-layer-tree-test-no-timeout", -+ "cc-rebaseline-pixeltests", -+ "cellular-first", -+ "cellular-only", -+ "check-for-update-interval", -+ "check-layout-test-sys-deps", -+ "child-wallpaper-large", -+ "child-wallpaper-small", -+ "chrome-home-swipe-logic", -+ "ChromeOSMemoryPressureHandling", -+ "cipher-suite-blacklist", -+ "clamshell", -+ "class", -+ "clear-token-service", -+ "cloud-print-file", -+ "cloud-print-file-type", -+ "cloud-print-job-title", -+ "cloud-print-print-ticket", -+ "cloud-print-setup-proxy", -+ "cloud-print-url", -+ "cloud-print-xmpp-endpoint", -+ "color", -+ "compensate-for-unstable-pinch-zoom", -+ "compile-shader-always-succeeds", -+ "component-updater", -+ "connectivity-check-url", -+ "conservative", -+ "content-image-texture-target", -+ "content-shell-host-window-size", -+ "controller", -+ "crash-dumps-dir", -+ "crash-on-failure", -+ "crash-on-hang-threads", -+ "crashpad-handler", -+ "crash-server-url", -+ "crash-test", -+ "create-browser-on-startup-for-tests", -+ "cros-gaia-api-v1", -+ "crosh-command", -+ "cros-region", -+ "cros-regions-mode", -+ "cryptauth-http-host", -+ "custom-devtools-frontend", -+ "custom-launcher-page", -+ "custom_summary", -+ "d3d11", -+ "d3d9", -+ "d3d-support", -+ "daemon", -+ "dark_muted", -+ "dark_vibrant", -+ "data-path", -+ "data-reduction-proxy-config-url", -+ "data-reduction-proxy-experiment", -+ "data-reduction-proxy-http-proxies", -+ "data-reduction-proxy-lo-fi", -+ "data-reduction-proxy-pingback-url", -+ "data-reduction-proxy-secure-proxy-check-url", -+ "data-reduction-proxy-server-experiments-disabled", -+ "dbus-stub", -+ "debug-devtools", -+ "debug-enable-frame-toggle", -+ "debug-packed-apps", -+ "debug-print", -+ "default", -+ "default-background-color", -+ "default-tile-height", -+ "default-tile-width", -+ "default-wallpaper-is-oem", -+ "default-wallpaper-large", -+ "default-wallpaper-small", -+ "demo", -+ "derelict-detection-timeout", -+ "derelict-idle-timeout", -+ "desktop", -+ "desktop-window-1080p", -+ "deterministic-fetch", -+ "device-management-url", -+ "device-scale-factor", -+ "devtools-flags", -+ "diagnostics", -+ "diagnostics-format", -+ "diagnostics-recovery", -+ "dice", -+ "dice_fix_auth_errors", -+ "disable", -+ "disable-2d-canvas-clip-aa", -+ "disable-2d-canvas-image-chromium", -+ "disable-3d-apis", -+ "disable-accelerated-2d-canvas", -+ "disable-accelerated-jpeg-decoding", -+ "disable-accelerated-mjpeg-decode", -+ "disable-accelerated-video-decode", -+ "disable-appcontainer", -+ "disable-app-info-dialog-mac", -+ "disable-app-list-dismiss-on-blur", -+ "disable-app-window-cycling", -+ "disable-arc-data-wipe", -+ "disable-arc-opt-in-verification", -+ "disable-audio-support-for-desktop-share", -+ "disable-avfoundation-overlays", -+ "disable-backgrounding-occluded-windows", -+ "disable-background-networking", -+ "disable-background-timer-throttling", -+ "disable-backing-store-limit", -+ "disable-blink-features", -+ "disable-boot-animation", -+ "disable-breakpad", -+ "disable-browser-task-scheduler", -+ "disable-bundled-ppapi-flash", -+ "disable-canvas-aa", -+ "disable-captive-portal-bypass-proxy", -+ "disable-cast-streaming-hw-encoding", -+ "disable-checker-imaging", -+ "disable-clear-browsing-data-counters", -+ "disable-client-side-phishing-detection", -+ "disable-cloud-import", -+ "disable-component-cloud-policy", -+ "disable-component-extensions-with-background-pages", -+ "disable-component-update", -+ "disable-composited-antialiasing", -+ "disable-contextual-search", -+ "disabled", -+ "disable-d3d11", -+ "disable-databases", -+ "disable-datasaver-prompt", -+ "disable-default-apps", -+ "disable-demo-mode", -+ "disable-device-disabling", -+ "disable-device-discovery-notifications", -+ "disable-dinosaur-easter-egg", -+ "disable-direct-composition", -+ "disable-direct-composition-layers", -+ "disable-directwrite-for-ui", -+ "disable-display-list-2d-canvas", -+ "disable-distance-field-text", -+ "disabled-new-style-notification", -+ "disable-domain-blocking-for-3d-apis", -+ "disable-domain-reliability", -+ "disable-drive-search-in-app-launcher", -+ "disable-dwm-composition", -+ "disable-encryption-migration", -+ "disable-eol-notification", -+ "disable-es3-apis", -+ "disable-es3-gl-context", -+ "disable-extensions", -+ "disable-extensions-except", -+ "disable-extensions-file-access-check", -+ "disable-extensions-http-throttling", -+ "disable-features", -+ "disable-field-trial-config", -+ "disable-file-manager-touch-mode", -+ "disable-file-system", -+ "disable-flash-3d", -+ "disable-flash-stage3d", -+ "disable-fullscreen-low-power-mode", -+ "disable-fullscreen-tab-detaching", -+ "disable-gaia-services", -+ "disable-gesture-editing", -+ "disable-gesture-requirement-for-presentation", -+ "disable-gesture-typing", -+ "disable-gl-drawing-for-tests", -+ "disable-gl-error-limit", -+ "disable-gl-extensions", -+ "disable-glsl-translator", -+ "disable-gpu", -+ "disable-gpu-compositing", -+ "disable-gpu-driver-bug-workarounds", -+ "disable-gpu-early-init", -+ "disable-gpu-memory-buffer-compositor-resources", -+ "disable-gpu-memory-buffer-video-frames", -+ "disable-gpu-process-crash-limit", -+ "disable-gpu-program-cache", -+ "disable-gpu-rasterization", -+ "disable-gpu-sandbox", -+ "disable-gpu-shader-disk-cache", -+ "disable-gpu-vsync", -+ "disable-gpu-watchdog", -+ "disable-hang-monitor", -+ "disable-hid-detection-on-oobe", -+ "disable-histogram-customizer", -+ "disable-hosted-app-shim-creation", -+ "disable-hosted-apps-in-windows", -+ "disable-infobars", -+ "disable-in-process-stack-traces", -+ "disable-input-ime-api", -+ "disable-input-view", -+ "disable-ios-password-suggestions", -+ "disable-javascript-harmony-shipping", -+ "disable-kill-after-bad-ipc", -+ "disable-lcd-text", -+ "disable-legacy-window", -+ "disable-local-storage", -+ "disable-lock-screen-apps", -+ "disable-logging", -+ "disable-logging-redirect", -+ "disable-login-animations", -+ "disable-login-screen-apps", -+ "disable-low-end-device-mode", -+ "disable-low-latency-dxva", -+ "disable-low-res-tiling", -+ "disable-machine-cert-request", -+ "disable-mac-overlays", -+ "disable-mac-views-native-app-windows", -+ "disable-main-frame-before-activation", -+ "disable-md-error-screen", -+ "disable-md-oobe", -+ "disable-media-session-api", -+ "disable-media-suspend", -+ "disable-merge-key-char-events", -+ "disable-mojo-local-storage", -+ "disable-mojo-renderer", -+ "disable-mtp-write-support", -+ "disable-multi-display-layout", -+ "disable-namespace-sandbox", -+ "disable-native-gpu-memory-buffers", -+ "disable-network-portal-notification", -+ "disable-new-korean-ime", -+ "disable-new-virtual-keyboard-behavior", -+ "disable-new-zip-unpacker", -+ "disable-notifications", -+ "disable-ntp-most-likely-favicons-from-server", -+ "disable-ntp-popular-sites", -+ "disable-nv12-dxgi-video", -+ "disable-offer-store-unmasked-wallet-cards", -+ "disable-offer-upload-credit-cards", -+ "disable-office-editing-component-extension", -+ "disable-offline-auto-reload", -+ "disable-offline-auto-reload-visible-only", -+ "disable-origin-trial-controlled-blink-features", -+ "disable-overscroll-edge-effect", -+ "disable-panel-fitting", -+ "disable-partial-raster", -+ "disable-password-generation", -+ "disable-pepper-3d", -+ "disable-pepper-3d-image-chromium", -+ "disable-permission-action-reporting", -+ "disable-permissions-api", -+ "disable-per-user-timezone", -+ "disable-physical-keyboard-autocorrect", -+ "disable-pinch", -+ "disable-pnacl-crash-throttling", -+ "disable-popup-blocking", -+ "disable-prefer-compositing-to-lcd-text", -+ "disable-presentation-api", -+ "disable-print-preview", -+ "disable-prompt-on-repost", -+ "disable-proximity-auth-bluetooth-low-energy-discovery", -+ "disable-pull-to-refresh-effect", -+ "disable-push-api-background-mode", -+ "disable-reading-from-canvas", -+ "disable-remote-core-animation", -+ "disable-remote-fonts", -+ "disable-remote-playback-api", -+ "disable-renderer-accessibility", -+ "disable-renderer-backgrounding", -+ "disable-resize-lock", -+ "disable-rgba-4444-textures", -+ "disable-rollback-option", -+ "disable-rtc-smoothness-algorithm", -+ "disable-screen-orientation-lock", -+ "disable-search-geolocation-disclosure", -+ "disable-seccomp-filter-sandbox", -+ "disable-setuid-sandbox", -+ "disable-shader-name-hashing", -+ "disable-shared-workers", -+ "disable-signin-promo", -+ "disable-signin-scoped-device-id", -+ "disable-single-click-autofill", -+ "disable-skia-runtime-opts", -+ "disable-slimming-paint-invalidation", -+ "disable-slim-navigation-manager", -+ "disable-smooth-scrolling", -+ "disable-software-rasterizer", -+ "disable-speech-api", -+ "disable-suggestions-ui", -+ "disable-surface-references", -+ "disable-sync", -+ "disable-sync-app-list", -+ "disable-sync-types", -+ "disable-system-timezone-automatic-detection", -+ "disable-tab-for-desktop-share", -+ "disable-third-party-keyboard-workaround", -+ "disable-threaded-animation", -+ "disable-threaded-compositing", -+ "disable-threaded-scrolling", -+ "disable-timeouts-for-profiling", -+ "disable-touch-adjustment", -+ "disable-touch-drag-drop", -+ "disable-translate-new-ux", -+ "disable-usb-keyboard-detect", -+ "disable-v8-idle-tasks", -+ "disable-vaapi-accelerated-video-encode", -+ "disable-virtual-keyboard-overscroll", -+ "disable-voice-input", -+ "disable-volume-adjust-sound", -+ "disable-wake-on-wifi", -+ "disable-webgl", -+ "disable-webgl-image-chromium", -+ "disable-web-notification-custom-layouts", -+ "disable-webrtc-encryption", -+ "disable-webrtc-hw-decoding", -+ "disable-webrtc-hw-encoding", -+ "disable-web-security", -+ "disable-win32k-lockdown", -+ "disable-xss-auditor", -+ "disable-zero-browsers-open-for-tests", -+ "disable-zero-copy", -+ "disable-zero-copy-dxgi-video", -+ "disallow-non-exact-resource-reuse", -+ "disk-cache-dir", -+ "disk-cache-size", -+ "display", -+ "dmg-device", -+ "dns-log-details", -+ "document-user-activation-required", -+ "dom-automation", -+ "dotfile", -+ "draft", -+ "draw-view-bounds-rects", -+ "duck-flash", -+ "dump-blink-runtime-call-stats", -+ "dump-browser-histograms", -+ "dump-dom", -+ "eafe-path", -+ "eafe-url", -+ "easy-unlock-app-path", -+ "edge-touch-filtering", -+ "egl", -+ "elevate", -+ "embedded-extension-options", -+ "emphasize-titles-in-omnibox-dropdown", -+ "emulate-shader-precision", -+ "enable-accelerated-2d-canvas", -+ "enable-accelerated-vpx-decode", -+ "enable-accessibility-tab-switcher", -+ "enable-adaptive-selection-handle-orientation", -+ "enable-aggressive-domstorage-flushing", -+ "enable-android-wallpapers-app", -+ "enable-appcontainer", -+ "enable-app-info-dialog-mac", -+ "enable-app-list", -+ "enable-app-window-cycling", -+ "enable-arc", -+ "enable-arc-oobe-optin", -+ "enable-async-event-targeting", -+ "enable-audio-debug-recordings-from-extension", -+ "enable-audio-focus", -+ "enable-automation", -+ "enable-background-fetch-persistence", -+ "enable-benchmarking", -+ "enable-ble-advertising-in-apps", -+ "enable-blink-features", -+ "enable-bookmark-undo", -+ "enable-browser-side-navigation", -+ "enable-browser-task-scheduler", -+ "enable-cast-receiver", -+ "enable-checker-imaging", -+ "enable-chromevox-arc-support", -+ "enable-clear-browsing-data-counters", -+ "enable-cloud-print-proxy", -+ "enable-cloud-print-xps", -+ "enable-consumer-kiosk", -+ "enable-contextual-search", -+ "enable-crash-reporter", -+ "enable-crash-reporter-for-testing", -+ "enable-crx-hash-check", -+ "enabled", -+ "enabled-2g", -+ "enabled-3g", -+ "enable-data-reduction-proxy-bypass-warning", -+ "enable-data-reduction-proxy-force-pingback", -+ "enable-data-reduction-proxy-lite-page", -+ "enable-data-reduction-proxy-savings-promo", -+ "enable-datasaver-prompt", -+ "enable-device-discovery-notifications", -+ "enable-devtools-experiments", -+ "enable-direct-composition-layers", -+ "enable-display-list-2d-canvas", -+ "enable-distance-field-text", -+ "enable-distillability-service", -+ "enabled-new-style-notification", -+ "enable-domain-reliability", -+ "enable-dom-distiller", -+ "enable-drive-search-in-app-launcher", -+ "enable-drm-atomic", -+ "enabled-slow2g", -+ "enable-embedded-extension-options", -+ "enable-encryption-migration", -+ "enable-encryption-selection", -+ "enable-es3-apis", -+ "enable-exclusive-audio", -+ "enable-experimental-accessibility-features", -+ "enable-experimental-canvas-features", -+ "enable-experimental-extension-apis", -+ "enable-experimental-fullscreen-exit-ui", -+ "enable-experimental-input-view-features", -+ "enable-experimental-web-platform-features", -+ "enable-extension-activity-logging", -+ "enable-extension-activity-log-testing", -+ "enable-extension-assets-sharing", -+ "enable-external-drive-rename", -+ "enable-fast-unload", -+ "enable-features", -+ "enable-file-manager-touch-mode", -+ "enable-first-run-ui-transitions", -+ "enable-floating-virtual-keyboard", -+ "enable-font-antialiasing", -+ "enable-fullscreen-tab-detaching", -+ "enable-fullscreen-toolbar-reveal", -+ "enable-google-branded-context-menu", -+ "enable-gpu-async-worker-context", -+ "enable-gpu-benchmarking", -+ "enable-gpu-client-logging", -+ "enable-gpu-client-tracing", -+ "enable-gpu-command-logging", -+ "enable-gpu-debugging", -+ "enable-gpu-driver-debug-logging", -+ "enable-gpu-memory-buffer-compositor-resources", -+ "enable-gpu-memory-buffer-video-frames", -+ "enable-gpu-rasterization", -+ "enable-gpu-service-logging", -+ "enable-gpu-service-tracing", -+ "enable-hardware-overlays", -+ "enable-harfbuzz-rendertext", -+ "enable-heap-profiling", -+ "enable-hosted-app-quit-notification", -+ "enable-hosted-apps-in-windows", -+ "enable-hotword-hardware", -+ "enable-hung-renderer-infobar", -+ "enable-inband-text-tracks", -+ "enable-input-ime-api", -+ "enable-instant-tethering", -+ "enable-internal-media-session", -+ "enable-ios-handoff-to-other-devices", -+ "enable-layer-lists", -+ "enable-lcd-text", -+ "enable-leak-detection", -+ "enable-local-file-accesses", -+ "enable-local-sync-backend", -+ "enable-logging", -+ "enable-longpress-drag-selection", -+ "enable-low-end-device-mode", -+ "enable-low-res-tiling", -+ "enable-mac-views-native-app-windows", -+ "enable-main-frame-before-activation", -+ "enable-md-feedback", -+ "enable-media-suspend", -+ "enable-merge-key-char-events", -+ "enable-message-center-always-scroll-up-upon-notification-removal", -+ "enable-nacl", -+ "enable-nacl-debug", -+ "enable-nacl-nonsfi-mode", -+ "enable-native-gpu-memory-buffers", -+ "enable-natural-scroll-default", -+ "enable-navigation-tracing", -+ "enable-net-benchmarking", -+ "enable-network-information-downlink-max", -+ "enable-network-portal-notification", -+ "enable-new-app-menu-icon", -+ "enable-ntp-most-likely-favicons-from-server", -+ "enable-ntp-popular-sites", -+ "enable-ntp-search-engine-country-detection", -+ "enable-offer-store-unmasked-wallet-cards", -+ "enable-offer-upload-credit-cards", -+ "enable-offline-auto-reload", -+ "enable-offline-auto-reload-visible-only", -+ "enable-oop-rasterization", -+ "enable-osk-overscroll", -+ "enable-override-bookmarks-ui", -+ "enable-partial-raster", -+ "enable-password-generation", -+ "enable-pepper-testing", -+ "enable-permission-action-reporting", -+ "enable-physical-keyboard-autocorrect", -+ "enable-picture-in-picture", -+ "enable-pinch", -+ "enable-pixel-canvas-recording", -+ "enable-pixel-output-in-tests", -+ "enable-plugin-placeholder-testing", -+ "enable-potentially-annoying-security-features", -+ "enable-power-overlay", -+ "enable-precise-memory-info", -+ "enable-prefer-compositing-to-lcd-text", -+ "enable-print-browser", -+ "enable-print-preview-register-promos", -+ "enable-profile-shortcut-manager", -+ "enable-profiling", -+ "enable-push-api-background-mode", -+ "enable-refresh-token-annotation-request", -+ "enable-request-tablet-site", -+ "enable-rgba-4444-textures", -+ "enable-sandbox", -+ "enable-sandbox-logging", -+ "enable-screenshot-testing-with-mode", -+ "enable-scripts-require-action", -+ "enable-scroll-prediction", -+ "enable-service-manager-tracing", -+ "enable-sgi-video-sync", -+ "enable-signin-promo", -+ "enable-single-click-autofill", -+ "enable-site-settings", -+ "enable-skia-benchmarking", -+ "enable-slimming-paint-invalidation", -+ "enable-slimming-paint-v2", -+ "enable-slim-navigation-manager", -+ "enable-smooth-scrolling", -+ "enable-spatial-navigation", -+ "enable-spdy-proxy-auth", -+ "enable-speech-dispatcher", -+ "enable-spelling-feedback-field-trial", -+ "enable-spotlight-actions", -+ "enable-stats-collection-bindings", -+ "enable-stats-table", -+ "enable-strict-mixed-content-checking", -+ "enable-strict-powerful-feature-restrictions", -+ "enable-suggestions-ui", -+ "enable-suggestions-with-substring-match", -+ "enable-supervised-user-managed-bookmarks-folder", -+ "enable-surface-synchronization", -+ "enable-swap-buffers-with-bounds", -+ "enable-sync-app-list", -+ "enable-sync-articles", -+ "enable-tab-audio-muting", -+ "enable-tablet-splitview", -+ "enable-tcp-fastopen", -+ "enable-third-party-keyboard-workaround", -+ "enable-threaded-compositing", -+ "enable-threaded-texture-mailboxes", -+ "enable-tile-compression", -+ "enable-touch-calibration-setting", -+ "enable-touch-drag-drop", -+ "enable-touchpad-three-finger-click", -+ "enable-touchview", -+ "enable-trace-app-source", -+ "enable-tracing", -+ "enable-tracing-output", -+ "enable-translate-new-ux", -+ "enable-ui-devtools", -+ "enable-usermedia-screen-capturing", -+ "enable-user-metrics", -+ "enable-use-zoom-for-dsf", -+ "enable-video-player-chromecast-support", -+ "enable-viewport", -+ "enable-virtual-keyboard", -+ "enable-voice-interaction", -+ "enable-vtune-support", -+ "enable-vulkan", -+ "enable-wayland-server", -+ "enable-webfonts-intervention-trigger", -+ "enable-webfonts-intervention-v2", -+ "enable-webgl-draft-extensions", -+ "enable-webgl-image-chromium", -+ "enable-web-notification-custom-layouts", -+ "enable-webrtc-event-logging-from-extension", -+ "enable-webrtc-srtp-aes-gcm", -+ "enable-webrtc-srtp-encrypted-headers", -+ "enable-webrtc-stun-origin", -+ "enable-webview-variations", -+ "enable-webvr", -+ "enable-wifi-credential-sync", -+ "enable-win7-webrtc-hw-h264-decoding", -+ "enable-zero-copy", -+ "enable-zip-archiver-on-file-manager", -+ "encode-binary", -+ "enforce", -+ "enforce-gl-minimums", -+ "enforce_strict", -+ "enforce-webrtc-ip-permission-check", -+ "enterprise-disable-arc", -+ "enterprise-enable-forced-re-enrollment", -+ "enterprise-enable-license-type-selection", -+ "enterprise-enable-zero-touch-enrollment", -+ "enterprise-enrollment-initial-modulus", -+ "enterprise-enrollment-modulus-limit", -+ "error-console", -+ "evaluate_capability", -+ "evaluate-type", -+ "experiment", -+ "explicitly-allowed-ports", -+ "expose-internals-for-testing", -+ "extension-content-verification", -+ "extension-process", -+ "extensions-install-verification", -+ "extensions-multi-account", -+ "extensions-not-webstore", -+ "extensions-on-chrome-urls", -+ "extensions-update-frequency", -+ "extra-search-query-params", -+ "fail-on-unused-args", -+ "fake-variations-channel", -+ "false", -+ "fast", -+ "fast-start", -+ "feedback-server", -+ "field-trial-handle", -+ "first-exec-after-boot", -+ "flag-switches-begin", -+ "flag-switches-end", -+ "font-cache-shared-handle", -+ "force-android-app-mode", -+ "force-app-mode", -+ "force-clamshell-power-button", -+ "force-color-profile", -+ "force-desktop-ios-promotion", -+ "force-device-scale-factor", -+ "force-dev-mode-highlighting", -+ "force-display-list-2d-canvas", -+ "force-effective-connection-type", -+ "force-enable-metrics-reporting", -+ "force-enable-stylus-tools", -+ "force-fieldtrial-params", -+ "force-fieldtrials", -+ "force-first-run", -+ "force-first-run-ui", -+ "force-gpu-mem-available-mb", -+ "force-gpu-rasterization", -+ "force-happiness-tracking-system", -+ "force-load-easy-unlock-app-in-tests", -+ "force-local-ntp", -+ "force-login-manager-in-tests", -+ "force-mediafoundation", -+ "force-overlay-fullscreen-video", -+ "force-password-reauth", -+ "force-pnacl-subzero", -+ "force-presentation-receiver-for-testing", -+ "force-renderer-accessibility", -+ "force-show-update-menu-badge", -+ "force-show-update-menu-item", -+ "force-system-compositor-mode", -+ "force-tablet-mode", -+ "force-text-direction", -+ "force-ui-direction", -+ "force-variation-ids", -+ "force-video-overlays", -+ "force-wave-audio", -+ "force-webrtc-ip-handling-policy", -+ "full-memory-crash-report", -+ "gaia-url", -+ "gcm-checkin-url", -+ "gcm-mcs-endpoint", -+ "gcm-registration-url", -+ "generate-accessibility-test-expectations", -+ "gl", -+ "gl-composited-overlay-candidate-quad-border", -+ "gles", -+ "gl-shader-interm-output", -+ "golden-screenshots-dir", -+ "google-apis-url", -+ "google-base-url", -+ "google-doodle-url", -+ "google-url", -+ "gpu-active-device-id", -+ "gpu-active-vendor-id", -+ "gpu-device-id", -+ "gpu-driver-date", -+ "gpu-driver-vendor", -+ "gpu-driver-version", -+ "gpu-launcher", -+ "gpu-no-complete-info-collection", -+ "gpu-no-context-lost", -+ "gpu-process", -+ "gpu-program-cache-size-kb", -+ "gpu-rasterization-msaa-sample-count", -+ "gpu-sandbox-allow-sysv-shm", -+ "gpu-sandbox-failures-fatal", -+ "gpu-sandbox-start-early", -+ "gpu-secondary-device-ids", -+ "gpu-secondary-vendor-ids", -+ "gpu-startup-dialog", -+ "gpu-testing-device-id", -+ "gpu-testing-driver-date", -+ "gpu-testing-gl-renderer", -+ "gpu-testing-gl-vendor", -+ "gpu-testing-gl-version", -+ "gpu-testing-os-version", -+ "gpu-testing-secondary-device-ids", -+ "gpu-testing-secondary-vendor-ids", -+ "gpu-testing-vendor-id", -+ "gpu-vendor-id", -+ "graphics-buffer-count", -+ "guest-wallpaper-large", -+ "guest-wallpaper-small", -+ "h", -+ "has-chromeos-diamond-key", -+ "has-chromeos-keyboard", -+ "has-internal-stylus", -+ "headless", -+ "help", -+ "hide", -+ "hide-icons", -+ "hide-scrollbars", -+ "history-entry-requires-user-gesture", -+ "homedir", -+ "homepage", -+ "host", -+ "host-pairing-oobe", -+ "host-resolver-rules", -+ "icu-data-dir", -+ "ignore-autocomplete-off-autofill", -+ "ignore-autoplay-restrictions", -+ "ignore-certificate-errors", -+ "ignore-certificate-errors-spki-list", -+ "ignore-gpu-blacklist", -+ "ignore-urlfetcher-cert-requests", -+ "ignore-user-profile-mapping-for-tests", -+ "incognito", -+ "in-process-gpu", -+ "input", -+ "install-chrome-app", -+ "install-supervised-user-whitelists", -+ "instant-process", -+ "invalidation-use-gcm-channel", -+ "ipc-connection-timeout", -+ "ipc-dump-directory", -+ "ipc-fuzzer-testcase", -+ "isolate-origins", -+ "isolate-sites-for-testing", -+ "is-running-in-mash", -+ "javascript-harmony", -+ "js-flags", -+ "keep-alive-for-test", -+ "kiosk", -+ "kiosk-printing", -+ "lang", -+ "last-launched-app", -+ "layer", -+ "light_muted", -+ "light_vibrant", -+ "limit-fps", -+ "load-and-launch-app", -+ "load-apps", -+ "load-extension", -+ "load-media-router-component-extension", -+ "local-heuristics-only-for-password-generation", -+ "local-ntp-reload", -+ "local-sync-backend-dir", -+ "log-gpu-control-list-decisions", -+ "login-manager", -+ "login-profile", -+ "login-user", -+ "log-level", -+ "log-net-log", -+ "loopback-i2s-bits", -+ "loopback-i2s-bus-name", -+ "loopback-i2s-channels", -+ "loopback-i2s-rate-hz", -+ "lso-url", -+ "ltr", -+ "main-frame-resizes-are-orientation-changes", -+ "make-chrome-default", -+ "make-default-browser", -+ "managed-user-id", -+ "managed-user-sync-token", -+ "markdown", -+ "market-url-for-testing", -+ "mark-non-secure-as", -+ "mash", -+ "material", -+ "material-design-ink-drop-animation-speed", -+ "material-hybrid", -+ "max-gum-fps", -+ "max-output-volume-dba1m", -+ "max-untiled-layer-height", -+ "max-untiled-layer-width", -+ "media-cache-size", -+ "memlog", -+ "memory-pressure-off", -+ "memory-pressure-thresholds", -+ "memory-pressure-thresholds-mb", -+ "mem-pressure-system-reserved-kb", -+ "message-center-changes-while-open", -+ "method", -+ "metrics-client-id", -+ "metrics-recording-only", -+ "mhtml-generator-option", -+ "mirror", -+ "mock", -+ "mojo-local-storage", -+ "mojo-pipe-token", -+ "monitoring-destination-id", -+ "mse-audio-buffer-size-limit", -+ "mse-video-buffer-size-limit", -+ "mus", -+ "mus-config", -+ "mute-audio", -+ "nacl-broker", -+ "nacl-dangerous-no-sandbox-nonsfi", -+ "nacl-debug-mask", -+ "nacl-gdb", -+ "nacl-gdb-script", -+ "nacl-loader", -+ "nacl-loader-nonsfi", -+ "native", -+ "native-crx-bindings", -+ "need-arc-migration-policy-check", -+ "netifs-to-ignore", -+ "net-log-capture-mode", -+ "network-country-iso", -+ "network-settings-config", -+ "new-window", -+ "nocolor", -+ "no-default-browser-check", -+ "noerrdialogs", -+ "no-experiments", -+ "no-first-run", -+ "no-managed-user-acknowledgment-check", -+ "none", -+ "no-network-profile-warning", -+ "non-material", -+ "non-secure", -+ "non-secure-after-editing", -+ "non-secure-while-incognito", -+ "non-secure-while-incognito-or-editing", -+ "no-pings", -+ "no-proxy-server", -+ "no-referrers", -+ "normal_muted", -+ "normal_vibrant", -+ "no-sandbox", -+ "no-service-autorun", -+ "no-session-id", -+ "no-startup-window", -+ "note-taking-app-ids", -+ "no-user-gesture-required", -+ "no-wifi", -+ "no-zygote", -+ "ntp-snippets-add-incomplete", -+ "null", -+ "num-raster-threads", -+ "oauth2-client-id", -+ "oauth2-client-secret", -+ "off", -+ "on", -+ "oobe-bootstrapping-master", -+ "oobe-force-show-screen", -+ "oobe-guest-session", -+ "oobe-skip-postlogin", -+ "oobe-timer-interval", -+ "open-ash", -+ "opengraph", -+ "original-process-start-time", -+ "origin-trial-disabled-features", -+ "origin-trial-disabled-tokens", -+ "origin-trial-public-key", -+ "osmesa", -+ "output", -+ "override", -+ "override-metrics-upload-url", -+ "override-plugin-power-saver-for-testing", -+ "override-use-software-gl-for-tests", -+ "overscroll-history-navigation", -+ "overscroll-start-threshold", -+ "ozone-dump-file", -+ "ozone-platform", -+ "pack-extension", -+ "pack-extension-key", -+ "parent-profile", -+ "parent-window", -+ "passive-listeners-default", -+ "password-store", -+ "permission-request-api-scope", -+ "permission-request-api-url", -+ "ppapi", -+ "ppapi-antialiased-text-enabled", -+ "ppapi-broker", -+ "ppapi-flash-args", -+ "ppapi-flash-path", -+ "ppapi-flash-version", -+ "ppapi-in-process", -+ "ppapi-plugin-launcher", -+ "ppapi-startup-dialog", -+ "ppapi-subpixel-rendering-setting", -+ "/prefetch:1", -+ "/prefetch:2", -+ "/prefetch:3", -+ "/prefetch:4", -+ "/prefetch:5", -+ "/prefetch:6", -+ "/prefetch:8", -+ "previous-app", -+ "primary", -+ "print-to-pdf", -+ "privet-ipv6-only", -+ "process-per-site", -+ "process-per-tab", -+ "product-version", -+ "profile-directory", -+ "profiler-timing", -+ "profiling-at-start", -+ "profiling-file", -+ "profiling-flush", -+ "progress-bar-animation", -+ "progress-bar-completion", -+ "prompt-for-external-extensions", -+ "proxy-auto-detect", -+ "proxy-bypass-list", -+ "proxy-pac-url", -+ "proxy-server", -+ "pull-to-refresh", -+ "q", -+ "rdp_desktop_session", -+ "reader-mode-feedback", -+ "reader-mode-heuristics", -+ "rebaseline-pixel-tests", -+ "record-type", -+ "reduced-referrer-granularity", -+ "reduce-security-for-testing", -+ "register-font-files", -+ "register-pepper-plugins", -+ "relauncher", -+ "remote-debugging-address", -+ "remote-debugging-port", -+ "remote-debugging-socket-fd", -+ "remote-debugging-socket-name", -+ "remote-debugging-targets", -+ "renderer", -+ "renderer-client-id", -+ "renderer-cmd-prefix", -+ "renderer-process-limit", -+ "renderer-startup-dialog", -+ "renderer-wait-for-java-debugger", -+ "renderpass", -+ "repl", -+ "report-vp9-as-an-unsupported-mime-type", -+ "require-audio-hardware-for-testing", -+ "reset-app-list-install-state", -+ "reset-variation-state", -+ "restore-last-session", -+ "root", -+ "root-layer-scrolls", -+ "rtl", -+ "run-all-compositor-stages-before-draw", -+ "run-layout-test", -+ "runtime-deps-list-file", -+ "safebrowsing-disable-auto-update", -+ "safebrowsing-disable-download-protection", -+ "safebrowsing-disable-extension-blacklist", -+ "safebrowsing-manual-download-blacklist", -+ "SafeSites", -+ "sandbox-ipc", -+ "save-page-as-mhtml", -+ "screen-config", -+ "screenshot", -+ "script-executable", -+ "scripts-require-action", -+ "search-provider-logo-url", -+ "secondary", -+ "secondary-display-layout", -+ "secondary-ui-md", -+ "service", -+ "service-manager", -+ "service-name", -+ "service-pipe-token", -+ "service-request-channel-token", -+ "service-runner", -+ "shared-files", -+ "shill-stub", -+ "show-app-list", -+ "show-autofill-signatures", -+ "show-autofill-type-predictions", -+ "show-cert-link", -+ "show-component-extension-options", -+ "show-composited-layer-borders", -+ "show-fps-counter", -+ "show-icons", -+ "show-layer-animation-bounds", -+ "show-login-dev-overlay", -+ "show-mac-overlay-borders", -+ "show-md-login", -+ "show-non-md-login", -+ "show-overdraw-feedback", -+ "show-paint-rects", -+ "show-property-changed-rects", -+ "show-saved-copy", -+ "show-screenspace-rects", -+ "show-surface-damage-rects", -+ "silent-debugger-extension-api", -+ "silent-launch", -+ "simulate-critical-update", -+ "simulate-elevated-recovery", -+ "simulate-outdated", -+ "simulate-outdated-no-au", -+ "simulate-upgrade", -+ "single-process", -+ "site-per-process", -+ "skip-gpu-data-loading", -+ "skip-nostore-all", -+ "skip-nostore-main", -+ "skip-reencoding-on-skp-capture", -+ "slow", -+ "slow-connections-only", -+ "slow-down-compositing-scale-factor", -+ "slow-down-raster-scale-factor", -+ "sms-test-messages", -+ "spdy-proxy-auth-fallback", -+ "spdy-proxy-auth-origin", -+ "spdy-proxy-auth-value", -+ "spelling-service-feedback-interval-seconds", -+ "spelling-service-feedback-url", -+ "spurious-power-button-accel-count", -+ "spurious-power-button-keyboard-accel", -+ "spurious-power-button-lid-angle-change", -+ "spurious-power-button-screen-accel", -+ "spurious-power-button-window", -+ "ssl-key-log-file", -+ "ssl-version-max", -+ "ssl-version-min", -+ "stable-release-mode", -+ "started", -+ "start-fullscreen", -+ "start-maximized", -+ "start-stack-profiler", -+ "stub", -+ "stub-cros-settings", -+ "surface", -+ "swiftshader", -+ "swiftshader-webgl", -+ "sync-allow-insecure-xmpp-connection", -+ "sync-deferred-startup-timeout-seconds", -+ "sync-disable-deferred-startup", -+ "sync-enable-get-update-avoidance", -+ "sync-notification-host-port", -+ "sync-on-draw-hardware", -+ "sync-short-initial-retry-override", -+ "sync-short-nudge-delay-for-test", -+ "sync-url", -+ "system-developer-mode", -+ "system-log-upload-frequency", -+ "tab-management-experiment-type-disabled", -+ "tab-management-experiment-type-elderberry", -+ "task-manager-show-extra-renderers", -+ "task-profiler", -+ "team-drives", -+ "test-auto-update-ui", -+ "test-child-process", -+ "test-cros-gaia-id-migration", -+ "test-do-not-initialize-icu", -+ "test-encryption-migration-ui", -+ "test-gl-lib", -+ "testing-fixed-http-port", -+ "testing-fixed-https-port", -+ "test-launcher-batch-limit", -+ "test-launcher-bot-mode", -+ "test-launcher-debug-launcher", -+ "test-launcher-filter-file", -+ "test-launcher-force-run-broken-tests", -+ "test-launcher-jobs", -+ "test-launcher-list-tests", -+ "test-launcher-output", -+ "test-launcher-print-test-stdio", -+ "test-launcher-print-writable-path", -+ "test-launcher-retry-limit", -+ "test-launcher-shard-index", -+ "test-launcher-summary-output", -+ "test-launcher-test-part-results-limit", -+ "test-launcher-timeout", -+ "test-launcher-total-shards", -+ "test-launcher-trace", -+ "test-name", -+ "test-tiny-timeout", -+ "test-type", -+ "tether-stub", -+ "third-party-doodle-url", -+ "threads", -+ "time", -+ "timeout", -+ "tls1", -+ "tls1.1", -+ "tls1.2", -+ "tls1.3", -+ "tls13-variant", -+ "top-chrome-md", -+ "top-controls-hide-threshold", -+ "top-controls-show-threshold", -+ "touch-calibration", -+ "touch-devices", -+ "touch-events", -+ "touch-noise-filtering", -+ "touch-selection-strategy", -+ "touch_view", -+ "trace-config-file", -+ "trace-export-events-to-etw", -+ "tracelog", -+ "trace-shutdown", -+ "trace-shutdown-file", -+ "trace-startup", -+ "trace-startup-duration", -+ "trace-startup-file", -+ "trace-to-console", -+ "trace-to-file", -+ "trace-to-file-name", -+ "trace-upload-url", -+ "translate-ranker-model-url", -+ "translate-script-url", -+ "translate-security-origin", -+ "true", -+ "trusted-download-sources", -+ "try-chrome-again", -+ "try-supported-channel-layouts", -+ "type", -+ "ui-disable-partial-swap", -+ "ui-enable-layer-lists", -+ "ui-enable-rgba-4444-textures", -+ "ui-enable-zero-copy", -+ "ui-prioritize-in-gpu-process", -+ "ui-show-composited-layer-borders", -+ "ui-show-fps-counter", -+ "ui-show-layer-animation-bounds", -+ "ui-show-paint-rects", -+ "ui-show-property-changed-rects", -+ "ui-show-screenspace-rects", -+ "ui-show-surface-damage-rects", -+ "ui-slow-animations", -+ "ui-test-action-max-timeout", -+ "ui-test-action-timeout", -+ "uninstall", -+ "unlimited-storage", -+ "unsafely-allow-protected-media-identifier-for-domain", -+ "unsafely-treat-insecure-origin-as-secure", -+ "unsafe-pac-url", -+ "use-angle", -+ "use-cras", -+ "use-fake-device-for-media-stream", -+ "use-fake-jpeg-decode-accelerator", -+ "use-fake-ui-for-media-stream", -+ "use-file-for-fake-audio-capture", -+ "use-file-for-fake-video-capture", -+ "use-first-display-as-internal", -+ "use-gl", -+ "use-gpu-in-tests", -+ "use-ime-service", -+ "use-mobile-user-agent", -+ "use-mock-keychain", -+ "use-passthrough-cmd-decoder", -+ "user-agent", -+ "user-always-affiliated", -+ "user-data-dir", -+ "user-gesture-required", -+ "user-gesture-required-for-cross-origin", -+ "use-skia-renderer", -+ "use-system-default-printer", -+ "use-test-config", -+ "use-viz-hit-test", -+ "utility", -+ "utility-allowed-dir", -+ "utility-cmd-prefix", -+ "utility-run-elevated", -+ "utility-sandbox-type", -+ "utility-startup-dialog", -+ "v", -+ "v2-sandbox", -+ "v2-sandbox-enabled", -+ "v8-cache-options", -+ "v8-cache-strategies-for-cache-storage", -+ "validate-crx", -+ "validate-input-event-stream", -+ "variations-override-country", -+ "variations-server-url", -+ "version", -+ "video-image-texture-target", -+ "video-threads", -+ "video-underflow-threshold-ms", -+ "virtual-time-budget", -+ "vmodule", -+ "voice-interaction-supported-locales", -+ "wait-for-debugger", -+ "wait-for-debugger-children", -+ "wake-on-wifi-packet", -+ "wallet-service-use-sandbox", -+ "watcher", -+ "waveout-buffers", -+ "webapk-server-url", -+ "webrtc-stun-probe-trial", -+ "webview-enable-safebrowsing-support", -+ "webview-sandboxed-renderer", -+ "whitelisted-extension-id", -+ "window-position", -+ "windows10-custom-titlebar", -+ "window-size", -+ "window-workspace", -+ "winhttp-proxy-resolver", -+ "win-jumplist-action", -+ "wm-window-animations-disabled", -+ "yield-between-content-script-runs", -+ "zygote", -+ "zygote-cmd-prefix" -+}; -+ -+bool IsBlacklistedArg(const base::CommandLine::CharType* arg) { -+#if defined(OS_WIN) -+ const auto converted = base::WideToUTF8(arg); -+ const char* a = converted.c_str(); -+#else -+ const char* a = arg; -+#endif -+ -+ static const char* prefixes[] = {"--", "-", "/"}; -+ -+ int prefix_length = 0; -+ for (auto& prefix : prefixes) { -+ if (base::StartsWith(a, prefix, base::CompareCase::SENSITIVE)) { -+ prefix_length = strlen(prefix); -+ break; -+ } -+ } -+ -+ if (prefix_length > 0) { -+ a += prefix_length; -+ std::string switch_name = -+ base::ToLowerASCII(base::StringPiece(a, strcspn(a, "="))); -+ for (auto& item : blacklist) { -+ if (switch_name == item) -+ return true; -+ } -+ } -+ -+ return false; -+} -+ -+>>>>>>> .their - } // namespace - - namespace atom { - - bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv) { - const base::CommandLine::StringType dashdash(2, '-'); -+<<<<<<< .our - bool block_args = false; - for (int i = 0; i < argc; ++i) { - if (argv[i] == dashdash) -@@ -45,6 +1416,17 @@ - return false; - } else if (IsUrlArg(argv[i])) { - block_args = true; -+======= -+ bool block_blacklisted_args = false; -+ for (int i = 0; i < argc; ++i) { -+ if (argv[i] == dashdash) -+ break; -+ if (block_blacklisted_args) { -+ if (IsBlacklistedArg(argv[i])) -+ return false; -+ } else if (IsUrlArg(argv[i])) { -+ block_blacklisted_args = true; -+>>>>>>> .their - } - } - return true; -added in both - our 100644 2c0acc1648ff3b4bc574f000643069f8ef8e94bb atom/app/command_line_args.h - their 100644 1f5fd756868898e7a304c754d89625059d36441f atom/app/command_line_args.h -@@ -14,3 +14,7 @@ - } // namespace atom - - #endif // ATOM_APP_COMMAND_LINE_ARGS_H_ -+<<<<<<< .our -+======= -+ -+>>>>>>> .their -changed in both - base 100644 1024bb0c6ccbe529f8302e1d08cf48ce147ff364 atom/browser/api/atom_api_app.cc - our 100644 089a2b63d1bae3afebea925582a3aac81ddeaa4f atom/browser/api/atom_api_app.cc - their 100644 03a6fd0c745a88dfe470e4235a3efcc25cdd37e1 atom/browser/api/atom_api_app.cc -changed in both - base 100644 77c3212e2e02cbfd1187c630cd6c04942a7fc14a atom/browser/atom_browser_client.cc - our 100644 57c4ee582405e6d501ec23940ccb10689ecd64a1 atom/browser/atom_browser_client.cc - their 100644 af4de9f924b98b659722cd9ef4e22b9e7652ce30 atom/browser/atom_browser_client.cc -@@ -27,6 +27,7 @@ - #include "base/command_line.h" - #include "base/environment.h" - #include "base/files/file_util.h" -+#include "base/path_service.h" - #include "base/stl_util.h" - #include "base/strings/string_number_conversions.h" - #include "base/strings/string_util.h" -@@ -41,7 +42,10 @@ - #include "content/public/browser/site_instance.h" - #include "content/public/browser/web_contents.h" - #include "content/public/common/content_paths.h" -+<<<<<<< .our - #include "content/public/common/content_switches.h" -+======= -+>>>>>>> .their - #include "content/public/common/url_constants.h" - #include "content/public/common/web_preferences.h" - #include "net/ssl/ssl_cert_request_info.h" -@@ -296,6 +300,7 @@ - base::CommandLine* command_line, - int process_id) { - // Make sure we're about to launch a known executable -+<<<<<<< .our - { - base::FilePath child_path; - PathService::Get(content::CHILD_PROCESS_EXE, &child_path); -@@ -307,6 +312,14 @@ - std::string process_type = - command_line->GetSwitchValueASCII(::switches::kProcessType); - if (process_type != ::switches::kRendererProcess) -+======= -+ base::FilePath child_path; -+ PathService::Get(content::CHILD_PROCESS_EXE, &child_path); -+ CHECK(base::MakeAbsoluteFilePath(command_line->GetProgram()) == child_path); -+ -+ std::string process_type = command_line->GetSwitchValueASCII("type"); -+ if (process_type != "renderer") -+>>>>>>> .their - return; - - // Copy following switches to child process. -changed in both - base 100644 abd2fb53f1e2ad7b6df9f25f216b5ccb9d6dc7c6 atom/browser/atom_resource_dispatcher_host_delegate.cc - our 100644 934b0ebaa49b711490c58fc73b91985633cba439 atom/browser/atom_resource_dispatcher_host_delegate.cc - their 100644 12038ff1bf501dffa1df6512d7a66cfa3666bd29 atom/browser/atom_resource_dispatcher_host_delegate.cc -@@ -5,13 +5,24 @@ - #include "atom/browser/atom_resource_dispatcher_host_delegate.h" - - #include "atom/browser/atom_browser_context.h" -+<<<<<<< .our - #include "atom/browser/web_contents_permission_helper.h" - #include "atom/browser/web_contents_preferences.h" -+======= -+#include "atom/browser/login_handler.h" -+#include "atom/browser/web_contents_permission_helper.h" -+#include "atom/browser/web_contents_preferences.h" -+#include "atom/common/atom_constants.h" -+>>>>>>> .their - #include "atom/common/platform_util.h" - #include "base/strings/utf_string_conversions.h" - #include "content/public/browser/browser_thread.h" - #include "content/public/browser/download_manager.h" -+<<<<<<< .our - #include "content/public/browser/render_frame_host.h" -+======= -+#include "content/public/browser/stream_info.h" -+>>>>>>> .their - #include "net/base/escape.h" - #include "url/gurl.h" - -@@ -69,6 +80,7 @@ - if (!web_contents) - return; - -+<<<<<<< .our - auto* web_preferences = WebContentsPreferences::From(web_contents); - if (!web_preferences || !web_preferences->IsEnabled(options::kPlugins)) { - auto* browser_context = web_contents->GetBrowserContext(); -@@ -78,6 +90,16 @@ - download_manager->DownloadUrl( - content::DownloadUrlParameters::CreateForWebContentsMainFrame( - web_contents, original_url, NO_TRAFFIC_ANNOTATION_YET)); -+======= -+ if (!WebContentsPreferences::IsPluginsEnabled(web_contents)) { -+ auto browser_context = web_contents->GetBrowserContext(); -+ auto download_manager = -+ content::BrowserContext::GetDownloadManager(browser_context); -+ -+ download_manager->DownloadUrl( -+ content::DownloadUrlParameters::CreateForWebContentsMainFrame( -+ web_contents, original_url)); -+>>>>>>> .their - return; - } - -changed in both - base 100644 9610d80693b1670f696f82812442419504d61454 atom/browser/relauncher.cc - our 100644 35c6785e3d87d21eaea27ad5818434d870326047 atom/browser/relauncher.cc - their 100644 9dfb6edd06661f302ca7498a2ba34f0ce70c938b atom/browser/relauncher.cc -changed in both - base 100644 d260d2e71f37054b1d948ae5ace28bbfd557cc7d atom/browser/resources/mac/Info.plist - our 100644 9094f0f7335edf833d51f688851e6a105de60433 atom/browser/resources/mac/Info.plist - their 100644 f752915815a454c7bd99b1c285c7438e3303261a atom/browser/resources/mac/Info.plist -@@ -17,9 +17,15 @@ - <key>CFBundleIconFile</key> - <string>electron.icns</string> - <key>CFBundleVersion</key> -+<<<<<<< .our - <string>4.0.0</string> - <key>CFBundleShortVersionString</key> - <string>4.0.0</string> -+======= -+ <string>1.6.18</string> -+ <key>CFBundleShortVersionString</key> -+ <string>1.6.18</string> -+>>>>>>> .their - <key>LSApplicationCategoryType</key> - <string>public.app-category.developer-tools</string> - <key>LSMinimumSystemVersion</key> -changed in both - base 100644 de126c8f957c96561b27cfa62212ac1d2f3ea36c atom/browser/resources/win/atom.rc - our 100644 c0bd831e8bddf10180f75cd40694831e2e98622d atom/browser/resources/win/atom.rc - their 100644 b7bed46340edf0b11522421b793d3e9b3be8c205 atom/browser/resources/win/atom.rc -@@ -56,8 +56,13 @@ - // - - VS_VERSION_INFO VERSIONINFO -+<<<<<<< .our - FILEVERSION 4,0,0,20180821 - PRODUCTVERSION 4,0,0,20180821 -+======= -+ FILEVERSION 1,6,18,0 -+ PRODUCTVERSION 1,6,18,0 -+>>>>>>> .their - FILEFLAGSMASK 0x3fL - #ifdef _DEBUG - FILEFLAGS 0x1L -@@ -74,12 +79,20 @@ - BEGIN - VALUE "CompanyName", "GitHub, Inc." - VALUE "FileDescription", "Electron" -+<<<<<<< .our - VALUE "FileVersion", "4.0.0" -+======= -+ VALUE "FileVersion", "1.6.18" -+>>>>>>> .their - VALUE "InternalName", "electron.exe" - VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." - VALUE "OriginalFilename", "electron.exe" - VALUE "ProductName", "Electron" -+<<<<<<< .our - VALUE "ProductVersion", "4.0.0" -+======= -+ VALUE "ProductVersion", "1.6.18" -+>>>>>>> .their - VALUE "SquirrelAwareVersion", "1" - END - END -changed in both - base 100644 266d10b96db9b8fb553f94027a9bc871008e5c38 atom/browser/ui/views/global_menu_bar_x11.cc - our 100644 656bd8f991f87c06a240cdc09a3bfcd500d1c1c8 atom/browser/ui/views/global_menu_bar_x11.cc - their 100644 b3f37880ce8b302c5a805e81c62d1b52df1a99c0 atom/browser/ui/views/global_menu_bar_x11.cc -@@ -159,9 +159,15 @@ - std::string GetMenuModelStatus(AtomMenuModel* model) { - std::string ret; - for (int i = 0; i < model->GetItemCount(); ++i) { -+<<<<<<< .our - int status = model->GetTypeAt(i) | (model->IsVisibleAt(i) << 3) | - (model->IsEnabledAt(i) << 4) | - (model->IsItemCheckedAt(i) << 5); -+======= -+ int status = model->GetTypeAt(i) | (model->IsVisibleAt(i) << 3) -+ | (model->IsEnabledAt(i) << 4) -+ | (model->IsItemCheckedAt(i) << 5); -+>>>>>>> .their - ret += base::StringPrintf( - "%s-%X\n", base::UTF16ToUTF8(model->GetLabelAt(i)).c_str(), status); - } -changed in both - base 100644 7bb8605039a10e0c98d75559052a3f7701f1e9c1 atom/browser/web_contents_preferences.cc - our 100644 c21c93383155091a7481cdd4e741cefad90a4a55 atom/browser/web_contents_preferences.cc - their 100644 14e82398ccf86316cf2df336a583d143475a77d2 atom/browser/web_contents_preferences.cc -@@ -334,10 +334,44 @@ - } - } - -+<<<<<<< .our - // We are appending args to a webContents so let's save the current state - // of our preferences object so that during the lifetime of the WebContents - // we can fetch the options used to initally configure the WebContents - last_preference_ = preference_.Clone(); -+======= -+ if (window) { -+ bool visible = window->IsVisible() && !window->IsMinimized(); -+ if (!visible) // Default state is visible. -+ command_line->AppendSwitch(switches::kHiddenPage); -+ } -+} -+ -+bool WebContentsPreferences::IsPreferenceEnabled( -+ const std::string& attribute_name, -+ content::WebContents* web_contents) { -+ WebContentsPreferences* self; -+ if (!web_contents) -+ return false; -+ -+ self = FromWebContents(web_contents); -+ if (!self) -+ return false; -+ -+ base::DictionaryValue& web_preferences = self->web_preferences_; -+ bool bool_value = false; -+ web_preferences.GetBoolean(attribute_name, &bool_value); -+ return bool_value; -+} -+ -+bool WebContentsPreferences::IsSandboxed(content::WebContents* web_contents) { -+ return IsPreferenceEnabled("sandbox", web_contents); -+} -+ -+bool WebContentsPreferences::IsPluginsEnabled( -+ content::WebContents* web_contents) { -+ return IsPreferenceEnabled("plugins", web_contents); -+>>>>>>> .their - } - - void WebContentsPreferences::OverrideWebkitPrefs( -changed in both - base 100644 f6e44c51b10abbd3cf3c5c8b94956347a029e521 atom/browser/web_contents_preferences.h - our 100644 d835347afcd259f473f95271a2c19e42afcc6f2b atom/browser/web_contents_preferences.h - their 100644 607b4223852c3e7cd1e58e3812285f235699d3cb atom/browser/web_contents_preferences.h -@@ -29,8 +29,27 @@ - class WebContentsPreferences - : public content::WebContentsUserData<WebContentsPreferences> { - public: -+<<<<<<< .our - // Get self from WebContents. - static WebContentsPreferences* From(content::WebContents* web_contents); -+======= -+ // Get WebContents according to process ID. -+ // FIXME(zcbenz): This method does not belong here. -+ static content::WebContents* GetWebContentsFromProcessID(int process_id); -+ -+ // Append command paramters according to |web_contents|'s preferences. -+ static void AppendExtraCommandLineSwitches( -+ content::WebContents* web_contents, base::CommandLine* command_line); -+ -+ static bool IsPreferenceEnabled(const std::string& attribute_name, -+ content::WebContents* web_contents); -+ static bool IsSandboxed(content::WebContents* web_contents); -+ static bool IsPluginsEnabled(content::WebContents* web_contents); -+ -+ // Modify the WebPreferences according to |web_contents|'s preferences. -+ static void OverrideWebkitPrefs( -+ content::WebContents* web_contents, content::WebPreferences* prefs); -+>>>>>>> .their - - WebContentsPreferences(content::WebContents* web_contents, - const mate::Dictionary& web_preferences); -changed in both - base 100644 08880ffe4a3591d9010f55ef18ce288e69101fe1 atom/common/atom_command_line.cc - our 100644 287e43f75fef778948ef9acdac8b9a7edfe07d0a atom/common/atom_command_line.cc - their 100644 54420b533a6b2600a87c95645b73bc01fbf0122f atom/common/atom_command_line.cc -changed in both - base 100644 5e7df1040f829acfc43130f307f41c3819b258c5 atom/common/atom_version.h - our 100644 65e7d19911559a40b1b258319df5fe0fa180354f atom/common/atom_version.h - their 100644 d4aefe90dd22ed5d783ab5ec42ef2b7593c47180 atom/common/atom_version.h -@@ -5,10 +5,22 @@ - #ifndef ATOM_COMMON_ATOM_VERSION_H_ - #define ATOM_COMMON_ATOM_VERSION_H_ - -+<<<<<<< .our - #define ATOM_MAJOR_VERSION 4 - #define ATOM_MINOR_VERSION 0 - #define ATOM_PATCH_VERSION 0 - #define ATOM_PRE_RELEASE_VERSION -nightly.20180821 -+======= -+#define ATOM_MAJOR_VERSION 1 -+#define ATOM_MINOR_VERSION 6 -+#define ATOM_PATCH_VERSION 18 -+ -+#define ATOM_VERSION_IS_RELEASE 1 -+ -+#ifndef ATOM_TAG -+# define ATOM_TAG "" -+#endif -+>>>>>>> .their - - #ifndef ATOM_STRINGIFY - #define ATOM_STRINGIFY(n) ATOM_STRINGIFY_HELPER(n) -changed in both - base 100644 ae757b1da88331bf904df6e2198d5aa222a4149b atom/common/node_bindings.cc - our 100644 e6aded2e661af919c2d89c2f9bd46b4921d4aec4 atom/common/node_bindings.cc - their 100644 b5f1379059e24aa6b9823d1ed011ee8907a312d5 atom/common/node_bindings.cc -@@ -228,8 +228,12 @@ - } - - node::Environment* NodeBindings::CreateEnvironment( -+<<<<<<< .our - v8::Handle<v8::Context> context, - node::MultiIsolatePlatform* platform) { -+======= -+ v8::Handle<v8::Context> context) { -+>>>>>>> .their - #if defined(OS_WIN) - auto& atom_args = AtomCommandLine::argv(); - std::vector<std::string> args(atom_args.size()); -@@ -255,8 +259,13 @@ - base::FilePath resources_path = GetResourcesPath(browser_env_ == BROWSER); - base::FilePath script_path = - resources_path.Append(FILE_PATH_LITERAL("electron.asar")) -+<<<<<<< .our - .Append(process_type) - .Append(FILE_PATH_LITERAL("init.js")); -+======= -+ .Append(process_type) -+ .Append(FILE_PATH_LITERAL("init.js")); -+>>>>>>> .their - args.insert(args.begin() + 1, script_path.AsUTF8Unsafe()); - - std::unique_ptr<const char* []> c_argv = StringVectorToArgArray(args); -changed in both - base 100644 f103b89391d3bc54d364e48c39f45e971c15dbe8 atom/renderer/api/atom_api_web_frame.cc - our 100644 f0f7ef249d73876f7107d3d3865e8fc71ee33945 atom/renderer/api/atom_api_web_frame.cc - their 100644 0bc9e6ea4e81e33b183f11222999846faacc12c6 atom/renderer/api/atom_api_web_frame.cc -@@ -282,9 +282,18 @@ - } - - void WebFrame::InsertText(const std::string& text) { -+<<<<<<< .our - web_frame_->FrameWidget()->GetActiveWebInputMethodController()->CommitText( - blink::WebString::FromUTF8(text), - blink::WebVector<blink::WebImeTextSpan>(), blink::WebRange(), 0); -+======= -+ web_frame_->frameWidget() -+ ->getActiveWebInputMethodController() -+ ->commitText(blink::WebString::fromUTF8(text), -+ blink::WebVector<blink::WebCompositionUnderline>(), -+ blink::WebRange(), -+ 0); -+>>>>>>> .their - } - - void WebFrame::InsertCSS(const std::string& css) { -changed in both - base 100644 5dafe084ce279a8b1b761d8cb7b7aa9c4469c504 atom/renderer/atom_renderer_client.cc - our 100644 204f17c2cf0d2d4ec4a71bdbecfcd1cbdc5fc8be atom/renderer/atom_renderer_client.cc - their 100644 f8744b7be8236b5bb200654aa28bb6f653d3a479 atom/renderer/atom_renderer_client.cc -changed in both - base 100644 cf537474af244ef281567dc03879ca88400340c5 docs/api/app.md - our 100644 14dc557e237404cbbd5bcebabb0e65486dc36926 docs/api/app.md - their 100644 614989dc99c609075fb7d34782cffc237b141db6 docs/api/app.md -@@ -773,6 +773,8 @@ - - Returns `Boolean` - -+Returns `Boolean`. -+ - This method makes your application a Single Instance Application - instead of - allowing multiple instances of your app to run, this will ensure that only a - single instance of your app is running, and other instances signal this -changed in both - base 100644 3b7e6f9b9bf39edf56e18c0c9bd533ecc460593e docs/api/browser-view.md - our 100644 ee1780942db5565c9c9a9e3a4139345c413e1eb9 docs/api/browser-view.md - their 100644 2779beebfab48dec68181111ed9b63ea30be9cad docs/api/browser-view.md -@@ -72,6 +72,7 @@ - ### Instance Methods - - Objects created with `new BrowserView` have the following instance methods: -+<<<<<<< .our - - #### `view.destroy()` - -@@ -82,6 +83,8 @@ - #### `view.isDestroyed()` - - Returns `Boolean` - Whether the view is destroyed. -+======= -+>>>>>>> .their - - #### `view.setAutoResize(options)` _Experimental_ - -changed in both - base 100644 8fcc3f8213d0b2c79b97d368574e5cd6f1efb273 docs/api/browser-window.md - our 100644 dff61dd336f047cf2f6f06228b2df2b98ff2304d docs/api/browser-window.md - their 100644 cf46fac8ea4ee5eb81ff74b72b6356cefa61e2be docs/api/browser-window.md -@@ -1165,7 +1165,11 @@ - * `httpReferrer` (String | [Referrer](structures/referrer.md)) (optional) - An HTTP Referrer url. - * `userAgent` String (optional) - A user agent originating the request. - * `extraHeaders` String (optional) - Extra headers separated by "\n" -+<<<<<<< .our - * `postData` ([UploadRawData[]](structures/upload-raw-data.md) | [UploadFile[]](structures/upload-file.md) | [UploadBlob[]](structures/upload-blob.md)) (optional) -+======= -+ * `postData` ([UploadRawData[]](structures/upload-raw-data.md) | [UploadFile[]](structures/upload-file.md) | [UploadFileSystem[]](structures/upload-file-system.md) | [UploadBlob[]](structures/upload-blob.md)) - (optional) -+>>>>>>> .their - * `baseURLForDataURL` String (optional) - Base url (with trailing path separator) for files to be loaded by the data url. This is needed only if the specified `url` is a data url and needs to load other files. - - Same as `webContents.loadURL(url[, options])`. -changed in both - base 100644 da496436b324dfc0ad670cd6634c6eb91664b089 docs/api/native-image.md - our 100644 d2951b5b273d3803d46b370d5652669b0349442f docs/api/native-image.md - their 100644 8163c23396250bd997c080a00ddcfc2e72a32392 docs/api/native-image.md -changed in both - base 100644 69c67f16cc82eab6bd9c9adbe8dd9a229598f5f2 docs/api/structures/memory-info.md - our 100644 fe0b7d4d7efc965c2435af3e4fe5580f5867a8f3 docs/api/structures/memory-info.md - their 100644 f6b9d17aaa19749f48d81241adc41638cb90fd67 docs/api/structures/memory-info.md -changed in both - base 100644 98b1cbd2f24196747ea01690456cabec37c5070f docs/api/web-contents.md - our 100644 8990fe2e97ab62eafdd3f7a4eb8ee782415124c5 docs/api/web-contents.md - their 100644 965c6e4df4769f7cd16cbcbe32c3e9baeca0e7ba docs/api/web-contents.md -@@ -633,8 +633,13 @@ - * `options` Object (optional) - * `httpReferrer` (String | [Referrer](structures/referrer.md)) (optional) - An HTTP Referrer url. - * `userAgent` String (optional) - A user agent originating the request. -+<<<<<<< .our - * `extraHeaders` String (optional) - Extra headers separated by "\n". - * `postData` ([UploadRawData[]](structures/upload-raw-data.md) | [UploadFile[]](structures/upload-file.md) | [UploadBlob[]](structures/upload-blob.md)) (optional) -+======= -+ * `extraHeaders` String (optional) - Extra headers separated by "\n" -+ * `postData` ([UploadRawData[]](structures/upload-raw-data.md) | [UploadFile[]](structures/upload-file.md) | [UploadFileSystem[]](structures/upload-file-system.md) | [UploadBlob[]](structures/upload-blob.md)) - (optional) -+>>>>>>> .their - * `baseURLForDataURL` String (optional) - Base url (with trailing path separator) for files to be loaded by the data url. This is needed only if the specified `url` is a data url and needs to load other files. - - Loads the `url` in the window. The `url` must contain the protocol prefix, -changed in both - base 100644 1da5679c18ad9b86fb354b934efc850b82cd99fc docs/api/webview-tag.md - our 100644 8dc16b4a4e92ad132c7722ac400e2be851723f9b docs/api/webview-tag.md - their 100644 8c5ce3ddd15567e763ccd103cfe866b9332f4d45 docs/api/webview-tag.md -@@ -266,7 +266,11 @@ - * `httpReferrer` (String | [Referrer](structures/referrer.md)) (optional) - An HTTP Referrer url. - * `userAgent` String (optional) - A user agent originating the request. - * `extraHeaders` String (optional) - Extra headers separated by "\n" -+<<<<<<< .our - * `postData` ([UploadRawData[]](structures/upload-raw-data.md) | [UploadFile[]](structures/upload-file.md) | [UploadBlob[]](structures/upload-blob.md)) (optional) -+======= -+ * `postData` ([UploadRawData[]](structures/upload-raw-data.md) | [UploadFile[]](structures/upload-file.md) | [UploadFileSystem[]](structures/upload-file-system.md) | [UploadBlob[]](structures/upload-blob.md)) - (optional) -+>>>>>>> .their - * `baseURLForDataURL` String (optional) - Base url (with trailing path separator) for files to be loaded by the data url. This is needed only if the specified `url` is a data url and needs to load other files. - - Loads the `url` in the webview, the `url` must contain the protocol prefix, -@@ -469,6 +473,7 @@ - - * `text` String - Content to be searched, must not be empty. - * `options` Object (optional) -+<<<<<<< .our - * `forward` Boolean (optional) - Whether to search forward or backward, defaults to `true`. - * `findNext` Boolean (optional) - Whether the operation is first request or a follow up, - defaults to `false`. -@@ -477,6 +482,16 @@ - * `wordStart` Boolean (optional) - Whether to look only at the start of words. - defaults to `false`. - * `medialCapitalAsWordStart` Boolean (optional) - When combined with `wordStart`, -+======= -+ * `forward` Boolean - (optional) Whether to search forward or backward, defaults to `true`. -+ * `findNext` Boolean - (optional) Whether the operation is first request or a follow up, -+ defaults to `false`. -+ * `matchCase` Boolean - (optional) Whether search should be case-sensitive, -+ defaults to `false`. -+ * `wordStart` Boolean - (optional) Whether to look only at the start of words. -+ defaults to `false`. -+ * `medialCapitalAsWordStart` Boolean - (optional) When combined with `wordStart`, -+>>>>>>> .their - accepts a match in the middle of a word if the match begins with an - uppercase letter followed by a lowercase or non-letter. - Accepts several other intra-word matches, defaults to `false`. -changed in both - base 100644 5987a5b541a4c048c88689a15fa158a65d595761 electron.gyp - our 100644 944ddab2a3fd879044e31677e4bac2843fffbdee electron.gyp - their 100644 2cf6bd03301819081502b7ea4d6b91a31a2e3e01 electron.gyp -@@ -4,7 +4,11 @@ - 'product_name%': 'Electron', - 'company_name%': 'GitHub, Inc', - 'company_abbr%': 'github', -+<<<<<<< .our - 'version%': '4.0.0-nightly.20180821', -+======= -+ 'version%': '1.6.18', -+>>>>>>> .their - 'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c', - }, - 'includes': [ -changed in both - base 100644 8408b273e660abe6dddc9f84c90adb2bff42171e filenames.gypi - our 100644 f57860558f06b7e5d8a50f48cfc7e53044df0bc6 filenames.gypi - their 100644 05103b458f292c4327162130853a6562569afece filenames.gypi -@@ -114,6 +114,11 @@ - 'atom/app/atom_main_delegate_mac.mm', - 'atom/app/command_line_args.cc', - 'atom/app/command_line_args.h', -+<<<<<<< .our -+======= -+ 'atom/app/node_main.cc', -+ 'atom/app/node_main.h', -+>>>>>>> .their - 'atom/app/uv_task_runner.cc', - 'atom/app/uv_task_runner.h', - 'atom/browser/api/atom_api_app.cc', -changed in both - base 100644 d1ca60280e9371c3c6697081079b8c97f0b66629 lib/browser/api/app.js - our 100644 66f6ae651acf10fb19b8ec068fc5280850dd3d91 lib/browser/api/app.js - their 100644 8564c1394d7e85c1a05c84e039d7467cfd95f11c lib/browser/api/app.js -@@ -78,6 +78,14 @@ - } - } - -+// end-of-life support warning. goodbye, `electron/1-6-x` ... -+console.warn( -+ 'Electron 1.6.x has reached the end of its support cycle.\n', -+ 'Developers are encouraged to upgrade their applications to a newer series.\n', -+ 'Read about newer series at https://electronjs.org/releases .\n', -+ 'Read about Electron support at https://electronjs.org/docs/tutorial/support#supported-versions .' -+) -+ - if (process.platform === 'linux') { - app.launcher = { - setBadgeCount: bindings.unityLauncherSetBadgeCount, -changed in both - base 100644 55b8372f52cf485ea5f812baed5f48296bacb962 lib/browser/api/auto-updater/auto-updater-win.js - our 100644 7fead4aabb4a8768db4e4d3bc13da4927cf3c42e lib/browser/api/auto-updater/auto-updater-win.js - their 100644 fced1258797756160d28cd1a16e0e5515d39bf5b lib/browser/api/auto-updater/auto-updater-win.js -changed in both - base 100644 4783a9dd98852f303fe50e6fd03dabdecd6d0693 lib/browser/api/auto-updater/squirrel-update-win.js - our 100644 fecf7958cd0afd54e978f011f5f87eea751faf6d lib/browser/api/auto-updater/squirrel-update-win.js - their 100644 60345f1a1abead139d280b14457e558c6467de45 lib/browser/api/auto-updater/squirrel-update-win.js -changed in both - base 100644 8d543f2d7d3003de981a3067eedecf12887c4eed lib/browser/rpc-server.js - our 100644 ff9f77321de3a4145946b67f3fe2a597f98e2510 lib/browser/rpc-server.js - their 100644 815298d3d9de8af137f8b3c7a5cf6dd47c5d66c8 lib/browser/rpc-server.js -@@ -387,12 +387,21 @@ - objectsRegistry.remove(event.sender, contextId, id) - }) - -+<<<<<<< .our - ipcMain.on('ELECTRON_BROWSER_CONTEXT_RELEASE', (event, contextId) => { - objectsRegistry.clear(event.sender, contextId) - event.returnValue = null - }) - - ipcMain.on('ELECTRON_BROWSER_GUEST_WEB_CONTENTS', function (event, contextId, guestInstanceId) { -+======= -+ipcMain.on('ELECTRON_BROWSER_CONTEXT_RELEASE', (e) => { -+ objectsRegistry.clear(e.sender.getId()) -+ e.returnValue = null -+}) -+ -+ipcMain.on('ELECTRON_BROWSER_GUEST_WEB_CONTENTS', function (event, guestInstanceId) { -+>>>>>>> .their - try { - let guestViewManager = require('./guest-view-manager') - event.returnValue = valueToMeta(event.sender, contextId, guestViewManager.getGuest(guestInstanceId)) -changed in both - base 100644 5e790133d383a5cb413030ecdee9049507960828 lib/renderer/api/remote.js - our 100644 59117f8f2dd977fc1817a6b1d540b616ddcb0dae lib/renderer/api/remote.js - their 100644 fdc95cdb5cdd66e503f605e1456a040cb7bc465c lib/renderer/api/remote.js -@@ -293,10 +293,20 @@ - callbacksRegistry.remove(id) - }) - -+<<<<<<< .our - exports.require = (module) => { - const command = 'ELECTRON_BROWSER_REQUIRE' - const meta = ipcRenderer.sendSync(command, contextId, module) - return metaToValue(meta) -+======= -+process.on('exit', () => { -+ ipcRenderer.sendSync('ELECTRON_BROWSER_CONTEXT_RELEASE') -+}) -+ -+// Get remote module. -+exports.require = function (module) { -+ return metaToValue(ipcRenderer.sendSync('ELECTRON_BROWSER_REQUIRE', module)) -+>>>>>>> .their - } - - // Alias to remote.require('electron').xxx. -added in both - our 100755 48cdef8f1988b6d3d6ab27a7adc598108c2e987d npm/cli.js - their 100755 bfe2c11be311eff92a95b576d04d08db4a29f52b npm/cli.js -@@ -8,6 +8,7 @@ - child.on('close', function (code) { - process.exit(code) - }) -+<<<<<<< .our - - const handleTerminationSignal = function (signal) { - process.on(signal, function signalHandler () { -@@ -19,3 +20,5 @@ - - handleTerminationSignal('SIGINT') - handleTerminationSignal('SIGTERM') -+======= -+>>>>>>> .their -added in both - our 100644 b33c9b493f3bbbbc47a945b0ef0d19d003ced3b6 npm/index.js - their 100644 eb480b9e01dd1cae541ebb8295ce7a766beb38a0 npm/index.js -@@ -3,6 +3,7 @@ - - var pathFile = path.join(__dirname, 'path.txt') - -+<<<<<<< .our - function getElectronPath () { - if (fs.existsSync(pathFile)) { - var executablePath = fs.readFileSync(pathFile, 'utf-8') -@@ -16,3 +17,10 @@ - } - - module.exports = getElectronPath() -+======= -+if (fs.existsSync(pathFile)) { -+ module.exports = path.join(__dirname, fs.readFileSync(pathFile, 'utf-8')) -+} else { -+ throw new Error('Electron failed to install correctly, please delete node_modules/electron and try installing again') -+} -+>>>>>>> .their -added in both - our 100755 ed208de247ef151147c58d9efc4af9519e983f86 npm/install.js - their 100755 3a93295f35db537f92c7599518ee798bf70852ed npm/install.js -@@ -1,6 +1,11 @@ - #!/usr/bin/env node - -+<<<<<<< .our - var version = require('./package').version -+======= -+// maintainer note - x.y.z-ab version in package.json -> x.y.z -+var version = require('./package').version.replace(/-.*/, '') -+>>>>>>> .their - - var fs = require('fs') - var os = require('os') -@@ -17,9 +22,13 @@ - - var platformPath = getPlatformPath() - -+<<<<<<< .our - var electronPath = process.env.ELECTRON_OVERRIDE_DIST_PATH || path.join(__dirname, 'dist', platformPath) - - if (installedVersion === version && fs.existsSync(electronPath)) { -+======= -+if (installedVersion === version && fs.existsSync(path.join(__dirname, platformPath))) { -+>>>>>>> .their - process.exit(0) - } - -@@ -31,7 +40,11 @@ - arch: process.env.npm_config_arch, - strictSSL: process.env.npm_config_strict_ssl === 'true', - force: process.env.force_no_cache === 'true', -+<<<<<<< .our - quiet: process.env.npm_config_loglevel === 'silent' || process.env.CI -+======= -+ quiet: ['info', 'verbose', 'silly', 'http'].indexOf(process.env.npm_config_loglevel) === -1 -+>>>>>>> .their - }, extractFile) - - // unzips and makes path.txt point at the correct executable -@@ -54,12 +67,21 @@ - - switch (platform) { - case 'darwin': -+<<<<<<< .our - return 'Electron.app/Contents/MacOS/Electron' - case 'freebsd': - case 'linux': - return 'electron' - case 'win32': - return 'electron.exe' -+======= -+ return 'dist/Electron.app/Contents/MacOS/Electron' -+ case 'freebsd': -+ case 'linux': -+ return 'dist/electron' -+ case 'win32': -+ return 'dist/electron.exe' -+>>>>>>> .their - default: - throw new Error('Electron builds are not available on platform: ' + platform) - } -added in both - our 100644 788f4681727fa501a87262d16ccbe6186ed74818 npm/package.json - their 100644 87935105dca77cfbb830ae4e4db76ce65d99f0e3 npm/package.json -@@ -11,8 +11,13 @@ - "main": "index.js", - "types": "electron.d.ts", - "dependencies": { -+<<<<<<< .our - "@types/node": "^8.0.24", - "electron-download": "^4.1.0", -+======= -+ "@types/node": "^7.0.18", -+ "electron-download": "^3.0.1", -+>>>>>>> .their - "extract-zip": "^1.0.3" - }, - "devDependencies": { -@@ -22,8 +27,11 @@ - }, - "directories": { - "test": "test" -+<<<<<<< .our - }, - "engines": { - "node": ">= 4.0" -+======= -+>>>>>>> .their - } - } -changed in both - base 100644 a6ab2737818e36c514576ae34ef6dc88a5b7b5e2 package.json - our 100644 c081cd89450cd50efba1ec280ff1349a96ea3ce0 package.json - their 100644 6efecd9c6aa915c7ef83f6732684d1f9d4125310 package.json -@@ -1,5 +1,6 @@ - { - "name": "electron", -+<<<<<<< .our - "version": "4.0.0-nightly.20180821", - "repository": "https://github.com/electron/electron", - "description": "Build cross platform desktop apps with JavaScript, HTML, and CSS", -@@ -31,6 +32,28 @@ - "standard-markdown": "^4.0.0", - "sumchecker": "^2.0.2", - "temp": "^0.8.3" -+======= -+ "version": "1.6.18", -+ "devDependencies": { -+ "asar": "^0.11.0", -+ "browserify": "^13.1.0", -+ "colors": "^1.1.2", -+ "dugite": "^1.57.0", -+ "electabul": "~0.0.4", -+ "electron-docs-linter": "^2.3.3", -+ "electron-typescript-definitions": "1.2.7", -+ "github": "^9.2.0", -+ "heads": "^1.3.0", -+ "minimist": "^1.2.0", -+ "nugget": "^2.0.1", -+ "request": "*", -+ "standard": "^8.4.0", -+ "standard-markdown": "^2.1.1", -+ "sumchecker": "^2.0.2" -+ }, -+ "optionalDependencies": { -+ "runas": "^3.0.0" -+>>>>>>> .their - }, - "standard": { - "ignore": [ -@@ -59,6 +82,7 @@ - "clang-format": "find atom/ brightray/ chromium_src/ -iname *.h -o -iname *.cc -o -iname *.mm | xargs clang-format -i", - "coverage": "npm run instrument-code-coverage && npm test -- --use_instrumented_asar", - "instrument-code-coverage": "electabul instrument --input-path ./lib --output-path ./out/coverage/electron.asar", -+<<<<<<< .our - "lint": "npm run lint:js && npm run lint:cpp && npm run lint:clang-format && npm run lint:py && npm run lint:docs", - "lint:js": "standard && cd spec && standard", - "lint:clang-format": "python script/run-clang-format.py -r -c atom/ chromium_src/ brightray/ || (echo \"\\nCode not formatted correctly.\" && exit 1)", -@@ -75,6 +99,17 @@ - "precommit": "python script/run-clang-format.py -r -c atom/ chromium_src/ brightray/ && npm run lint:js && remark docs -qf || (echo \"Code not formatted correctly.\" && exit 1)", - "prepack": "check-for-leaks", - "prepush": "check-for-leaks", -+======= -+ "lint": "npm run lint-js && npm run lint-cpp && npm run lint-py && npm run lint-api-docs-js && npm run lint-api-docs", -+ "lint-js": "standard && cd spec && standard", -+ "lint-cpp": "python ./script/cpplint.py", -+ "lint-py": "python ./script/pylint.py", -+ "lint-api-docs-js": "standard-markdown docs && standard-markdown docs-translations", -+ "lint-api-docs": "electron-docs-linter", -+ "create-api-json": "electron-docs-linter docs --outfile=out/electron-api.json --version=$npm_package_version", -+ "create-typescript-definitions": "npm run create-api-json && electron-typescript-definitions --in=out/electron-api.json --out=out/electron.d.ts", -+ "preinstall": "node -e 'process.exit(0)'", -+>>>>>>> .their - "prepare-release": "node ./script/prepare-release.js", - "prerelease": "python ./script/bootstrap.py -v --dev && npm run build", - "release": "node ./script/release.js", -changed in both - base 100755 4db30b71fca9996003fe44a71fa9d81499677bd2 script/bump-version.py - our 100755 564adb2116312b0f6d0351096bd89cb373cd3bab script/bump-version.py - their 100755 f7a78a6da63c56eeed78edd7b81362a35bcfea0b script/bump-version.py -@@ -103,10 +103,14 @@ - update_package_json(version, suffix) - tag_version(version, suffix) - -+<<<<<<< .our - print 'Bumped to version: {0}'.format(version + suffix) - - def not_reached(): - raise Exception('Unreachable code was reached') -+======= -+ print 'Bumped to version: {0}'.format(version) -+>>>>>>> .their - - def increase_version(versions, index): - for i in range(index + 1, 4): -added in both - our 100644 be9f9597387f5f8b7bfddc61c202f32ce4c6d478 script/ci-release-build.js - their 100644 0335f1b0afd118d6166cf2a963633d3924cdf385 script/ci-release-build.js -@@ -1,3 +1,4 @@ -+<<<<<<< .our - require('dotenv-safe').load() - - const assert = require('assert') -@@ -21,6 +22,22 @@ - const vstsJobs = [ - 'electron-release-mas-x64', - 'electron-release-osx-x64' -+======= -+const assert = require('assert') -+const request = require('request') -+const buildAppVeyorURL = 'https://windows-ci.electronjs.org/api/builds' -+const jenkinsServer = 'https://mac-ci.electronjs.org' -+ -+const circleCIJobs = [ -+ 'electron-linux-arm', -+ 'electron-linux-ia32', -+ 'electron-linux-x64' -+] -+ -+const jenkinsJobs = [ -+ 'electron-mas-x64-release', -+ 'electron-osx-x64-release' -+>>>>>>> .their - ] - - async function makeRequest (requestOptions, parseResponse) { -@@ -34,6 +51,7 @@ - resolve(body) - } - } else { -+<<<<<<< .our - console.error('Error occurred while requesting:', requestOptions.url) - if (parseResponse) { - try { -@@ -41,6 +59,10 @@ - } catch (err) { - console.log('Error: ', `(status ${res.statusCode})`, err || res.body, requestOptions) - } -+======= -+ if (parseResponse) { -+ console.log('Error: ', `(status ${res.statusCode})`, err || JSON.parse(res.body), requestOptions) -+>>>>>>> .their - } else { - console.log('Error: ', `(status ${res.statusCode})`, err || res.body, requestOptions) - } -@@ -50,7 +72,12 @@ - }) - } - -+<<<<<<< .our - async function circleCIcall (buildUrl, targetBranch, job, options) { -+======= -+async function circleCIcall (buildUrl, targetBranch, job, ghRelease) { -+ assert(process.env.CIRCLE_TOKEN, 'CIRCLE_TOKEN not found in environment') -+>>>>>>> .their - console.log(`Triggering CircleCI to run build job: ${job} on branch: ${targetBranch} with release flag.`) - let buildRequest = { - 'build_parameters': { -@@ -58,16 +85,23 @@ - } - } - -+<<<<<<< .our - if (options.ghRelease) { -+======= -+ if (ghRelease) { -+>>>>>>> .their - buildRequest.build_parameters.ELECTRON_RELEASE = 1 - } else { - buildRequest.build_parameters.RUN_RELEASE_BUILD = 'true' - } - -+<<<<<<< .our - if (options.automaticRelease) { - buildRequest.build_parameters.AUTO_RELEASE = 'true' - } - -+======= -+>>>>>>> .their - let circleResponse = await makeRequest({ - method: 'POST', - url: buildUrl, -@@ -79,6 +113,7 @@ - }, true).catch(err => { - console.log('Error calling CircleCI:', err) - }) -+<<<<<<< .our - console.log(`CircleCI release build request for ${job} successful. Check ${circleResponse.build_url} for status.`) - } - -@@ -97,15 +132,29 @@ - let environmentVariables = {} - - if (options.ghRelease) { -+======= -+ console.log(`Check ${circleResponse.build_url} for status. (${job})`) -+} -+ -+async function buildAppVeyor (targetBranch, ghRelease) { -+ console.log(`Triggering AppVeyor to run build on branch: ${targetBranch} with release flag.`) -+ assert(process.env.APPVEYOR_TOKEN, 'APPVEYOR_TOKEN not found in environment') -+ let environmentVariables = {} -+ -+ if (ghRelease) { -+>>>>>>> .their - environmentVariables.ELECTRON_RELEASE = 1 - } else { - environmentVariables.RUN_RELEASE_BUILD = 'true' - } - -+<<<<<<< .our - if (options.automaticRelease) { - environmentVariables.AUTO_RELEASE = 'true' - } - -+======= -+>>>>>>> .their - const requestOpts = { - url: buildAppVeyorURL, - auth: { -@@ -116,7 +165,11 @@ - }, - body: JSON.stringify({ - accountName: 'AppVeyor', -+<<<<<<< .our - projectSlug: appVeyorJobs[job], -+======= -+ projectSlug: 'electron', -+>>>>>>> .their - branch: targetBranch, - environmentVariables - }), -@@ -125,6 +178,7 @@ - let appVeyorResponse = await makeRequest(requestOpts, true).catch(err => { - console.log('Error calling AppVeyor:', err) - }) -+<<<<<<< .our - const buildUrl = `https://windows-ci.electronjs.org/project/AppVeyor/${appVeyorJobs[job]}/build/${appVeyorResponse.version}` - console.log(`AppVeyor release build request for ${job} successful. Check build status at ${buildUrl}`) - } -@@ -200,12 +254,89 @@ - console.log(`Error calling VSTS for job ${build.name}`, err) - }) - console.log(`VSTS release build request for ${build.name} successful. Check ${vstsResponse._links.web.href} for status.`) -+======= -+ const buildUrl = `https://windows-ci.electronjs.org/project/AppVeyor/electron/build/${appVeyorResponse.version}` -+ console.log(`AppVeyor release build request successful. Check build status at ${buildUrl}`) -+} -+ -+function buildCircleCI (targetBranch, ghRelease, job) { -+ const circleBuildUrl = `https://circleci.com/api/v1.1/project/github/electron/electron/tree/${targetBranch}?circle-token=${process.env.CIRCLE_TOKEN}` -+ if (job) { -+ assert(circleCIJobs.includes(job), `Unknown CI job name: ${job}.`) -+ circleCIcall(circleBuildUrl, targetBranch, job, ghRelease) -+ } else { -+ circleCIJobs.forEach((job) => circleCIcall(circleBuildUrl, targetBranch, job, ghRelease)) -+ } -+} -+ -+async function buildJenkins (targetBranch, ghRelease, job) { -+ assert(process.env.JENKINS_AUTH_TOKEN, 'JENKINS_AUTH_TOKEN not found in environment') -+ assert(process.env.JENKINS_BUILD_TOKEN, 'JENKINS_BUILD_TOKEN not found in environment') -+ let jenkinsCrumb = await getJenkinsCrumb() -+ -+ if (job) { -+ assert(jenkinsJobs.includes(job), `Unknown CI job name: ${job}.`) -+ callJenkinsBuild(job, jenkinsCrumb, targetBranch, ghRelease) -+ } else { -+ jenkinsJobs.forEach((job) => { -+ callJenkinsBuild(job, jenkinsCrumb, targetBranch, ghRelease) -+ }) -+ } -+} -+ -+async function callJenkins (path, requestParameters, requestHeaders) { -+ let requestOptions = { -+ url: `${jenkinsServer}/${path}`, -+ auth: { -+ user: 'build', -+ pass: process.env.JENKINS_AUTH_TOKEN -+ }, -+ qs: requestParameters -+ } -+ if (requestHeaders) { -+ requestOptions.headers = requestHeaders -+ } -+ let jenkinsResponse = await makeRequest(requestOptions).catch(err => { -+ console.log(`Error calling Jenkins:`, err) -+ }) -+ return jenkinsResponse -+} -+ -+async function callJenkinsBuild (job, jenkinsCrumb, targetBranch, ghRelease) { -+ console.log(`Triggering Jenkins to run build job: ${job} on branch: ${targetBranch} with release flag.`) -+ let jenkinsParams = { -+ token: process.env.JENKINS_BUILD_TOKEN, -+ BRANCH: targetBranch -+ } -+ if (!ghRelease) { -+ jenkinsParams.RUN_RELEASE_BUILD = 1 -+ } -+ await callJenkins(`job/${job}/buildWithParameters`, jenkinsParams, jenkinsCrumb) -+ .catch(err => { -+ console.log(`Error calling Jenkins build`, err) -+ }) -+ let buildUrl = `${jenkinsServer}/job/${job}/lastBuild/` -+ console.log(`Jenkins build request successful. Check build status at ${buildUrl}.`) -+} -+ -+async function getJenkinsCrumb () { -+ let crumbResponse = await callJenkins('crumbIssuer/api/xml', { -+ xpath: 'concat(//crumbRequestField,":",//crumb)' -+ }).catch(err => { -+ console.log(`Error getting jenkins crumb:`, err) -+ }) -+ let crumbDetails = crumbResponse.split(':') -+ let crumbHeader = {} -+ crumbHeader[crumbDetails[0]] = crumbDetails[1] -+ return crumbHeader -+>>>>>>> .their - } - - function runRelease (targetBranch, options) { - if (options.ci) { - switch (options.ci) { - case 'CircleCI': { -+<<<<<<< .our - buildCircleCI(targetBranch, options) - break - } -@@ -226,12 +357,31 @@ - buildCircleCI(targetBranch, options) - buildAppVeyor(targetBranch, options) - buildVSTS(targetBranch, options) -+======= -+ buildCircleCI(targetBranch, options.ghRelease, options.job) -+ break -+ } -+ case 'AppVeyor': { -+ buildAppVeyor(targetBranch, options.ghRelease) -+ break -+ } -+ case 'Jenkins': { -+ buildJenkins(targetBranch, options.ghRelease, options.job) -+ break -+ } -+ } -+ } else { -+ buildCircleCI(targetBranch, options.ghRelease, options.job) -+ buildAppVeyor(targetBranch, options.ghRelease) -+ buildJenkins(targetBranch, options.ghRelease, options.job) -+>>>>>>> .their - } - } - - module.exports = runRelease - - if (require.main === module) { -+<<<<<<< .our - const args = require('minimist')(process.argv.slice(2), { - boolean: ['ghRelease', 'automaticRelease'] - }) -@@ -239,6 +389,13 @@ - if (args._.length < 1) { - console.log(`Trigger CI to build release builds of electron. - Usage: ci-release-build.js [--job=CI_JOB_NAME] [--ci=CircleCI|AppVeyor|VSTS] [--ghRelease] [--automaticRelease] TARGET_BRANCH -+======= -+ const args = require('minimist')(process.argv.slice(2)) -+ const targetBranch = args._[0] -+ if (args._.length < 1) { -+ console.log(`Trigger CI to build release builds of electron. -+ Usage: ci-release-build.js [--job=CI_JOB_NAME] [--ci=CircleCI|AppVeyor|Jenkins] [--ghRelease] TARGET_BRANCH -+>>>>>>> .their - `) - process.exit(0) - } -changed in both - base 100755 f523fa1af5fa2aea22381d5eb443b7e9c51ffea3 script/cibuild - our 100755 758dc2c794e642430ab6a0d966e7a41863be947c script/cibuild - their 100755 7d7bdb5a65114e6f38db35f8e060c4385b52564a script/cibuild -@@ -57,6 +57,18 @@ - if os.environ.has_key('TARGET_ARCH'): - target_arch = os.environ['TARGET_ARCH'] - -+<<<<<<< .our -+======= -+ is_travis = (os.getenv('TRAVIS') == 'true') -+ if is_travis and PLATFORM == 'linux': -+ print 'Setup travis CI' -+ execute(['sudo', 'apt-get', 'update']) -+ deps = LINUX_DEPS -+ if target_arch == 'arm': -+ deps += LINUX_DEPS_ARM -+ execute(['sudo', 'apt-get', 'install'] + deps) -+ -+>>>>>>> .their - if PLATFORM == 'linux' and target_arch == 'x64': - os.environ['DISPLAY'] = ':99.0' - execute(['sh', '-e', '/etc/init.d/xvfb', 'start']) -@@ -72,8 +84,13 @@ - os.environ['PATH'] = os.path.pathsep.join([node_bin_dir, - os.environ.get('PATH', '')]) - -+<<<<<<< .our - is_release = os.environ.get('ELECTRON_RELEASE', '') == '1' - args = ['--target_arch=' + target_arch] -+======= -+ is_release = os.environ.has_key('ELECTRON_RELEASE') -+ args = ['--target_arch=' + target_arch, '-v'] -+>>>>>>> .their - if not is_release: - args += ['--dev'] - run_script('bootstrap.py', args) -changed in both - base 100644 5818571089ff51c8090fc58a598f56f075c2809b script/lib/config.py - our 100644 9ad0fbc680e5ecdeb8c13d0f0d6678bbba7d9031 script/lib/config.py - their 100644 bab9dc213c39421e643bf31d286bc4f787df8d4a script/lib/config.py -@@ -13,6 +13,11 @@ - - BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ - 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' -+<<<<<<< .our -+======= -+LIBCHROMIUMCONTENT_COMMIT = os.getenv('LIBCHROMIUMCONTENT_COMMIT') or \ -+ '19ca886975716c02d6de9fd41b8297a4e1774be2' -+>>>>>>> .their - - PLATFORM = { - 'cygwin': 'win32', -added in remote - their 100755 0c776e03d65f01bdaa9a7faaf810d130f586ed08 script/merge-release.js -@@ -0,0 +1,116 @@ -+#!/usr/bin/env node -+ -+require('colors') -+const assert = require('assert') -+const branchToRelease = process.argv[2] -+const fail = '\u2717'.red -+const { GitProcess, GitError } = require('dugite') -+const pass = '\u2713'.green -+const path = require('path') -+const pkg = require('../package.json') -+ -+assert(process.env.ELECTRON_GITHUB_TOKEN, 'ELECTRON_GITHUB_TOKEN not found in environment') -+if (!branchToRelease) { -+ console.log(`Usage: merge-release branch`) -+ process.exit(1) -+} -+const gitDir = path.resolve(__dirname, '..') -+ -+async function callGit (args, errorMessage, successMessage) { -+ let gitResult = await GitProcess.exec(args, gitDir) -+ if (gitResult.exitCode === 0) { -+ console.log(`${pass} ${successMessage}`) -+ return true -+ } else { -+ console.log(`${fail} ${errorMessage} ${gitResult.stderr}`) -+ process.exit(1) -+ } -+} -+ -+async function checkoutBranch (branchName) { -+ console.log(`Checking out ${branchName}.`) -+ let errorMessage = `Error checking out branch ${branchName}:` -+ let successMessage = `Successfully checked out branch ${branchName}.` -+ return callGit(['checkout', branchName], errorMessage, successMessage) -+} -+ -+async function commitMerge () { -+ console.log(`Committing the merge for v${pkg.version}`) -+ let errorMessage = `Error committing merge:` -+ let successMessage = `Successfully committed the merge for v${pkg.version}` -+ let gitArgs = ['commit', '-m', `v${pkg.version}`] -+ return callGit(gitArgs, errorMessage, successMessage) -+} -+ -+async function mergeReleaseIntoBranch (branchName) { -+ console.log(`Merging release branch into ${branchName}.`) -+ let mergeArgs = ['merge', 'release-1-6-x', '--squash'] -+ let mergeDetails = await GitProcess.exec(mergeArgs, gitDir) -+ if (mergeDetails.exitCode === 0) { -+ return true -+ } else { -+ const error = GitProcess.parseError(mergeDetails.stderr) -+ if (error === GitError.MergeConflicts) { -+ console.log(`${fail} Could not merge release branch into ${branchName} ` + -+ `due to merge conflicts.`) -+ return false -+ } else { -+ console.log(`${fail} Could not merge release branch into ${branchName} ` + -+ `due to an error: ${mergeDetails.stderr}.`) -+ process.exit(1) -+ } -+ } -+} -+ -+async function pushBranch (branchName) { -+ console.log(`Pushing branch ${branchName}.`) -+ let pushArgs = ['push', 'origin', branchName] -+ let errorMessage = `Could not push branch ${branchName} due to an error:` -+ let successMessage = `Successfully pushed branch ${branchName}.` -+ return callGit(pushArgs, errorMessage, successMessage) -+} -+ -+async function pull () { -+ console.log(`Performing a git pull`) -+ let errorMessage = `Could not pull due to an error:` -+ let successMessage = `Successfully performed a git pull` -+ return callGit(['pull'], errorMessage, successMessage) -+} -+ -+async function rebase (targetBranch) { -+ console.log(`Rebasing release branch from ${targetBranch}`) -+ let errorMessage = `Could not rebase due to an error:` -+ let successMessage = `Successfully rebased release branch from ` + -+ `${targetBranch}` -+ return callGit(['rebase', targetBranch], errorMessage, successMessage) -+} -+ -+async function mergeRelease () { -+ await checkoutBranch(branchToRelease) -+ let mergeSuccess = await mergeReleaseIntoBranch(branchToRelease) -+ if (mergeSuccess) { -+ console.log(`${pass} Successfully merged release branch into ` + -+ `${branchToRelease}.`) -+ await commitMerge() -+ let pushSuccess = await pushBranch(branchToRelease) -+ if (pushSuccess) { -+ console.log(`${pass} Success!!! ${branchToRelease} now has the latest release!`) -+ } -+ } else { -+ console.log(`Trying rebase of ${branchToRelease} into release branch.`) -+ await pull() -+ await checkoutBranch('release-1-6-x') -+ let rebaseResult = await rebase(branchToRelease) -+ if (rebaseResult) { -+ let pushResult = pushBranch('HEAD') -+ if (pushResult) { -+ console.log(`Rebase of ${branchToRelease} into release branch was ` + -+ `successful. Let release builds run and then try this step again.`) -+ } -+ // Exit as failure so release doesn't continue -+ process.exit(1) -+ } -+ } -+} -+ -+mergeRelease() -added in both - our 100755 72a28b719bf1ff7770692caef86c76746c4d8edf script/prepare-release.js - their 100755 21d924c32105a12115d653c359e3c2df8a4cca69 script/prepare-release.js -@@ -1,5 +1,6 @@ - #!/usr/bin/env node - -+<<<<<<< .our - if (!process.env.CI) require('dotenv-safe').load() - require('colors') - const args = require('minimist')(process.argv.slice(2), { -@@ -9,20 +10,40 @@ - const { execSync } = require('child_process') - const fail = '\u2717'.red - const { GitProcess } = require('dugite') -+======= -+require('colors') -+const args = require('minimist')(process.argv.slice(2)) -+const assert = require('assert') -+const ciReleaseBuild = require('./ci-release-build') -+const { execSync } = require('child_process') -+const fail = '\u2717'.red -+const { GitProcess, GitError } = require('dugite') -+>>>>>>> .their - const GitHub = require('github') - const pass = '\u2713'.green - const path = require('path') - const pkg = require('../package.json') -+<<<<<<< .our - const readline = require('readline') - const versionType = args._[0] - const targetRepo = versionType === 'nightly' ? 'nightlies' : 'electron' -+======= -+const versionType = args._[0] -+>>>>>>> .their - - // TODO (future) automatically determine version based on conventional commits - // via conventional-recommended-bump - -+<<<<<<< .our - if (!versionType && !args.notesOnly) { - console.log(`Usage: prepare-release versionType [stable | beta | nightly]` + - ` (--stable) (--notesOnly) (--automaticRelease) (--branch)`) -+======= -+assert(process.env.ELECTRON_GITHUB_TOKEN, 'ELECTRON_GITHUB_TOKEN not found in environment') -+if (!versionType && !args.notesOnly) { -+ console.log(`Usage: prepare-release versionType [major | minor | patch ]` + -+ ` (--notesOnly)`) -+>>>>>>> .their - process.exit(1) - } - -@@ -30,6 +51,7 @@ - const gitDir = path.resolve(__dirname, '..') - github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN}) - -+<<<<<<< .our - async function getNewVersion (dryRun) { - if (!dryRun) { - console.log(`Bumping for new "${versionType}" version.`) -@@ -42,10 +64,38 @@ - if (dryRun) { - scriptArgs.push('--dry-run') - } -+======= -+async function createReleaseBranch () { -+ console.log(`Creating release branch.`) -+ let checkoutDetails = await GitProcess.exec([ 'checkout', '-b', 'release-1-6-x' ], gitDir) -+ if (checkoutDetails.exitCode === 0) { -+ console.log(`${pass} Successfully created the release branch.`) -+ } else { -+ const error = GitProcess.parseError(checkoutDetails.stderr) -+ if (error === GitError.BranchAlreadyExists) { -+ console.log(`${fail} Release branch already exists, aborting prepare ` + -+ `release process.`) -+ } else { -+ console.log(`${fail} Error creating release branch: ` + -+ `${checkoutDetails.stderr}`) -+ } -+ process.exit(1) -+ } -+} -+ -+function getNewVersion () { -+ console.log(`Bumping for new "${versionType}" version.`) -+ let bumpScript = path.join(__dirname, 'bump-version.py') -+ let scriptArgs = [bumpScript, `${versionType}`] -+ if (args.stable) { -+ scriptArgs.push('--stable') -+ } -+>>>>>>> .their - try { - let bumpVersion = execSync(scriptArgs.join(' '), {encoding: 'UTF-8'}) - bumpVersion = bumpVersion.substr(bumpVersion.indexOf(':') + 1).trim() - let newVersion = `v${bumpVersion}` -+<<<<<<< .our - if (!dryRun) { - console.log(`${pass} Successfully bumped version to ${newVersion}`) - } -@@ -53,6 +103,12 @@ - } catch (err) { - console.log(`${fail} Could not bump version, error was:`, err) - throw err -+======= -+ console.log(`${pass} Successfully bumped version to ${newVersion}`) -+ return newVersion -+ } catch (err) { -+ console.log(`${fail} Could not bump version, error was:`, err) -+>>>>>>> .their - } - } - -@@ -74,6 +130,7 @@ - } - - async function getReleaseNotes (currentBranch) { -+<<<<<<< .our - if (versionType === 'nightly') { - return 'Nightlies do not get release notes, please compare tags for info' - } -@@ -94,10 +151,25 @@ - let commitComparison = await github.repos.compareCommits(githubOpts) - .catch(err => { - console.log(`${fail} Error checking for commits from ${pkg.version} to ` + -+======= -+ console.log(`Generating release notes for ${currentBranch}.`) -+ let githubOpts = { -+ owner: 'electron', -+ repo: 'electron', -+ base: `v${pkg.version}`, -+ head: currentBranch -+ } -+ let releaseNotes = '(placeholder)\n' -+ console.log(`Checking for commits from ${pkg.version} to ${currentBranch}`) -+ let commitComparison = await github.repos.compareCommits(githubOpts) -+ .catch(err => { -+ console.log(`{$fail} Error checking for commits from ${pkg.version} to ` + -+>>>>>>> .their - `${currentBranch}`, err) - process.exit(1) - }) - -+<<<<<<< .our - if (commitComparison.data.commits.length === 0) { - console.log(`${pass} There are no commits from ${pkg.version} to ` + - `${currentBranch}, skipping release.`) -@@ -137,16 +209,32 @@ - } - }) - console.log(`${pass} Done generating release notes for ${currentBranch}. Found ${prCount} PRs.`) -+======= -+ commitComparison.data.commits.forEach(commitEntry => { -+ let commitMessage = commitEntry.commit.message -+ if (commitMessage.toLowerCase().indexOf('merge') > -1) { -+ releaseNotes += `${commitMessage} \n` -+ } -+ }) -+ console.log(`${pass} Done generating release notes for ${currentBranch}.`) -+>>>>>>> .their - return releaseNotes - } - - async function createRelease (branchToTarget, isBeta) { - let releaseNotes = await getReleaseNotes(branchToTarget) -+<<<<<<< .our - let newVersion = await getNewVersion() - await tagRelease(newVersion) - const githubOpts = { - owner: 'electron', - repo: targetRepo -+======= -+ let newVersion = getNewVersion() -+ const githubOpts = { -+ owner: 'electron', -+ repo: 'electron' -+>>>>>>> .their - } - console.log(`Checking for existing draft release.`) - let releases = await github.repos.getReleases(githubOpts) -@@ -161,6 +249,7 @@ - process.exit(1) - } - console.log(`${pass} A draft release does not exist; creating one.`) -+<<<<<<< .our - githubOpts.draft = true - githubOpts.name = `electron ${newVersion}` - if (isBeta) { -@@ -182,6 +271,21 @@ - } - githubOpts.tag_name = newVersion - githubOpts.target_commitish = newVersion.indexOf('nightly') !== -1 ? 'master' : branchToTarget -+======= -+ githubOpts.body = releaseNotes -+ githubOpts.draft = true -+ githubOpts.name = `electron ${newVersion}` -+ if (isBeta) { -+ githubOpts.body = `Note: This is a beta release. Please file new issues ` + -+ `for any bugs you find in it.\n \n This release is published to npm ` + -+ `under the beta tag and can be installed via npm install electron@beta, ` + -+ `or npm i electron@${newVersion.substr(1)}.` -+ githubOpts.name = `${githubOpts.name}` -+ githubOpts.prerelease = true -+ } -+ githubOpts.tag_name = newVersion -+ githubOpts.target_commitish = branchToTarget -+>>>>>>> .their - await github.repos.createRelease(githubOpts) - .catch(err => { - console.log(`${fail} Error creating new release: `, err) -@@ -190,6 +294,7 @@ - console.log(`${pass} Draft release for ${newVersion} has been created.`) - } - -+<<<<<<< .our - async function pushRelease (branch) { - let pushDetails = await GitProcess.exec(['push', 'origin', `HEAD:${branch}`, '--follow-tags'], gitDir) - if (pushDetails.exitCode === 0) { -@@ -197,11 +302,21 @@ - `release builds to finish before running "npm run release".`) - } else { - console.log(`${fail} Error pushing the release: ` + -+======= -+async function pushRelease () { -+ let pushDetails = await GitProcess.exec(['push', 'origin', 'HEAD'], gitDir) -+ if (pushDetails.exitCode === 0) { -+ console.log(`${pass} Successfully pushed the release branch. Wait for ` + -+ `release builds to finish before running "npm run release".`) -+ } else { -+ console.log(`${fail} Error pushing the release branch: ` + -+>>>>>>> .their - `${pushDetails.stderr}`) - process.exit(1) - } - } - -+<<<<<<< .our - async function runReleaseBuilds (branch) { - await ciReleaseBuild(branch, { - ghRelease: true, -@@ -278,6 +393,24 @@ - process.exit(1) - } - } -+======= -+async function runReleaseBuilds () { -+ await ciReleaseBuild('release-1-6-x', { -+ ghRelease: true -+ }) -+} -+ -+async function prepareRelease (isBeta, notesOnly) { -+ let currentBranch = await getCurrentBranch(gitDir) -+ if (notesOnly) { -+ let releaseNotes = await getReleaseNotes(currentBranch) -+ console.log(`Draft release notes are: ${releaseNotes}`) -+ } else { -+ await createReleaseBranch() -+ await createRelease(currentBranch, isBeta) -+ await pushRelease() -+ await runReleaseBuilds() -+>>>>>>> .their - } - } - -added in remote - their 100755 78b63933009cf47cc50130dabaa8fe6f5f73b30f script/prerelease.js -@@ -0,0 +1,112 @@ -+#!/usr/bin/env node -+ -+require('colors') -+const assert = require('assert') -+const GitHub = require('github') -+const heads = require('heads') -+const pkg = require('../package.json') -+const pass = '\u2713'.green -+const fail = '\u2717'.red -+let failureCount = 0 -+ -+assert(process.env.ELECTRON_GITHUB_TOKEN, 'ELECTRON_GITHUB_TOKEN not found in environment') -+ -+const github = new GitHub() -+github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN}) -+github.repos.getReleases({owner: 'electron', repo: 'electron'}) -+ .then(res => { -+ const releases = res.data -+ const drafts = releases -+ .filter(release => release.draft) // comment out for testing -+ // .filter(release => release.tag_name === 'v1.7.5') // uncomment for testing -+ -+ check(drafts.length === 1, 'one draft exists', true) -+ const draft = drafts[0] -+ -+ check(draft.tag_name === `v${pkg.version}`, `draft release version matches local package.json (v${pkg.version})`) -+ check(draft.prerelease, 'draft is a prerelease') -+ check(draft.body.length > 50 && !draft.body.includes('(placeholder)'), 'draft has release notes') -+ -+ const requiredAssets = assetsForVersion(draft.tag_name).sort() -+ const extantAssets = draft.assets.map(asset => asset.name).sort() -+ -+ requiredAssets.forEach(asset => { -+ check(extantAssets.includes(asset), asset) -+ }) -+ -+ const s3Urls = s3UrlsForVersion(draft.tag_name) -+ heads(s3Urls) -+ .then(results => { -+ results.forEach((result, i) => { -+ check(result === 200, s3Urls[i]) -+ }) -+ -+ process.exit(failureCount > 0 ? 1 : 0) -+ }) -+ .catch(err => { -+ console.error('Error making HEAD requests for S3 assets') -+ console.error(err) -+ process.exit(1) -+ }) -+ }) -+ -+function check (condition, statement, exitIfFail = false) { -+ if (condition) { -+ console.log(`${pass} ${statement}`) -+ } else { -+ failureCount++ -+ console.log(`${fail} ${statement}`) -+ if (exitIfFail) process.exit(1) -+ } -+} -+ -+function assetsForVersion (version) { -+ const patterns = [ -+ 'electron-{{VERSION}}-darwin-x64-dsym.zip', -+ 'electron-{{VERSION}}-darwin-x64-symbols.zip', -+ 'electron-{{VERSION}}-darwin-x64.zip', -+ 'electron-{{VERSION}}-linux-arm-symbols.zip', -+ 'electron-{{VERSION}}-linux-arm.zip', -+ 'electron-{{VERSION}}-linux-armv7l-symbols.zip', -+ 'electron-{{VERSION}}-linux-armv7l.zip', -+ 'electron-{{VERSION}}-linux-ia32-symbols.zip', -+ 'electron-{{VERSION}}-linux-ia32.zip', -+ 'electron-{{VERSION}}-linux-x64-symbols.zip', -+ 'electron-{{VERSION}}-linux-x64.zip', -+ 'electron-{{VERSION}}-mas-x64-dsym.zip', -+ 'electron-{{VERSION}}-mas-x64-symbols.zip', -+ 'electron-{{VERSION}}-mas-x64.zip', -+ 'electron-{{VERSION}}-win32-ia32-pdb.zip', -+ 'electron-{{VERSION}}-win32-ia32-symbols.zip', -+ 'electron-{{VERSION}}-win32-ia32.zip', -+ 'electron-{{VERSION}}-win32-x64-pdb.zip', -+ 'electron-{{VERSION}}-win32-x64-symbols.zip', -+ 'electron-{{VERSION}}-win32-x64.zip', -+ 'electron-api.json', -+ 'electron.d.ts', -+ 'ffmpeg-{{VERSION}}-darwin-x64.zip', -+ 'ffmpeg-{{VERSION}}-linux-arm.zip', -+ 'ffmpeg-{{VERSION}}-linux-armv7l.zip', -+ 'ffmpeg-{{VERSION}}-linux-ia32.zip', -+ 'ffmpeg-{{VERSION}}-linux-x64.zip', -+ 'ffmpeg-{{VERSION}}-mas-x64.zip', -+ 'ffmpeg-{{VERSION}}-win32-ia32.zip', -+ 'ffmpeg-{{VERSION}}-win32-x64.zip' -+ ] -+ return patterns.map(pattern => pattern.replace(/{{VERSION}}/g, version)) -+} -+ -+function s3UrlsForVersion (version) { -+ const bucket = 'https://gh-contractor-zcbenz.s3.amazonaws.com/' -+ const patterns = [ -+ 'atom-shell/dist/{{VERSION}}/iojs-{{VERSION}}-headers.tar.gz', -+ 'atom-shell/dist/{{VERSION}}/iojs-{{VERSION}}.tar.gz', -+ 'atom-shell/dist/{{VERSION}}/node-{{VERSION}}.tar.gz', -+ 'atom-shell/dist/{{VERSION}}/node.lib', -+ 'atom-shell/dist/{{VERSION}}/win-x64/iojs.lib', -+ 'atom-shell/dist/{{VERSION}}/win-x86/iojs.lib', -+ 'atom-shell/dist/{{VERSION}}/x64/node.lib', -+ 'atom-shell/dist/index.json' -+ ] -+ return patterns.map(pattern => bucket + pattern.replace(/{{VERSION}}/g, version)) -+} -added in both - our 100644 27290c513bb28d9bd394575d833f1e6786e3b479 script/publish-to-npm.js - their 100644 21960455cfe96fa3a6ba7802747666772febf9ea script/publish-to-npm.js -@@ -3,6 +3,7 @@ - const path = require('path') - const childProcess = require('child_process') - const GitHubApi = require('github') -+<<<<<<< .our - const {GitProcess} = require('dugite') - const request = require('request') - const rootPackageJson = require('../package.json') -@@ -12,6 +13,12 @@ - process.exit(1) - } - -+======= -+const request = require('request') -+const assert = require('assert') -+const rootPackageJson = require('../package.json') -+ -+>>>>>>> .their - const github = new GitHubApi({ - // debug: true, - headers: { 'User-Agent': 'electron-npm-publisher' }, -@@ -26,8 +33,12 @@ - 'index.js', - 'install.js', - 'package.json', -+<<<<<<< .our - 'README.md', - 'LICENSE' -+======= -+ 'README.md' -+>>>>>>> .their - ] - - const jsonFields = [ -@@ -55,10 +66,16 @@ - tempDir = dirPath - // copy files from `/npm` to temp directory - files.forEach((name) => { -+<<<<<<< .our - const noThirdSegment = name === 'README.md' || name === 'LICENSE' - fs.writeFileSync( - path.join(tempDir, name), - fs.readFileSync(path.join(__dirname, '..', noThirdSegment ? '' : 'npm', name)) -+======= -+ fs.writeFileSync( -+ path.join(tempDir, name), -+ fs.readFileSync(path.join(__dirname, '..', name === 'README.md' ? '' : 'npm', name)) -+>>>>>>> .their - ) - }) - // copy from root package.json to temp/package.json -@@ -73,7 +90,11 @@ - - return github.repos.getReleases({ - owner: 'electron', -+<<<<<<< .our - repo: rootPackageJson.version.indexOf('nightly') > 0 ? 'nightlies' : 'electron' -+======= -+ repo: 'electron' -+>>>>>>> .their - }) - }) - .then((releases) => { -@@ -108,6 +129,7 @@ - }) - }) - }) -+<<<<<<< .our - .then(async (release) => { - if (release.tag_name.indexOf('nightly') > 0) { - const currentBranch = await getCurrentBranch() -@@ -119,6 +141,10 @@ - } else { - npmTag = release.prerelease ? 'beta' : 'latest' - } -+======= -+.then((release) => { -+ npmTag = release.prerelease ? 'beta' : 'latest' -+>>>>>>> .their - }) - .then(() => childProcess.execSync('npm pack', { cwd: tempDir })) - .then(() => { -@@ -129,14 +155,24 @@ - env: Object.assign({}, process.env, { electron_config_cache: tempDir }), - cwd: tempDir - }) -+<<<<<<< .our - resolve(tarballPath) - }) - }) - .then((tarballPath) => childProcess.execSync(`npm publish ${tarballPath} --tag ${npmTag} --otp=${process.env.ELECTRON_NPM_OTP}`)) -+======= -+ const checkVersion = childProcess.execSync(`${path.join(tempDir, 'node_modules', '.bin', 'electron')} -v`) -+ assert.strictEqual(checkVersion.toString().trim(), `v${rootPackageJson.version}`) -+ resolve(tarballPath) -+ }) -+}) -+.then((tarballPath) => childProcess.execSync(`npm publish ${tarballPath} --tag ${npmTag}`)) -+>>>>>>> .their - .catch((err) => { - console.error(`Error: ${err}`) - process.exit(1) - }) -+<<<<<<< .our - - async function getCurrentBranch () { - const gitDir = path.resolve(__dirname, '..') -@@ -155,3 +191,5 @@ - process.exit(1) - } - } -+======= -+>>>>>>> .their -added in both - our 100755 84e00ad4f309201f151c3f8fcbaf9ee536c9b6cb script/release.js - their 100755 df662e5608ee50ec838764bcc26dbe908c6e6e61 script/release.js -@@ -1,8 +1,14 @@ - #!/usr/bin/env node - -+<<<<<<< .our - if (!process.env.CI) require('dotenv-safe').load() - require('colors') - const args = require('minimist')(process.argv.slice(2)) -+======= -+require('colors') -+const args = require('minimist')(process.argv.slice(2)) -+const assert = require('assert') -+>>>>>>> .their - const fs = require('fs') - const { execSync } = require('child_process') - const GitHub = require('github') -@@ -16,16 +22,30 @@ - const sumchecker = require('sumchecker') - const temp = require('temp').track() - const { URL } = require('url') -+<<<<<<< .our - const targetRepo = pkgVersion.indexOf('nightly') > 0 ? 'nightlies' : 'electron' - let failureCount = 0 - -+======= -+let failureCount = 0 -+ -+assert(process.env.ELECTRON_GITHUB_TOKEN, 'ELECTRON_GITHUB_TOKEN not found in environment') -+ -+>>>>>>> .their - const github = new GitHub({ - followRedirects: false - }) - github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN}) -+<<<<<<< .our - - async function getDraftRelease (version, skipValidation) { - let releaseInfo = await github.repos.getReleases({owner: 'electron', repo: targetRepo}) -+======= -+const gitDir = path.resolve(__dirname, '..') -+ -+async function getDraftRelease (version, skipValidation) { -+ let releaseInfo = await github.repos.getReleases({owner: 'electron', repo: 'electron'}) -+>>>>>>> .their - let drafts - let versionToCheck - if (version) { -@@ -49,8 +69,13 @@ - return draft - } - -+<<<<<<< .our - async function validateReleaseAssets (release, validatingRelease) { - const requiredAssets = assetsForVersion(release.tag_name, validatingRelease).sort() -+======= -+async function validateReleaseAssets (release) { -+ const requiredAssets = assetsForVersion(release.tag_name).sort() -+>>>>>>> .their - const extantAssets = release.assets.map(asset => asset.name).sort() - const downloadUrls = release.assets.map(asset => asset.browser_download_url).sort() - -@@ -60,6 +85,7 @@ - }) - check((failureCount === 0), `All required GitHub assets exist for release`, true) - -+<<<<<<< .our - if (!validatingRelease || !release.draft) { - if (release.draft) { - await verifyAssets(release) -@@ -72,6 +98,18 @@ - const s3Urls = s3UrlsForVersion(release.tag_name) - await verifyShasums(s3Urls, true) - } -+======= -+ if (release.draft) { -+ await verifyAssets(release) -+ } else { -+ await verifyShasums(downloadUrls) -+ .catch(err => { -+ console.log(`${fail} error verifyingShasums`, err) -+ }) -+ } -+ const s3Urls = s3UrlsForVersion(release.tag_name) -+ await verifyShasums(s3Urls, true) -+>>>>>>> .their - } - - function check (condition, statement, exitIfFail = false) { -@@ -84,13 +122,22 @@ - } - } - -+<<<<<<< .our - function assetsForVersion (version, validatingRelease) { -+======= -+function assetsForVersion (version) { -+>>>>>>> .their - const patterns = [ - `electron-${version}-darwin-x64-dsym.zip`, - `electron-${version}-darwin-x64-symbols.zip`, - `electron-${version}-darwin-x64.zip`, -+<<<<<<< .our - `electron-${version}-linux-arm64-symbols.zip`, - `electron-${version}-linux-arm64.zip`, -+======= -+ `electron-${version}-linux-arm-symbols.zip`, -+ `electron-${version}-linux-arm.zip`, -+>>>>>>> .their - `electron-${version}-linux-armv7l-symbols.zip`, - `electron-${version}-linux-armv7l.zip`, - `electron-${version}-linux-ia32-symbols.zip`, -@@ -109,17 +156,27 @@ - `electron-api.json`, - `electron.d.ts`, - `ffmpeg-${version}-darwin-x64.zip`, -+<<<<<<< .our - `ffmpeg-${version}-linux-arm64.zip`, -+======= -+ `ffmpeg-${version}-linux-arm.zip`, -+>>>>>>> .their - `ffmpeg-${version}-linux-armv7l.zip`, - `ffmpeg-${version}-linux-ia32.zip`, - `ffmpeg-${version}-linux-x64.zip`, - `ffmpeg-${version}-mas-x64.zip`, - `ffmpeg-${version}-win32-ia32.zip`, -+<<<<<<< .our - `ffmpeg-${version}-win32-x64.zip` - ] - if (!validatingRelease) { - patterns.push('SHASUMS256.txt') - } -+======= -+ `ffmpeg-${version}-win32-x64.zip`, -+ `SHASUMS256.txt` -+ ] -+>>>>>>> .their - return patterns - } - -@@ -141,6 +198,7 @@ - } - - function checkVersion () { -+<<<<<<< .our - if (args.skipVersionCheck) return - - console.log(`Verifying that app version matches package version ${pkgVersion}.`) -@@ -150,6 +208,11 @@ - scriptArgs.unshift('-R') - } - let appVersion = runScript(startScript, scriptArgs).trim() -+======= -+ console.log(`Verifying that app version matches package version ${pkgVersion}.`) -+ let startScript = path.join(__dirname, 'start.py') -+ let appVersion = runScript(startScript, ['--version']).trim() -+>>>>>>> .their - check((pkgVersion.indexOf(appVersion) === 0), `App version ${appVersion} matches ` + - `package version ${pkgVersion}.`, true) - } -@@ -180,7 +243,11 @@ - function uploadIndexJson () { - console.log('Uploading index.json to S3.') - let scriptPath = path.join(__dirname, 'upload-index-json.py') -+<<<<<<< .our - runScript(scriptPath, [pkgVersion]) -+======= -+ runScript(scriptPath, []) -+>>>>>>> .their - console.log(`${pass} Done uploading index.json to S3.`) - } - -@@ -191,7 +258,11 @@ - console.log(`${fileName} already exists on GitHub; deleting before creating new file.`) - await github.repos.deleteAsset({ - owner: 'electron', -+<<<<<<< .our - repo: targetRepo, -+======= -+ repo: 'electron', -+>>>>>>> .their - id: existingAssets[0].id - }).catch(err => { - console.log(`${fail} Error deleting ${fileName} on GitHub:`, err) -@@ -210,7 +281,11 @@ - async function uploadShasumFile (filePath, fileName, release) { - let githubOpts = { - owner: 'electron', -+<<<<<<< .our - repo: targetRepo, -+======= -+ repo: 'electron', -+>>>>>>> .their - id: release.id, - filePath, - name: fileName -@@ -245,7 +320,11 @@ - async function publishRelease (release) { - let githubOpts = { - owner: 'electron', -+<<<<<<< .our - repo: targetRepo, -+======= -+ repo: 'electron', -+>>>>>>> .their - id: release.id, - tag_name: release.tag_name, - draft: false -@@ -259,6 +338,7 @@ - - async function makeRelease (releaseToValidate) { - if (releaseToValidate) { -+<<<<<<< .our - if (releaseToValidate === true) { - releaseToValidate = pkgVersion - } else { -@@ -267,18 +347,31 @@ - console.log(`Validating release ${releaseToValidate}`) - let release = await getDraftRelease(releaseToValidate) - await validateReleaseAssets(release, true) -+======= -+ console.log(`Validating release ${args.validateRelease}`) -+ let release = await getDraftRelease(args.validateRelease) -+ await validateReleaseAssets(release) -+>>>>>>> .their - } else { - checkVersion() - let draftRelease = await getDraftRelease() - uploadNodeShasums() - uploadIndexJson() -+<<<<<<< .our - -+======= -+>>>>>>> .their - await createReleaseShasums(draftRelease) - // Fetch latest version of release before verifying - draftRelease = await getDraftRelease(pkgVersion, true) - await validateReleaseAssets(draftRelease) -+<<<<<<< .our - await tagLibCC() - await publishRelease(draftRelease) -+======= -+ await publishRelease(draftRelease) -+ await cleanupReleaseBranch() -+>>>>>>> .their - console.log(`${pass} SUCCESS!!! Release has been published. Please run ` + - `"npm run publish-to-npm" to publish release to npm.`) - } -@@ -300,7 +393,11 @@ - let downloadDir = await makeTempDir() - let githubOpts = { - owner: 'electron', -+<<<<<<< .our - repo: targetRepo, -+======= -+ repo: 'electron', -+>>>>>>> .their - headers: { - Accept: 'application/octet-stream' - } -@@ -446,6 +543,7 @@ - `shasums defined in ${validationArgs.shaSumFile}.`) - } - -+<<<<<<< .our - async function tagLibCC () { - const tag = `electron-${pkg.version}` - const libccDir = path.join(path.resolve(__dirname, '..'), 'vendor', 'libchromiumcontent') -@@ -462,6 +560,26 @@ - } else { - console.log(`${fail} Error tagging libchromiumcontent with ${tag}: ` + - `${tagDetails.stderr}`) -+======= -+async function cleanupReleaseBranch () { -+ console.log(`Cleaning up release branch.`) -+ let errorMessage = `Could not delete local release branch.` -+ let successMessage = `Successfully deleted local release branch.` -+ await callGit(['branch', '-D', 'release-1-6-x'], errorMessage, successMessage) -+ errorMessage = `Could not delete remote release branch.` -+ successMessage = `Successfully deleted remote release branch.` -+ return callGit(['push', 'origin', ':release'], errorMessage, successMessage) -+} -+ -+async function callGit (args, errorMessage, successMessage) { -+ let gitResult = await GitProcess.exec(args, gitDir) -+ if (gitResult.exitCode === 0) { -+ console.log(`${pass} ${successMessage}`) -+ return true -+ } else { -+ console.log(`${fail} ${errorMessage} ${gitResult.stderr}`) -+ process.exit(1) -+>>>>>>> .their - } - } - -added in both - our 100644 2facda2daa1b8a8ccb63a28198a15b7e7ecb0880 script/upload-to-github.js - their 100644 7c3f8d9c11ce7b75f307850663efd2e571e8644a script/upload-to-github.js -@@ -1,16 +1,24 @@ -+<<<<<<< .our - if (!process.env.CI) require('dotenv-safe').load() - -+======= -+>>>>>>> .their - const GitHub = require('github') - const github = new GitHub() - github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN}) - -+<<<<<<< .our - if (process.argv.length < 6) { -+======= -+if (process.argv.length < 5) { -+>>>>>>> .their - console.log('Usage: upload-to-github filePath fileName releaseId') - process.exit(1) - } - let filePath = process.argv[2] - let fileName = process.argv[3] - let releaseId = process.argv[4] -+<<<<<<< .our - let releaseVersion = process.argv[5] - - const targetRepo = releaseVersion.indexOf('nightly') > 0 ? 'nightlies' : 'electron' -@@ -18,6 +26,12 @@ - let githubOpts = { - owner: 'electron', - repo: targetRepo, -+======= -+ -+let githubOpts = { -+ owner: 'electron', -+ repo: 'electron', -+>>>>>>> .their - id: releaseId, - filePath: filePath, - name: fileName -@@ -39,7 +53,11 @@ - console.log(`${fileName} already exists; will delete before retrying upload.`) - github.repos.deleteAsset({ - owner: 'electron', -+<<<<<<< .our - repo: targetRepo, -+======= -+ repo: 'electron', -+>>>>>>> .their - id: existingAssets[0].id - }).then(uploadToGitHub).catch(uploadToGitHub) - } else { -changed in both - base 100755 7d689f6cae87a51154297561139285168a70458c script/upload.py - our 100755 2d9eaa201265971ca01acaea6e84a440e5db0532 script/upload.py - their 100755 c02fdd0ae92e2f2a8da1bb64c4d47ee3d2b25303 script/upload.py -@@ -51,6 +51,7 @@ - return 1 - - tag_exists = False -+<<<<<<< .our - release = get_release(args.version) - if not release['draft']: - tag_exists = True -@@ -64,6 +65,35 @@ - upload_electron(release, os.path.join(DIST_DIR, DIST_NAME), args) - if get_target_arch() != 'mips64el': - upload_electron(release, os.path.join(DIST_DIR, SYMBOLS_NAME), args) -+======= -+ for release in releases: -+ if not release['draft'] and release['tag_name'] == args.version: -+ tag_exists = True -+ break -+ -+ release = create_or_get_release_draft(github, releases, args.version, -+ tag_exists) -+ -+ if args.publish_release: -+ # Upload the Node SHASUMS*.txt. -+ run_python_script('upload-node-checksums.py', '-v', ELECTRON_VERSION) -+ -+ # Upload the index.json. -+ run_python_script('upload-index-json.py') -+ -+ # Create and upload the Electron SHASUMS*.txt -+ release_electron_checksums(release) -+ -+ # Press the publish button. -+ publish_release(github, release['id']) -+ -+ # Do not upload other files when passed "-p". -+ return -+ -+ # Upload Electron with GitHub Releases API. -+ upload_electron(github, release, os.path.join(DIST_DIR, DIST_NAME)) -+ upload_electron(github, release, os.path.join(DIST_DIR, SYMBOLS_NAME)) -+>>>>>>> .their - if PLATFORM == 'darwin': - upload_electron(release, os.path.join(DIST_DIR, 'electron-api.json'), args) - upload_electron(release, os.path.join(DIST_DIR, 'electron.d.ts'), args) -@@ -149,7 +179,66 @@ - return dist_time > int(head_time) - - -+<<<<<<< .our - def upload_electron(release, file_path, args): -+======= -+def get_text_with_editor(name): -+ editor = os.environ.get('EDITOR', 'nano') -+ initial_message = '\n# Please enter the body of your release note for %s.' \ -+ % name -+ -+ t = tempfile.NamedTemporaryFile(suffix='.tmp', delete=False) -+ t.write(initial_message) -+ t.close() -+ subprocess.call([editor, t.name]) -+ -+ text = '' -+ for line in open(t.name, 'r'): -+ if len(line) == 0 or line[0] != '#': -+ text += line -+ -+ os.unlink(t.name) -+ return text -+ -+def create_or_get_release_draft(github, releases, tag, tag_exists): -+ # Search for existing draft. -+ for release in releases: -+ if release['draft'] and release['tag_name'] == tag: -+ return release -+ -+ if tag_exists: -+ tag = 'do-not-publish-me' -+ return create_release_draft(github, tag) -+ -+ -+def create_release_draft(github, tag): -+ name = '{0} {1}'.format(PROJECT_NAME, tag) -+ if os.environ.has_key('CI'): -+ body = '(placeholder)' -+ else: -+ body = get_text_with_editor(name) -+ if body == '': -+ sys.stderr.write('Quit due to empty release note.\n') -+ sys.exit(0) -+ data = dict(tag_name=tag, name=name, body=body, draft=True, -+ target_commitish='1-6-x') -+ r = github.repos(ELECTRON_REPO).releases.post(data=data) -+ return r -+ -+ -+def release_electron_checksums(release): -+ checksums = run_python_script('merge-electron-checksums.py', -+ '-v', ELECTRON_VERSION) -+ filename = 'SHASUMS256.txt' -+ filepath = os.path.join(SOURCE_ROOT, filename) -+ with open(filepath, 'w') as sha_file: -+ sha_file.write(checksums.decode('utf-8')) -+ upload_io_to_github(release, filename, filepath) -+ -+ -+def upload_electron(github, release, file_path): -+ # Delete the original file before uploading in CI. -+>>>>>>> .their - filename = os.path.basename(file_path) - - # if upload_to_s3 is set, skip github upload. -@@ -165,18 +254,30 @@ - return - - # Upload the file. -+<<<<<<< .our - upload_io_to_github(release, filename, file_path, args.version) -+======= -+ upload_io_to_github(release, filename, file_path) -+>>>>>>> .their - - # Upload the checksum file. - upload_sha256_checksum(args.version, file_path) - - -+<<<<<<< .our - def upload_io_to_github(release, filename, filepath, version): - print 'Uploading %s to Github' % \ - (filename) - script_path = os.path.join(SOURCE_ROOT, 'script', 'upload-to-github.js') - execute(['node', script_path, filepath, filename, str(release['id']), - version]) -+======= -+def upload_io_to_github(release, filename, filepath): -+ print 'Uploading %s to Github' % \ -+ (filename) -+ script_path = os.path.join(SOURCE_ROOT, 'script', 'upload-to-github.js') -+ execute(['node', script_path, filepath, filename, str(release['id'])]) -+>>>>>>> .their - - - def upload_sha256_checksum(version, file_path, key_prefix=None): -changed in both - base 100644 1bcc1a5c6223f44e4e9af61ce0bce81cb8aeb522 spec/api-app-spec.js - our 100644 d224eda2989332c18d655cef05a8bacc2eb6d4b8 spec/api-app-spec.js - their 100644 bfebd8a44b3c66f0cd18c2ac24e2c6f9e9ef25b2 spec/api-app-spec.js -@@ -294,8 +294,15 @@ - }) - }) - -+<<<<<<< .our - xdescribe('app.importCertificate', () => { - let w = null -+======= -+ xdescribe('app.importCertificate', function () { -+ if (process.platform !== 'linux') return -+ -+ var w = null -+>>>>>>> .their - - before(function () { - if (process.platform !== 'linux') { -@@ -535,7 +542,11 @@ - }) - }) - -+<<<<<<< .our - describe('select-client-certificate event', () => { -+======= -+ xdescribe('select-client-certificate event', function () { -+>>>>>>> .their - let w = null - - before(function () { -@@ -689,36 +700,80 @@ - } - }) - -+<<<<<<< .our - it('does not launch for argument following a URL', done => { - const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app') - // App should exit with non 123 code. - const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'electron-test:?', 'abc']) - first.once('exit', code => { - expect(code).to.not.equal(123) -+======= -+ it('does not launch for blacklisted argument', function (done) { -+ const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app') -+ // App should exit with non 123 code. -+ const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'electron-test://?', '--no-sandbox', '--gpu-launcher=cmd.exe /c start calc']) -+ first.once('exit', (code) => { -+ assert.notEqual(code, 123) -+>>>>>>> .their - done() - }) - }) - -+<<<<<<< .our - it('launches successfully for argument following a file path', done => { - const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app') - // App should exit with code 123. - const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'e:\\abc', 'abc']) - first.once('exit', code => { - expect(code).to.equal(123) -+======= -+ it('launches successfully for multiple uris in cmd args', function (done) { -+ const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app') -+ // App should exit with code 123. -+ const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'http://electronjs.org', 'electron-test://testdata']) -+ first.once('exit', (code) => { -+ assert.equal(code, 123) -+>>>>>>> .their - done() - }) - }) - -+<<<<<<< .our - it('launches successfully for multiple URIs following --', done => { - const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app') - // App should exit with code 123. - const first = ChildProcess.spawn(remote.process.execPath, [appPath, '--', 'http://electronjs.org', 'electron-test://testdata']) - first.once('exit', code => { - expect(code).to.equal(123) -+======= -+ it('does not launch for encoded space', function (done) { -+ const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app') -+ // App should exit with non 123 code. -+ const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'electron-test://?', '--no-sandbox', '--gpu-launcher%20"cmd.exe /c start calc']) -+ first.once('exit', (code) => { -+ assert.notEqual(code, 123) -+ done() -+ }) -+ }) -+ -+ it('launches successfully for argnames similar to blacklisted ones', function (done) { -+ const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app') -+ // inspect is blacklisted, but inspector should work, and app launch should succeed -+ const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'electron-test://?', '--inspector']) -+ first.once('exit', (code) => { -+ assert.equal(code, 123) -+>>>>>>> .their - done() - }) - }) - }) -+<<<<<<< .our -+======= -+ -+ describe('getFileIcon() API', function () { -+ // FIXME Get these specs running on Linux CI -+ if (process.platform === 'linux' && isCI) return -+>>>>>>> .their - - describe('getFileIcon() API', () => { - const iconPath = path.join(__dirname, 'fixtures/assets/icon.ico') -changed in both - base 100644 ff2734b5ea2c5da5843b8c952a5ed1602fd586c8 spec/api-browser-window-spec.js - our 100644 f4cba12ec19d224bc46fca898db42a99baf4972e spec/api-browser-window-spec.js - their 100644 2ce18b856e9156c0a70b7e6a7a18c4a793edec92 spec/api-browser-window-spec.js -@@ -1589,8 +1589,11 @@ - sandbox: true - } - }) -+<<<<<<< .our - ipcRenderer.send('set-web-preferences-on-next-new-window', w.webContents.id, 'preload', preload) - -+======= -+>>>>>>> .their - w.loadURL('file://' + path.join(fixtures, 'api', 'sandbox.html?reload-remote-child')) - - ipcMain.on('get-remote-module-path', (event) => { -@@ -1614,6 +1617,7 @@ - done() - }) - }) -+<<<<<<< .our - - it('validates process APIs access in sandboxed renderer', (done) => { - ipcMain.once('answer', function (event, test) { -@@ -1657,6 +1661,8 @@ - const [, id] = await emittedOnce(ipcMain, 'webview-dom-ready') - expect(webContents.id).to.equal(id) - }) -+======= -+>>>>>>> .their - }) - - describe('nativeWindowOpen option', () => { -changed in both - base 100644 92020dbea6233c09025a2c7c51cd37f82bfc58c9 spec/api-crash-reporter-spec.js - our 100644 dd31b91e1244785412b87db96bb141599e5ccb0f spec/api-crash-reporter-spec.js - their 100644 a08cbaaa09dddf868234dab67465eed058522718 spec/api-crash-reporter-spec.js -@@ -10,6 +10,7 @@ - const {closeWindow} = require('./window-helpers') - - const {remote} = require('electron') -+const isCI = remote.getGlobal('isCi') - const {app, BrowserWindow, crashReporter} = remote.require('electron') - - describe('crashReporter module', () => { -@@ -18,8 +19,19 @@ - // TODO(alexeykuzmin): [Ch66] Fails. Fix it and enable back. - if (process.platform === 'linux') return - -+<<<<<<< .our - let originalTempDirectory = null - let tempDirectory = null -+======= -+ // FIXME internal Linux CI is failing when it detects a process crashes -+ // which is a false positive here since crashes are explicitly triggered -+ if (isCI && process.platform === 'linux') { -+ return -+ } -+ -+ var originalTempDirectory = null -+ var tempDirectory = null -+>>>>>>> .their - - before(() => { - tempDirectory = temp.mkdirSync('electronCrashReporterSpec-') -changed in both - base 100644 1302fbbc433125e390a60bab5333477405cc3a91 spec/chromium-spec.js - our 100644 d90269769d269e4054d25cba4b6c4ac8a1929aa6 spec/chromium-spec.js - their 100644 892992a543fa5006e7d95b46f3229d9a96e0d02d spec/chromium-spec.js -@@ -1055,6 +1055,7 @@ - } - }) - -+<<<<<<< .our - beforeEach(() => { - this.pdfSource = url.format({ - pathname: path.join(fixtures, 'assets', 'cat.pdf').replace(/\\/g, '/'), -@@ -1070,6 +1071,22 @@ - }, - protocol: 'file', - slashes: true -+======= -+ function createBrowserWindow ({plugins}) { -+ w = new BrowserWindow({ -+ show: false, -+ webPreferences: { -+ preload: path.join(fixtures, 'module', 'preload-inject-ipc.js'), -+ plugins: plugins -+ } -+ }) -+ } -+ -+ it('opens when loading a pdf resource as top level navigation', function (done) { -+ createBrowserWindow({plugins: true}) -+ ipcMain.once('pdf-loaded', function (event, success) { -+ if (success) done() -+>>>>>>> .their - }) - - this.createBrowserWindow = ({plugins, preload}) => { -@@ -1121,11 +1138,34 @@ - w.webContents.loadURL(this.pdfSource) - }) - -+<<<<<<< .our - it('opens a pdf link given params, the query string should be escaped', (done) => { - this.createBrowserWindow({plugins: true, preload: 'preload-pdf-loaded.js'}) - ipcMain.once('pdf-loaded', (event, state) => { - assert.equal(state, 'success') - done() -+======= -+ it('should download a pdf when plugins are disabled', function (done) { -+ createBrowserWindow({plugins: false}) -+ ipcRenderer.sendSync('set-download-option', false, false) -+ ipcRenderer.once('download-done', function (event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) { -+ assert.equal(state, 'completed') -+ assert.equal(filename, 'cat.pdf') -+ assert.equal(mimeType, 'application/pdf') -+ fs.unlinkSync(path.join(fixtures, 'mock.pdf')) -+ done() -+ }) -+ w.webContents.loadURL(pdfSource) -+ }) -+ -+ it('should not open when pdf is requested as sub resource', function (done) { -+ createBrowserWindow({plugins: true}) -+ webFrame.registerURLSchemeAsPrivileged('file', { -+ secure: false, -+ bypassCSP: false, -+ allowServiceWorkers: false, -+ corsEnabled: false -+>>>>>>> .their - }) - w.webContents.on('page-title-updated', () => { - const parsedURL = url.parse(w.webContents.getURL(), true) -changed in both - base 100644 f8d7aa7921de1b025bc0beb1b3659d0713da6aeb spec/fixtures/api/sandbox.html - our 100644 af796ebc988b648455025934a991719135853694 spec/fixtures/api/sandbox.html - their 100644 5353d8815a7582443f50f34dbde6ff7d01101cba spec/fixtures/api/sandbox.html -changed in both - base 100644 15d6e06a862cf69ad592601bd3d376bec20c05f8 spec/fixtures/module/preload-sandbox.js - our 100644 6901be56d0c5fa9f0a318edeb235eef60624ac52 spec/fixtures/module/preload-sandbox.js - their 100644 f8f88339852039ecaa3b5c23eae382e06ad06d58 spec/fixtures/module/preload-sandbox.js -changed in both - base 160000 3fe90cfcf54dd946980e59daf550a7cdb2317c8f vendor/node - our 160000 ece0a06ac8147efb5b5af431c21f312f1884616e vendor/node - their 160000 9b1683e7000481ec6214eafa3eef7ac4594eb410 vendor/node diff --git a/app/test/fixtures/merge-parser/electron/merge-1-7-x-into-master.txt b/app/test/fixtures/merge-parser/electron/merge-1-7-x-into-master.txt deleted file mode 100644 index 75f1d6a588b..00000000000 --- a/app/test/fixtures/merge-parser/electron/merge-1-7-x-into-master.txt +++ /dev/null @@ -1,17080 +0,0 @@ -added in both - our 100644 6d44d618aabcce04c60344f2274dec5b0c2a1f68 .circleci/config.yml - their 100644 160f3ae69ca901061a37f7eb2999dd2a41288be4 .circleci/config.yml -@@ -1,3 +1,4 @@ -+<<<<<<< .our - notify-slack-failure: ¬ify-slack-failure - run: - name: Send a slack notification on failure -@@ -348,10 +349,13 @@ - docker: - - image: electronbuilds/electron:0.0.8 - <<: *build-steps -+======= -+>>>>>>> .their - - version: 2 - jobs: - electron-linux-arm: -+<<<<<<< .our - environment: - TARGET_ARCH: arm - <<: *build-defaults -@@ -469,10 +473,321 @@ - NIGHTLY_BUILD: true - <<: *build-defaults - resource_class: xlarge -+======= -+ docker: -+ - image: electronbuilds/electron:0.0.7 -+ environment: -+ TARGET_ARCH: arm -+ resource_class: 2xlarge -+ steps: -+ - checkout -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Zip out directory -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ zip -r electron.zip out/D -+ fi -+ - persist_to_workspace: -+ root: /home/builduser -+ paths: -+ - project/out -+ - store_artifacts: -+ path: electron.zip -+ electron-linux-ia32: -+ docker: -+ - image: electronbuilds/electron:0.0.7 -+ environment: -+ TARGET_ARCH: ia32 -+ DISPLAY: ':99.0' -+ resource_class: xlarge -+ steps: -+ - checkout -+ - run: -+ name: Setup for headless testing -+ command: sh -e /etc/init.d/xvfb start -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Test -+ environment: -+ MOCHA_FILE: junit/test-results.xml -+ MOCHA_REPORTER: mocha-junit-reporter -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Testing Electron debug build' -+ out/D/electron --version -+ mkdir junit -+ script/test.py --ci -+ else -+ echo 'Skipping testing on release build' -+ fi -+ - run: -+ name: Verify FFmpeg -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Verifying ffmpeg on debug build' -+ script/verify-ffmpeg.py -+ else -+ echo 'Skipping verify ffmpeg on release build' -+ fi -+ - store_test_results: -+ path: junit -+ - store_artifacts: -+ path: junit -+ electron-linux-mips64el: -+ docker: -+ - image: electronbuilds/electron:0.0.7 -+ environment: -+ TARGET_ARCH: mips64el -+ resource_class: xlarge -+ steps: -+ - checkout -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ -+ electron-linux-x64: -+ docker: -+ - image: electronbuilds/electron:0.0.7 -+ environment: -+ TARGET_ARCH: x64 -+ DISPLAY: ':99.0' -+ resource_class: xlarge -+ steps: -+ - checkout -+ - run: -+ name: Setup for headless testing -+ command: sh -e /etc/init.d/xvfb start -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Test -+ environment: -+ MOCHA_FILE: junit/test-results.xml -+ MOCHA_REPORTER: mocha-junit-reporter -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Testing Electron debug build' -+ mkdir junit -+ script/test.py --ci -+ else -+ echo 'Skipping testing on release build' -+ fi -+ - run: -+ name: Verify FFmpeg -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Verifying ffmpeg on debug build' -+ script/verify-ffmpeg.py -+ else -+ echo 'Skipping verify ffmpeg on release build' -+ fi -+ - run: -+ name: Generate Typescript Definitions -+ command: npm run create-typescript-definitions -+ - store_test_results: -+ path: junit -+ - store_artifacts: -+ path: junit -+ - store_artifacts: -+ path: out/electron.d.ts -+ - store_artifacts: -+ path: out/electron-api.json -+>>>>>>> .their - - electron-osx-x64: - environment: - TARGET_ARCH: x64 -+<<<<<<< .our - RUN_TESTS: true - INSTALL_MACOS_NODE: true - macos: -@@ -488,11 +803,106 @@ - macos: - xcode: "8.3.3" - <<: *build-steps -+======= -+ macos: -+ xcode: "8.3.3" -+ steps: -+ - checkout -+ - run: -+ name: Install node -+ command: | -+ brew update -+ brew install node@8 -+ brew link node@8 --force -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Test -+ environment: -+ MOCHA_FILE: junit/test-results.xml -+ MOCHA_REPORTER: mocha-junit-reporter -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Testing Electron debug build' -+ mkdir junit -+ script/test.py --ci -+ else -+ echo 'Skipping testing on release build' -+ fi -+ - run: -+ name: Verify FFmpeg -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Verifying ffmpeg on debug build' -+ script/verify-ffmpeg.py -+ else -+ echo 'Skipping verify ffmpeg on release build' -+ fi -+ - run: -+ name: Generate Typescript Definitions -+ command: npm run create-typescript-definitions -+ - store_test_results: -+ path: junit -+ - store_artifacts: -+ path: junit -+ - store_artifacts: -+ path: out/electron.d.ts -+ - store_artifacts: -+ path: out/electron-api.json -+>>>>>>> .their - - electron-mas-x64: - environment: - TARGET_ARCH: x64 - MAS_BUILD: 1 -+<<<<<<< .our - RUN_TESTS: true - INSTALL_MACOS_NODE: true - macos: -@@ -668,12 +1078,108 @@ - GN_EXTRA_ARGS: 'is_mas_build = true' - <<: *gn-mac-build-machine - <<: *gn-mac-build-steps -+======= -+ macos: -+ xcode: "8.3.3" -+ steps: -+ - checkout -+ - run: -+ name: Install node -+ command: | -+ brew update -+ brew install node@8 -+ brew link node@8 --force -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Test -+ environment: -+ MOCHA_FILE: junit/test-results.xml -+ MOCHA_REPORTER: mocha-junit-reporter -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Testing Electron debug build' -+ mkdir junit -+ script/test.py --ci -+ else -+ echo 'Skipping testing on release build' -+ fi -+ - run: -+ name: Verify FFmpeg -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Verifying ffmpeg on debug build' -+ script/verify-ffmpeg.py -+ else -+ echo 'Skipping verify ffmpeg on release build' -+ fi -+ - run: -+ name: Generate Typescript Definitions -+ command: npm run create-typescript-definitions -+ - store_test_results: -+ path: junit -+ - store_artifacts: -+ path: junit -+ - store_artifacts: -+ path: out/electron.d.ts -+ - store_artifacts: -+ path: out/electron-api.json -+ -+>>>>>>> .their - - workflows: - version: 2 - build-arm: - jobs: - - electron-linux-arm -+<<<<<<< .our - - electron-linux-arm-test: - requires: - - electron-linux-arm -@@ -683,6 +1189,8 @@ - - electron-linux-arm64-test: - requires: - - electron-linux-arm64 -+======= -+>>>>>>> .their - build-ia32: - jobs: - - electron-linux-ia32 -@@ -695,6 +1203,7 @@ - build-mas-x64: - jobs: - - electron-mas-x64 -+<<<<<<< .our - build-gn-linux: - jobs: - - electron-gn-linux-x64-debug-fyi -@@ -745,3 +1254,5 @@ - - electron-gn-linux-arm64-release-fyi - - electron-gn-mas-release-fyi - - electron-gn-osx-release-fyi -+======= -+>>>>>>> .their -added in remote - their 100644 51ad1b492dcbbd0c79bb9986bac35f1e3a007c2a Jenkinsfile -@@ -0,0 +1,44 @@ -+pipeline { -+ agent none -+ stages { -+ stage('Build') { -+ parallel { -+ stage('electron-osx-x64') { -+ agent { -+ label 'osx' -+ } -+ steps { -+ sh 'script/bootstrap.py --target_arch=x64 --dev' -+ sh 'npm run lint' -+ sh 'script/build.py -c D' -+ sh 'script/test.py --ci --rebuild_native_modules' -+ } -+ post { -+ always { -+ cleanWs() -+ } -+ } -+ } -+ stage('electron-mas-x64') { -+ agent { -+ label 'osx' -+ } -+ environment { -+ MAS_BUILD = '1' -+ } -+ steps { -+ sh 'script/bootstrap.py --target_arch=x64 --dev' -+ sh 'npm run lint' -+ sh 'script/build.py -c D' -+ sh 'script/test.py --ci --rebuild_native_modules' -+ } -+ post { -+ always { -+ cleanWs() -+ } -+ } -+ } -+ } -+ } -+ } -+} -changed in both - base 100644 ce0baaf989bdbd6897fa333d3af88d1d573a2bd2 appveyor.yml - our 100644 67a2b2124619d866f67d849f57f3548ba28be26a appveyor.yml - their 100644 5ee73c661b1079e9bf252868b31814d3aa4c2760 appveyor.yml -@@ -1,3 +1,4 @@ -+<<<<<<< .our - version: 1.0.{build} - branches: - except: -@@ -6,6 +7,10 @@ - image: electron-16-vs2017-15.4.5 - environment: - DISABLE_CRASH_REPORTER_TESTS: true -+======= -+build_cloud: electron-16 -+image: electron-16-vs2015 -+>>>>>>> .their - build_script: - - ps: >- - if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) { -@@ -61,6 +66,7 @@ - - path: test-results.xml - name: test-results.xml - deploy_script: -+<<<<<<< .our - - ps: >- - if (Test-Path Env:\ELECTRON_RELEASE) { - if (Test-Path Env:\RUN_RELEASE_BUILD) { -@@ -71,3 +77,6 @@ - & python script\upload.py - } - } -+======= -+- ps: "if (Test-Path Env:\\ELECTRON_RELEASE) {\n if (Test-Path Env:\\RUN_RELEASE_BUILD) {\n Write-Output \"Uploading Electron release distribution to s3\"\n & python script\\upload.py --upload_to_s3\n } else {\n Write-Output \"Uploading Electron release distribution to github releases\"\n & python script\\upload.py\n }\n} else {\n Write-Output \"Skipping upload distribution because build is not for release\"\n}" -+>>>>>>> .their -changed in both - base 100644 e1603fa5942f7b000c3385648530255032e775a2 atom/app/atom_library_main.h - our 100644 2c7a27caa20a411558010c3c58bd78e7850c0737 atom/app/atom_library_main.h - their 100644 63d285bb5e4838578d23505d7738c9ac88575df1 atom/app/atom_library_main.h -@@ -9,7 +9,12 @@ - - #if defined(OS_MACOSX) - extern "C" { -+<<<<<<< .our - __attribute__((visibility("default"))) int AtomMain(int argc, char* argv[]); -+======= -+__attribute__((visibility("default"))) -+int AtomMain(int argc, char* argv[]); -+>>>>>>> .their - - #ifdef ENABLE_RUN_AS_NODE - __attribute__((visibility("default"))) int AtomInitializeICUandStartNode( -changed in both - base 100644 7ee7522934689937f7be7b0f866134bf611c7d69 atom/app/atom_library_main.mm - our 100644 57a519fcd0db28548ea75034cf92191161183385 atom/app/atom_library_main.mm - their 100644 ae096acd4a931d397e285643d36580625dde14bf atom/app/atom_library_main.mm -@@ -14,6 +14,10 @@ - #include "brightray/common/mac/main_application_bundle.h" - #include "content/public/app/content_main.h" - -+<<<<<<< .our -+======= -+#if defined(OS_MACOSX) -+>>>>>>> .their - int AtomMain(int argc, char* argv[]) { - atom::AtomMainDelegate delegate; - content::ContentMainParams params(&delegate); -changed in both - base 100644 de8e2b6068786b21f45e2a04490e46c8ffb15656 atom/app/atom_main.cc - our 100644 fc77100d9acb58221c35f364c4db7866a44d347d atom/app/atom_main.cc - their 100644 a9f39ab51547c6e86e47449b11250827e961abde atom/app/atom_main.cc -@@ -71,7 +71,11 @@ - - #ifdef _DEBUG - // Don't display assert dialog boxes in CI test runs -+<<<<<<< .our - static const char* kCI = "ELECTRON_CI"; -+======= -+ static const auto kCI = "ELECTRON_CI"; -+>>>>>>> .their - bool is_ci = IsEnvSet(kCI); - if (!is_ci) { - for (int i = 0; i < arguments.argc; ++i) { -@@ -88,6 +92,7 @@ - - _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE); - _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); -+<<<<<<< .our - - _set_error_mode(_OUT_TO_STDERR); - } -@@ -98,6 +103,14 @@ - #else - bool run_as_node = false; - #endif -+======= -+ -+ _set_error_mode(_OUT_TO_STDERR); -+ } -+#endif -+ -+ bool run_as_node = IsEnvSet(kRunAsNode); -+>>>>>>> .their - - // Make sure the output is printed to console. - if (run_as_node || !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE")) -@@ -117,7 +130,13 @@ - // from within the CRT's atexit facility, ensuring the heap functions are - // still active. The second invocation from the OS loader will be a no-op. - extern void NTAPI OnThreadExit(PVOID module, DWORD reason, PVOID reserved); -+<<<<<<< .our - atexit([]() { OnThreadExit(nullptr, DLL_THREAD_DETACH, nullptr); }); -+======= -+ atexit([]() { -+ OnThreadExit(nullptr, DLL_THREAD_DETACH, nullptr); -+ }); -+>>>>>>> .their - #endif - - #ifdef ENABLE_RUN_AS_NODE -@@ -132,10 +151,14 @@ - auto ret = atom::NodeMain(argv.size(), argv.data()); - std::for_each(argv.begin(), argv.end(), free); - return ret; -+<<<<<<< .our - } - #endif - - if (IsEnvSet("ELECTRON_INTERNAL_CRASH_SERVICE")) { -+======= -+ } else if (IsEnvSet("ELECTRON_INTERNAL_CRASH_SERVICE")) { -+>>>>>>> .their - return crash_service::Main(cmd); - } - -@@ -156,7 +179,10 @@ - #elif defined(OS_LINUX) // defined(OS_WIN) - - int main(int argc, char* argv[]) { -+<<<<<<< .our - #ifdef ENABLE_RUN_AS_NODE -+======= -+>>>>>>> .their - if (IsEnvSet(kRunAsNode)) { - base::i18n::InitializeICU(); - base::AtExitManager atexit_manager; -@@ -175,7 +201,10 @@ - #else // defined(OS_LINUX) - - int main(int argc, char* argv[]) { -+<<<<<<< .our - #ifdef ENABLE_RUN_AS_NODE -+======= -+>>>>>>> .their - if (IsEnvSet(kRunAsNode)) { - return AtomInitializeICUandStartNode(argc, argv); - } -added in both - our 100644 23e870cf4a32aecfc246a81edad46971b4456a55 atom/app/command_line_args.cc - their 100644 a5f0183991a2df7890c4d389a3fcd4b99e0574e0 atom/app/command_line_args.cc -@@ -2,15 +2,30 @@ - // Use of this source code is governed by the MIT license that can be - // found in the LICENSE file. - -+<<<<<<< .our - #include "atom/app/command_line_args.h" - -+======= -+#include <string> -+ -+#include "atom/app/command_line_args.h" -+ -+#include "base/strings/string_util.h" -+#include "base/strings/utf_string_conversions.h" -+#include "content/public/common/content_switches.h" -+ -+>>>>>>> .their - namespace { - - bool IsUrlArg(const base::CommandLine::CharType* arg) { - // the first character must be a letter for this to be a URL - auto c = *arg; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) { -+<<<<<<< .our - for (auto* p = arg + 1; *p; ++p) { -+======= -+ for (auto p = arg + 1; *p; ++p) { -+>>>>>>> .their - c = *p; - - // colon indicates that the argument starts with a URI scheme -@@ -31,12 +46,1323 @@ - return false; - } - -+<<<<<<< .our -+======= -+const char* blacklist[] = { -+ // node -+ "inspect", -+ "inspect-brk", -+ -+ -+ // chromium switches: -+ // find ./ \( -name "*switches.cc" -o -name "*switch_list.h" \) \ -+ // | xargs grep -P --no-filename '"\S+"[);]$' \ -+ // | perl -pe 's|^.*?"(\S+)"[);]$| "$1",|'; \ -+ // | LANG="C" sort | uniq -+ "/prefetch:1", -+ "/prefetch:2", -+ "/prefetch:3", -+ "/prefetch:4", -+ "/prefetch:5", -+ "/prefetch:6", -+ "/prefetch:8", -+ "0", -+ "?", -+ "BlacklistOnly", -+ "ChromeOSMemoryPressureHandling", -+ "Disabled", -+ "NewProfileManagement", -+ "OnlineCheckOnly", -+ "SafeSites", -+ "accept-resource-provider", -+ "adaboost", -+ "aec-refined-adaptive-filter", -+ "agc-startup-min-volume", -+ "aggressive", -+ "aggressive-cache-discard", -+ "aggressive-tab-discard", -+ "all-toolchains", -+ "allow-cross-origin-auth-prompt", -+ "allow-external-pages", -+ "allow-failed-policy-fetch-for-test", -+ "allow-file-access-from-files", -+ "allow-hidden-media-playback", -+ "allow-http-background-page", -+ "allow-http-screen-capture", -+ "allow-insecure-localhost", -+ "allow-legacy-extension-manifests", -+ "allow-loopback-in-peer-connection", -+ "allow-nacl-crxfs-api", -+ "allow-nacl-file-handle-api", -+ "allow-nacl-socket-api", -+ "allow-no-sandbox-job", -+ "allow-outdated-plugins", -+ "allow-ra-in-dev-mode", -+ "allow-running-insecure-content", -+ "allow-sandbox-debugging", -+ "allow-silent-push", -+ "alsa-check-close-timeout", -+ "alsa-enable-upsampling", -+ "alsa-fixed-output-sample-rate", -+ "alsa-input-device", -+ "alsa-output-avail-min", -+ "alsa-output-buffer-size", -+ "alsa-output-device", -+ "alsa-output-period-size", -+ "alsa-output-start-threshold", -+ "also-emit-success-logs", -+ "always-authorize-plugins", -+ "always-on", -+ "always-use-complex-text", -+ "alwaystrue", -+ "android-fonts-path", -+ "android-stderr-port", -+ "android-stdin-port", -+ "android-stdout-port", -+ "angle", -+ "app", -+ "app-auto-launched", -+ "app-id", -+ "app-mode-auth-code", -+ "app-mode-oauth-token", -+ "app-mode-oem-manifest", -+ "app-shell-allow-roaming", -+ "app-shell-host-window-size", -+ "app-shell-preferred-network", -+ "app-shell-refresh-token", -+ "app-shell-user", -+ "apple", -+ "apps-gallery-download-url", -+ "apps-gallery-update-url", -+ "apps-gallery-url", -+ "apps-keep-chrome-alive-in-tests", -+ "arc-availability", -+ "arc-available", -+ "args", -+ "artifacts-dir", -+ "ash-adjustable-large-cursor", -+ "ash-animate-from-boot-splash-screen", -+ "ash-constrain-pointer-to-root", -+ "ash-copy-host-background-at-boot", -+ "ash-debug-shortcuts", -+ "ash-dev-shortcuts", -+ "ash-disable-maximize-mode-window-backdrop", -+ "ash-disable-screen-orientation-lock", -+ "ash-disable-touch-exploration-mode", -+ "ash-enable-docked-windows", -+ "ash-enable-magnifier-key-scroller", -+ "ash-enable-mirrored-screen", -+ "ash-enable-palette-on-all-displays", -+ "ash-enable-software-mirroring", -+ "ash-enable-unified-desktop", -+ "ash-force-enable-palette", -+ "ash-hide-notifications-for-factory", -+ "ash-host-window-bounds", -+ "ash-shelf-color", -+ "ash-touch-hud", -+ "ash-webui-init", -+ "attestation-server", -+ "audio-buffer-size", -+ "aura-legacy-power-button", -+ "auth-ext-path", -+ "auth-server-whitelist", -+ "auth-spnego-account-type", -+ "auto", -+ "auto-open-devtools-for-tabs", -+ "auto-select-desktop-capture-source", -+ "blink-settings", -+ "bootstrap", -+ "browser-subprocess-path", -+ "browser-test", -+ "bwsi", -+ "bypass-app-banner-engagement-checks", -+ "canvas-msaa-sample-count", -+ "cast-initial-screen-height", -+ "cast-initial-screen-width", -+ "cc-layer-tree-test-long-timeout", -+ "cc-layer-tree-test-no-timeout", -+ "cc-rebaseline-pixeltests", -+ "cellular-first", -+ "cellular-only", -+ "check-for-update-interval", -+ "check-layout-test-sys-deps", -+ "child-process", -+ "child-wallpaper-large", -+ "child-wallpaper-small", -+ "cipher-suite-blacklist", -+ "class", -+ "clear-token-service", -+ "cloud-print-file", -+ "cloud-print-file-type", -+ "cloud-print-job-title", -+ "cloud-print-print-ticket", -+ "cloud-print-setup-proxy", -+ "cloud-print-url", -+ "cloud-print-xmpp-endpoint", -+ "color", -+ "compensate-for-unstable-pinch-zoom", -+ "compile-shader-always-succeeds", -+ "component-updater", -+ "connectivity-check-url", -+ "conservative", -+ "content-image-texture-target", -+ "content-shell-host-window-size", -+ "controller", -+ "crash-dumps-dir", -+ "crash-on-failure", -+ "crash-on-hang-threads", -+ "crash-server-url", -+ "crash-test", -+ "crashpad-handler", -+ "create-browser-on-startup-for-tests", -+ "create-default-gl-context", -+ "cros-region", -+ "cros-regions-mode", -+ "crosh-command", -+ "cryptauth-http-host", -+ "custom-devtools-frontend", -+ "custom-launcher-page", -+ "custom_summary", -+ "d3d11", -+ "d3d9", -+ "daemon", -+ "dark_muted", -+ "dark_vibrant", -+ "data-path", -+ "data-reduction-proxy-config-url", -+ "data-reduction-proxy-enable-quic-on-non-core-proxies", -+ "data-reduction-proxy-experiment", -+ "data-reduction-proxy-http-proxies", -+ "data-reduction-proxy-lo-fi", -+ "data-reduction-proxy-pingback-url", -+ "data-reduction-proxy-secure-proxy-check-url", -+ "data-reduction-proxy-server-experiments-disabled", -+ "data-reduction-proxy-warmup-url", -+ "dbus-stub", -+ "debug-devtools", -+ "debug-enable-frame-toggle", -+ "debug-packed-apps", -+ "debug-print", -+ "default", -+ "default-tile-height", -+ "default-tile-width", -+ "default-wallpaper-is-oem", -+ "default-wallpaper-large", -+ "default-wallpaper-small", -+ "demo", -+ "derelict-detection-timeout", -+ "derelict-idle-timeout", -+ "desktop", -+ "desktop-window-1080p", -+ "deterministic-fetch", -+ "device-management-url", -+ "device-scale-factor", -+ "devtools-flags", -+ "diagnostics", -+ "diagnostics-format", -+ "diagnostics-recovery", -+ "disable", -+ "disable-2d-canvas-clip-aa", -+ "disable-2d-canvas-image-chromium", -+ "disable-3d-apis", -+ "disable-accelerated-2d-canvas", -+ "disable-accelerated-jpeg-decoding", -+ "disable-accelerated-mjpeg-decode", -+ "disable-accelerated-video-decode", -+ "disable-account-consistency", -+ "disable-add-to-shelf", -+ "disable-app-info-dialog-mac", -+ "disable-app-list-dismiss-on-blur", -+ "disable-app-window-cycling", -+ "disable-appcontainer", -+ "disable-arc-data-wipe", -+ "disable-arc-opt-in-verification", -+ "disable-audio-support-for-desktop-share", -+ "disable-autofill-keyboard-accessory-view", -+ "disable-avfoundation-overlays", -+ "disable-background-networking", -+ "disable-background-timer-throttling", -+ "disable-backgrounding-occluded-windows", -+ "disable-backing-store-limit", -+ "disable-blink-features", -+ "disable-boot-animation", -+ "disable-breakpad", -+ "disable-browser-task-scheduler", -+ "disable-bundled-ppapi-flash", -+ "disable-canvas-aa", -+ "disable-captive-portal-bypass-proxy", -+ "disable-cast-streaming-hw-encoding", -+ "disable-clear-browsing-data-counters", -+ "disable-client-side-phishing-detection", -+ "disable-cloud-import", -+ "disable-component-cloud-policy", -+ "disable-component-extensions-with-background-pages", -+ "disable-component-update", -+ "disable-composited-antialiasing", -+ "disable-contextual-search", -+ "disable-d3d11", -+ "disable-databases", -+ "disable-datasaver-prompt", -+ "disable-default-apps", -+ "disable-demo-mode", -+ "disable-device-disabling", -+ "disable-device-discovery-notifications", -+ "disable-dinosaur-easter-egg", -+ "disable-direct-composition", -+ "disable-directwrite-for-ui", -+ "disable-display-color-calibration", -+ "disable-display-list-2d-canvas", -+ "disable-distance-field-text", -+ "disable-domain-blocking-for-3d-apis", -+ "disable-domain-reliability", -+ "disable-download-image-renaming", -+ "disable-drive-search-in-app-launcher", -+ "disable-dwm-composition", -+ "disable-eol-notification", -+ "disable-es3-apis", -+ "disable-es3-gl-context", -+ "disable-extensions", -+ "disable-extensions-except", -+ "disable-extensions-file-access-check", -+ "disable-extensions-http-throttling", -+ "disable-fast-web-scroll-view-insets", -+ "disable-features", -+ "disable-field-trial-config", -+ "disable-file-system", -+ "disable-flash-3d", -+ "disable-flash-stage3d", -+ "disable-fullscreen-low-power-mode", -+ "disable-fullscreen-tab-detaching", -+ "disable-gaia-services", -+ "disable-gesture-editing", -+ "disable-gesture-requirement-for-media-playback", -+ "disable-gesture-requirement-for-presentation", -+ "disable-gesture-typing", -+ "disable-gl-drawing-for-tests", -+ "disable-gl-error-limit", -+ "disable-gl-extensions", -+ "disable-glsl-translator", -+ "disable-gpu", -+ "disable-gpu-async-worker-context", -+ "disable-gpu-compositing", -+ "disable-gpu-driver-bug-workarounds", -+ "disable-gpu-early-init", -+ "disable-gpu-memory-buffer-compositor-resources", -+ "disable-gpu-memory-buffer-video-frames", -+ "disable-gpu-process-crash-limit", -+ "disable-gpu-program-cache", -+ "disable-gpu-rasterization", -+ "disable-gpu-sandbox", -+ "disable-gpu-shader-disk-cache", -+ "disable-gpu-vsync", -+ "disable-gpu-watchdog", -+ "disable-hang-monitor", -+ "disable-hid-detection-on-oobe", -+ "disable-hide-inactive-stacked-tab-close-buttons", -+ "disable-histogram-customizer", -+ "disable-hosted-app-shim-creation", -+ "disable-hosted-apps-in-windows", -+ "disable-http2", -+ "disable-in-process-stack-traces", -+ "disable-infobars", -+ "disable-input-ime-api", -+ "disable-input-view", -+ "disable-ios-password-generation", -+ "disable-ios-password-suggestions", -+ "disable-ios-physical-web", -+ "disable-javascript-harmony-shipping", -+ "disable-kill-after-bad-ipc", -+ "disable-lcd-text", -+ "disable-legacy-window", -+ "disable-local-storage", -+ "disable-logging", -+ "disable-login-animations", -+ "disable-low-end-device-mode", -+ "disable-low-latency-dxva", -+ "disable-low-res-tiling", -+ "disable-lru-snapshot-cache", -+ "disable-mac-overlays", -+ "disable-mac-views-native-app-windows", -+ "disable-main-frame-before-activation", -+ "disable-md-oobe", -+ "disable-media-session-api", -+ "disable-media-suspend", -+ "disable-merge-key-char-events", -+ "disable-minimize-on-second-launcher-item-click", -+ "disable-mojo-renderer", -+ "disable-mtp-write-support", -+ "disable-multi-display-layout", -+ "disable-namespace-sandbox", -+ "disable-native-gpu-memory-buffers", -+ "disable-network-portal-notification", -+ "disable-new-bookmark-apps", -+ "disable-new-channel-switcher-ui", -+ "disable-new-kiosk-ui", -+ "disable-new-korean-ime", -+ "disable-new-profile-management", -+ "disable-new-zip-unpacker", -+ "disable-notifications", -+ "disable-ntp-popular-sites", -+ "disable-nv12-dxgi-video", -+ "disable-offer-store-unmasked-wallet-cards", -+ "disable-offer-upload-credit-cards", -+ "disable-office-editing-component-extension", -+ "disable-offline-auto-reload", -+ "disable-offline-auto-reload-visible-only", -+ "disable-overlay-scrollbar", -+ "disable-overscroll-edge-effect", -+ "disable-panel-fitting", -+ "disable-partial-raster", -+ "disable-password-generation", -+ "disable-payment-request", -+ "disable-pepper-3d", -+ "disable-pepper-3d-image-chromium", -+ "disable-per-monitor-dpi", -+ "disable-permission-action-reporting", -+ "disable-permissions-api", -+ "disable-physical-keyboard-autocorrect", -+ "disable-pinch", -+ "disable-pnacl-crash-throttling", -+ "disable-popup-blocking", -+ "disable-prefer-compositing-to-lcd-text", -+ "disable-presentation-api", -+ "disable-print-preview", -+ "disable-prompt-on-repost", -+ "disable-pull-to-refresh-effect", -+ "disable-push-api-background-mode", -+ "disable-quic", -+ "disable-reading-from-canvas", -+ "disable-remote-core-animation", -+ "disable-remote-fonts", -+ "disable-remote-playback-api", -+ "disable-renderer-accessibility", -+ "disable-renderer-backgrounding", -+ "disable-renderer-priority-management", -+ "disable-resize-lock", -+ "disable-rgba-4444-textures", -+ "disable-rollback-option", -+ "disable-rtc-smoothness-algorithm", -+ "disable-screen-orientation-lock", -+ "disable-search-geolocation-disclosure", -+ "disable-seccomp-filter-sandbox", -+ "disable-settings-window", -+ "disable-setuid-sandbox", -+ "disable-shader-name-hashing", -+ "disable-shared-workers", -+ "disable-signin-scoped-device-id", -+ "disable-single-click-autofill", -+ "disable-slimming-paint-invalidation", -+ "disable-smart-virtual-keyboard", -+ "disable-smooth-scrolling", -+ "disable-software-rasterizer", -+ "disable-speech-api", -+ "disable-suggestions-ui", -+ "disable-sync", -+ "disable-sync-app-list", -+ "disable-sync-types", -+ "disable-system-timezone-automatic-detection", -+ "disable-tab-for-desktop-share", -+ "disable-tab-strip-autoscroll-new-tabs", -+ "disable-threaded-animation", -+ "disable-threaded-compositing", -+ "disable-threaded-scrolling", -+ "disable-touch-adjustment", -+ "disable-touch-drag-drop", -+ "disable-translate", -+ "disable-translate-new-ux", -+ "disable-usb-keyboard-detect", -+ "disable-v8-idle-tasks", -+ "disable-vaapi-accelerated-video-encode", -+ "disable-views-rect-based-targeting", -+ "disable-virtual-keyboard-overscroll", -+ "disable-voice-input", -+ "disable-volume-adjust-sound", -+ "disable-wake-on-wifi", -+ "disable-web-notification-custom-layouts", -+ "disable-web-security", -+ "disable-webgl", -+ "disable-webgl-image-chromium", -+ "disable-webrtc-encryption", -+ "disable-webrtc-hw-decoding", -+ "disable-webrtc-hw-encoding", -+ "disable-webrtc-hw-vp8-encoding", -+ "disable-win32k-lockdown", -+ "disable-xss-auditor", -+ "disable-zero-browsers-open-for-tests", -+ "disable-zero-copy", -+ "disable-zero-copy-dxgi-video", -+ "disabled", -+ "disk-cache-dir", -+ "disk-cache-size", -+ "display", -+ "dmg-device", -+ "dns-log-details", -+ "dom-automation", -+ "dotfile", -+ "duck-flash", -+ "dump-browser-histograms", -+ "dump-dom", -+ "eafe-path", -+ "eafe-url", -+ "early-tracing", -+ "easy-unlock-app-path", -+ "edge-touch-filtering", -+ "egl", -+ "elevate", -+ "embedded-extension-options", -+ "emphasize-titles-in-omnibox-dropdown", -+ "emulate-shader-precision", -+ "enable-accelerated-2d-canvas", -+ "enable-accelerated-vpx-decode", -+ "enable-accessibility-tab-switcher", -+ "enable-account-consistency", -+ "enable-ad", -+ "enable-adaptive-selection-handle-orientation", -+ "enable-add-to-shelf", -+ "enable-aggressive-domstorage-flushing", -+ "enable-android-wallpapers-app", -+ "enable-app-info-dialog-mac", -+ "enable-app-list", -+ "enable-app-window-cycling", -+ "enable-appcontainer", -+ "enable-arc", -+ "enable-arc-oobe-optin", -+ "enable-audio-debug-recordings-from-extension", -+ "enable-autofill-keyboard-accessory-view", -+ "enable-automation", -+ "enable-benchmarking", -+ "enable-ble-advertising-in-apps", -+ "enable-blink-features", -+ "enable-bookmark-undo", -+ "enable-browser-side-navigation", -+ "enable-browser-task-scheduler", -+ "enable-canvas-2d-dynamic-rendering-mode-switching", -+ "enable-checker-imaging", -+ "enable-chromevox-arc-support", -+ "enable-clear-browsing-data-counters", -+ "enable-cloud-print-proxy", -+ "enable-cloud-print-xps", -+ "enable-color-correct-rendering", -+ "enable-color-correct-rendering-default-mode", -+ "enable-consumer-kiosk", -+ "enable-content-intent-detection", -+ "enable-contextual-search", -+ "enable-crash-reporter", -+ "enable-crash-reporter-for-testing", -+ "enable-crx-hash-check", -+ "enable-data-reduction-proxy-bypass-warning", -+ "enable-data-reduction-proxy-carrier-test", -+ "enable-data-reduction-proxy-force-pingback", -+ "enable-data-reduction-proxy-lite-page", -+ "enable-data-reduction-proxy-savings-promo", -+ "enable-datasaver-prompt", -+ "enable-default-media-session", -+ "enable-device-discovery-notifications", -+ "enable-devtools-experiments", -+ "enable-display-list-2d-canvas", -+ "enable-distance-field-text", -+ "enable-distillability-service", -+ "enable-dom-distiller", -+ "enable-domain-reliability", -+ "enable-download-image-renaming", -+ "enable-drive-search-in-app-launcher", -+ "enable-drm-atomic", -+ "enable-embedded-extension-options", -+ "enable-es3-apis", -+ "enable-exclusive-audio", -+ "enable-experimental-accessibility-features", -+ "enable-experimental-canvas-features", -+ "enable-experimental-extension-apis", -+ "enable-experimental-input-view-features", -+ "enable-experimental-web-platform-features", -+ "enable-extension-activity-log-testing", -+ "enable-extension-activity-logging", -+ "enable-extension-assets-sharing", -+ "enable-fast-unload", -+ "enable-fast-web-scroll-view-insets", -+ "enable-features", -+ "enable-first-run-ui-transitions", -+ "enable-floating-virtual-keyboard", -+ "enable-font-antialiasing", -+ "enable-fullscreen-tab-detaching", -+ "enable-fullscreen-toolbar-reveal", -+ "enable-google-branded-context-menu", -+ "enable-gpu-async-worker-context", -+ "enable-gpu-benchmarking", -+ "enable-gpu-client-logging", -+ "enable-gpu-client-tracing", -+ "enable-gpu-command-logging", -+ "enable-gpu-debugging", -+ "enable-gpu-driver-debug-logging", -+ "enable-gpu-memory-buffer-compositor-resources", -+ "enable-gpu-memory-buffer-video-frames", -+ "enable-gpu-rasterization", -+ "enable-gpu-service-logging", -+ "enable-gpu-service-tracing", -+ "enable-grouped-history", -+ "enable-hardware-overlays", -+ "enable-harfbuzz-rendertext", -+ "enable-hdr-output", -+ "enable-heap-profiling", -+ "enable-hosted-app-quit-notification", -+ "enable-hosted-apps-in-windows", -+ "enable-hosted-mode", -+ "enable-hotword-hardware", -+ "enable-hung-renderer-infobar", -+ "enable-inband-text-tracks", -+ "enable-input-ime-api", -+ "enable-ios-handoff-to-other-devices", -+ "enable-ios-password-generation", -+ "enable-ios-physical-web", -+ "enable-kiosk-mode", -+ "enable-layer-lists", -+ "enable-lcd-text", -+ "enable-leak-detection", -+ "enable-local-file-accesses", -+ "enable-local-sync-backend", -+ "enable-logging", -+ "enable-longpress-drag-selection", -+ "enable-low-end-device-mode", -+ "enable-low-res-tiling", -+ "enable-lru-snapshot-cache", -+ "enable-mac-views-native-app-windows", -+ "enable-main-frame-before-activation", -+ "enable-md-feedback", -+ "enable-md-policy-page", -+ "enable-media-suspend", -+ "enable-merge-key-char-events", -+ "enable-message-center-always-scroll-up-upon-notification-removal", -+ "enable-nacl", -+ "enable-nacl-debug", -+ "enable-nacl-nonsfi-mode", -+ "enable-native-cups", -+ "enable-native-gpu-memory-buffers", -+ "enable-natural-scroll-default", -+ "enable-navigation-tracing", -+ "enable-net-benchmarking", -+ "enable-network-information", -+ "enable-network-portal-notification", -+ "enable-new-bookmark-apps", -+ "enable-ntp-popular-sites", -+ "enable-ntp-search-engine-country-detection", -+ "enable-offer-store-unmasked-wallet-cards", -+ "enable-offer-upload-credit-cards", -+ "enable-offline-auto-reload", -+ "enable-offline-auto-reload-visible-only", -+ "enable-osk-overscroll", -+ "enable-overlay-scrollbar", -+ "enable-override-bookmarks-ui", -+ "enable-partial-raster", -+ "enable-password-generation", -+ "enable-payment-request", -+ "enable-pepper-testing", -+ "enable-per-monitor-dpi", -+ "enable-permission-action-reporting", -+ "enable-physical-keyboard-autocorrect", -+ "enable-pinch", -+ "enable-pixel-output-in-tests", -+ "enable-plugin-placeholder-testing", -+ "enable-potentially-annoying-security-features", -+ "enable-power-overlay", -+ "enable-precache", -+ "enable-precise-memory-info", -+ "enable-prefer-compositing-to-lcd-text", -+ "enable-print-browser", -+ "enable-print-preview-register-promos", -+ "enable-profile-shortcut-manager", -+ "enable-profiling", -+ "enable-proximity-auth-bluetooth-low-energy-discovery", -+ "enable-proximity-auth-proximity-detection", -+ "enable-push-api-background-mode", -+ "enable-quic", -+ "enable-reader-mode-toolbar-icon", -+ "enable-refresh-token-annotation-request", -+ "enable-request-tablet-site", -+ "enable-rgba-4444-textures", -+ "enable-sandbox", -+ "enable-sandbox-logging", -+ "enable-screenshot-testing-with-mode", -+ "enable-scripts-require-action", -+ "enable-scroll-prediction", -+ "enable-service-manager-tracing", -+ "enable-settings-window", -+ "enable-sgi-video-sync", -+ "enable-single-click-autofill", -+ "enable-site-engagement-eviction-policy", -+ "enable-site-settings", -+ "enable-skia-benchmarking", -+ "enable-slimming-paint-invalidation", -+ "enable-slimming-paint-v2", -+ "enable-smooth-scrolling", -+ "enable-spatial-navigation", -+ "enable-spdy-proxy-auth", -+ "enable-speech-dispatcher", -+ "enable-spelling-feedback-field-trial", -+ "enable-spotlight-actions", -+ "enable-stats-collection-bindings", -+ "enable-stats-table", -+ "enable-strict-mixed-content-checking", -+ "enable-strict-powerful-feature-restrictions", -+ "enable-suggestions-ui", -+ "enable-suggestions-with-substring-match", -+ "enable-supervised-user-managed-bookmarks-folder", -+ "enable-swap-buffers-with-bounds", -+ "enable-sync-app-list", -+ "enable-sync-articles", -+ "enable-tab-audio-muting", -+ "enable-tcp-fastopen", -+ "enable-tether", -+ "enable-threaded-compositing", -+ "enable-threaded-texture-mailboxes", -+ "enable-thumbnail-retargeting", -+ "enable-tile-compression", -+ "enable-touch-calibration-setting", -+ "enable-touch-drag-drop", -+ "enable-touch-support-for-screen-magnifier", -+ "enable-touchpad-three-finger-click", -+ "enable-touchview", -+ "enable-trace-app-source", -+ "enable-tracing", -+ "enable-tracing-output", -+ "enable-translate-new-ux", -+ "enable-true-color-rendering", -+ "enable-ui-devtools", -+ "enable-use-zoom-for-dsf", -+ "enable-user-controlled-alternate-protocol-ports", -+ "enable-user-metrics", -+ "enable-usermedia-screen-capturing", -+ "enable-video-player-chromecast-support", -+ "enable-viewport", -+ "enable-virtual-keyboard", -+ "enable-vp9-in-mp4", -+ "enable-vtune-support", -+ "enable-vulkan", -+ "enable-wayland-server", -+ "enable-web-notification-custom-layouts", -+ "enable-webfonts-intervention-trigger", -+ "enable-webfonts-intervention-v2", -+ "enable-webgl-draft-extensions", -+ "enable-webgl-image-chromium", -+ "enable-webrtc-event-logging-from-extension", -+ "enable-webrtc-stun-origin", -+ "enable-webvr", -+ "enable-wifi-credential-sync", -+ "enable-win7-webrtc-hw-h264-decoding", -+ "enable-zero-copy", -+ "enabled", -+ "enabled-2g", -+ "enabled-3g", -+ "enabled-slow2g", -+ "encode-binary", -+ "enforce", -+ "enforce-gl-minimums", -+ "enforce-webrtc-ip-permission-check", -+ "enforce_strict", -+ "enterprise-disable-arc", -+ "enterprise-enable-forced-re-enrollment", -+ "enterprise-enable-zero-touch-enrollment", -+ "enterprise-enrollment-initial-modulus", -+ "enterprise-enrollment-modulus-limit", -+ "error-console", -+ "explicitly-allowed-ports", -+ "expose-internals-for-testing", -+ "extension-content-verification", -+ "extension-process", -+ "extensions-install-verification", -+ "extensions-multi-account", -+ "extensions-not-webstore", -+ "extensions-on-chrome-urls", -+ "extensions-update-frequency", -+ "extra-search-query-params", -+ "fail-on-unused-args", -+ "fake-variations-channel", -+ "false", -+ "fast", -+ "fast-start", -+ "feedback-server", -+ "field-trial-handle", -+ "first-exec-after-boot", -+ "flag-switches-begin", -+ "flag-switches-end", -+ "font-cache-shared-handle", -+ "force-android-app-mode", -+ "force-app-mode", -+ "force-desktop-ios-promotion", -+ "force-dev-mode-highlighting", -+ "force-device-scale-factor", -+ "force-display-list-2d-canvas", -+ "force-fieldtrial-params", -+ "force-fieldtrials", -+ "force-first-run", -+ "force-first-run-ui", -+ "force-gpu-mem-available-mb", -+ "force-gpu-rasterization", -+ "force-happiness-tracking-system", -+ "force-load-easy-unlock-app-in-tests", -+ "force-local-ntp", -+ "force-login-manager-in-tests", -+ "force-mediafoundation", -+ "force-overlay-fullscreen-video", -+ "force-pnacl-subzero", -+ "force-renderer-accessibility", -+ "force-show-update-menu-badge", -+ "force-show-update-menu-item", -+ "force-system-compositor-mode", -+ "force-ui-direction", -+ "force-variation-ids", -+ "force-video-overlays", -+ "force-wave-audio", -+ "force-webrtc-ip-handling-policy", -+ "full-memory-crash-report", -+ "gaia-url", -+ "gcm-checkin-url", -+ "gcm-mcs-endpoint", -+ "gcm-registration-url", -+ "generate-accessibility-test-expectations", -+ "gl", -+ "gl-composited-texture-quad-border", -+ "gl-shader-interm-output", -+ "gles", -+ "golden-screenshots-dir", -+ "google-apis-url", -+ "google-base-url", -+ "google-doodle-url", -+ "google-profile-info", -+ "google-url", -+ "gpu-active-device-id", -+ "gpu-active-vendor-id", -+ "gpu-device-id", -+ "gpu-driver-bug-workarounds", -+ "gpu-driver-date", -+ "gpu-driver-vendor", -+ "gpu-driver-version", -+ "gpu-launcher", -+ "gpu-no-complete-info-collection", -+ "gpu-no-context-lost", -+ "gpu-process", -+ "gpu-program-cache-size-kb", -+ "gpu-rasterization-msaa-sample-count", -+ "gpu-sandbox-allow-sysv-shm", -+ "gpu-sandbox-failures-fatal", -+ "gpu-sandbox-start-early", -+ "gpu-secondary-device-ids", -+ "gpu-secondary-vendor-ids", -+ "gpu-startup-dialog", -+ "gpu-testing-device-id", -+ "gpu-testing-driver-date", -+ "gpu-testing-gl-renderer", -+ "gpu-testing-gl-vendor", -+ "gpu-testing-gl-version", -+ "gpu-testing-os-version", -+ "gpu-testing-secondary-device-ids", -+ "gpu-testing-secondary-vendor-ids", -+ "gpu-testing-vendor-id", -+ "gpu-vendor-id", -+ "guest-wallpaper-large", -+ "guest-wallpaper-small", -+ "h", -+ "has-chromeos-diamond-key", -+ "headless", -+ "help", -+ "hide", -+ "hide-icons", -+ "hide-scrollbars", -+ "history-entry-requires-user-gesture", -+ "homedir", -+ "homepage", -+ "host", -+ "host-pairing-oobe", -+ "host-resolver-retry-attempts", -+ "host-resolver-rules", -+ "host-rules", -+ "icu-data-dir", -+ "ignore-autocomplete-off-autofill", -+ "ignore-certificate-errors", -+ "ignore-gpu-blacklist", -+ "ignore-missing-cdm-host-file", -+ "ignore-urlfetcher-cert-requests", -+ "ignore-user-profile-mapping-for-tests", -+ "in-process-gpu", -+ "incognito", -+ "inert-visual-viewport", -+ "input", -+ "inspect", -+ "inspect-brk", -+ "install-chrome-app", -+ "install-supervised-user-whitelists", -+ "instant-process", -+ "interests-url", -+ "invalidation-use-gcm-channel", -+ "ipc-connection-timeout", -+ "ipc-dump-directory", -+ "ipc-fuzzer-testcase", -+ "is-running-in-mash", -+ "isolate-extensions", -+ "isolate-sites-for-testing", -+ "javascript-harmony", -+ "js-flags", -+ "keep-alive-for-test", -+ "kiosk", -+ "kiosk-printing", -+ "lang", -+ "last-launched-app", -+ "light_muted", -+ "light_vibrant", -+ "load-and-launch-app", -+ "load-apps", -+ "load-extension", -+ "load-media-router-component-extension", -+ "local-heuristics-only-for-password-generation", -+ "local-ntp-reload", -+ "local-sync-backend-dir", -+ "log-gpu-control-list-decisions", -+ "log-level", -+ "log-net-log", -+ "login-manager", -+ "login-profile", -+ "login-user", -+ "lso-url", -+ "ltr", -+ "main-frame-resizes-are-orientation-changes", -+ "make-chrome-default", -+ "make-default-browser", -+ "managed-user-id", -+ "managed-user-sync-token", -+ "mark-non-secure-as", -+ "markdown", -+ "market-url-for-testing", -+ "mash", -+ "material", -+ "material-design-ink-drop-animation-speed", -+ "material-hybrid", -+ "max-gum-fps", -+ "max-untiled-layer-height", -+ "max-untiled-layer-width", -+ "media-cache-size", -+ "mem-pressure-system-reserved-kb", -+ "memory-metrics", -+ "memory-pressure-off", -+ "memory-pressure-thresholds", -+ "memory-pressure-thresholds-mb", -+ "message-center-changes-while-open", -+ "metrics-client-id", -+ "metrics-recording-only", -+ "mhtml-generator-option", -+ "mock", -+ "mojo-channel-token", -+ "mojo-local-storage", -+ "mojo-pipe-token", -+ "monitoring-destination-id", -+ "mse-audio-buffer-size-limit", -+ "mse-video-buffer-size-limit", -+ "mute-audio", -+ "nacl-broker", -+ "nacl-dangerous-no-sandbox-nonsfi", -+ "nacl-debug-mask", -+ "nacl-gdb", -+ "nacl-gdb-script", -+ "nacl-loader", -+ "nacl-loader-nonsfi", -+ "native", -+ "native-crx-bindings", -+ "net-log-capture-mode", -+ "netifs-to-ignore", -+ "network-country-iso", -+ "new-profile-management", -+ "new-window", -+ "no-default-browser-check", -+ "no-experiments", -+ "no-first-run", -+ "no-managed-user-acknowledgment-check", -+ "no-network-profile-warning", -+ "no-pings", -+ "no-proxy-server", -+ "no-referrers", -+ "no-sandbox", -+ "no-service-autorun", -+ "no-startup-window", -+ "no-use-mus-in-renderer", -+ "no-wifi", -+ "no-zygote", -+ "nocolor", -+ "noerrdialogs", -+ "non-material", -+ "non-secure", -+ "none", -+ "normal_muted", -+ "normal_vibrant", -+ "note-taking-app-ids", -+ "ntp-snippets-add-incomplete", -+ "ntp-switch-to-existing-tab", -+ "null", -+ "num-pac-threads", -+ "num-raster-threads", -+ "oauth2-client-id", -+ "oauth2-client-secret", -+ "off", -+ "on", -+ "oobe-bootstrapping-master", -+ "oobe-guest-session", -+ "oobe-skip-postlogin", -+ "oobe-timer-interval", -+ "open-ash", -+ "opengraph", -+ "origin-to-force-quic-on", -+ "origin-trial-disabled-features", -+ "origin-trial-disabled-tokens", -+ "origin-trial-public-key", -+ "original-process-start-time", -+ "osmesa", -+ "output", -+ "override", -+ "override-metrics-upload-url", -+ "override-plugin-power-saver-for-testing", -+ "override-use-software-gl-for-tests", -+ "overscroll-history-navigation", -+ "ozone-dump-file", -+ "ozone-platform", -+ "pack-extension", -+ "pack-extension-key", -+ "parent-profile", -+ "parent-window", -+ "passive-listeners-default", -+ "password-store", -+ "permission-request-api-scope", -+ "permission-request-api-url", -+ "power-stub", -+ "ppapi", -+ "ppapi-antialiased-text-enabled", -+ "ppapi-broker", -+ "ppapi-flash-args", -+ "ppapi-flash-path", -+ "ppapi-flash-version", -+ "ppapi-in-process", -+ "ppapi-plugin-launcher", -+ "ppapi-startup-dialog", -+ "ppapi-subpixel-rendering-setting", -+ "precache-config-settings-url", -+ "precache-manifest-url-prefix", -+ "prerender-from-omnibox", -+ "previous-app", -+ "primary", -+ "primordial-pipe-token", -+ "privet-ipv6-only", -+ "process-per-site", -+ "process-per-tab", -+ "process-service-name", -+ "product-version", -+ "profile-directory", -+ "profiler-timing", -+ "profiling-at-start", -+ "profiling-file", -+ "profiling-flush", -+ "progress-bar-animation", -+ "progress-bar-completion", -+ "prompt-for-external-extensions", -+ "proxy-auto-detect", -+ "proxy-bypass-list", -+ "proxy-pac-url", -+ "proxy-server", -+ "q", -+ "quic-connection-options", -+ "quic-host-whitelist", -+ "quic-max-packet-length", -+ "quic-version", -+ "rdp_desktop_session", -+ "reader-mode-feedback", -+ "reader-mode-heuristics", -+ "rebaseline-pixel-tests", -+ "reduce-security-for-testing", -+ "reduced-referrer-granularity", -+ "register-font-files", -+ "register-pepper-plugins", -+ "relauncher", -+ "remote-debugging-address", -+ "remote-debugging-port", -+ "remote-debugging-socket-name", -+ "remote-debugging-targets", -+ "renderer", -+ "renderer-client-id", -+ "renderer-cmd-prefix", -+ "renderer-process-limit", -+ "renderer-startup-dialog", -+ "renderer-wait-for-java-debugger", -+ "repl", -+ "report-vp9-as-an-unsupported-mime-type", -+ "require-audio-hardware-for-testing", -+ "reset-app-list-install-state", -+ "reset-variation-state", -+ "restore-last-session", -+ "root", -+ "root-layer-scrolls", -+ "rtl", -+ "run-layout-test", -+ "runtime-deps-list-file", -+ "safebrowsing-disable-auto-update", -+ "safebrowsing-disable-download-protection", -+ "safebrowsing-disable-extension-blacklist", -+ "safebrowsing-manual-download-blacklist", -+ "sandbox-ipc", -+ "save-page-as-mhtml", -+ "saveas-menu-label", -+ "screen-config", -+ "screenshot", -+ "script-executable", -+ "scripts-require-action", -+ "scroll-end-effect", -+ "secondary", -+ "secondary-display-layout", -+ "secondary-ui-md", -+ "service", -+ "service-overrides", -+ "service-request-channel-token", -+ "shared-files", -+ "shill-stub", -+ "show-app-list", -+ "show-autofill-signatures", -+ "show-autofill-type-predictions", -+ "show-component-extension-options", -+ "show-composited-layer-borders", -+ "show-fps-counter", -+ "show-icons", -+ "show-layer-animation-bounds", -+ "show-mac-overlay-borders", -+ "show-overdraw-feedback", -+ "show-paint-rects", -+ "show-property-changed-rects", -+ "show-saved-copy", -+ "show-screenspace-rects", -+ "show-surface-damage-rects", -+ "show_summary", -+ "silent-debugger-extension-api", -+ "silent-launch", -+ "simulate-critical-update", -+ "simulate-elevated-recovery", -+ "simulate-outdated", -+ "simulate-outdated-no-au", -+ "simulate-upgrade", -+ "single-process", -+ "site-per-process", -+ "skip-gpu-data-loading", -+ "skip-nostore-all", -+ "skip-nostore-main", -+ "skip-reencoding-on-skp-capture", -+ "slow", -+ "slow-connections-only", -+ "slow-down-raster-scale-factor", -+ "sms-test-messages", -+ "spdy-proxy-auth-fallback", -+ "spdy-proxy-auth-origin", -+ "spdy-proxy-auth-value", -+ "spelling-service-feedback-interval-seconds", -+ "spelling-service-feedback-url", -+ "ssl-key-log-file", -+ "ssl-version-max", -+ "ssl-version-min", -+ "stable-release-mode", -+ "start-fullscreen", -+ "start-maximized", -+ "start-stack-profiler", -+ "started", -+ "stub", -+ "stub-cros-settings", -+ "supports-dual-gpus", -+ "swiftshader", -+ "swiftshader-path", -+ "swiftshader-webgl", -+ "sync-allow-insecure-xmpp-connection", -+ "sync-deferred-startup-timeout-seconds", -+ "sync-disable-deferred-startup", -+ "sync-enable-get-update-avoidance", -+ "sync-notification-host-port", -+ "sync-on-draw-hardware", -+ "sync-short-initial-retry-override", -+ "sync-short-nudge-delay-for-test", -+ "sync-url", -+ "system-developer-mode", -+ "system-log-upload-frequency", -+ "tab-management-experiment-type-disabled", -+ "tab-management-experiment-type-elderberry", -+ "task-profiler", -+ "team-drives", -+ "test-auto-update-ui", -+ "test-child-process", -+ "test-cros-gaia-id-migration", -+ "test-do-not-initialize-icu", -+ "test-gl-lib", -+ "test-launcher-batch-limit", -+ "test-launcher-bot-mode", -+ "test-launcher-debug-launcher", -+ "test-launcher-filter-file", -+ "test-launcher-force-run-broken-tests", -+ "test-launcher-jobs", -+ "test-launcher-list-tests", -+ "test-launcher-output", -+ "test-launcher-print-test-stdio", -+ "test-launcher-print-writable-path", -+ "test-launcher-retry-limit", -+ "test-launcher-shard-index", -+ "test-launcher-summary-output", -+ "test-launcher-timeout", -+ "test-launcher-total-shards", -+ "test-launcher-trace", -+ "test-name", -+ "test-tiny-timeout", -+ "test-type", -+ "testing-fixed-http-port", -+ "testing-fixed-https-port", -+ "threads", -+ "time", -+ "timeout", -+ "tls1", -+ "tls1.1", -+ "tls1.2", -+ "tls1.3", -+ "top-chrome-md", -+ "top-controls-hide-threshold", -+ "top-controls-show-threshold", -+ "top-document-isolation", -+ "touch-calibration", -+ "touch-devices", -+ "touch-events", -+ "touch-noise-filtering", -+ "touch-selection-strategy", -+ "trace-config-file", -+ "trace-export-events-to-etw", -+ "trace-shutdown", -+ "trace-shutdown-file", -+ "trace-startup", -+ "trace-startup-duration", -+ "trace-startup-file", -+ "trace-to-console", -+ "trace-to-file", -+ "trace-to-file-name", -+ "trace-upload-url", -+ "tracelog", -+ "translate-ranker-model-url", -+ "translate-script-url", -+ "translate-security-origin", -+ "true", -+ "try-chrome-again", -+ "try-supported-channel-layouts", -+ "type", -+ "ui-disable-partial-swap", -+ "ui-enable-layer-lists", -+ "ui-enable-rgba-4444-textures", -+ "ui-enable-zero-copy", -+ "ui-prioritize-in-gpu-process", -+ "ui-show-fps-counter", -+ "ui-show-layer-animation-bounds", -+ "ui-show-layer-borders", -+ "ui-show-paint-rects", -+ "ui-show-property-changed-rects", -+ "ui-show-screenspace-rects", -+ "ui-show-surface-damage-rects", -+ "ui-slow-animations", -+ "ui-test-action-max-timeout", -+ "ui-test-action-timeout", -+ "uninstall", -+ "unlimited-storage", -+ "unsafe-pac-url", -+ "unsafely-treat-insecure-origin-as-secure", -+ "use-angle", -+ "use-cras", -+ "use-fake-device-for-media-stream", -+ "use-fake-ui-for-media-stream", -+ "use-file-for-fake-audio-capture", -+ "use-file-for-fake-video-capture", -+ "use-first-display-as-internal", -+ "use-gl", -+ "use-gpu-in-tests", -+ "use-mobile-user-agent", -+ "use-mock-keychain", -+ "use-new-virtual-keyboard-behavior", -+ "use-passthrough-cmd-decoder", -+ "use-simple-cache-backend", -+ "use-test-config", -+ "use_new_features_summary", -+ "user-agent", -+ "user-always-affiliated", -+ "user-data-dir", -+ "utility", -+ "utility-allowed-dir", -+ "utility-cmd-prefix", -+ "utility-run-elevated", -+ "v", -+ "v8-cache-options", -+ "v8-cache-strategies-for-cache-storage", -+ "validate-crx", -+ "validate-input-event-stream", -+ "variations-server-url", -+ "version", -+ "video-image-texture-target", -+ "video-threads", -+ "video-underflow-threshold-ms", -+ "viewer-launch-via-appid", -+ "virtual-time-budget", -+ "vmodule", -+ "wait-for-debugger", -+ "wait-for-debugger-children", -+ "wake-on-wifi-packet", -+ "wallet-service-use-sandbox", -+ "watcher", -+ "waveout-buffers", -+ "webapk-server-url", -+ "webrtc-stun-probe-trial", -+ "webview-enable-safebrowsing-support", -+ "webview-sandboxed-renderer", -+ "whitelisted-extension-id", -+ "win-jumplist-action", -+ "window-position", -+ "window-size", -+ "window-workspace", -+ "windows10-custom-titlebar", -+ "windows8-search", -+ "winhttp-proxy-resolver", -+ "wm-window-animations-disabled", -+ "zygote", -+ "zygote-cmd-prefix" -+}; -+ -+bool IsBlacklistedArg(const base::CommandLine::CharType* arg) { -+#if defined(OS_WIN) -+ const auto converted = base::WideToUTF8(arg); -+ const char* a = converted.c_str(); -+#else -+ const char* a = arg; -+#endif -+ -+ static const char* prefixes[] = {"--", "-", "/"}; -+ -+ int prefix_length = 0; -+ for (auto& prefix : prefixes) { -+ if (base::StartsWith(a, prefix, base::CompareCase::SENSITIVE)) { -+ prefix_length = strlen(prefix); -+ break; -+ } -+ } -+ -+ if (prefix_length > 0) { -+ a += prefix_length; -+ std::string switch_name = -+ base::ToLowerASCII(base::StringPiece(a, strcspn(a, "="))); -+ for (auto& item : blacklist) { -+ if (switch_name == item) -+ return true; -+ } -+ } -+ -+ return false; -+} -+ -+>>>>>>> .their - } // namespace - - namespace atom { - - bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv) { - const base::CommandLine::StringType dashdash(2, '-'); -+<<<<<<< .our - bool block_args = false; - for (int i = 0; i < argc; ++i) { - if (argv[i] == dashdash) -@@ -45,6 +1371,17 @@ - return false; - } else if (IsUrlArg(argv[i])) { - block_args = true; -+======= -+ bool block_blacklisted_args = false; -+ for (int i = 0; i < argc; ++i) { -+ if (argv[i] == dashdash) -+ break; -+ if (block_blacklisted_args) { -+ if (IsBlacklistedArg(argv[i])) -+ return false; -+ } else if (IsUrlArg(argv[i])) { -+ block_blacklisted_args = true; -+>>>>>>> .their - } - } - return true; -added in both - our 100644 2c0acc1648ff3b4bc574f000643069f8ef8e94bb atom/app/command_line_args.h - their 100644 1f5fd756868898e7a304c754d89625059d36441f atom/app/command_line_args.h -@@ -14,3 +14,7 @@ - } // namespace atom - - #endif // ATOM_APP_COMMAND_LINE_ARGS_H_ -+<<<<<<< .our -+======= -+ -+>>>>>>> .their -changed in both - base 100644 06d4dd8aaf5b1d64db4b8b6a1ed11f67ab5e9835 atom/browser/api/atom_api_app.cc - our 100644 089a2b63d1bae3afebea925582a3aac81ddeaa4f atom/browser/api/atom_api_app.cc - their 100644 620abed67081a04788d03f358f787ad0bb7502df atom/browser/api/atom_api_app.cc -@@ -618,7 +618,10 @@ - } - - void App::OnPreMainMessageLoopRun() { -+<<<<<<< .our - content::BrowserChildProcessObserver::Add(this); -+======= -+>>>>>>> .their - if (process_singleton_) { - process_singleton_->OnBrowserReady(); - } -changed in both - base 100644 694a3e3047303a953f098610504c65ce7b4c9003 atom/browser/api/atom_api_app.h - our 100644 ee0ad42c05fe33be17146b79cbe3422953516621 atom/browser/api/atom_api_app.h - their 100644 15141391e067d1b44a45255a1b5cca265ea0b5a8 atom/browser/api/atom_api_app.h -changed in both - base 100644 7496b8389aceee1db3a028b86d50a7bdc56d375b atom/browser/api/atom_api_notification.cc - our 100644 06d22455c7024a41799d5003a755588bb67437a9 atom/browser/api/atom_api_notification.cc - their 100644 ef5b9ce1296a3e6f535ae1f77614028ca4dfa6d9 atom/browser/api/atom_api_notification.cc -@@ -72,7 +72,10 @@ - opts.Get("hasReply", &has_reply_); - opts.Get("actions", &actions_); - opts.Get("sound", &sound_); -+<<<<<<< .our - opts.Get("closeButtonText", &close_button_text_); -+======= -+>>>>>>> .their - } - } - -@@ -123,8 +126,13 @@ - return actions_; - } - -+<<<<<<< .our - base::string16 Notification::GetCloseButtonText() const { - return close_button_text_; -+======= -+base::string16 Notification::GetSound() const { -+ return sound_; -+>>>>>>> .their - } - - // Setters -@@ -161,8 +169,13 @@ - actions_ = actions; - } - -+<<<<<<< .our - void Notification::SetCloseButtonText(const base::string16& text) { - close_button_text_ = text; -+======= -+void Notification::SetSound(const base::string16& new_sound) { -+ sound_ = new_sound; -+>>>>>>> .their - } - - void Notification::NotificationAction(int index) { -@@ -211,7 +224,10 @@ - options.reply_placeholder = reply_placeholder_; - options.actions = actions_; - options.sound = sound_; -+<<<<<<< .our - options.close_button_text = close_button_text_; -+======= -+>>>>>>> .their - notification_->Show(options); - } - } -@@ -241,8 +257,13 @@ - .SetProperty("sound", &Notification::GetSound, &Notification::SetSound) - .SetProperty("actions", &Notification::GetActions, - &Notification::SetActions) -+<<<<<<< .our - .SetProperty("closeButtonText", &Notification::GetCloseButtonText, - &Notification::SetCloseButtonText); -+======= -+ .SetProperty("sound", &Notification::GetSound, -+ &Notification::SetSound); -+>>>>>>> .their - } - - } // namespace api -changed in both - base 100644 9c2dcd4b5107932ab668464d6199f7a3193100f0 atom/browser/api/atom_api_notification.h - our 100644 91a5b72c983c95b20315384091048e50ad08d27f atom/browser/api/atom_api_notification.h - their 100644 d4679e7c2c90df3b8e20cd95c8e3a96a412b2492 atom/browser/api/atom_api_notification.h -@@ -56,7 +56,11 @@ - base::string16 GetReplyPlaceholder() const; - base::string16 GetSound() const; - std::vector<brightray::NotificationAction> GetActions() const; -+<<<<<<< .our - base::string16 GetCloseButtonText() const; -+======= -+ base::string16 GetSound() const; -+>>>>>>> .their - - // Prop Setters - void SetTitle(const base::string16& new_title); -@@ -67,7 +71,11 @@ - void SetReplyPlaceholder(const base::string16& new_reply_placeholder); - void SetSound(const base::string16& sound); - void SetActions(const std::vector<brightray::NotificationAction>& actions); -+<<<<<<< .our - void SetCloseButtonText(const base::string16& text); -+======= -+ void SetSound(const base::string16& sound); -+>>>>>>> .their - - private: - base::string16 title_; -@@ -81,7 +89,11 @@ - base::string16 reply_placeholder_; - base::string16 sound_; - std::vector<brightray::NotificationAction> actions_; -+<<<<<<< .our - base::string16 close_button_text_; -+======= -+ base::string16 sound_; -+>>>>>>> .their - - brightray::NotificationPresenter* presenter_; - -changed in both - base 100644 a23d2817b87df8c7bfb63465afbb8b0852bd8b2f atom/browser/api/atom_api_web_contents.cc - our 100644 20a1ac2e672f08ffea528b6e094ba530ff8083d1 atom/browser/api/atom_api_web_contents.cc - their 100644 95fb99a2351be4df43415302bca700042a4c9f16 atom/browser/api/atom_api_web_contents.cc -@@ -397,8 +397,8 @@ - options.Get("transparent", &transparent); - - content::WebContents::CreateParams params(session->browser_context()); -- auto* view = new OffScreenWebContentsView( -- transparent, base::Bind(&WebContents::OnPaint, base::Unretained(this))); -+ auto* view = new OffScreenWebContentsView(transparent, -+ base::Bind(&WebContents::OnPaint, base::Unretained(this))); - params.view = view; - params.delegate_view = view; - -@@ -1742,7 +1742,12 @@ - return; - - #if defined(ENABLE_OSR) -+<<<<<<< .our - auto* osr_wcv = GetOffScreenWebContentsView(); -+======= -+ const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents()); -+ auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView()); -+>>>>>>> .their - if (osr_wcv) - osr_wcv->SetPainting(true); - #endif -@@ -1753,7 +1758,12 @@ - return; - - #if defined(ENABLE_OSR) -+<<<<<<< .our - auto* osr_wcv = GetOffScreenWebContentsView(); -+======= -+ const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents()); -+ auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView()); -+>>>>>>> .their - if (osr_wcv) - osr_wcv->SetPainting(false); - #endif -@@ -1764,7 +1774,13 @@ - return false; - - #if defined(ENABLE_OSR) -+<<<<<<< .our - auto* osr_wcv = GetOffScreenWebContentsView(); -+======= -+ const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents()); -+ auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView()); -+ -+>>>>>>> .their - return osr_wcv && osr_wcv->IsPainting(); - #else - return false; -@@ -1776,7 +1792,13 @@ - return; - - #if defined(ENABLE_OSR) -+<<<<<<< .our - auto* osr_wcv = GetOffScreenWebContentsView(); -+======= -+ const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents()); -+ auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView()); -+ -+>>>>>>> .their - if (osr_wcv) - osr_wcv->SetFrameRate(frame_rate); - #endif -@@ -1787,7 +1809,13 @@ - return 0; - - #if defined(ENABLE_OSR) -+<<<<<<< .our - auto* osr_wcv = GetOffScreenWebContentsView(); -+======= -+ const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents()); -+ auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView()); -+ -+>>>>>>> .their - return osr_wcv ? osr_wcv->GetFrameRate() : 0; - #else - return 0; -@@ -1871,6 +1899,7 @@ - return mate::ConvertToV8(isolate, *web_preferences->preference()); - } - -+<<<<<<< .our - v8::Local<v8::Value> WebContents::GetLastWebPreferences( - v8::Isolate* isolate) const { - auto* web_preferences = WebContentsPreferences::From(web_contents()); -@@ -1880,6 +1909,17 @@ - } - - v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() const { -+======= -+v8::Local<v8::Value> WebContents::GetLastWebPreferences(v8::Isolate* isolate) { -+ WebContentsPreferences* web_preferences = -+ WebContentsPreferences::FromWebContents(web_contents()); -+ if (!web_preferences) -+ return v8::Null(isolate); -+ return mate::ConvertToV8(isolate, *web_preferences->last_web_preferences()); -+} -+ -+v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() { -+>>>>>>> .their - if (owner_window()) - return BrowserWindow::From(isolate(), owner_window()); - else -changed in both - base 100644 1270a0ce2c79edab0c1be08450f06eef7b8cdd49 atom/browser/api/atom_api_web_contents.h - our 100644 7939f8268aa8c3371623e0c15f3b6001d7f1efa4 atom/browser/api/atom_api_web_contents.h - their 100644 99e64f8ff8d9dc41eadc8d022d149e68679382f7 atom/browser/api/atom_api_web_contents.h -@@ -234,8 +234,13 @@ - v8::Local<v8::Value> GetPreloadPath(v8::Isolate* isolate) const; - - // Returns the web preferences of current WebContents. -+<<<<<<< .our - v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate) const; - v8::Local<v8::Value> GetLastWebPreferences(v8::Isolate* isolate) const; -+======= -+ v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate); -+ v8::Local<v8::Value> GetLastWebPreferences(v8::Isolate* isolate); -+>>>>>>> .their - - // Returns the owner window. - v8::Local<v8::Value> GetOwnerBrowserWindow() const; -changed in both - base 100644 61c97f2c35ce3c9e76cee59f9e4becd9649c993b atom/browser/atom_browser_client.cc - our 100644 57c4ee582405e6d501ec23940ccb10689ecd64a1 atom/browser/atom_browser_client.cc - their 100644 713b1bc6ec037aaa9f845b98d26a959d7d7688bc atom/browser/atom_browser_client.cc -@@ -27,6 +27,7 @@ - #include "base/command_line.h" - #include "base/environment.h" - #include "base/files/file_util.h" -+#include "base/path_service.h" - #include "base/stl_util.h" - #include "base/strings/string_number_conversions.h" - #include "base/strings/string_util.h" -@@ -296,6 +297,7 @@ - base::CommandLine* command_line, - int process_id) { - // Make sure we're about to launch a known executable -+<<<<<<< .our - { - base::FilePath child_path; - PathService::Get(content::CHILD_PROCESS_EXE, &child_path); -@@ -303,6 +305,11 @@ - base::ThreadRestrictions::ScopedAllowIO allow_io; - CHECK(base::MakeAbsoluteFilePath(command_line->GetProgram()) == child_path); - } -+======= -+ base::FilePath child_path; -+ PathService::Get(content::CHILD_PROCESS_EXE, &child_path); -+ CHECK(base::MakeAbsoluteFilePath(command_line->GetProgram()) == child_path); -+>>>>>>> .their - - std::string process_type = - command_line->GetSwitchValueASCII(::switches::kProcessType); -changed in both - base 100644 190898fdef9afb08c5110185136d3016bfd7edc2 atom/browser/atom_browser_main_parts.cc - our 100644 5229b19ca9af7845a3f2f13b7e0913f633b68b1d atom/browser/atom_browser_main_parts.cc - their 100644 89ab75c33cbe8bac8b50be241ae0ac82ea000ac6 atom/browser/atom_browser_main_parts.cc -@@ -223,7 +223,10 @@ - Browser::Get()->DidFinishLaunching(base::DictionaryValue()); - #endif - -+<<<<<<< .our - // Notify observers that main thread message loop was initialized. -+======= -+>>>>>>> .their - Browser::Get()->PreMainMessageLoopRun(); - } - -changed in both - base 100644 c714dc1f46ab633127a65a997e1adca4b240d2e8 atom/browser/browser.cc - our 100644 ce35de64d60c6767ac52596c1b32e7bde5ceefa0 atom/browser/browser.cc - their 100644 1e4bc5e8e72c21735530960fe617e07c3afeaa0c atom/browser/browser.cc -changed in both - base 100644 2204eafdd5503ab90c67659c2d3c377dd745cc68 atom/browser/browser.h - our 100644 aed7d25c37da59c0dd5e09940a064c329353a0b2 atom/browser/browser.h - their 100644 d0f929caf1792c3e62bc7e6f52ad9cf0b9655a91 atom/browser/browser.h -@@ -238,7 +238,13 @@ - - void PreMainMessageLoopRun(); - -+<<<<<<< .our - void AddObserver(BrowserObserver* obs) { observers_.AddObserver(obs); } -+======= -+ void AddObserver(BrowserObserver* obs) { -+ observers_.AddObserver(obs); -+ } -+>>>>>>> .their - - void RemoveObserver(BrowserObserver* obs) { observers_.RemoveObserver(obs); } - -changed in both - base 100644 3e50fc228b9ad5699dba2e2ecb70ee6212d6e5c1 atom/browser/browser_observer.h - our 100644 d518e8d6a7c6e8e30c09498883719a58c8a9f5e8 atom/browser/browser_observer.h - their 100644 fce24d8ac792e2262b1c5097d3b82bccfb0c2ca7 atom/browser/browser_observer.h -changed in both - base 100644 1ad07a90869708c653e38f0ee7924bcff761419d atom/browser/mac/atom_application_delegate.mm - our 100644 683f7a84bcaa2c47bb78cf299314a5afeb15639b atom/browser/mac/atom_application_delegate.mm - their 100644 ccf51133ce2594f2095455e2f30172ffcf7f2f72 atom/browser/mac/atom_application_delegate.mm -@@ -8,13 +8,21 @@ - #import "atom/browser/mac/atom_application.h" - #include "atom/browser/mac/dict_util.h" - #include "base/allocator/allocator_shim.h" -+<<<<<<< .our - #include "base/allocator/buildflags.h" -+======= -+#include "base/allocator/features.h" -+>>>>>>> .their - #include "base/mac/mac_util.h" - #include "base/mac/scoped_objc_class_swizzler.h" - #include "base/strings/sys_string_conversions.h" - #include "base/values.h" - -+<<<<<<< .our - #if BUILDFLAG(USE_ALLOCATOR_SHIM) -+======= -+#if BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM) -+>>>>>>> .their - // On macOS 10.12, the IME system attempts to allocate a 2^64 size buffer, - // which would typically cause an OOM crash. To avoid this, the problematic - // method is swizzled out and the make-OOM-fatal bit is disabled for the -@@ -35,7 +43,11 @@ - base::allocator::SetCallNewHandlerOnMallocFailure(true); - } - @end -+<<<<<<< .our - #endif // BUILDFLAG(USE_ALLOCATOR_SHIM) -+======= -+#endif // BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM) -+>>>>>>> .their - - @implementation AtomApplicationDelegate - -@@ -65,7 +77,11 @@ - atom::Browser::Get()->DidFinishLaunching(base::DictionaryValue()); - } - -+<<<<<<< .our - #if BUILDFLAG(USE_ALLOCATOR_SHIM) -+======= -+#if BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM) -+>>>>>>> .their - // Disable fatal OOM to hack around an OS bug https://crbug.com/654695. - if (base::mac::IsOS10_12()) { - g_swizzle_imk_input_session = new base::mac::ScopedObjCClassSwizzler( -changed in both - base 100644 949e5e9ec96d42d75e975e6e4facc249079bce9e atom/browser/native_browser_view.cc - our 100644 6460f2bfbd22f7809ce92325ffb36ddbe3512a9f atom/browser/native_browser_view.cc - their 100644 c97fe683e6c56b17a32eede8d397d2c2d47efa2b atom/browser/native_browser_view.cc -changed in both - base 100644 236f615c2b0664ee0c2f2c80182a1a6070956170 atom/browser/native_browser_view.h - our 100644 56937e4c8c69e3605d2b6cc71a0877b74ff4e83d atom/browser/native_browser_view.h - their 100644 7c154b60b00e25c42847ceefb98723b50ea03dd0 atom/browser/native_browser_view.h -@@ -48,7 +48,11 @@ - - // Called when the window needs to update its draggable region. - virtual void UpdateDraggableRegions( -+<<<<<<< .our - const std::vector<gfx::Rect>& system_drag_exclude_areas) {} -+======= -+ const std::vector<gfx::Rect>& system_drag_exclude_areas) {} -+>>>>>>> .their - - protected: - explicit NativeBrowserView( -changed in both - base 100644 4e7aa429ce27ae12e495ab579247d2d244fdd18f atom/browser/native_browser_view_mac.h - our 100644 726ca75433e8091a344ef8d731e51c27f8a23450 atom/browser/native_browser_view_mac.h - their 100644 0b04edad729faa8e2f79b4653426db1d941dafe3 atom/browser/native_browser_view_mac.h -@@ -23,6 +23,8 @@ - void SetAutoResizeFlags(uint8_t flags) override; - void SetBounds(const gfx::Rect& bounds) override; - void SetBackgroundColor(SkColor color) override; -+ void UpdateDraggableRegions( -+ const std::vector<gfx::Rect>& system_drag_exclude_areas) override; - - void UpdateDraggableRegions( - const std::vector<gfx::Rect>& system_drag_exclude_areas) override; -changed in both - base 100644 2ce2adc1f4fe02a600c18c2c7b0852e1fcf27710 atom/browser/native_browser_view_mac.mm - our 100644 0416e26e89f1e0f37366ef1798b4359da0729225 atom/browser/native_browser_view_mac.mm - their 100644 3d77b2a84891a724336e83af2284543470a57cf1 atom/browser/native_browser_view_mac.mm -@@ -15,16 +15,25 @@ - - @interface DragRegionView : NSView - -+<<<<<<< .our - @property(assign) NSPoint initialLocation; -+======= -+@property (assign) NSPoint initialLocation; -+>>>>>>> .their - - @end - - @interface NSWindow () -+<<<<<<< .our - - (void)performWindowDragWithEvent:(NSEvent*)event; -+======= -+- (void)performWindowDragWithEvent:(NSEvent *)event; -+>>>>>>> .their - @end - - @implementation DragRegionView - -+<<<<<<< .our - @synthesize initialLocation; - - - (BOOL)mouseDownCanMoveWindow { -@@ -56,32 +65,67 @@ - } - - if (self.window.styleMask & NSFullScreenWindowMask) { -+======= -+- (BOOL)mouseDownCanMoveWindow -+{ -+ return NO; -+} -+ -+- (NSView *)hitTest:(NSPoint)aPoint -+{ -+ // Pass-through events that don't hit one of the exclusion zones -+ for (NSView *exlusion_zones in [self subviews]) { -+ if ([exlusion_zones hitTest:aPoint]) -+ return nil; -+ } -+ -+ return self; -+} -+ -+- (void)mouseDown:(NSEvent *)event -+{ -+ if ([self.window respondsToSelector:@selector(performWindowDragWithEvent)]) { -+ [self.window performWindowDragWithEvent:event]; -+>>>>>>> .their - return; - } - - self.initialLocation = [event locationInWindow]; - } - -+<<<<<<< .our - - (void)mouseDragged:(NSEvent*)theEvent { -+======= -+- (void)mouseDragged:(NSEvent *)theEvent -+{ -+>>>>>>> .their - if ([self.window respondsToSelector:@selector(performWindowDragWithEvent)]) { - return; - } - -+<<<<<<< .our - if (self.window.styleMask & NSFullScreenWindowMask) { - return; - } - -+======= -+>>>>>>> .their - NSPoint currentLocation = [NSEvent mouseLocation]; - NSPoint newOrigin; - - NSRect screenFrame = [[NSScreen mainScreen] frame]; -+<<<<<<< .our - NSSize screenSize = screenFrame.size; - NSRect windowFrame = [self.window frame]; - NSSize windowSize = windowFrame.size; -+======= -+ NSRect windowFrame = [self.window frame]; -+>>>>>>> .their - - newOrigin.x = currentLocation.x - self.initialLocation.x; - newOrigin.y = currentLocation.y - self.initialLocation.y; - -+<<<<<<< .our - BOOL inMenuBar = (newOrigin.y + windowSize.height) > - (screenFrame.origin.y + screenSize.height); - BOOL screenAboveMainScreen = false; -@@ -116,6 +160,11 @@ - if (inMenuBar && !screenAboveMainScreen) { - newOrigin.y = screenFrame.origin.y + - (screenFrame.size.height - windowFrame.size.height); -+======= -+ // Don't let window get dragged up under the menu bar -+ if ((newOrigin.y + windowFrame.size.height) > (screenFrame.origin.y + screenFrame.size.height)) { -+ newOrigin.y = screenFrame.origin.y + (screenFrame.size.height - windowFrame.size.height); -+>>>>>>> .their - } - - // Move the window to the new location -@@ -195,6 +244,7 @@ - } - - void NativeBrowserViewMac::UpdateDraggableRegions( -+<<<<<<< .our - const std::vector<gfx::Rect>& drag_exclude_rects) { - NSView* web_view = GetWebContents()->GetNativeView(); - NSView* inspectable_view = GetInspectableWebContentsView()->GetNativeView(); -@@ -229,6 +279,58 @@ - initWithFrame:drag_region_view_exclude_rect]); - [drag_region_view addSubview:exclude_drag_region_view]; - } -+======= -+ const std::vector<gfx::Rect>& system_drag_exclude_areas) { -+ NSView* webView = GetInspectableWebContentsView()->GetNativeView(); -+ -+ NSInteger superViewHeight = NSHeight([webView.superview bounds]); -+ NSInteger webViewHeight = NSHeight([webView bounds]); -+ NSInteger webViewWidth = NSWidth([webView bounds]); -+ NSInteger webViewX = NSMinX([webView frame]); -+ NSInteger webViewY = 0; -+ -+ // Apple's NSViews have their coordinate system originate at the bottom left, -+ // meaning that we need to be a bit smarter when it comes to calculating our -+ // current top offset -+ if (webViewHeight > superViewHeight) { -+ webViewY = std::abs(webViewHeight - superViewHeight - (std::abs(NSMinY([webView frame])))); -+ } else { -+ webViewY = superViewHeight - NSMaxY([webView frame]); -+ } -+ -+ // Remove all DraggableRegionViews that are added last time. -+ // Note that [webView subviews] returns the view's mutable internal array and -+ // it should be copied to avoid mutating the original array while enumerating -+ // it. -+ base::scoped_nsobject<NSArray> subviews([[webView subviews] copy]); -+ for (NSView* subview in subviews.get()) -+ if ([subview isKindOfClass:[DragRegionView class]]) -+ [subview removeFromSuperview]; -+ -+ // Create one giant NSView that is draggable. -+ base::scoped_nsobject<NSView> dragRegion( -+ [[DragRegionView alloc] initWithFrame:NSZeroRect]); -+ [dragRegion setFrame:NSMakeRect(0, -+ 0, -+ webViewWidth, -+ webViewHeight)]; -+ -+ // Then, on top of that, add "exclusion zones" -+ for (auto iter = system_drag_exclude_areas.begin(); -+ iter != system_drag_exclude_areas.end(); -+ ++iter) { -+ base::scoped_nsobject<NSView> controlRegion( -+ [[ExcludeDragRegionView alloc] initWithFrame:NSZeroRect]); -+ [controlRegion setFrame:NSMakeRect(iter->x() - webViewX, -+ webViewHeight - iter->bottom() + webViewY, -+ iter->width(), -+ iter->height())]; -+ [dragRegion addSubview:controlRegion]; -+ } -+ -+ // Add the DragRegion to the WebView -+ [webView addSubview:dragRegion]; -+>>>>>>> .their - } - - // static -changed in both - base 100644 3dfb88d5398fc9c6c2985cd3df58c5a10ea56462 atom/browser/native_window_mac.h - our 100644 44a78198f44cdba9875e3fb27c8e2c87eaa6f33b atom/browser/native_window_mac.h - their 100644 45636eb7025e1c7250db17496e3553ce9422b2e4 atom/browser/native_window_mac.h -@@ -163,7 +163,16 @@ - void InternalSetParentWindow(NativeWindow* parent, bool attach); - void ShowWindowButton(NSWindowButton button); - -+<<<<<<< .our - void SetForwardMouseMessages(bool forward); -+======= -+ void InstallView(); -+ void UninstallView(); -+ -+ // Install the drag view, which will cover the whole window and decides -+ // whether we can drag. -+ void UpdateDraggableRegionViews(const std::vector<DraggableRegion>& regions); -+>>>>>>> .their - - AtomNSWindow* window_; // Weak ref, managed by widget_. - -changed in both - base 100644 2719c672954ab0eb2b8090fb25c9c9965c99e410 atom/browser/native_window_mac.mm - our 100644 004263ec127709067e903ffbf31003b8844226b4 atom/browser/native_window_mac.mm - their 100644 a0af83de3574e3a86f1e0064c8212dd6c526d40d atom/browser/native_window_mac.mm -@@ -1387,10 +1387,45 @@ - [parent->GetNativeWindow() addChildWindow:window_ ordered:NSWindowAbove]; - } - -+<<<<<<< .our - void NativeWindowMac::ShowWindowButton(NSWindowButton button) { - auto view = [window_ standardWindowButton:button]; - [view.superview addSubview:view positioned:NSWindowAbove relativeTo:nil]; - } -+======= -+ // Remove all ControlRegionViews that are added last time. -+ // Note that [webView subviews] returns the view's mutable internal array and -+ // it should be copied to avoid mutating the original array while enumerating -+ // it. -+ base::scoped_nsobject<NSArray> subviews([[webView subviews] copy]); -+ for (NSView* subview in subviews.get()) -+ if ([subview isKindOfClass:[ControlRegionView class]]) -+ [subview removeFromSuperview]; -+ -+ // Draggable regions is implemented by having the whole web view draggable -+ // (mouseDownCanMoveWindow) and overlaying regions that are not draggable. -+ std::vector<gfx::Rect> system_drag_exclude_areas = -+ CalculateNonDraggableRegions(regions, webViewWidth, webViewHeight); -+ -+ if (browser_view_) { -+ browser_view_->UpdateDraggableRegions(system_drag_exclude_areas); -+ } -+ -+ // Create and add a ControlRegionView for each region that needs to be -+ // excluded from the dragging. -+ for (std::vector<gfx::Rect>::const_iterator iter = -+ system_drag_exclude_areas.begin(); -+ iter != system_drag_exclude_areas.end(); -+ ++iter) { -+ base::scoped_nsobject<NSView> controlRegion( -+ [[ControlRegionView alloc] initWithFrame:NSZeroRect]); -+ [controlRegion setFrame:NSMakeRect(iter->x(), -+ webViewHeight - iter->bottom(), -+ iter->width(), -+ iter->height())]; -+ [webView addSubview:controlRegion]; -+ } -+>>>>>>> .their - - void NativeWindowMac::SetForwardMouseMessages(bool forward) { - [window_ setAcceptsMouseMovedEvents:forward]; -changed in both - base 100644 ad02ed620d6d94ba15e7f8d154063a0968178110 atom/browser/net/asar/url_request_asar_job.cc - our 100644 85eb2e1dd142b6d64aafb5350ae47603db989e8f atom/browser/net/asar/url_request_asar_job.cc - their 100644 5c4472a315911a6c2da533b35d489f8f9da5cd53 atom/browser/net/asar/url_request_asar_job.cc -@@ -243,6 +243,24 @@ - meta_info->mime_type_result = net::GetWellKnownMimeTypeFromExtension( - file_extension.substr(1), &meta_info->mime_type); - } -+<<<<<<< .our -+======= -+ -+ // We use GetWellKnownMimeTypeFromExtension() to ensure that configurations -+ // that may have been set by other programs on a user's machine don't affect -+ // the mime type returned (in particular, JS should always be -+ // (application/javascript). See https://crbug.com/797712. Using an accurate -+ // mime type is necessary at least for modules and sw, which enforce strict -+ // mime type requirements. -+ // TODO(deepak1556): Revert this when sw support is removed for file scheme. -+ base::FilePath::StringType file_extension = file_path.Extension(); -+ if (file_extension.empty()) { -+ meta_info->mime_type_result = false; -+ } else { -+ meta_info->mime_type_result = net::GetWellKnownMimeTypeFromExtension( -+ file_extension.substr(1), &meta_info->mime_type); -+ } -+>>>>>>> .their - } - - void URLRequestAsarJob::DidFetchMetaInfo(const FileMetaInfo* meta_info) { -changed in both - base 100644 ff426dd08c8e39bcb23aeff2cdf03f2db414529e atom/browser/net/url_request_fetch_job.cc - our 100644 68539433f4de80a96bc672de3a2834b299d6c04b atom/browser/net/url_request_fetch_job.cc - their 100644 04d0ddd1e6af761c8e36d6cb93b99866a886457a atom/browser/net/url_request_fetch_job.cc -changed in both - base 100644 c35e364236f68545a869ecfb34a6b9f496c0511f atom/browser/osr/osr_output_device.cc - our 100644 e5c1e7fd95fc6443e77f86c86645c51ca36d0d9b atom/browser/osr/osr_output_device.cc - their 100644 1234a17b842074ca4236066f09994cccf1a6a83b atom/browser/osr/osr_output_device.cc -@@ -80,7 +80,11 @@ - return; - active_ = active; - -+<<<<<<< .our - if (!active_ && !pending_damage_rect_.IsEmpty() && paint) -+======= -+ if (active_ && paint) -+>>>>>>> .their - OnPaint(gfx::Rect(viewport_pixel_size_)); - } - -changed in both - base 100644 5710bc41b8319597ae37c0cb995e42b24562de17 atom/browser/osr/osr_output_device.h - our 100644 4c62414fd0c57ba650c04e23a75fe9be82999b2e atom/browser/osr/osr_output_device.h - their 100644 a65865316fa4398d8aa161264a30dd19762eae27 atom/browser/osr/osr_output_device.h -changed in both - base 100644 11523a660b8f1d6972254117e84fd69588b1421a atom/browser/osr/osr_render_widget_host_view.cc - our 100644 4a2a0747fe2e6bf38c8999b80dbfea31e52a17fd atom/browser/osr/osr_render_widget_host_view.cc - their 100644 e2e521dbadd20313ebb92af117a21c407ffe05b5 atom/browser/osr/osr_render_widget_host_view.cc -@@ -259,12 +259,27 @@ - native_window_(native_window), - transparent_(transparent), - callback_(callback), -+<<<<<<< .our - frame_rate_(frame_rate), -+======= -+ parent_callback_(nullptr), -+ frame_rate_(frame_rate), -+ frame_rate_threshold_us_(0), -+ last_time_(base::Time::Now()), -+>>>>>>> .their - scale_factor_(kDefaultScaleFactor), - size_(native_window->GetSize()), - painting_(painting), - is_showing_(!render_widget_host_->is_hidden()), -+<<<<<<< .our - mouse_wheel_phase_handler_(render_widget_host_, this), -+======= -+ is_destroyed_(false), -+ popup_position_(gfx::Rect()), -+ hold_resize_(false), -+ pending_resize_(false), -+ paint_callback_running_(false), -+>>>>>>> .their - weak_ptr_factory_(this) { - DCHECK(render_widget_host_); - bool is_guest_view_hack = parent_host_view_ != nullptr; -@@ -292,9 +307,13 @@ - compositor_.reset( - new ui::Compositor(context_factory_private->AllocateFrameSinkId(), - content::GetContextFactory(), context_factory_private, -+<<<<<<< .our - base::ThreadTaskRunnerHandle::Get(), - features::IsSurfaceSynchronizationEnabled(), - false /* enable_pixel_canvas */)); -+======= -+ base::ThreadTaskRunnerHandle::Get())); -+>>>>>>> .their - compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget); - compositor_->SetRootLayer(root_layer_.get()); - #endif -@@ -713,8 +732,18 @@ - } - - return new OffScreenRenderWidgetHostView( -+<<<<<<< .our - transparent_, true, embedder_host_view->GetFrameRate(), callback_, - render_widget_host, embedder_host_view, native_window_); -+======= -+ transparent_, -+ true, -+ embedder_host_view->GetFrameRate(), -+ callback_, -+ render_widget_host, -+ embedder_host_view, -+ native_window_); -+>>>>>>> .their - } - - #if !defined(OS_MACOSX) -@@ -1204,7 +1233,11 @@ - - SetupFrameRate(true); - -+<<<<<<< .our - for (auto* guest_host_view : guest_host_views_) -+======= -+ for (auto guest_host_view : guest_host_views_) -+>>>>>>> .their - guest_host_view->SetFrameRate(frame_rate); - } - -@@ -1233,10 +1266,15 @@ - - frame_rate_threshold_us_ = 1000000 / frame_rate_; - -+<<<<<<< .our - if (GetCompositor()) { - GetCompositor()->SetAuthoritativeVSyncInterval( - base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_)); - } -+======= -+ GetCompositor()->SetAuthoritativeVSyncInterval( -+ base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_)); -+>>>>>>> .their - - if (copy_frame_generator_.get()) { - copy_frame_generator_->set_frame_rate_threshold_us( -changed in both - base 100644 dc204a311ff557a1f2b38c2933fbcec47c8751a7 atom/browser/osr/osr_render_widget_host_view.h - our 100644 b81f6310f864c00fea50b1aac49dc89173eaa302 atom/browser/osr/osr_render_widget_host_view.h - their 100644 a4b5593cf28a2b09c28c4285efa7a0cdae2b76da atom/browser/osr/osr_render_widget_host_view.h -@@ -317,6 +317,8 @@ - viz::LocalSurfaceId local_surface_id_; - viz::ParentLocalSurfaceIdAllocator local_surface_id_allocator_; - -+ bool paint_callback_running_; -+ - std::unique_ptr<ui::Layer> root_layer_; - std::unique_ptr<ui::Compositor> compositor_; - std::unique_ptr<content::DelegatedFrameHost> delegated_frame_host_; -changed in both - base 100644 0e10abf6a034ab604f51553eb905b18e18f45552 atom/browser/osr/osr_web_contents_view.cc - our 100644 c8223df0d8c6f3436d323059686e42684ff98462 atom/browser/osr/osr_web_contents_view.cc - their 100644 4cbc6a5c42f9762b81fc4d601ebb534dedcd4914 atom/browser/osr/osr_web_contents_view.cc -@@ -13,9 +13,18 @@ - namespace atom { - - OffScreenWebContentsView::OffScreenWebContentsView( -+<<<<<<< .our - bool transparent, - const OnPaintCallback& callback) - : transparent_(transparent), callback_(callback) { -+======= -+ bool transparent, const OnPaintCallback& callback) -+ : transparent_(transparent), -+ painting_(true), -+ frame_rate_(60), -+ callback_(callback), -+ web_contents_(nullptr) { -+>>>>>>> .their - #if defined(OS_MACOSX) - PlatformCreate(); - #endif -@@ -104,8 +113,18 @@ - - auto* relay = NativeWindowRelay::FromWebContents(web_contents_); - return new OffScreenRenderWidgetHostView( -+<<<<<<< .our - transparent_, painting_, GetFrameRate(), callback_, render_widget_host, - nullptr, relay->window.get()); -+======= -+ transparent_, -+ painting_, -+ GetFrameRate(), -+ callback_, -+ render_widget_host, -+ nullptr, -+ relay->window.get()); -+>>>>>>> .their - } - - content::RenderWidgetHostViewBase* -@@ -124,8 +143,18 @@ - : web_contents_impl->GetRenderWidgetHostView()); - - return new OffScreenRenderWidgetHostView( -+<<<<<<< .our - transparent_, true, view->GetFrameRate(), callback_, render_widget_host, - view, relay->window.get()); -+======= -+ transparent_, -+ true, -+ view->GetFrameRate(), -+ callback_, -+ render_widget_host, -+ view, -+ relay->window.get()); -+>>>>>>> .their - } - - void OffScreenWebContentsView::SetPageTitle(const base::string16& title) {} -@@ -209,6 +238,42 @@ - } - } - -+void OffScreenWebContentsView::SetPainting(bool painting) { -+ auto* view = GetView(); -+ if (view != nullptr) { -+ view->SetPainting(painting); -+ } else { -+ painting_ = painting; -+ } -+} -+ -+bool OffScreenWebContentsView::IsPainting() const { -+ auto* view = GetView(); -+ if (view != nullptr) { -+ return view->IsPainting(); -+ } else { -+ return painting_; -+ } -+} -+ -+void OffScreenWebContentsView::SetFrameRate(int frame_rate) { -+ auto* view = GetView(); -+ if (view != nullptr) { -+ view->SetFrameRate(frame_rate); -+ } else { -+ frame_rate_ = frame_rate; -+ } -+} -+ -+int OffScreenWebContentsView::GetFrameRate() const { -+ auto* view = GetView(); -+ if (view != nullptr) { -+ return view->GetFrameRate(); -+ } else { -+ return frame_rate_; -+ } -+} -+ - OffScreenRenderWidgetHostView* OffScreenWebContentsView::GetView() const { - if (web_contents_) { - return static_cast<OffScreenRenderWidgetHostView*>( -changed in both - base 100644 ffb3b38619c4521f9947fe29e3871ed06d97978e atom/browser/osr/osr_web_contents_view.h - our 100644 206ab9dd3421af522a12aba615c6f040ba176ba4 atom/browser/osr/osr_web_contents_view.h - their 100644 788e55bf316d8069811fc026bf610ad231371fce atom/browser/osr/osr_web_contents_view.h -@@ -83,8 +83,13 @@ - OffScreenRenderWidgetHostView* GetView() const; - - const bool transparent_; -+<<<<<<< .our - bool painting_ = true; - int frame_rate_ = 60; -+======= -+ bool painting_; -+ int frame_rate_; -+>>>>>>> .their - OnPaintCallback callback_; - - // Weak refs. -changed in both - base 100644 9610d80693b1670f696f82812442419504d61454 atom/browser/relauncher.cc - our 100644 35c6785e3d87d21eaea27ad5818434d870326047 atom/browser/relauncher.cc - their 100644 9dfb6edd06661f302ca7498a2ba34f0ce70c938b atom/browser/relauncher.cc -changed in both - base 100644 e4207b2f46835a44089d4e23a5e973e5ff401f4d atom/browser/resources/mac/Info.plist - our 100644 9094f0f7335edf833d51f688851e6a105de60433 atom/browser/resources/mac/Info.plist - their 100644 cd8c6245a978327778f3f45b106347287d6a9ecb atom/browser/resources/mac/Info.plist -@@ -17,9 +17,15 @@ - <key>CFBundleIconFile</key> - <string>electron.icns</string> - <key>CFBundleVersion</key> -+<<<<<<< .our - <string>4.0.0</string> - <key>CFBundleShortVersionString</key> - <string>4.0.0</string> -+======= -+ <string>1.7.16</string> -+ <key>CFBundleShortVersionString</key> -+ <string>1.7.16</string> -+>>>>>>> .their - <key>LSApplicationCategoryType</key> - <string>public.app-category.developer-tools</string> - <key>LSMinimumSystemVersion</key> -changed in both - base 100644 9035ccc9e4608312b0fef482afaafbc0f2fb8486 atom/browser/resources/win/atom.rc - our 100644 c0bd831e8bddf10180f75cd40694831e2e98622d atom/browser/resources/win/atom.rc - their 100644 bb309c131cc0946c5683a026d0561c82e54510ce atom/browser/resources/win/atom.rc -@@ -56,8 +56,13 @@ - // - - VS_VERSION_INFO VERSIONINFO -+<<<<<<< .our - FILEVERSION 4,0,0,20180821 - PRODUCTVERSION 4,0,0,20180821 -+======= -+ FILEVERSION 1,7,16,0 -+ PRODUCTVERSION 1,7,16,0 -+>>>>>>> .their - FILEFLAGSMASK 0x3fL - #ifdef _DEBUG - FILEFLAGS 0x1L -@@ -74,12 +79,20 @@ - BEGIN - VALUE "CompanyName", "GitHub, Inc." - VALUE "FileDescription", "Electron" -+<<<<<<< .our - VALUE "FileVersion", "4.0.0" -+======= -+ VALUE "FileVersion", "1.7.16" -+>>>>>>> .their - VALUE "InternalName", "electron.exe" - VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." - VALUE "OriginalFilename", "electron.exe" - VALUE "ProductName", "Electron" -+<<<<<<< .our - VALUE "ProductVersion", "4.0.0" -+======= -+ VALUE "ProductVersion", "1.7.16" -+>>>>>>> .their - VALUE "SquirrelAwareVersion", "1" - END - END -changed in both - base 100644 26662cf48502d880f6c18d9cb3236a42e2a813e4 atom/browser/ui/cocoa/atom_touch_bar.h - our 100644 fd6bb0cdc449d6d8f48a208f3300e857045d4686 atom/browser/ui/cocoa/atom_touch_bar.h - their 100644 d36e45898ea54f9e4205786f6b1fe9592c5acd67 atom/browser/ui/cocoa/atom_touch_bar.h -@@ -17,9 +17,13 @@ - #include "native_mate/constructor.h" - #include "native_mate/persistent_dictionary.h" - -+<<<<<<< .our - @interface AtomTouchBar : NSObject <NSScrubberDelegate, - NSScrubberDataSource, - NSScrubberFlowLayoutDelegate> { -+======= -+@interface AtomTouchBar : NSObject<NSScrubberDelegate, NSScrubberDataSource, NSScrubberFlowLayoutDelegate> { -+>>>>>>> .their - @protected - std::vector<mate::PersistentDictionary> ordered_settings_; - std::map<std::string, mate::PersistentDictionary> settings_; -changed in both - base 100644 30a3e6643fb89ca09e4310f789b20f1e22b1962c atom/browser/ui/cocoa/atom_touch_bar.mm - our 100644 72777c491f8a6024b61ed8cd3b849a5637f394a7 atom/browser/ui/cocoa/atom_touch_bar.mm - their 100644 366cb9e2d0c8adc3cee70a87d08f8ea9f2eca9d2 atom/browser/ui/cocoa/atom_touch_bar.mm -@@ -765,15 +765,21 @@ - return itemView; - } - -+<<<<<<< .our - - (NSSize)scrubber:(NSScrubber*)scrubber - layout:(NSScrubberFlowLayout*)layout - sizeForItemAtIndex:(NSInteger)itemIndex API_AVAILABLE(macosx(10.12.2)) { -+======= -+- (NSSize)scrubber:(NSScrubber *)scrubber layout:(NSScrubberFlowLayout *)layout sizeForItemAtIndex:(NSInteger)itemIndex -+{ -+>>>>>>> .their - NSInteger width = 50; - NSInteger height = 30; - NSInteger margin = 15; - NSSize defaultSize = NSMakeSize(width, height); - - std::string s_id([[scrubber identifier] UTF8String]); -+<<<<<<< .our - if (![self hasItemWithID:s_id]) - return defaultSize; - -@@ -784,12 +790,22 @@ - - if (itemIndex >= static_cast<NSInteger>(items.size())) - return defaultSize; -+======= -+ if (![self hasItemWithID:s_id]) return defaultSize; -+ -+ mate::PersistentDictionary settings = settings_[s_id]; -+ std::vector<mate::PersistentDictionary> items; -+ if (!settings.Get("items", &items)) return defaultSize; -+ -+ if (itemIndex >= static_cast<NSInteger>(items.size())) return defaultSize; -+>>>>>>> .their - - mate::PersistentDictionary item = items[itemIndex]; - std::string title; - - if (item.Get("label", &title)) { - NSSize size = NSMakeSize(CGFLOAT_MAX, CGFLOAT_MAX); -+<<<<<<< .our - NSRect textRect = [base::SysUTF8ToNSString(title) - boundingRectWithSize:size - options:NSStringDrawingUsesLineFragmentOrigin | -@@ -797,6 +813,11 @@ - attributes:@{ - NSFontAttributeName : [NSFont systemFontOfSize:0] - }]; -+======= -+ NSRect textRect = [base::SysUTF8ToNSString(title) boundingRectWithSize:size -+ options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading -+ attributes:@{ NSFontAttributeName: [NSFont systemFontOfSize:0]}]; -+>>>>>>> .their - - width = textRect.size.width + margin; - } else { -changed in both - base 100644 6fe7c820a1ccda7befcabbb6b9e740cab8d33afc atom/browser/ui/cocoa/touch_bar_forward_declarations.h - our 100644 281672c30420d3e1abb77cb96db69e375f4d5ea7 atom/browser/ui/cocoa/touch_bar_forward_declarations.h - their 100644 062723bca670a1bb5a5b4c34524d7eecfa52f50d atom/browser/ui/cocoa/touch_bar_forward_declarations.h -@@ -14,11 +14,16 @@ - #pragma clang assume_nonnull begin - - @class NSTouchBar, NSTouchBarItem; -+<<<<<<< .our - @class NSScrubber, NSScrubberItemView, NSScrubberArrangedView, - NSScrubberTextItemView, NSScrubberImageItemView, NSScrubberSelectionStyle; - @protocol NSTouchBarDelegate - , NSScrubberDelegate, NSScrubberDataSource, NSScrubberFlowLayoutDelegate, - NSScrubberFlowLayout; -+======= -+@class NSScrubber, NSScrubberItemView, NSScrubberArrangedView, NSScrubberTextItemView, NSScrubberImageItemView, NSScrubberSelectionStyle; -+@protocol NSTouchBarDelegate, NSScrubberDelegate, NSScrubberDataSource, NSScrubberFlowLayoutDelegate, NSScrubberFlowLayout; -+>>>>>>> .their - - typedef float NSTouchBarItemPriority; - static const NSTouchBarItemPriority NSTouchBarItemPriorityHigh = 1000; -@@ -150,10 +155,17 @@ - - @end - -+<<<<<<< .our - @interface NSScrubberFlowLayout : NSObject - @end - - @interface NSScrubberSelectionStyle : NSObject <NSCoding> -+======= -+@interface NSScrubberFlowLayout: NSObject -+@end -+ -+@interface NSScrubberSelectionStyle : NSObject<NSCoding> -+>>>>>>> .their - - @property(class, strong, readonly) - NSScrubberSelectionStyle* outlineOverlayStyle; -@@ -245,6 +257,12 @@ - - @end - -+@protocol NSScrubberFlowLayoutDelegate<NSObject> -+ -+- (NSSize)scrubber:(NSScrubber *)scrubber layout:(NSScrubberFlowLayout *)layout sizeForItemAtIndex:(NSInteger)itemIndex; -+ -+@end -+ - #pragma clang assume_nonnull end - - #elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12_1 -changed in both - base 100644 be9c15e7238987eeb533d6b981edea5b4125f8be atom/browser/ui/file_dialog_mac.mm - our 100644 18b18a8b240cda5512ae49e0afde5c749bdf75c0 atom/browser/ui/file_dialog_mac.mm - their 100644 cdc10d6cb430b6521e262ba5d19acaeb23859f42 atom/browser/ui/file_dialog_mac.mm -@@ -94,6 +94,7 @@ - - // Passing empty array to setAllowedFileTypes will cause exception. - NSArray* file_types = nil; -+<<<<<<< .our - NSUInteger count = [file_types_list count]; - if (count > 0) { - file_types = [[file_types_list objectAtIndex:0] allObjects]; -@@ -102,6 +103,11 @@ - if ([file_types count] == 0 || [file_types containsObject:@"*"]) - file_types = nil; - } -+======= -+ if ([file_type_set count]) -+ file_types = [file_type_set allObjects]; -+ -+>>>>>>> .their - [dialog setAllowedFileTypes:file_types]; - - if (count <= 1) -changed in both - base 100644 cc621625818feaeddf4fb76cd9103c822795e652 atom/browser/web_contents_preferences.cc - our 100644 c21c93383155091a7481cdd4e741cefad90a4a55 atom/browser/web_contents_preferences.cc - their 100644 701791b41d871d605367604e872f17668a7d24b5 atom/browser/web_contents_preferences.cc -@@ -97,6 +97,7 @@ - instances_.push_back(this); - - // Set WebPreferences defaults onto the JS object -+<<<<<<< .our - SetDefaultBoolIfUndefined(options::kPlugins, false); - SetDefaultBoolIfUndefined(options::kExperimentalFeatures, false); - bool node = SetDefaultBoolIfUndefined(options::kNodeIntegration, true); -@@ -104,11 +105,22 @@ - SetDefaultBoolIfUndefined(options::kWebviewTag, node); - SetDefaultBoolIfUndefined(options::kSandbox, false); - SetDefaultBoolIfUndefined(options::kNativeWindowOpen, false); -+======= -+ SetDefaultBoolIfUndefined("plugins", false); -+ SetDefaultBoolIfUndefined(options::kExperimentalFeatures, false); -+ SetDefaultBoolIfUndefined(options::kExperimentalCanvasFeatures, false); -+ bool node = SetDefaultBoolIfUndefined(options::kNodeIntegration, true); -+ SetDefaultBoolIfUndefined(options::kNodeIntegrationInWorker, false); -+ SetDefaultBoolIfUndefined(options::kWebviewTag, node); -+ SetDefaultBoolIfUndefined("sandbox", false); -+ SetDefaultBoolIfUndefined("nativeWindowOpen", false); -+>>>>>>> .their - SetDefaultBoolIfUndefined(options::kContextIsolation, false); - SetDefaultBoolIfUndefined("javascript", true); - SetDefaultBoolIfUndefined("images", true); - SetDefaultBoolIfUndefined("textAreasAreResizable", true); - SetDefaultBoolIfUndefined("webgl", true); -+<<<<<<< .our - bool webSecurity = true; - SetDefaultBoolIfUndefined(options::kWebSecurity, webSecurity); - // If webSecurity was explicity set to false, let's inherit that into -@@ -125,6 +137,15 @@ - SetDefaultBoolIfUndefined(options::kOffscreen, false); - - last_preference_ = preference_.Clone(); -+======= -+ SetDefaultBoolIfUndefined("webSecurity", true); -+ SetDefaultBoolIfUndefined("allowRunningInsecureContent", false); -+ #if defined(OS_MACOSX) -+ SetDefaultBoolIfUndefined(options::kScrollBounce, false); -+ #endif -+ SetDefaultBoolIfUndefined("offscreen", false); -+ last_web_preferences_.MergeDictionary(&web_preferences_); -+>>>>>>> .their - } - - WebContentsPreferences::~WebContentsPreferences() { -@@ -154,6 +175,16 @@ - return default_value; - } - -+bool WebContentsPreferences::SetDefaultBoolIfUndefined(const std::string key, -+ bool val) { -+ bool existing; -+ if (!web_preferences_.GetBoolean(key, &existing)) { -+ web_preferences_.SetBoolean(key, val); -+ return val; -+ } -+ return existing; -+} -+ - void WebContentsPreferences::Merge(const base::DictionaryValue& extend) { - if (preference_.is_dict()) - static_cast<base::DictionaryValue*>(&preference_)->MergeDictionary(&extend); -@@ -212,8 +243,18 @@ - return FromWebContents(web_contents); - } - -+<<<<<<< .our - void WebContentsPreferences::AppendCommandLineSwitches( - base::CommandLine* command_line) { -+======= -+ // We are appending args to a webContents so let's save the current state -+ // of our preferences object so that during the lifetime of the WebContents -+ // we can fetch the options used to initally configure the WebContents -+ self->last_web_preferences_.Clear(); -+ self->last_web_preferences_.MergeDictionary(&web_preferences); -+ -+ bool b; -+>>>>>>> .their - // Check if plugins are enabled. - if (IsEnabled(options::kPlugins)) - command_line->AppendSwitch(switches::kEnablePlugins); -changed in both - base 100644 366aa1d9520847d6b81e673cc5a2156d53cc5ba5 atom/browser/web_contents_preferences.h - our 100644 d835347afcd259f473f95271a2c19e42afcc6f2b atom/browser/web_contents_preferences.h - their 100644 be277487d1d669b5e85676ff1a7ca4da365c0572 atom/browser/web_contents_preferences.h -@@ -59,8 +59,15 @@ - bool GetPreloadPath(base::FilePath::StringType* path) const; - - // Returns the web preferences. -+<<<<<<< .our - base::Value* preference() { return &preference_; } - base::Value* last_preference() { return &last_preference_; } -+======= -+ base::DictionaryValue* web_preferences() { return &web_preferences_; } -+ base::DictionaryValue* last_web_preferences() { -+ return &last_web_preferences_; -+ } -+>>>>>>> .their - - private: - friend class content::WebContentsUserData<WebContentsPreferences>; -@@ -75,6 +82,14 @@ - static std::vector<WebContentsPreferences*> instances_; - - content::WebContents* web_contents_; -+<<<<<<< .our -+======= -+ base::DictionaryValue web_preferences_; -+ base::DictionaryValue last_web_preferences_; -+ -+ // Set preference value to given bool if user did not provide value -+ bool SetDefaultBoolIfUndefined(const std::string key, bool val); -+>>>>>>> .their - - base::Value preference_ = base::Value(base::Value::Type::DICTIONARY); - base::Value last_preference_ = base::Value(base::Value::Type::DICTIONARY); -changed in both - base 100644 08880ffe4a3591d9010f55ef18ce288e69101fe1 atom/common/atom_command_line.cc - our 100644 287e43f75fef778948ef9acdac8b9a7edfe07d0a atom/common/atom_command_line.cc - their 100644 54420b533a6b2600a87c95645b73bc01fbf0122f atom/common/atom_command_line.cc -changed in both - base 100644 0f58ceb5123e85577732993552c326640d71de54 atom/common/atom_version.h - our 100644 65e7d19911559a40b1b258319df5fe0fa180354f atom/common/atom_version.h - their 100644 2b564da8029267a5d66e908b46da11a0a9870376 atom/common/atom_version.h -@@ -5,10 +5,22 @@ - #ifndef ATOM_COMMON_ATOM_VERSION_H_ - #define ATOM_COMMON_ATOM_VERSION_H_ - -+<<<<<<< .our - #define ATOM_MAJOR_VERSION 4 - #define ATOM_MINOR_VERSION 0 - #define ATOM_PATCH_VERSION 0 - #define ATOM_PRE_RELEASE_VERSION -nightly.20180821 -+======= -+#define ATOM_MAJOR_VERSION 1 -+#define ATOM_MINOR_VERSION 7 -+#define ATOM_PATCH_VERSION 16 -+// #define ATOM_PRE_RELEASE_VERSION -+#define ATOM_VERSION_IS_RELEASE 1 -+ -+#ifndef ATOM_TAG -+# define ATOM_TAG "" -+#endif -+>>>>>>> .their - - #ifndef ATOM_STRINGIFY - #define ATOM_STRINGIFY(n) ATOM_STRINGIFY_HELPER(n) -changed in both - base 100644 03e96ae8a4f3cb7e656143fb46dff58eb924fa12 atom/common/node_bindings.cc - our 100644 e6aded2e661af919c2d89c2f9bd46b4921d4aec4 atom/common/node_bindings.cc - their 100644 84792c58207dd85de2d2b60bd789417346c31b50 atom/common/node_bindings.cc -@@ -228,8 +228,12 @@ - } - - node::Environment* NodeBindings::CreateEnvironment( -+<<<<<<< .our - v8::Handle<v8::Context> context, - node::MultiIsolatePlatform* platform) { -+======= -+ v8::Handle<v8::Context> context) { -+>>>>>>> .their - #if defined(OS_WIN) - auto& atom_args = AtomCommandLine::argv(); - std::vector<std::string> args(atom_args.size()); -@@ -255,8 +259,13 @@ - base::FilePath resources_path = GetResourcesPath(browser_env_ == BROWSER); - base::FilePath script_path = - resources_path.Append(FILE_PATH_LITERAL("electron.asar")) -+<<<<<<< .our - .Append(process_type) - .Append(FILE_PATH_LITERAL("init.js")); -+======= -+ .Append(process_type) -+ .Append(FILE_PATH_LITERAL("init.js")); -+>>>>>>> .their - args.insert(args.begin() + 1, script_path.AsUTF8Unsafe()); - - std::unique_ptr<const char* []> c_argv = StringVectorToArgArray(args); -changed in both - base 100644 a56d2e24c0e77dcdcfd240c366daede6e3f2f709 brightray/browser/mac/cocoa_notification.mm - our 100644 57f53931e972adac9cbadf643c737b21d6b9b712 brightray/browser/mac/cocoa_notification.mm - their 100644 cd7b69ef4058ebc5ccf3396474551f2fc065d20f brightray/browser/mac/cocoa_notification.mm -@@ -48,7 +48,13 @@ - - if (options.silent) { - [notification_ setSoundName:nil]; -+<<<<<<< .our - } else if (options.sound.empty()) { -+======= -+ } else if (options.sound != nil) { -+ [notification_ setSoundName:base::SysUTF16ToNSString(options.sound)]; -+ } else { -+>>>>>>> .their - [notification_ setSoundName:NSUserNotificationDefaultSoundName]; - } else { - [notification_ setSoundName:base::SysUTF16ToNSString(options.sound)]; -changed in both - base 100644 017fdd85261df0df1b885ef8a15fed74ed86c8de brightray/browser/notification.h - our 100644 efb8752f3595f81d8f080573924791cd1411ae84 brightray/browser/notification.h - their 100644 69efcff386f544f84074eb39781e3daa083ae64f brightray/browser/notification.h -changed in both - base 100644 eab6c35479a3551de482e323fce00a962de423a5 chromium_src/chrome/browser/process_singleton.h - our 100644 b2909e8d1852c8fa69daa21b83432bb7c36f17c9 chromium_src/chrome/browser/process_singleton.h - their 100644 d77f5b41df88e4dba037c5946715bf690e28f95e chromium_src/chrome/browser/process_singleton.h -changed in both - base 100644 e1e25cf91de0195202cae646dda4f124ee161dc2 chromium_src/chrome/browser/process_singleton_posix.cc - our 100644 4891743710d16673c6a72d76a303f6ac56a5ad32 chromium_src/chrome/browser/process_singleton_posix.cc - their 100644 1943ad51f635b19379753b67bc45d8ad316d6eb1 chromium_src/chrome/browser/process_singleton_posix.cc -@@ -883,8 +883,15 @@ - void ProcessSingleton::StartListeningOnSocket() { - watcher_ = new LinuxWatcher(this); - BrowserThread::PostTask( -+<<<<<<< .our - BrowserThread::IO, FROM_HERE, - base::Bind(&ProcessSingleton::LinuxWatcher::StartListening, watcher_, -+======= -+ BrowserThread::IO, -+ FROM_HERE, -+ base::Bind(&ProcessSingleton::LinuxWatcher::StartListening, -+ watcher_, -+>>>>>>> .their - sock_)); - } - -changed in both - base 100644 b488ad457674287187b9b0edf24a423f774ff9c6 chromium_src/chrome/browser/process_singleton_win.cc - our 100644 6d0d102430ff700e703cef7e3189403c4a35218f chromium_src/chrome/browser/process_singleton_win.cc - their 100644 cce6054d1230c396f18a1eb358aa87faf1b29fd5 chromium_src/chrome/browser/process_singleton_win.cc -changed in both - base 100644 9036102668286db7ca4d338dc8f326f1bd3653b7 docs/api/notification.md - our 100644 08776a9d3b8fb0969a5538981a2dd991b248fb82 docs/api/notification.md - their 100644 6dab356bbda50812a241fa150f39a03580d8cfae docs/api/notification.md -@@ -30,6 +30,7 @@ - ### `new Notification([options])` _Experimental_ - - * `options` Object -+<<<<<<< .our - * `title` String - A title for the notification, which will be shown at the top of the notification window when it is shown. - * `subtitle` String (optional) _macOS_ - A subtitle for the notification, which will be displayed below the title. - * `body` String - The body text of the notification, which will be displayed below the title or subtitle. -@@ -40,6 +41,18 @@ - * `sound` String (optional) _macOS_ - The name of the sound file to play when the notification is shown. - * `actions` [NotificationAction[]](structures/notification-action.md) (optional) _macOS_ - Actions to add to the notification. Please read the available actions and limitations in the `NotificationAction` documentation. - * `closeButtonText` String (optional) _macOS_ - A custom title for the close button of an alert. An empty string will cause the default localized text to be used. -+======= -+ * `title` String - A title for the notification, which will be shown at the top of the notification window when it is shown -+ * `subtitle` String - (optional) A subtitle for the notification, which will be displayed below the title. _macOS_ -+ * `body` String - The body text of the notification, which will be displayed below the title or subtitle -+ * `silent` Boolean - (optional) Whether or not to emit an OS notification noise when showing the notification -+ * `icon` [NativeImage](native-image.md) - (optional) An icon to use in the notification -+ * `hasReply` Boolean - (optional) Whether or not to add an inline reply option to the notification. _macOS_ -+ * `replyPlaceholder` String - (optional) The placeholder to write in the inline reply input field. _macOS_ -+ * `sound` String - (optional) The name of the sound file to play when the notification is shown. _macOS_ -+ * `actions` [NotificationAction[]](structures/notification-action.md) - (optional) Actions to add to the notification. Please read the available actions and limitations in the `NotificationAction` documentation _macOS_ -+ -+>>>>>>> .their - - ### Instance Events - -@@ -104,6 +117,7 @@ - not immediately show it to the user, you need to call this method before the OS - will display it. - -+<<<<<<< .our - If the notification has been shown before, this method will dismiss the previously - shown notification and create a new one with identical properties. - -@@ -111,6 +125,8 @@ - - Dismisses the notification. - -+======= -+>>>>>>> .their - ### Playing Sounds - - On macOS, you can specify the name of the sound you'd like to play when the -changed in both - base 100644 456fc207fe98260b4f971154f9260fad685fc563 docs/api/touch-bar-button.md - our 100644 4f3e2906ecd35c700c47edf358cd8ef2a4977050 docs/api/touch-bar-button.md - their 100644 461c0c5155227adf2306cb37865151aec48f7f7e docs/api/touch-bar-button.md -changed in both - base 100644 17d416608b94068be43459bf2ce9ca18fc4dcedc electron.gyp - our 100644 944ddab2a3fd879044e31677e4bac2843fffbdee electron.gyp - their 100644 29a0f6ea3c58105659d1603447729d9021f1775e electron.gyp -@@ -4,7 +4,11 @@ - 'product_name%': 'Electron', - 'company_name%': 'GitHub, Inc', - 'company_abbr%': 'github', -+<<<<<<< .our - 'version%': '4.0.0-nightly.20180821', -+======= -+ 'version%': '1.7.16', -+>>>>>>> .their - 'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c', - }, - 'includes': [ -@@ -255,6 +259,11 @@ - ], - }, - ], -+ 'link_settings': { -+ 'ldflags': [ -+ '-Wl,-z,noexecstack', -+ ], -+ }, - }], # OS=="linux" - ], - }, # target <(project_name) -changed in both - base 100644 e90fe322ba15d1613f7fa300427bcb96c10d351f filenames.gypi - our 100644 f57860558f06b7e5d8a50f48cfc7e53044df0bc6 filenames.gypi - their 100644 22d8b072a7bbd28e0a9c67896210d54640b1628a filenames.gypi -@@ -114,6 +114,11 @@ - 'atom/app/atom_main_delegate_mac.mm', - 'atom/app/command_line_args.cc', - 'atom/app/command_line_args.h', -+<<<<<<< .our -+======= -+ 'atom/app/node_main.cc', -+ 'atom/app/node_main.h', -+>>>>>>> .their - 'atom/app/uv_task_runner.cc', - 'atom/app/uv_task_runner.h', - 'atom/browser/api/atom_api_app.cc', -changed in both - base 100644 55b8372f52cf485ea5f812baed5f48296bacb962 lib/browser/api/auto-updater/auto-updater-win.js - our 100644 7fead4aabb4a8768db4e4d3bc13da4927cf3c42e lib/browser/api/auto-updater/auto-updater-win.js - their 100644 fced1258797756160d28cd1a16e0e5515d39bf5b lib/browser/api/auto-updater/auto-updater-win.js -changed in both - base 100644 4783a9dd98852f303fe50e6fd03dabdecd6d0693 lib/browser/api/auto-updater/squirrel-update-win.js - our 100644 fecf7958cd0afd54e978f011f5f87eea751faf6d lib/browser/api/auto-updater/squirrel-update-win.js - their 100644 60345f1a1abead139d280b14457e558c6467de45 lib/browser/api/auto-updater/squirrel-update-win.js -changed in both - base 100644 731f82838af35a13442a2723b843cf0bcfb4717c lib/browser/guest-view-manager.js - our 100644 1e4029e39a981c85fb6ff18c5ccd52f81b3c56f2 lib/browser/guest-view-manager.js - their 100644 039753b7aef48f9ff8e9f507f7cb5d13458413b5 lib/browser/guest-view-manager.js -changed in both - base 100644 bd9473dda879723625af24c0f98de2855234a2c7 lib/browser/guest-window-manager.js - our 100644 7253c1942b0956ae6b9b0c80a23470fc26669b8a lib/browser/guest-window-manager.js - their 100644 15137992b19d7a8f666dd54936200f728013e71c lib/browser/guest-window-manager.js -@@ -65,7 +65,11 @@ - // Inherit certain option values from parent window - const webPreferences = embedder.getLastWebPreferences() - for (const [name, value] of inheritedWebPreferences) { -+<<<<<<< .our - if (webPreferences[name] === value) { -+======= -+ if (embedder.getLastWebPreferences()[name] === value) { -+>>>>>>> .their - options.webPreferences[name] = value - } - } -added in both - our 100644 b1d8824658ea05c277e82d1ac6c6febab9c55030 package-lock.json - their 100644 514c02bdd3fcc3df56524925fec36baab9db77f7 package-lock.json -@@ -1,13 +1,23 @@ - { - "name": "electron", -+<<<<<<< .our - "version": "4.0.0-nightly.20180819", -+======= -+ "version": "1.7.15", -+>>>>>>> .their - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/node": { -+<<<<<<< .our - "version": "7.0.69", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.69.tgz", - "integrity": "sha512-S5NC8HV6HnRipg8nC0j30TPl7ktXjRTKqgyINLNe8K/64UJUI8Lq0sRopXC0hProsV2F5ibj8IqPkl1xpGggrw==", -+======= -+ "version": "7.0.56", -+ "resolved": "http://registry.npmjs.org/@types/node/-/node-7.0.56.tgz", -+ "integrity": "sha512-NgjN3xPyqbAXSIpznNAR5Cisx5uKqJWxcS9kefzSFEX/9J7O01/FHyfnvPI7SztBf9p6c8mqOn3olZWJx3ja6g==", -+>>>>>>> .their - "dev": true - }, - "JSONStream": { -@@ -30,6 +40,7 @@ - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", -+<<<<<<< .our - "integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg=", - "dev": true - }, -@@ -43,6 +54,11 @@ - "negotiator": "0.6.1" - } - }, -+======= -+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", -+ "dev": true -+ }, -+>>>>>>> .their - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", -@@ -109,12 +125,15 @@ - "integrity": "sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=", - "dev": true - }, -+<<<<<<< .our - "address": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/address/-/address-1.0.3.tgz", - "integrity": "sha512-z55ocwKBRLryBs394Sm3ushTtBeg6VAeuku7utSoSnsJKvKcnXFIyC6vh27n3rXyxSgkJBBCAvyOn7gSUcTYjg==", - "dev": true - }, -+======= -+>>>>>>> .their - "agent-base": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", -@@ -192,7 +211,11 @@ - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", -+<<<<<<< .our - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", -+======= -+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", -+>>>>>>> .their - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", -@@ -231,13 +254,18 @@ - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", -+<<<<<<< .our - "integrity": "sha1-VT3Lj5HjyImEXf26NMd3IbkLnXo=", -+======= -+ "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", -+>>>>>>> .their - "dev": true, - "requires": { - "micromatch": "2.3.11", - "normalize-path": "2.1.1" - } - }, -+<<<<<<< .our - "arch": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.1.tgz", -@@ -250,6 +278,8 @@ - "integrity": "sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w==", - "dev": true - }, -+======= -+>>>>>>> .their - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", -@@ -259,6 +289,7 @@ - "sprintf-js": "1.0.3" - } - }, -+<<<<<<< .our - "args": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/args/-/args-4.0.0.tgz", -@@ -314,6 +345,8 @@ - } - } - }, -+======= -+>>>>>>> .their - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", -@@ -326,7 +359,11 @@ - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", -+<<<<<<< .our - "integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=", -+======= -+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", -+>>>>>>> .their - "dev": true - }, - "array-filter": { -@@ -347,12 +384,15 @@ - "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", - "dev": true - }, -+<<<<<<< .our - "array-iterate": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-1.1.2.tgz", - "integrity": "sha512-1hWSHTIlG/8wtYD+PPX5AOBtKWngpDFjrsrHgZpe+JdgNGz0udYu6ZIkAa/xuenIUEqFv7DvE2Yr60jxweJSrQ==", - "dev": true - }, -+======= -+>>>>>>> .their - "array-map": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", -@@ -393,7 +433,11 @@ - "dev": true, - "requires": { - "define-properties": "1.1.2", -+<<<<<<< .our - "es-abstract": "1.11.0" -+======= -+ "es-abstract": "1.10.0" -+>>>>>>> .their - } - }, - "arrify": { -@@ -409,7 +453,11 @@ - "dev": true, - "requires": { - "chromium-pickle-js": "0.1.0", -+<<<<<<< .our - "commander": "2.15.1", -+======= -+ "commander": "2.15.0", -+>>>>>>> .their - "cuint": "0.2.2", - "glob": "6.0.4", - "minimatch": "3.0.4", -@@ -431,7 +479,11 @@ - "requires": { - "bn.js": "4.11.8", - "inherits": "2.0.3", -+<<<<<<< .our - "minimalistic-assert": "1.0.1" -+======= -+ "minimalistic-assert": "1.0.0" -+>>>>>>> .their - } - }, - "assert": { -@@ -464,12 +516,15 @@ - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, -+<<<<<<< .our - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true - }, -+======= -+>>>>>>> .their - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", -@@ -483,9 +538,15 @@ - "dev": true - }, - "aws4": { -+<<<<<<< .our - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", - "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", -+======= -+ "version": "1.6.0", -+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", -+ "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", -+>>>>>>> .their - "dev": true - }, - "babel-code-frame": { -@@ -499,12 +560,15 @@ - "js-tokens": "3.0.2" - } - }, -+<<<<<<< .our - "bail": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.3.tgz", - "integrity": "sha512-1X8CnjFVQ+a+KW36uBNMTU5s8+v5FzeqrP7hTG5aTb4aPreSbZJlhwPon9VKMuEVgV++JM+SQrALY3kr7eswdg==", - "dev": true - }, -+======= -+>>>>>>> .their - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", -@@ -512,6 +576,7 @@ - "dev": true - }, - "base64-js": { -+<<<<<<< .our - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", -@@ -534,6 +599,13 @@ - } - } - }, -+======= -+ "version": "1.2.3", -+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.3.tgz", -+ "integrity": "sha512-MsAhsUW1GxCdgYSO6tAfZrNapmUKk7mWx/k5mFY/A1gBtkaCaNapTg+FExCw1r9yeaZhqx/xPg43xgTFH6KL5w==", -+ "dev": true -+ }, -+>>>>>>> .their - "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", -@@ -554,6 +626,7 @@ - "chainsaw": "0.1.0" - } - }, -+<<<<<<< .our - "binary-extensions": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", -@@ -568,6 +641,15 @@ - "requires": { - "readable-stream": "2.3.6", - "safe-buffer": "5.1.2" -+======= -+ "bl": { -+ "version": "1.2.1", -+ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz", -+ "integrity": "sha1-ysMo977kVzDUBLaSID/LWQ4XLV4=", -+ "dev": true, -+ "requires": { -+ "readable-stream": "2.3.5" -+>>>>>>> .their - }, - "dependencies": { - "isarray": { -@@ -577,31 +659,52 @@ - "dev": true - }, - "readable-stream": { -+<<<<<<< .our - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", -+======= -+ "version": "2.3.5", -+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", -+ "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", -+>>>>>>> .their - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", -+======= -+ "safe-buffer": "5.1.1", -+ "string_decoder": "1.0.3", -+>>>>>>> .their - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { -+<<<<<<< .our - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" -+======= -+ "version": "1.0.3", -+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", -+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", -+ "dev": true, -+ "requires": { -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } - }, -+<<<<<<< .our - "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", -@@ -612,6 +715,12 @@ - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha1-LN4J617jQfSEdGuwMJsyU7GxRC8=", -+======= -+ "bn.js": { -+ "version": "4.11.8", -+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", -+ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", -+>>>>>>> .their - "dev": true - }, - "boolbase": { -@@ -637,7 +746,11 @@ - "requires": { - "ansi-align": "2.0.0", - "camelcase": "4.1.0", -+<<<<<<< .our - "chalk": "2.4.1", -+======= -+ "chalk": "2.3.2", -+>>>>>>> .their - "cli-boxes": "1.0.0", - "string-width": "2.1.1", - "term-size": "1.2.0", -@@ -666,14 +779,24 @@ - "dev": true - }, - "chalk": { -+<<<<<<< .our - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", -+======= -+ "version": "2.3.2", -+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", -+ "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", -+<<<<<<< .our - "supports-color": "5.4.0" -+======= -+ "supports-color": "5.3.0" -+>>>>>>> .their - } - }, - "has-flag": { -@@ -691,7 +814,11 @@ - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", -+<<<<<<< .our - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", -+======= -+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", -+>>>>>>> .their - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", -@@ -708,9 +835,15 @@ - } - }, - "supports-color": { -+<<<<<<< .our - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", -+======= -+ "version": "5.3.0", -+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", -+ "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", -+>>>>>>> .their - "dev": true, - "requires": { - "has-flag": "3.0.0" -@@ -746,15 +879,25 @@ - "dev": true - }, - "browser-pack": { -+<<<<<<< .our - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", - "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", -+======= -+ "version": "6.0.4", -+ "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.0.4.tgz", -+ "integrity": "sha512-Q4Rvn7P6ObyWfc4stqLWHtG1MJ8vVtjgT24Zbu+8UTzxYuZouqZsmNRRTFVMY/Ux0eIKv1d+JWzsInTX+fdHPQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "JSONStream": "1.3.2", - "combine-source-map": "0.8.0", - "defined": "1.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", -+======= -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "through2": "2.0.3", - "umd": "3.0.3" - } -@@ -784,7 +927,11 @@ - "requires": { - "JSONStream": "1.3.2", - "assert": "1.4.1", -+<<<<<<< .our - "browser-pack": "6.1.0", -+======= -+ "browser-pack": "6.0.4", -+>>>>>>> .their - "browser-resolve": "1.11.2", - "browserify-zlib": "0.1.4", - "buffer": "4.9.1", -@@ -803,8 +950,13 @@ - "htmlescape": "1.1.1", - "https-browserify": "0.0.1", - "inherits": "2.0.3", -+<<<<<<< .our - "insert-module-globals": "7.0.6", - "labeled-stream-splicer": "2.0.1", -+======= -+ "insert-module-globals": "7.0.2", -+ "labeled-stream-splicer": "2.0.0", -+>>>>>>> .their - "module-deps": "4.1.1", - "os-browserify": "0.1.2", - "parents": "1.0.1", -@@ -813,12 +965,21 @@ - "punycode": "1.4.1", - "querystring-es3": "0.2.1", - "read-only-stream": "2.0.0", -+<<<<<<< .our - "readable-stream": "2.3.6", - "resolve": "1.7.1", - "shasum": "1.0.2", - "shell-quote": "1.6.1", - "stream-browserify": "2.0.1", - "stream-http": "2.8.2", -+======= -+ "readable-stream": "2.3.5", -+ "resolve": "1.5.0", -+ "shasum": "1.0.2", -+ "shell-quote": "1.6.1", -+ "stream-browserify": "2.0.1", -+ "stream-http": "2.8.1", -+>>>>>>> .their - "string_decoder": "0.10.31", - "subarg": "1.0.0", - "syntax-error": "1.4.0", -@@ -834,7 +995,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -852,27 +1017,47 @@ - "dev": true - }, - "readable-stream": { -+<<<<<<< .our - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", -+======= -+ "version": "2.3.5", -+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", -+ "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", -+>>>>>>> .their - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", -+======= -+ "safe-buffer": "5.1.1", -+ "string_decoder": "1.0.3", -+>>>>>>> .their - "util-deprecate": "1.0.2" - }, - "dependencies": { - "string_decoder": { -+<<<<<<< .our - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" -+======= -+ "version": "1.0.3", -+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", -+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", -+ "dev": true, -+ "requires": { -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -880,13 +1065,20 @@ - } - }, - "browserify-aes": { -+<<<<<<< .our - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", -+======= -+ "version": "1.1.1", -+ "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", -+ "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", -+>>>>>>> .their - "dev": true, - "requires": { - "buffer-xor": "1.0.3", - "cipher-base": "1.0.4", -+<<<<<<< .our - "create-hash": "1.2.0", - "evp_bytestokey": "1.0.3", - "inherits": "2.0.3", -@@ -901,13 +1093,35 @@ - "requires": { - "browserify-aes": "1.2.0", - "browserify-des": "1.0.1", -+======= -+ "create-hash": "1.1.3", -+ "evp_bytestokey": "1.0.3", -+ "inherits": "2.0.3", -+ "safe-buffer": "5.1.1" -+ } -+ }, -+ "browserify-cipher": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", -+ "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", -+ "dev": true, -+ "requires": { -+ "browserify-aes": "1.1.1", -+ "browserify-des": "1.0.0", -+>>>>>>> .their - "evp_bytestokey": "1.0.3" - } - }, - "browserify-des": { -+<<<<<<< .our - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.1.tgz", - "integrity": "sha512-zy0Cobe3hhgpiOM32Tj7KQ3Vl91m0njwsjzZQK1L+JDf11dzP9qIvjreVinsvXrgfjhStXwUWAEpB9D7Gwmayw==", -+======= -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", -+ "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", -+>>>>>>> .their - "dev": true, - "requires": { - "cipher-base": "1.0.4", -@@ -933,11 +1147,19 @@ - "requires": { - "bn.js": "4.11.8", - "browserify-rsa": "4.0.1", -+<<<<<<< .our - "create-hash": "1.2.0", - "create-hmac": "1.1.7", - "elliptic": "6.4.0", - "inherits": "2.0.3", - "parse-asn1": "5.1.1" -+======= -+ "create-hash": "1.1.3", -+ "create-hmac": "1.1.6", -+ "elliptic": "6.4.0", -+ "inherits": "2.0.3", -+ "parse-asn1": "5.1.0" -+>>>>>>> .their - } - }, - "browserify-zlib": { -@@ -955,8 +1177,13 @@ - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "dev": true, - "requires": { -+<<<<<<< .our - "base64-js": "1.3.0", - "ieee754": "1.1.11", -+======= -+ "base64-js": "1.2.3", -+ "ieee754": "1.1.8", -+>>>>>>> .their - "isarray": "1.0.0" - }, - "dependencies": { -@@ -968,6 +1195,7 @@ - } - } - }, -+<<<<<<< .our - "buffer-alloc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.1.0.tgz", -@@ -996,6 +1224,8 @@ - "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==", - "dev": true - }, -+======= -+>>>>>>> .their - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", -@@ -1020,12 +1250,15 @@ - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, -+<<<<<<< .our - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, -+======= -+>>>>>>> .their - "cached-path-relative": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.1.tgz", -@@ -1085,12 +1318,15 @@ - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, -+<<<<<<< .our - "ccount": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.3.tgz", - "integrity": "sha512-Jt9tIBkRc9POUof7QA/VwWd+58fKkEEfI+/t1/eOlxKM7ZhrczNzMFefge7Ai+39y1pR/pP6cI19guHy3FSLmw==", - "dev": true - }, -+======= -+>>>>>>> .their - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", -@@ -1132,6 +1368,7 @@ - } - } - }, -+<<<<<<< .our - "character-entities": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.2.tgz", -@@ -1160,6 +1397,12 @@ - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/check-for-leaks/-/check-for-leaks-1.2.0.tgz", - "integrity": "sha1-6jtQFk6XV3kzLGKBMZX/jGr4Jsw=", -+======= -+ "check-for-leaks": { -+ "version": "1.2.0", -+ "resolved": "https://registry.npmjs.org/check-for-leaks/-/check-for-leaks-1.2.0.tgz", -+ "integrity": "sha512-bJ2Bzo6RtsYqamMnsjtVzowGvBNVrR5IPK8Bd+lx5W1TNgOKMsF+AyNHVkqFqO7cpDZNfny5SaqH6gEovpV5Gw==", -+>>>>>>> .their - "dev": true, - "requires": { - "anymatch": "1.3.2", -@@ -1201,6 +1444,7 @@ - "lodash.some": "4.6.0" - } - }, -+<<<<<<< .our - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", -@@ -1218,6 +1462,8 @@ - "readdirp": "2.1.0" - } - }, -+======= -+>>>>>>> .their - "chownr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", -@@ -1239,16 +1485,25 @@ - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", -+<<<<<<< .our - "integrity": "sha1-h2Dk7MJy9MNjUy+SbYdKriwTl94=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.2" -+======= -+ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", -+ "dev": true, -+ "requires": { -+ "inherits": "2.0.3", -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", -+<<<<<<< .our - "integrity": "sha1-gVyZ6oT2gJUp0vRXkb34JxE1LWY=", - "dev": true - }, -@@ -1279,6 +1534,11 @@ - } - } - }, -+======= -+ "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", -+ "dev": true -+ }, -+>>>>>>> .their - "clean-deep": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/clean-deep/-/clean-deep-2.0.2.tgz", -@@ -1317,6 +1577,7 @@ - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, -+<<<<<<< .our - "clipboardy": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-1.2.3.tgz", -@@ -1344,6 +1605,8 @@ - } - } - }, -+======= -+>>>>>>> .their - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", -@@ -1377,12 +1640,15 @@ - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, -+<<<<<<< .our - "collapse-white-space": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.4.tgz", - "integrity": "sha512-YfQ1tAUZm561vpYD+5eyWN8+UsceQbSrqqlc/6zDY2gtAE+uZLSdkkovhnGpmCThsvKBFakq4EdY/FF93E8XIw==", - "dev": true - }, -+======= -+>>>>>>> .their - "color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", -@@ -1399,9 +1665,15 @@ - "dev": true - }, - "colors": { -+<<<<<<< .our - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", - "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", -+======= -+ "version": "1.2.1", -+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.1.tgz", -+ "integrity": "sha512-s8+wktIuDSLffCywiwSxQOMqtPxML11a/dtHE17tMn4B1MSWw/C22EKf7M2KGUBcDaVFEGT+S8N02geDXeuNKg==", -+>>>>>>> .their - "dev": true - }, - "combine-source-map": { -@@ -1426,9 +1698,15 @@ - } - }, - "commander": { -+<<<<<<< .our - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", -+======= -+ "version": "2.15.0", -+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.0.tgz", -+ "integrity": "sha512-7B1ilBwtYSbetCgTY1NJFg+gVpestg0fdA1MhC1Vs4ssyfSXnCAjFr+QcQM9/RedXC0EaUx1sG8Smgw2VfgKEg==", -+>>>>>>> .their - "dev": true - }, - "compare-func": { -@@ -1441,6 +1719,7 @@ - "dot-prop": "3.0.0" - } - }, -+<<<<<<< .our - "compressible": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.14.tgz", -@@ -1473,6 +1752,8 @@ - "vary": "1.1.2" - } - }, -+======= -+>>>>>>> .their - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", -@@ -1519,14 +1800,24 @@ - } - }, - "configstore": { -+<<<<<<< .our - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", - "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", -+======= -+ "version": "3.1.1", -+ "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.1.tgz", -+ "integrity": "sha512-5oNkD/L++l0O6xGXxb1EWS7SivtjfGQlRyxJsYgE0Z495/L81e2h4/d3r969hoPXuFItzNOKMtsXgYG4c7dYvw==", -+>>>>>>> .their - "dev": true, - "requires": { - "dot-prop": "4.2.0", - "graceful-fs": "4.1.11", -+<<<<<<< .our - "make-dir": "1.3.0", -+======= -+ "make-dir": "1.2.0", -+>>>>>>> .their - "unique-string": "1.0.0", - "write-file-atomic": "2.3.0", - "xdg-basedir": "3.0.0" -@@ -1535,7 +1826,11 @@ - "dot-prop": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", -+<<<<<<< .our - "integrity": "sha1-HxngwuGqDjJ5fEl5nyg3rGr2nFc=", -+======= -+ "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "is-obj": "1.0.1" -@@ -1564,6 +1859,7 @@ - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, -+<<<<<<< .our - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", -@@ -1587,6 +1883,25 @@ - "conventional-changelog-jscs": "0.1.0", - "conventional-changelog-jshint": "0.3.8", - "conventional-changelog-preset-loader": "1.1.8" -+======= -+ "conventional-changelog": { -+ "version": "1.1.18", -+ "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-1.1.18.tgz", -+ "integrity": "sha512-swf5bqhm7PsY2cw6zxuPy6+rZiiGwEpQnrWki+L+z2oZI53QSYwU4brpljmmWss821AsiwmVL+7V6hP+ER+TBA==", -+ "dev": true, -+ "requires": { -+ "conventional-changelog-angular": "1.6.6", -+ "conventional-changelog-atom": "0.2.4", -+ "conventional-changelog-codemirror": "0.3.4", -+ "conventional-changelog-core": "2.0.5", -+ "conventional-changelog-ember": "0.3.6", -+ "conventional-changelog-eslint": "1.0.5", -+ "conventional-changelog-express": "0.3.4", -+ "conventional-changelog-jquery": "0.1.0", -+ "conventional-changelog-jscs": "0.1.0", -+ "conventional-changelog-jshint": "0.3.4", -+ "conventional-changelog-preset-loader": "1.1.6" -+>>>>>>> .their - } - }, - "conventional-changelog-angular": { -@@ -1600,15 +1915,22 @@ - } - }, - "conventional-changelog-atom": { -+<<<<<<< .our - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-0.2.8.tgz", - "integrity": "sha512-8pPZqhMbrnltNBizjoDCb/Sz85KyUXNDQxuAEYAU5V/eHn0okMBVjqc8aHWYpHrytyZWvMGbayOlDv7i8kEf6g==", -+======= -+ "version": "0.2.4", -+ "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-0.2.4.tgz", -+ "integrity": "sha512-4+hmbBwcAwx1XzDZ4aEOxk/ONU0iay10G0u/sld16ksgnRUHN7CxmZollm3FFaptr6VADMq1qxomA+JlpblBlg==", -+>>>>>>> .their - "dev": true, - "requires": { - "q": "1.5.1" - } - }, - "conventional-changelog-cli": { -+<<<<<<< .our - "version": "1.3.22", - "resolved": "https://registry.npmjs.org/conventional-changelog-cli/-/conventional-changelog-cli-1.3.22.tgz", - "integrity": "sha512-pnjdIJbxjkZ5VdAX/H1wndr1G10CY8MuZgnXuJhIHglOXfIrXygb7KZC836GW9uo1u8PjEIvIw/bKX0lOmOzZg==", -@@ -1618,19 +1940,37 @@ - "conventional-changelog": "1.1.24", - "lodash": "4.17.10", - "meow": "4.0.1", -+======= -+ "version": "1.3.16", -+ "resolved": "https://registry.npmjs.org/conventional-changelog-cli/-/conventional-changelog-cli-1.3.16.tgz", -+ "integrity": "sha512-zNDG/rNbh29Z+d6zzrHN63dFZ4q9k1Ri0V8lXGw1q2ia6+FaE7AqJKccObbBFRmRISXpFESrqZiXpM4QeA84YA==", -+ "dev": true, -+ "requires": { -+ "add-stream": "1.0.0", -+ "conventional-changelog": "1.1.18", -+ "lodash": "4.17.5", -+ "meow": "4.0.0", -+>>>>>>> .their - "tempfile": "1.1.1" - } - }, - "conventional-changelog-codemirror": { -+<<<<<<< .our - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-0.3.8.tgz", - "integrity": "sha512-3HFZKtBXTaUCHvz7ai6nk2+psRIkldDoNzCsom0egDtVmPsvvHZkzjynhdQyULfacRSsBTaiQ0ol6nBOL4dDiQ==", -+======= -+ "version": "0.3.4", -+ "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-0.3.4.tgz", -+ "integrity": "sha512-8M7pGgQVzRU//vG3rFlLYqqBywOLxu9XM0/lc1/1Ll7RuKA79PgK9TDpuPmQDHFnqGS7D1YiZpC3Z0D9AIYExg==", -+>>>>>>> .their - "dev": true, - "requires": { - "q": "1.5.1" - } - }, - "conventional-changelog-core": { -+<<<<<<< .our - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-2.0.11.tgz", - "integrity": "sha512-HvTE6RlqeEZ/NFPtQeFLsIDOLrGP3bXYr7lFLMhCVsbduF1MXIe8OODkwMFyo1i9ku9NWBwVnVn0jDmIFXjDRg==", -@@ -1644,6 +1984,21 @@ - "git-remote-origin-url": "2.0.0", - "git-semver-tags": "1.3.6", - "lodash": "4.17.10", -+======= -+ "version": "2.0.5", -+ "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-2.0.5.tgz", -+ "integrity": "sha512-lP1s7Z3NyEFcG78bWy7GG7nXsq9OpAJgo2xbyAlVBDweLSL5ghvyEZlkEamnAQpIUVK0CAVhs8nPvCiQuXT/VA==", -+ "dev": true, -+ "requires": { -+ "conventional-changelog-writer": "3.0.4", -+ "conventional-commits-parser": "2.1.5", -+ "dateformat": "3.0.3", -+ "get-pkg-repo": "1.4.0", -+ "git-raw-commits": "1.3.4", -+ "git-remote-origin-url": "2.0.0", -+ "git-semver-tags": "1.3.4", -+ "lodash": "4.17.5", -+>>>>>>> .their - "normalize-package-data": "2.4.0", - "q": "1.5.1", - "read-pkg": "1.1.0", -@@ -1652,27 +2007,45 @@ - } - }, - "conventional-changelog-ember": { -+<<<<<<< .our - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-0.3.12.tgz", - "integrity": "sha512-mmJzA7uzbrOqeF89dMMi6z17O07ORTXlTMArnLG9ZTX4oLaKNolUlxFUFlFm9JUoVWajVpaHQWjxH1EOQ+ARoQ==", -+======= -+ "version": "0.3.6", -+ "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-0.3.6.tgz", -+ "integrity": "sha512-hBM1xb5IrjNtsjXaGryPF/Wn36cwyjkNeqX/CIDbJv/1kRFBHsWoSPYBiNVEpg8xE5fcK4DbPhGTDN2sVoPeiA==", -+>>>>>>> .their - "dev": true, - "requires": { - "q": "1.5.1" - } - }, - "conventional-changelog-eslint": { -+<<<<<<< .our - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-1.0.9.tgz", - "integrity": "sha512-h87nfVh2fdk9fJIvz26wCBsbDC/KxqCc5wSlNMZbXcARtbgNbNDIF7Y7ctokFdnxkzVdaHsbINkh548T9eBA7Q==", -+======= -+ "version": "1.0.5", -+ "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-1.0.5.tgz", -+ "integrity": "sha512-7NUv+gMOS8Y49uPFRgF7kuLZqpnrKa2bQMZZsc62NzvaJmjUktnV03PYHuXhTDEHt5guvV9gyEFtUpgHCDkojg==", -+>>>>>>> .their - "dev": true, - "requires": { - "q": "1.5.1" - } - }, - "conventional-changelog-express": { -+<<<<<<< .our - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-0.3.6.tgz", - "integrity": "sha512-3iWVtBJZ9RnRnZveNDzOD8QRn6g6vUif0qVTWWyi5nUIAbuN1FfPVyKdAlJJfp5Im+dE8Kiy/d2SpaX/0X678Q==", -+======= -+ "version": "0.3.4", -+ "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-0.3.4.tgz", -+ "integrity": "sha512-M+UUb715TXT6l9vyMf4HYvAepnQn0AYTcPi6KHrFsd80E0HErjQnqStBg8i3+Qm7EV9+RyATQEnIhSzHbdQ7+A==", -+>>>>>>> .their - "dev": true, - "requires": { - "q": "1.5.1" -@@ -1697,9 +2070,15 @@ - } - }, - "conventional-changelog-jshint": { -+<<<<<<< .our - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-0.3.8.tgz", - "integrity": "sha512-hn9QU4ZI/5V50wKPJNPGT4gEWgiBFpV6adieILW4MaUFynuDYOvQ71EMSj3EznJyKi/KzuXpc9dGmX8njZMjig==", -+======= -+ "version": "0.3.4", -+ "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-0.3.4.tgz", -+ "integrity": "sha512-CdrqwDgL56b176FVxHmhuOvnO1dRDQvrMaHyuIVjcFlOXukATz2wVT17g8jQU3LvybVbyXvJRbdD5pboo7/1KQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "compare-func": "1.3.2", -@@ -1707,6 +2086,7 @@ - } - }, - "conventional-changelog-preset-loader": { -+<<<<<<< .our - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-1.1.8.tgz", - "integrity": "sha512-MkksM4G4YdrMlT2MbTsV2F6LXu/hZR0Tc/yenRrDIKRwBl/SP7ER4ZDlglqJsCzLJi4UonBc52Bkm5hzrOVCcw==", -@@ -1725,12 +2105,33 @@ - "json-stringify-safe": "5.0.1", - "lodash": "4.17.10", - "meow": "4.0.1", -+======= -+ "version": "1.1.6", -+ "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-1.1.6.tgz", -+ "integrity": "sha512-yWPIP9wwsCKeUSPYApnApWhKIDjWRIX/uHejGS1tYfEsQR/bwpDFET7LYiHT+ujNbrlf6h1s3NlPGheOd4yJRQ==", -+ "dev": true -+ }, -+ "conventional-changelog-writer": { -+ "version": "3.0.4", -+ "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-3.0.4.tgz", -+ "integrity": "sha512-EUf/hWiEj3IOa5Jk8XDzM6oS0WgijlYGkUfLc+mDnLH9RwpZqhYIBwgJHWHzEB4My013wx2FhmUu45P6tQrucw==", -+ "dev": true, -+ "requires": { -+ "compare-func": "1.3.2", -+ "conventional-commits-filter": "1.1.5", -+ "dateformat": "3.0.3", -+ "handlebars": "4.0.11", -+ "json-stringify-safe": "5.0.1", -+ "lodash": "4.17.5", -+ "meow": "4.0.0", -+>>>>>>> .their - "semver": "5.5.0", - "split": "1.0.1", - "through2": "2.0.3" - } - }, - "conventional-commits-filter": { -+<<<<<<< .our - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-1.1.6.tgz", - "integrity": "sha512-KcDgtCRKJCQhyk6VLT7zR+ZOyCnerfemE/CsR3iQpzRRFbLEs0Y6rwk3mpDvtOh04X223z+1xyJ582Stfct/0Q==", -@@ -1744,12 +2145,32 @@ - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-2.1.7.tgz", - "integrity": "sha512-BoMaddIEJ6B4QVMSDu9IkVImlGOSGA1I2BQyOZHeLQ6qVOJLcLKn97+fL6dGbzWEiqDzfH4OkcveULmeq2MHFQ==", -+======= -+ "version": "1.1.5", -+ "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-1.1.5.tgz", -+ "integrity": "sha512-mj3+WLj8UZE72zO9jocZjx8+W4Bwnx/KHoIz1vb4F8XUXj0XSjp8Y3MFkpRyIpsRiCBX+DkDjxGKF/nfeu7BGw==", -+ "dev": true, -+ "requires": { -+ "is-subset": "0.1.1", -+ "modify-values": "1.0.0" -+ } -+ }, -+ "conventional-commits-parser": { -+ "version": "2.1.5", -+ "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-2.1.5.tgz", -+ "integrity": "sha512-jaAP61py+ISMF3/n3yIiIuY5h6mJlucOqawu5mLB1HaQADLvg/y5UB3pT7HSucZJan34lp7+7ylQPfbKEGmxrA==", -+>>>>>>> .their - "dev": true, - "requires": { - "JSONStream": "1.3.2", - "is-text-path": "1.0.1", -+<<<<<<< .our - "lodash": "4.17.10", - "meow": "4.0.1", -+======= -+ "lodash": "4.17.5", -+ "meow": "4.0.0", -+>>>>>>> .their - "split2": "2.2.0", - "through2": "2.0.3", - "trim-off-newlines": "1.0.1" -@@ -1768,9 +2189,15 @@ - "dev": true - }, - "create-ecdh": { -+<<<<<<< .our - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", -+======= -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", -+ "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", -+>>>>>>> .their - "dev": true, - "requires": { - "bn.js": "4.11.8", -@@ -1787,13 +2214,20 @@ - } - }, - "create-hash": { -+<<<<<<< .our - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", -+======= -+ "version": "1.1.3", -+ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", -+ "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", -+>>>>>>> .their - "dev": true, - "requires": { - "cipher-base": "1.0.4", - "inherits": "2.0.3", -+<<<<<<< .our - "md5.js": "1.3.4", - "ripemd160": "2.0.2", - "sha.js": "2.4.11" -@@ -1811,6 +2245,24 @@ - "ripemd160": "2.0.2", - "safe-buffer": "5.1.2", - "sha.js": "2.4.11" -+======= -+ "ripemd160": "2.0.1", -+ "sha.js": "2.4.10" -+ } -+ }, -+ "create-hmac": { -+ "version": "1.1.6", -+ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", -+ "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", -+ "dev": true, -+ "requires": { -+ "cipher-base": "1.0.4", -+ "create-hash": "1.1.3", -+ "inherits": "2.0.3", -+ "ripemd160": "2.0.1", -+ "safe-buffer": "5.1.1", -+ "sha.js": "2.4.10" -+>>>>>>> .their - } - }, - "cross-spawn": { -@@ -1819,7 +2271,11 @@ - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { -+<<<<<<< .our - "lru-cache": "4.1.3", -+======= -+ "lru-cache": "4.1.2", -+>>>>>>> .their - "shebang-command": "1.2.0", - "which": "1.3.0" - } -@@ -1836,7 +2292,11 @@ - "boom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", -+<<<<<<< .our - "integrity": "sha1-XdnabuOl8wIHdDYpDLcX0/SlTgI=", -+======= -+ "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", -+>>>>>>> .their - "dev": true, - "requires": { - "hoek": "4.2.1" -@@ -1850,6 +2310,7 @@ - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { -+<<<<<<< .our - "browserify-cipher": "1.0.1", - "browserify-sign": "4.0.4", - "create-ecdh": "4.0.3", -@@ -1859,6 +2320,17 @@ - "inherits": "2.0.3", - "pbkdf2": "3.0.16", - "public-encrypt": "4.0.2", -+======= -+ "browserify-cipher": "1.0.0", -+ "browserify-sign": "4.0.4", -+ "create-ecdh": "4.0.0", -+ "create-hash": "1.1.3", -+ "create-hmac": "1.1.6", -+ "diffie-hellman": "5.0.2", -+ "inherits": "2.0.3", -+ "pbkdf2": "3.0.14", -+ "public-encrypt": "4.0.0", -+>>>>>>> .their - "randombytes": "2.0.6", - "randomfill": "1.0.4" - } -@@ -1924,7 +2396,11 @@ - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "dev": true, - "requires": { -+<<<<<<< .our - "es5-ext": "0.10.42" -+======= -+ "es5-ext": "0.10.40" -+>>>>>>> .their - } - }, - "dargs": { -@@ -1960,7 +2436,11 @@ - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", -+<<<<<<< .our - "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", -+======= -+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", -+>>>>>>> .their - "dev": true, - "requires": { - "ms": "2.0.0" -@@ -2018,9 +2498,15 @@ - "dev": true - }, - "deep-extend": { -+<<<<<<< .our - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", - "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", -+======= -+ "version": "0.4.2", -+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", -+ "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", -+>>>>>>> .their - "dev": true - }, - "deep-is": { -@@ -2061,16 +2547,26 @@ - "requires": { - "find-root": "1.1.0", - "glob": "7.1.2", -+<<<<<<< .our - "ignore": "3.3.8", - "pkg-config": "1.1.1", - "run-parallel": "1.1.9", -+======= -+ "ignore": "3.3.7", -+ "pkg-config": "1.1.1", -+ "run-parallel": "1.1.7", -+>>>>>>> .their - "uniq": "1.0.1" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -2091,7 +2587,11 @@ - "requires": { - "globby": "5.0.0", - "is-path-cwd": "1.0.0", -+<<<<<<< .our - "is-path-in-cwd": "1.0.1", -+======= -+ "is-path-in-cwd": "1.0.0", -+>>>>>>> .their - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", -@@ -2104,12 +2604,15 @@ - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, -+<<<<<<< .our - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", - "dev": true - }, -+======= -+>>>>>>> .their - "deps-sort": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", -@@ -2129,6 +2632,7 @@ - "dev": true, - "requires": { - "inherits": "2.0.3", -+<<<<<<< .our - "minimalistic-assert": "1.0.1" - } - }, -@@ -2146,6 +2650,9 @@ - "requires": { - "address": "1.0.3", - "debug": "2.6.9" -+======= -+ "minimalistic-assert": "1.0.0" -+>>>>>>> .their - } - }, - "detective": { -@@ -2173,9 +2680,15 @@ - "dev": true - }, - "diffie-hellman": { -+<<<<<<< .our - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", -+======= -+ "version": "5.0.2", -+ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", -+ "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", -+>>>>>>> .their - "dev": true, - "requires": { - "bn.js": "4.11.8", -@@ -2184,12 +2697,30 @@ - } - }, - "doctrine": { -+<<<<<<< .our - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "2.0.2" -+======= -+ "version": "1.5.0", -+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", -+ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", -+ "dev": true, -+ "requires": { -+ "esutils": "2.0.2", -+ "isarray": "1.0.0" -+ }, -+ "dependencies": { -+ "isarray": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", -+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", -+ "dev": true -+ } -+>>>>>>> .their - } - }, - "dom-serializer": { -@@ -2223,9 +2754,15 @@ - "dev": true - }, - "domhandler": { -+<<<<<<< .our - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", -+======= -+ "version": "2.4.1", -+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz", -+ "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=", -+>>>>>>> .their - "dev": true, - "requires": { - "domelementtype": "1.3.0" -@@ -2266,9 +2803,15 @@ - } - }, - "dugite": { -+<<<<<<< .our - "version": "1.63.0", - "resolved": "https://registry.npmjs.org/dugite/-/dugite-1.63.0.tgz", - "integrity": "sha512-CFd0sWTB2oouat0kJA4/rEQAeh6ZUvCDL9uFOaSBhLX+2CM/YL+ebKJXd8dYVIe8iVXmK5R9P31NVbRw4Ccoxw==", -+======= -+ "version": "1.60.0", -+ "resolved": "https://registry.npmjs.org/dugite/-/dugite-1.60.0.tgz", -+ "integrity": "sha512-HP5Qfx867ESOkrrEhXtxi72UQoNWaCSEcahGCmnBM/v+ldgbFu94s9CvG3tDcBtz1HJkvYEtkBd8V8Vb63nfUw==", -+>>>>>>> .their - "dev": true, - "requires": { - "checksum": "0.1.1", -@@ -2276,7 +2819,11 @@ - "progress": "2.0.0", - "request": "2.85.0", - "rimraf": "2.6.2", -+<<<<<<< .our - "tar": "4.4.2" -+======= -+ "tar": "4.4.0" -+>>>>>>> .their - } - }, - "duplexer2": { -@@ -2285,7 +2832,11 @@ - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dev": true, - "requires": { -+<<<<<<< .our - "readable-stream": "2.3.6" -+======= -+ "readable-stream": "2.3.5" -+>>>>>>> .their - }, - "dependencies": { - "isarray": { -@@ -2295,27 +2846,47 @@ - "dev": true - }, - "readable-stream": { -+<<<<<<< .our - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", -+======= -+ "version": "2.3.5", -+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", -+ "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", -+>>>>>>> .their - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", -+======= -+ "safe-buffer": "5.1.1", -+ "string_decoder": "1.0.3", -+>>>>>>> .their - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { -+<<<<<<< .our - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" -+======= -+ "version": "1.0.3", -+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", -+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", -+ "dev": true, -+ "requires": { -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -2327,14 +2898,24 @@ - "dev": true - }, - "duplexify": { -+<<<<<<< .our - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz", - "integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==", -+======= -+ "version": "3.5.4", -+ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.4.tgz", -+ "integrity": "sha512-JzYSLYMhoVVBe8+mbHQ4KgpvHpm0DZpJuL8PY93Vyv1fW7jYJ90LoXa1di/CVbJM+TgMs91rbDapE/RNIfnJsA==", -+>>>>>>> .their - "dev": true, - "requires": { - "end-of-stream": "1.4.1", - "inherits": "2.0.3", -+<<<<<<< .our - "readable-stream": "2.3.6", -+======= -+ "readable-stream": "2.3.5", -+>>>>>>> .their - "stream-shift": "1.0.0" - }, - "dependencies": { -@@ -2345,27 +2926,47 @@ - "dev": true - }, - "readable-stream": { -+<<<<<<< .our - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", -+======= -+ "version": "2.3.5", -+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", -+ "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", -+>>>>>>> .their - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", -+======= -+ "safe-buffer": "5.1.1", -+ "string_decoder": "1.0.3", -+>>>>>>> .their - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { -+<<<<<<< .our - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" -+======= -+ "version": "1.0.3", -+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", -+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", -+ "dev": true, -+ "requires": { -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -2380,12 +2981,15 @@ - "jsbn": "0.1.1" - } - }, -+<<<<<<< .our - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, -+======= -+>>>>>>> .their - "electabul": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/electabul/-/electabul-0.0.4.tgz", -@@ -2408,7 +3012,11 @@ - "dev": true, - "requires": { - "chromium-pickle-js": "0.2.0", -+<<<<<<< .our - "commander": "2.15.1", -+======= -+ "commander": "2.15.0", -+>>>>>>> .their - "cuint": "0.2.2", - "glob": "6.0.4", - "minimatch": "3.0.4", -@@ -2441,7 +3049,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -2467,7 +3079,11 @@ - "path-exists": "3.0.0", - "pify": "2.3.0", - "semver": "5.5.0", -+<<<<<<< .our - "tar-fs": "1.16.2" -+======= -+ "tar-fs": "1.16.0" -+>>>>>>> .their - }, - "dependencies": { - "ora": { -@@ -2523,6 +3139,7 @@ - } - }, - "electron-typescript-definitions": { -+<<<<<<< .our - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/electron-typescript-definitions/-/electron-typescript-definitions-1.3.6.tgz", - "integrity": "sha512-Wz6tPaaZ22lbfWwF9bzVSki7LMW96xilCT1M8eeNYZG6LcpA9x34jlrAZg5HZWTHXR2tfbTQhSmrY+FEVulD/A==", -@@ -2538,6 +3155,23 @@ - "rimraf": "2.6.2", - "tslint": "4.5.1", - "typescript": "2.9.2" -+======= -+ "version": "1.2.11", -+ "resolved": "https://registry.npmjs.org/electron-typescript-definitions/-/electron-typescript-definitions-1.2.11.tgz", -+ "integrity": "sha512-gBVmiGkw2hiut17wnSchYpFxrBmMb+jKFSjxbVFeivCn1OAAFykKtrsg26Sjcrra6AN1YiWyTC7SD9twPAO8dQ==", -+ "dev": true, -+ "requires": { -+ "@types/node": "7.0.56", -+ "colors": "1.2.1", -+ "debug": "2.6.9", -+ "electron-docs": "2.0.1", -+ "electron-docs-linter": "2.3.4", -+ "lodash": "4.17.5", -+ "mkdirp": "0.5.1", -+ "rimraf": "2.6.2", -+ "tslint": "4.5.1", -+ "typescript": "2.7.2" -+>>>>>>> .their - } - }, - "elliptic": { -@@ -2551,6 +3185,7 @@ - "hash.js": "1.1.3", - "hmac-drbg": "1.0.1", - "inherits": "2.0.3", -+<<<<<<< .our - "minimalistic-assert": "1.0.1", - "minimalistic-crypto-utils": "1.0.1" - } -@@ -2561,6 +3196,12 @@ - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, -+======= -+ "minimalistic-assert": "1.0.0", -+ "minimalistic-crypto-utils": "1.0.1" -+ } -+ }, -+>>>>>>> .their - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", -@@ -2592,9 +3233,15 @@ - } - }, - "es-abstract": { -+<<<<<<< .our - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.11.0.tgz", - "integrity": "sha512-ZnQrE/lXTTQ39ulXZ+J1DTFazV9qBy61x2bY071B+qGco8Z8q1QddsLdt/EF8Ai9hcWH72dWS0kFqXLxOxqslA==", -+======= -+ "version": "1.10.0", -+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", -+ "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "es-to-primitive": "1.1.1", -@@ -2616,6 +3263,7 @@ - } - }, - "es5-ext": { -+<<<<<<< .our - "version": "0.10.42", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.42.tgz", - "integrity": "sha512-AJxO1rmPe1bDEfSR6TJ/FgMFYuTBhR5R57KW58iCkYACMyFbrkqVyzXSurYoScDGvgyMpk7uRF/lPUPPTmsRSA==", -@@ -2624,6 +3272,15 @@ - "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1", - "next-tick": "1.0.0" -+======= -+ "version": "0.10.40", -+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.40.tgz", -+ "integrity": "sha512-S9Fh3oya5OOvYSNGvPZJ+vyrs6VYpe1IXPowVe3N1OhaiwVaGlwfn3Zf5P5klYcWOA0toIwYQW8XEv/QqhdHvQ==", -+ "dev": true, -+ "requires": { -+ "es6-iterator": "2.0.3", -+ "es6-symbol": "3.1.1" -+>>>>>>> .their - } - }, - "es6-iterator": { -@@ -2633,7 +3290,11 @@ - "dev": true, - "requires": { - "d": "1.0.0", -+<<<<<<< .our - "es5-ext": "0.10.42", -+======= -+ "es5-ext": "0.10.40", -+>>>>>>> .their - "es6-symbol": "3.1.1" - } - }, -@@ -2644,7 +3305,11 @@ - "dev": true, - "requires": { - "d": "1.0.0", -+<<<<<<< .our - "es5-ext": "0.10.42", -+======= -+ "es5-ext": "0.10.40", -+>>>>>>> .their - "es6-iterator": "2.0.3", - "es6-set": "0.1.5", - "es6-symbol": "3.1.1", -@@ -2658,7 +3323,11 @@ - "dev": true, - "requires": { - "d": "1.0.0", -+<<<<<<< .our - "es5-ext": "0.10.42", -+======= -+ "es5-ext": "0.10.40", -+>>>>>>> .their - "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" -@@ -2671,7 +3340,11 @@ - "dev": true, - "requires": { - "d": "1.0.0", -+<<<<<<< .our - "es5-ext": "0.10.42" -+======= -+ "es5-ext": "0.10.40" -+>>>>>>> .their - } - }, - "es6-weak-map": { -@@ -2681,17 +3354,24 @@ - "dev": true, - "requires": { - "d": "1.0.0", -+<<<<<<< .our - "es5-ext": "0.10.42", -+======= -+ "es5-ext": "0.10.40", -+>>>>>>> .their - "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1" - } - }, -+<<<<<<< .our - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, -+======= -+>>>>>>> .their - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", -@@ -2744,25 +3424,41 @@ - } - }, - "eslint": { -+<<<<<<< .our - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", - "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", -+======= -+ "version": "3.10.2", -+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.10.2.tgz", -+ "integrity": "sha1-yaEOi/bp1lZRIEd4xQM0Hx6sPOc=", -+>>>>>>> .their - "dev": true, - "requires": { - "babel-code-frame": "6.26.0", - "chalk": "1.1.3", - "concat-stream": "1.5.2", - "debug": "2.6.9", -+<<<<<<< .our - "doctrine": "2.1.0", - "escope": "3.6.0", - "espree": "3.5.4", - "esquery": "1.0.1", -+======= -+ "doctrine": "1.5.0", -+ "escope": "3.6.0", -+ "espree": "3.5.4", -+>>>>>>> .their - "estraverse": "4.2.0", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "glob": "7.1.2", - "globals": "9.18.0", -+<<<<<<< .our - "ignore": "3.3.8", -+======= -+ "ignore": "3.3.7", -+>>>>>>> .their - "imurmurhash": "0.1.4", - "inquirer": "0.12.0", - "is-my-json-valid": "2.17.2", -@@ -2770,7 +3466,11 @@ - "js-yaml": "3.11.0", - "json-stable-stringify": "1.0.1", - "levn": "0.3.0", -+<<<<<<< .our - "lodash": "4.17.10", -+======= -+ "lodash": "4.17.5", -+>>>>>>> .their - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", -@@ -2780,7 +3480,11 @@ - "require-uncached": "1.0.3", - "shelljs": "0.7.8", - "strip-bom": "3.0.0", -+<<<<<<< .our - "strip-json-comments": "2.0.1", -+======= -+ "strip-json-comments": "1.0.4", -+>>>>>>> .their - "table": "3.8.3", - "text-table": "0.2.0", - "user-home": "2.0.0" -@@ -2795,7 +3499,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -2826,10 +3534,20 @@ - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true -+<<<<<<< .our -+======= -+ }, -+ "strip-json-comments": { -+ "version": "1.0.4", -+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", -+ "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", -+ "dev": true -+>>>>>>> .their - } - } - }, - "eslint-config-standard": { -+<<<<<<< .our - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz", - "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=", -@@ -2839,6 +3557,17 @@ - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-4.0.2.tgz", - "integrity": "sha512-F8fRh2WFnTek7dZH9ZaE0PCBwdVGkwVWZmizla/DDNOmg7Tx6B/IlK5+oYpiX29jpu73LszeJj5i1axEZv6VMw==", -+======= -+ "version": "6.2.1", -+ "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-6.2.1.tgz", -+ "integrity": "sha1-06aKr8cZFjnn7kQec0hzkCY1QpI=", -+ "dev": true -+ }, -+ "eslint-config-standard-jsx": { -+ "version": "3.2.0", -+ "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-3.2.0.tgz", -+ "integrity": "sha1-wkDibtkZoRpCqk3oBZRys4Jo1iA=", -+>>>>>>> .their - "dev": true - }, - "eslint-import-resolver-node": { -@@ -2849,6 +3578,7 @@ - "requires": { - "debug": "2.6.9", - "object-assign": "4.1.1", -+<<<<<<< .our - "resolve": "1.7.1" - } - }, -@@ -2856,6 +3586,15 @@ - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz", - "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=", -+======= -+ "resolve": "1.5.0" -+ } -+ }, -+ "eslint-module-utils": { -+ "version": "2.1.1", -+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz", -+ "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==", -+>>>>>>> .their - "dev": true, - "requires": { - "debug": "2.6.9", -@@ -2873,11 +3612,16 @@ - "debug": "2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "0.2.3", -+<<<<<<< .our - "eslint-module-utils": "2.2.0", -+======= -+ "eslint-module-utils": "2.1.1", -+>>>>>>> .their - "has": "1.0.1", - "lodash.cond": "4.5.2", - "minimatch": "3.0.4", - "pkg-up": "1.0.0" -+<<<<<<< .our - }, - "dependencies": { - "doctrine": { -@@ -2896,11 +3640,14 @@ - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } -+======= -+>>>>>>> .their - } - }, - "eslint-plugin-node": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-4.2.3.tgz", -+<<<<<<< .our - "integrity": "sha1-wEOQq428u2iHF0Aj1vOnJ2nmO5c=", - "dev": true, - "requires": { -@@ -2908,6 +3655,15 @@ - "minimatch": "3.0.4", - "object-assign": "4.1.1", - "resolve": "1.7.1", -+======= -+ "integrity": "sha512-vIUQPuwbVYdz/CYnlTLsJrRy7iXHQjdEe5wz0XhhdTym3IInM/zZLlPf9nZ2mThsH0QcsieCOWs2vOeCy/22LQ==", -+ "dev": true, -+ "requires": { -+ "ignore": "3.3.7", -+ "minimatch": "3.0.4", -+ "object-assign": "4.1.1", -+ "resolve": "1.5.0", -+>>>>>>> .their - "semver": "5.3.0" - }, - "dependencies": { -@@ -2920,6 +3676,7 @@ - } - }, - "eslint-plugin-promise": { -+<<<<<<< .our - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz", - "integrity": "sha1-ePu2/+BHIBYnVp6FpsU3OvKmj8o=", -@@ -2960,6 +3717,27 @@ - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz", - "integrity": "sha1-NNDJFbRe3G8BA5PH7vOCOwhWXPI=", -+======= -+ "version": "3.4.2", -+ "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.4.2.tgz", -+ "integrity": "sha1-G+J5Pq/i0YtbEjuBNsJp+AT+cSI=", -+ "dev": true -+ }, -+ "eslint-plugin-react": { -+ "version": "6.7.1", -+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.7.1.tgz", -+ "integrity": "sha1-Gvlq6lRYVoJRV9l8G1DVqPtkpac=", -+ "dev": true, -+ "requires": { -+ "doctrine": "1.5.0", -+ "jsx-ast-utils": "1.4.1" -+ } -+ }, -+ "eslint-plugin-standard": { -+ "version": "2.0.1", -+ "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-2.0.1.tgz", -+ "integrity": "sha1-NYlpn/nJF/LCX3apFmh/ZBw2n/M=", -+>>>>>>> .their - "dev": true - }, - "espree": { -@@ -2987,9 +3765,15 @@ - "dev": true - }, - "esquery": { -+<<<<<<< .our - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", -+======= -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", -+ "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", -+>>>>>>> .their - "dev": true, - "requires": { - "estraverse": "4.2.0" -@@ -3032,12 +3816,15 @@ - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, -+<<<<<<< .our - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, -+======= -+>>>>>>> .their - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", -@@ -3045,7 +3832,11 @@ - "dev": true, - "requires": { - "d": "1.0.0", -+<<<<<<< .our - "es5-ext": "0.10.42" -+======= -+ "es5-ext": "0.10.40" -+>>>>>>> .their - } - }, - "events": { -@@ -3057,11 +3848,19 @@ - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", -+<<<<<<< .our - "integrity": "sha1-f8vbGY3HGVlDLv4ThCaE4FJaywI=", - "dev": true, - "requires": { - "md5.js": "1.3.4", - "safe-buffer": "5.1.2" -+======= -+ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", -+ "dev": true, -+ "requires": { -+ "md5.js": "1.3.4", -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - }, - "execa": { -@@ -3100,7 +3899,11 @@ - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { -+<<<<<<< .our - "fill-range": "2.2.4" -+======= -+ "fill-range": "2.2.3" -+>>>>>>> .their - } - }, - "extend": { -@@ -3142,6 +3945,7 @@ - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, -+<<<<<<< .our - "fault": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.2.tgz", -@@ -3151,6 +3955,8 @@ - "format": "0.2.2" - } - }, -+======= -+>>>>>>> .their - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", -@@ -3177,6 +3983,7 @@ - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, -+<<<<<<< .our - "filesize": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", -@@ -3187,11 +3994,21 @@ - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", -+======= -+ "fill-range": { -+ "version": "2.2.3", -+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", -+ "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", -+>>>>>>> .their - "dev": true, - "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", -+<<<<<<< .our - "randomatic": "3.0.0", -+======= -+ "randomatic": "1.1.7", -+>>>>>>> .their - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" - } -@@ -3199,7 +4016,11 @@ - "find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", -+<<<<<<< .our - "integrity": "sha1-q8/Iunb3CMQql7PWhbfpRQv7nOQ=", -+======= -+ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", -+>>>>>>> .their - "dev": true - }, - "find-up": { -@@ -3248,12 +4069,15 @@ - "write": "0.2.1" - } - }, -+<<<<<<< .our - "fn-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fn-name/-/fn-name-2.0.1.tgz", - "integrity": "sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc=", - "dev": true - }, -+======= -+>>>>>>> .their - "follow-redirects": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-0.0.7.tgz", -@@ -3302,6 +4126,7 @@ - "mime-types": "2.1.18" - } - }, -+<<<<<<< .our - "format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", -@@ -3320,6 +4145,8 @@ - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, -+======= -+>>>>>>> .their - "fs-extra": { - "version": "0.26.7", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", -@@ -3339,7 +4166,11 @@ - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", - "dev": true, - "requires": { -+<<<<<<< .our - "minipass": "2.3.0" -+======= -+ "minipass": "2.2.1" -+>>>>>>> .their - } - }, - "fs.realpath": { -@@ -3348,6 +4179,7 @@ - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, -+<<<<<<< .our - "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", -@@ -5046,2140 +5878,2034 @@ - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { -- "inflight": "1.0.6", -- "inherits": "2.0.3", -- "minimatch": "3.0.4", -- "once": "1.4.0", -- "path-is-absolute": "1.0.1" -- } -- }, -- "resolve": { -- "version": "1.1.7", -- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", -- "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", -- "dev": true -- }, -- "wordwrap": { -- "version": "1.0.0", -- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", -- "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", -- "dev": true -- } -- } -+======= -+ "function-bind": { -+ "version": "1.1.1", -+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", -+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", -+ "dev": true - }, -- "js-tokens": { -- "version": "3.0.2", -- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", -- "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", -+ "generate-function": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", -+ "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", - "dev": true - }, -- "js-yaml": { -- "version": "3.11.0", -- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", -- "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", -+ "generate-object-property": { -+ "version": "1.2.0", -+ "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", -+ "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "requires": { -- "argparse": "1.0.10", -- "esprima": "4.0.0" -- }, -- "dependencies": { -- "esprima": { -- "version": "4.0.0", -- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", -- "integrity": "sha1-RJnt3NERDgshi6zy+n9/WfVcqAQ=", -- "dev": true -- } -+ "is-property": "1.0.2" - } - }, -- "jsbn": { -- "version": "0.1.1", -- "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", -- "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", -- "dev": true, -- "optional": true -+ "get-caller-file": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", -+ "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", -+ "dev": true - }, -- "jsdom": { -- "version": "7.2.2", -- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-7.2.2.tgz", -- "integrity": "sha1-QLQCdwwr2iNGkJa+6Rq2deOx/G4=", -+ "get-pkg-repo": { -+ "version": "1.4.0", -+ "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz", -+ "integrity": "sha1-xztInAbYDMVTbCyFP54FIyBWly0=", - "dev": true, -- "optional": true, - "requires": { -- "abab": "1.0.4", -- "acorn": "2.7.0", -- "acorn-globals": "1.0.9", -- "cssom": "0.3.2", -- "cssstyle": "0.2.37", -- "escodegen": "1.8.1", -- "nwmatcher": "1.4.4", -- "parse5": "1.5.1", -- "request": "2.85.0", -- "sax": "1.2.4", -- "symbol-tree": "3.2.2", -- "tough-cookie": "2.3.4", -- "webidl-conversions": "2.0.1", -- "whatwg-url-compat": "0.6.5", -- "xml-name-validator": "2.0.1" -+ "hosted-git-info": "2.6.0", -+ "meow": "3.7.0", -+ "normalize-package-data": "2.4.0", -+ "parse-github-repo-url": "1.4.1", -+ "through2": "2.0.3" - }, - "dependencies": { -- "acorn": { -- "version": "2.7.0", -- "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz", -- "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc=", -+ "camelcase": { -+ "version": "2.1.1", -+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", -+ "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", -+ "dev": true -+ }, -+ "camelcase-keys": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", -+ "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, -- "optional": true -+ "requires": { -+ "camelcase": "2.1.1", -+ "map-obj": "1.0.1" -+ } -+ }, -+ "indent-string": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", -+ "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", -+ "dev": true, -+ "requires": { -+ "repeating": "2.0.1" -+ } -+ }, -+ "map-obj": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", -+ "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", -+ "dev": true -+ }, -+ "meow": { -+ "version": "3.7.0", -+ "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", -+ "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", -+ "dev": true, -+ "requires": { -+ "camelcase-keys": "2.1.0", -+ "decamelize": "1.2.0", -+ "loud-rejection": "1.6.0", -+ "map-obj": "1.0.1", -+ "minimist": "1.2.0", -+ "normalize-package-data": "2.4.0", -+ "object-assign": "4.1.1", -+ "read-pkg-up": "1.0.1", -+ "redent": "1.0.0", -+ "trim-newlines": "1.0.0" -+ } -+ }, -+ "redent": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", -+ "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", -+ "dev": true, -+ "requires": { -+ "indent-string": "2.1.0", -+ "strip-indent": "1.0.1" -+ } -+ }, -+ "strip-indent": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", -+ "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", -+ "dev": true, -+ "requires": { -+ "get-stdin": "4.0.1" -+ } -+ }, -+ "trim-newlines": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", -+ "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", -+ "dev": true - } - } - }, -- "json-parse-better-errors": { -- "version": "1.0.2", -- "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", -- "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", -- "dev": true -- }, -- "json-schema": { -- "version": "0.2.3", -- "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", -- "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", -+ "get-stdin": { -+ "version": "4.0.1", -+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", -+ "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, -- "json-schema-traverse": { -- "version": "0.3.1", -- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", -- "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", -+ "get-stream": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", -+ "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, -- "json-stable-stringify": { -- "version": "0.0.1", -- "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", -- "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", -+ "getpass": { -+ "version": "0.1.7", -+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", -+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { -- "jsonify": "0.0.0" -+ "assert-plus": "1.0.0" - } - }, -- "json-stringify-safe": { -- "version": "5.0.1", -- "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", -- "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", -- "dev": true -- }, -- "jsonfile": { -- "version": "2.4.0", -- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", -- "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", -+ "git-raw-commits": { -+ "version": "1.3.4", -+ "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-1.3.4.tgz", -+ "integrity": "sha512-G3O+41xHbscpgL5nA0DUkbFVgaAz5rd57AMSIMew8p7C8SyFwZDyn08MoXHkTl9zcD0LmxsLFPxbqFY4YPbpPA==", - "dev": true, - "requires": { -- "graceful-fs": "4.1.11" -+ "dargs": "4.1.0", -+ "lodash.template": "4.4.0", -+ "meow": "4.0.0", -+ "split2": "2.2.0", -+ "through2": "2.0.3" - } - }, -- "jsonify": { -- "version": "0.0.0", -- "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", -- "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", -- "dev": true -- }, -- "jsonparse": { -- "version": "1.3.1", -- "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", -- "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", -- "dev": true -- }, -- "jsonpointer": { -- "version": "4.0.1", -- "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", -- "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", -- "dev": true -- }, -- "jsprim": { -- "version": "1.4.1", -- "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", -- "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", -+ "git-remote-origin-url": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", -+ "integrity": "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=", - "dev": true, - "requires": { -- "assert-plus": "1.0.0", -- "extsprintf": "1.3.0", -- "json-schema": "0.2.3", -- "verror": "1.10.0" -+ "gitconfiglocal": "1.0.0", -+ "pify": "2.3.0" - } - }, -- "jsx-ast-utils": { -- "version": "1.4.1", -- "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz", -- "integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=", -- "dev": true -- }, -- "keyed-array": { -- "version": "2.1.2", -- "resolved": "https://registry.npmjs.org/keyed-array/-/keyed-array-2.1.2.tgz", -- "integrity": "sha1-isE3thMi7V7Rx7Qbn5zQZmMcrOA=", -- "dev": true -- }, -- "kind-of": { -- "version": "3.2.2", -- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", -- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", -+ "git-semver-tags": { -+ "version": "1.3.4", -+ "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-1.3.4.tgz", -+ "integrity": "sha512-Xe2Z74MwXZfAezuaO6e6cA4nsgeCiARPzaBp23gma325c/OXdt//PhrknptIaynNeUp2yWtmikV7k5RIicgGIQ==", - "dev": true, - "requires": { -- "is-buffer": "1.1.6" -+ "meow": "4.0.0", -+ "semver": "5.5.0" - } - }, -- "klaw": { -- "version": "1.3.1", -- "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", -- "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", -+ "gitconfiglocal": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", -+ "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=", - "dev": true, - "requires": { -- "graceful-fs": "4.1.11" -+ "ini": "1.3.5" - } - }, -- "labeled-stream-splicer": { -- "version": "2.0.1", -- "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz", -- "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", -+ "github": { -+ "version": "9.3.1", -+ "resolved": "https://registry.npmjs.org/github/-/github-9.3.1.tgz", -+ "integrity": "sha512-LvVb6iR8/7bqYgj0VeAtqys0t427jwIBkv/+or/ssypfIk5R1fnz4aeIEv4udPw6VFoH6vL4gi+foBoD5aazXg==", - "dev": true, - "requires": { -- "inherits": "2.0.3", -- "isarray": "2.0.4", -- "stream-splicer": "2.0.0" -- }, -- "dependencies": { -- "isarray": { -- "version": "2.0.4", -- "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", -- "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==", -- "dev": true -- } -+ "follow-redirects": "0.0.7", -+ "https-proxy-agent": "1.0.0", -+ "mime": "1.6.0", -+ "netrc": "0.1.4" - } - }, -- "latest-version": { -- "version": "3.1.0", -- "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", -- "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", -+ "glob": { -+ "version": "6.0.4", -+ "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", -+ "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { -- "package-json": "4.0.1" -+ "inflight": "1.0.6", -+ "inherits": "2.0.3", -+ "minimatch": "3.0.4", -+ "once": "1.4.0", -+ "path-is-absolute": "1.0.1" - } - }, -- "lazy-cache": { -- "version": "1.0.4", -- "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", -- "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", -- "dev": true, -- "optional": true -- }, -- "lcid": { -- "version": "1.0.0", -- "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", -- "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", -+ "glob-base": { -+ "version": "0.3.0", -+ "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", -+ "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { -- "invert-kv": "1.0.0" -+ "glob-parent": "2.0.0", -+ "is-glob": "2.0.1" - } - }, -- "leven": { -- "version": "2.1.0", -- "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", -- "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", -- "dev": true -- }, -- "levn": { -- "version": "0.3.0", -- "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", -- "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", -+ "glob-parent": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", -+ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { -- "prelude-ls": "1.1.2", -- "type-check": "0.3.2" -+ "is-glob": "2.0.1" - } - }, -- "lexical-scope": { -- "version": "1.2.0", -- "resolved": "https://registry.npmjs.org/lexical-scope/-/lexical-scope-1.2.0.tgz", -- "integrity": "sha1-/Ope3HBKSzqHls3KQZw6CvryLfQ=", -+ "global-dirs": { -+ "version": "0.1.1", -+ "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", -+ "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", - "dev": true, - "requires": { -- "astw": "2.2.0" -+ "ini": "1.3.5" - } - }, -- "linkify-it": { -- "version": "1.2.4", -- "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-1.2.4.tgz", -- "integrity": "sha1-B3NSbDF8j9E71TTuHRgP+Iq/iBo=", -+ "globals": { -+ "version": "9.18.0", -+ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", -+ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", -+ "dev": true -+ }, -+ "globby": { -+ "version": "5.0.0", -+ "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", -+ "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { -- "uc.micro": "1.0.5" -+ "array-union": "1.0.2", -+ "arrify": "1.0.1", -+ "glob": "7.1.2", -+ "object-assign": "4.1.1", -+ "pify": "2.3.0", -+ "pinkie-promise": "2.0.1" -+ }, -+ "dependencies": { -+ "glob": { -+ "version": "7.1.2", -+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+ "dev": true, -+ "requires": { -+ "fs.realpath": "1.0.0", -+>>>>>>> .their -+ "inflight": "1.0.6", -+ "inherits": "2.0.3", -+ "minimatch": "3.0.4", -+ "once": "1.4.0", -+ "path-is-absolute": "1.0.1" -+ } -+<<<<<<< .our -+ }, -+ "resolve": { -+ "version": "1.1.7", -+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", -+ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", -+ "dev": true -+ }, -+ "wordwrap": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", -+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", -+ "dev": true -+ } - } - }, -- "lint": { -- "version": "1.1.2", -- "resolved": "https://registry.npmjs.org/lint/-/lint-1.1.2.tgz", -- "integrity": "sha1-Ne0GTzIlR8MxNY2JmGhmSWi6Nx8=", -+ "js-tokens": { -+ "version": "3.0.2", -+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", -+ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, -- "load-json-file": { -- "version": "1.1.0", -- "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", -- "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", -+ "js-yaml": { -+ "version": "3.11.0", -+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", -+ "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", - "dev": true, - "requires": { -- "graceful-fs": "4.1.11", -- "parse-json": "2.2.0", -- "pify": "2.3.0", -- "pinkie-promise": "2.0.1", -- "strip-bom": "2.0.0" -+ "argparse": "1.0.10", -+ "esprima": "4.0.0" -+ }, -+ "dependencies": { -+ "esprima": { -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", -+ "integrity": "sha1-RJnt3NERDgshi6zy+n9/WfVcqAQ=", -+ "dev": true -+ } - } - }, -- "load-plugin": { -- "version": "2.2.2", -- "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-2.2.2.tgz", -- "integrity": "sha512-FYzamtURIJefQykZGtiClYuZkJBUKzmx8Tc74y8JGAulDzbzVm/C+w/MbAljHRr+REL0cRzy3WgnHE+T8gce5g==", -+ "jsbn": { -+ "version": "0.1.1", -+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", -+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, -- "requires": { -- "npm-prefix": "1.2.0", -- "resolve-from": "4.0.0" -- } -+ "optional": true - }, -- "locate-path": { -- "version": "2.0.0", -- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", -- "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", -+ "jsdom": { -+ "version": "7.2.2", -+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-7.2.2.tgz", -+ "integrity": "sha1-QLQCdwwr2iNGkJa+6Rq2deOx/G4=", - "dev": true, -+ "optional": true, - "requires": { -- "p-locate": "2.0.0", -- "path-exists": "3.0.0" -+ "abab": "1.0.4", -+ "acorn": "2.7.0", -+ "acorn-globals": "1.0.9", -+ "cssom": "0.3.2", -+ "cssstyle": "0.2.37", -+ "escodegen": "1.8.1", -+ "nwmatcher": "1.4.4", -+ "parse5": "1.5.1", -+ "request": "2.85.0", -+ "sax": "1.2.4", -+ "symbol-tree": "3.2.2", -+ "tough-cookie": "2.3.4", -+ "webidl-conversions": "2.0.1", -+ "whatwg-url-compat": "0.6.5", -+ "xml-name-validator": "2.0.1" - }, - "dependencies": { -- "path-exists": { -- "version": "3.0.0", -- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", -- "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", -- "dev": true -+ "acorn": { -+ "version": "2.7.0", -+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz", -+ "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc=", -+ "dev": true, -+ "optional": true - } - } - }, -- "lodash": { -- "version": "4.17.10", -- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", -- "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", -+ "json-parse-better-errors": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", -+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, -- "lodash._reinterpolate": { -- "version": "3.0.0", -- "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", -- "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", -+ "json-schema": { -+ "version": "0.2.3", -+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", -+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, -- "lodash.assign": { -- "version": "4.2.0", -- "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", -- "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", -+ "json-schema-traverse": { -+ "version": "0.3.1", -+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", -+ "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, -- "lodash.assignin": { -- "version": "4.2.0", -- "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", -- "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=", -- "dev": true -+ "json-stable-stringify": { -+ "version": "0.0.1", -+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", -+ "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", -+ "dev": true, -+ "requires": { -+ "jsonify": "0.0.0" -+ } - }, -- "lodash.bind": { -- "version": "4.2.1", -- "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", -- "integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=", -+ "json-stringify-safe": { -+ "version": "5.0.1", -+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", -+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, -- "lodash.cond": { -- "version": "4.5.2", -- "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", -- "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", -- "dev": true -+ "jsonfile": { -+ "version": "2.4.0", -+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", -+ "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", -+ "dev": true, -+ "requires": { -+ "graceful-fs": "4.1.11" -+ } - }, -- "lodash.defaults": { -- "version": "4.2.0", -- "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", -- "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", -+ "jsonify": { -+ "version": "0.0.0", -+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", -+ "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, -- "lodash.filter": { -- "version": "4.6.0", -- "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", -- "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=", -+ "jsonparse": { -+ "version": "1.3.1", -+ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", -+ "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", - "dev": true - }, -- "lodash.flatten": { -- "version": "4.4.0", -- "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", -- "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", -+ "jsonpointer": { -+ "version": "4.0.1", -+ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", -+ "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", - "dev": true - }, -- "lodash.foreach": { -- "version": "4.5.0", -- "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", -- "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=", -+ "jsprim": { -+ "version": "1.4.1", -+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", -+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", -+ "dev": true, -+ "requires": { -+ "assert-plus": "1.0.0", -+ "extsprintf": "1.3.0", -+ "json-schema": "0.2.3", -+ "verror": "1.10.0" -+ } -+ }, -+ "jsx-ast-utils": { -+ "version": "1.4.1", -+ "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz", -+ "integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=", - "dev": true - }, -- "lodash.isempty": { -- "version": "4.4.0", -- "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", -- "integrity": "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=", -- "dev": true -- }, -- "lodash.isplainobject": { -- "version": "4.0.6", -- "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", -- "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", -- "dev": true -- }, -- "lodash.map": { -- "version": "4.6.0", -- "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", -- "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", -+ "keyed-array": { -+ "version": "2.1.2", -+ "resolved": "https://registry.npmjs.org/keyed-array/-/keyed-array-2.1.2.tgz", -+ "integrity": "sha1-isE3thMi7V7Rx7Qbn5zQZmMcrOA=", - "dev": true - }, -- "lodash.memoize": { -- "version": "3.0.4", -- "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", -- "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", -- "dev": true -+ "kind-of": { -+ "version": "3.2.2", -+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", -+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", -+ "dev": true, -+ "requires": { -+ "is-buffer": "1.1.6" -+ } - }, -- "lodash.merge": { -- "version": "4.6.1", -- "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", -- "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==", -- "dev": true -+ "klaw": { -+ "version": "1.3.1", -+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", -+ "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", -+ "dev": true, -+ "requires": { -+ "graceful-fs": "4.1.11" -+ } - }, -- "lodash.pick": { -- "version": "4.4.0", -- "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", -- "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", -- "dev": true -+ "labeled-stream-splicer": { -+ "version": "2.0.1", -+ "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz", -+ "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", -+ "dev": true, -+ "requires": { -+ "inherits": "2.0.3", -+ "isarray": "2.0.4", -+ "stream-splicer": "2.0.0" -+ }, -+ "dependencies": { -+ "isarray": { -+ "version": "2.0.4", -+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", -+ "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==", -+ "dev": true -+ } -+ } - }, -- "lodash.range": { -- "version": "3.2.0", -- "resolved": "https://registry.npmjs.org/lodash.range/-/lodash.range-3.2.0.tgz", -- "integrity": "sha1-9GHliPZmg/fq3q3lE+OKaaVloV0=", -- "dev": true -+ "latest-version": { -+ "version": "3.1.0", -+ "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", -+ "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", -+ "dev": true, -+ "requires": { -+ "package-json": "4.0.1" -+ } - }, -- "lodash.reduce": { -- "version": "4.6.0", -- "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", -- "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=", -- "dev": true -+ "lazy-cache": { -+ "version": "1.0.4", -+ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", -+ "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", -+ "dev": true, -+ "optional": true - }, -- "lodash.reject": { -- "version": "4.6.0", -- "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", -- "integrity": "sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU=", -- "dev": true -+ "lcid": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", -+ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", -+ "dev": true, -+ "requires": { -+ "invert-kv": "1.0.0" -+ } - }, -- "lodash.some": { -- "version": "4.6.0", -- "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", -- "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", -+ "leven": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", -+ "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", - "dev": true - }, -- "lodash.template": { -- "version": "4.4.0", -- "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", -- "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", -+ "levn": { -+ "version": "0.3.0", -+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", -+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { -- "lodash._reinterpolate": "3.0.0", -- "lodash.templatesettings": "4.1.0" -+ "prelude-ls": "1.1.2", -+ "type-check": "0.3.2" - } - }, -- "lodash.templatesettings": { -- "version": "4.1.0", -- "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", -- "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", -+ "lexical-scope": { -+ "version": "1.2.0", -+ "resolved": "https://registry.npmjs.org/lexical-scope/-/lexical-scope-1.2.0.tgz", -+ "integrity": "sha1-/Ope3HBKSzqHls3KQZw6CvryLfQ=", - "dev": true, - "requires": { -- "lodash._reinterpolate": "3.0.0" -+ "astw": "2.2.0" - } - }, -- "lodash.transform": { -- "version": "4.6.0", -- "resolved": "https://registry.npmjs.org/lodash.transform/-/lodash.transform-4.6.0.tgz", -- "integrity": "sha1-EjBkIvYzJK7YSD0/ODMrX2cFR6A=", -- "dev": true -- }, -- "log-symbols": { -- "version": "1.0.2", -- "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", -- "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", -+ "linkify-it": { -+ "version": "1.2.4", -+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-1.2.4.tgz", -+ "integrity": "sha1-B3NSbDF8j9E71TTuHRgP+Iq/iBo=", - "dev": true, - "requires": { -- "chalk": "1.1.3" -+ "uc.micro": "1.0.5" - } - }, -- "longest": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", -- "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", -- "dev": true -- }, -- "longest-streak": { -- "version": "2.0.2", -- "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.2.tgz", -- "integrity": "sha512-TmYTeEYxiAmSVdpbnQDXGtvYOIRsCMg89CVZzwzc2o7GFL1CjoiRPjH5ec0NFAVlAx3fVof9dX/t6KKRAo2OWA==", -+ "lint": { -+ "version": "1.1.2", -+ "resolved": "https://registry.npmjs.org/lint/-/lint-1.1.2.tgz", -+ "integrity": "sha1-Ne0GTzIlR8MxNY2JmGhmSWi6Nx8=", - "dev": true - }, -- "loud-rejection": { -- "version": "1.6.0", -- "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", -- "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", -+ "load-json-file": { -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", -+ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { -- "currently-unhandled": "0.4.1", -- "signal-exit": "3.0.2" -+ "graceful-fs": "4.1.11", -+ "parse-json": "2.2.0", -+ "pify": "2.3.0", -+ "pinkie-promise": "2.0.1", -+ "strip-bom": "2.0.0" - } - }, -- "lowercase-keys": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", -- "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", -- "dev": true -- }, -- "lru-cache": { -- "version": "4.1.3", -- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", -- "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", -+ "load-plugin": { -+ "version": "2.2.2", -+ "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-2.2.2.tgz", -+ "integrity": "sha512-FYzamtURIJefQykZGtiClYuZkJBUKzmx8Tc74y8JGAulDzbzVm/C+w/MbAljHRr+REL0cRzy3WgnHE+T8gce5g==", - "dev": true, - "requires": { -- "pseudomap": "1.0.2", -- "yallist": "2.1.2" -- }, -- "dependencies": { -- "yallist": { -- "version": "2.1.2", -- "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", -- "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", -- "dev": true -- } -+ "npm-prefix": "1.2.0", -+ "resolve-from": "4.0.0" - } - }, -- "make-dir": { -- "version": "1.3.0", -- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", -- "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", -+ "locate-path": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", -+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { -- "pify": "3.0.0" -+ "p-locate": "2.0.0", -+ "path-exists": "3.0.0" - }, - "dependencies": { -- "pify": { -+ "path-exists": { - "version": "3.0.0", -- "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", -- "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", -- "dev": true -+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", -+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", -+======= - } - } - }, -- "map-obj": { -- "version": "2.0.0", -- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", -- "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", -- "dev": true -+ "got": { -+ "version": "6.7.1", -+ "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", -+ "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", -+ "dev": true, -+ "requires": { -+ "create-error-class": "3.0.2", -+ "duplexer3": "0.1.4", -+ "get-stream": "3.0.0", -+ "is-redirect": "1.0.0", -+ "is-retry-allowed": "1.1.0", -+ "is-stream": "1.1.0", -+ "lowercase-keys": "1.0.0", -+ "safe-buffer": "5.1.1", -+ "timed-out": "4.0.1", -+ "unzip-response": "2.0.1", -+ "url-parse-lax": "1.0.0" -+ } - }, -- "markdown-escapes": { -- "version": "1.0.2", -- "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.2.tgz", -- "integrity": "sha512-lbRZ2mE3Q9RtLjxZBZ9+IMl68DKIXaVAhwvwn9pmjnPLS0h/6kyBMgNhqi1xFJ/2yv6cSyv0jbiZavZv93JkkA==", -+ "graceful-fs": { -+ "version": "4.1.11", -+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", -+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, -- "markdown-extensions": { -- "version": "1.1.1", -- "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz", -- "integrity": "sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==", -- "dev": true -- }, -- "markdown-it": { -- "version": "6.1.1", -- "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-6.1.1.tgz", -- "integrity": "sha1-ztA39Ec+6fUVOsQU933IPJG6knw=", -- "dev": true, -- "requires": { -- "argparse": "1.0.10", -- "entities": "1.1.1", -- "linkify-it": "1.2.4", -- "mdurl": "1.0.1", -- "uc.micro": "1.0.5" -- } -- }, -- "markdown-it-named-headers": { -- "version": "0.0.4", -- "resolved": "https://registry.npmjs.org/markdown-it-named-headers/-/markdown-it-named-headers-0.0.4.tgz", -- "integrity": "sha1-gu/CgyQkCmsed7mq5QF3HV81HB8=", -+ "gunzip-maybe": { -+ "version": "1.4.1", -+ "resolved": "https://registry.npmjs.org/gunzip-maybe/-/gunzip-maybe-1.4.1.tgz", -+ "integrity": "sha512-qtutIKMthNJJgeHQS7kZ9FqDq59/Wn0G2HYCRNjpup7yKfVI6/eqwpmroyZGFoCYaG+sW6psNVb4zoLADHpp2g==", - "dev": true, - "requires": { -- "string": "3.3.3" -+ "browserify-zlib": "0.1.4", -+ "is-deflate": "1.0.0", -+ "is-gzip": "1.0.0", -+ "peek-stream": "1.1.2", -+ "pumpify": "1.4.0", -+ "through2": "2.0.3" - } - }, -- "markdown-table": { -- "version": "1.1.2", -- "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.2.tgz", -- "integrity": "sha512-NcWuJFHDA8V3wkDgR/j4+gZx+YQwstPgfQDV8ndUeWWzta3dnDTBxpVzqS9lkmJAuV5YX35lmyojl6HO5JXAgw==", -- "dev": true -- }, -- "marky-markdown-lite": { -- "version": "1.2.0", -- "resolved": "https://registry.npmjs.org/marky-markdown-lite/-/marky-markdown-lite-1.2.0.tgz", -- "integrity": "sha1-dO2phLgTZVfe4QZO/RXkBhdAaZc=", -+ "handlebars": { -+ "version": "4.0.11", -+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", -+ "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", - "dev": true, - "requires": { -- "cheerio": "0.20.0", -- "conventional-changelog-cli": "1.3.22", -- "is-file": "1.0.0", -- "markdown-it": "6.1.1", -- "markdown-it-named-headers": "0.0.4" -+ "async": "1.5.2", -+ "optimist": "0.6.1", -+ "source-map": "0.4.4", -+ "uglify-js": "2.8.29" - }, - "dependencies": { -- "cheerio": { -- "version": "0.20.0", -- "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.20.0.tgz", -- "integrity": "sha1-XHEPK6uVZTJyhCugHG6mGzVF7DU=", -- "dev": true, -- "requires": { -- "css-select": "1.2.0", -- "dom-serializer": "0.1.0", -- "entities": "1.1.1", -- "htmlparser2": "3.8.3", -- "jsdom": "7.2.2", -- "lodash": "4.17.10" -- } -+ "minimist": { -+ "version": "0.0.10", -+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", -+ "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", -+ "dev": true - }, -- "domhandler": { -- "version": "2.3.0", -- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", -- "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", -+ "optimist": { -+ "version": "0.6.1", -+ "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", -+ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { -- "domelementtype": "1.3.0" -+ "minimist": "0.0.10", -+ "wordwrap": "0.0.3" - } - }, -- "htmlparser2": { -- "version": "3.8.3", -- "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", -- "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", -+ "source-map": { -+ "version": "0.4.4", -+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", -+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, - "requires": { -- "domelementtype": "1.3.0", -- "domhandler": "2.3.0", -- "domutils": "1.5.1", -- "entities": "1.0.0", -- "readable-stream": "1.1.14" -- }, -- "dependencies": { -- "entities": { -- "version": "1.0.0", -- "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", -- "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", -- "dev": true -- } -+ "amdefine": "1.0.1" - } - } - } - }, -- "matcher-collection": { -- "version": "1.0.5", -- "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-1.0.5.tgz", -- "integrity": "sha1-LuCVQ4Nyy4iE8FgjQTjAXGROwzk=", -+ "har-schema": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", -+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", -+ "dev": true -+ }, -+ "har-validator": { -+ "version": "5.0.3", -+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", -+ "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", - "dev": true, - "requires": { -- "minimatch": "3.0.4" -+ "ajv": "5.5.2", -+ "har-schema": "2.0.0" - } - }, -- "math-random": { -+ "has": { - "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", -- "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", -+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", -+ "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", -+ "dev": true, -+ "requires": { -+ "function-bind": "1.1.1" -+ } -+ }, -+ "has-ansi": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", -+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", -+ "dev": true, -+ "requires": { -+ "ansi-regex": "2.1.1" -+ } -+ }, -+ "has-flag": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", -+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, -- "md5.js": { -- "version": "1.3.4", -- "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", -- "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", -+ "has-symbols": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", -+ "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", -+ "dev": true -+ }, -+ "hash-base": { -+ "version": "2.0.2", -+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", -+ "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", - "dev": true, - "requires": { -- "hash-base": "3.0.4", - "inherits": "2.0.3" - } - }, -- "mdast-comment-marker": { -- "version": "1.0.2", -- "resolved": "https://registry.npmjs.org/mdast-comment-marker/-/mdast-comment-marker-1.0.2.tgz", -- "integrity": "sha1-Hd8O+BH7UkOQF8jSwLkiA18rp0o=", -- "dev": true -+ "hash.js": { -+ "version": "1.1.3", -+ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", -+ "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", -+ "dev": true, -+ "requires": { -+ "inherits": "2.0.3", -+ "minimalistic-assert": "1.0.0" -+ } - }, -- "mdast-util-compact": { -+ "hawk": { -+ "version": "6.0.2", -+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", -+ "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", -+ "dev": true, -+ "requires": { -+ "boom": "4.3.1", -+ "cryptiles": "3.1.2", -+ "hoek": "4.2.1", -+ "sntp": "2.1.0" -+ } -+ }, -+ "heads": { -+ "version": "1.3.0", -+ "resolved": "https://registry.npmjs.org/heads/-/heads-1.3.0.tgz", -+ "integrity": "sha1-/p8Q01WjqYbeuO5MzZ8rvHVLZcA=", -+ "dev": true, -+ "requires": { -+ "async": "2.6.0", -+ "got": "6.7.1", -+ "pify": "2.3.0" -+ }, -+ "dependencies": { -+ "async": { -+ "version": "2.6.0", -+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", -+ "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", -+ "dev": true, -+ "requires": { -+ "lodash": "4.17.5" -+ } -+ } -+ } -+ }, -+ "hmac-drbg": { - "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.1.tgz", -- "integrity": "sha1-zbX4TitqLTEU3zO9BdnLMuPECDo=", -+ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", -+ "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { -- "unist-util-modify-children": "1.1.2", -- "unist-util-visit": "1.3.1" -+ "hash.js": "1.1.3", -+ "minimalistic-assert": "1.0.0", -+ "minimalistic-crypto-utils": "1.0.1" - } - }, -- "mdast-util-heading-style": { -- "version": "1.0.3", -- "resolved": "https://registry.npmjs.org/mdast-util-heading-style/-/mdast-util-heading-style-1.0.3.tgz", -- "integrity": "sha1-77OQ28iqAWw89XegNJANsn7nJHw=", -+ "hoek": { -+ "version": "4.2.1", -+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", -+ "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", - "dev": true - }, -- "mdast-util-to-string": { -- "version": "1.0.4", -- "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.0.4.tgz", -- "integrity": "sha1-XEVch4yTVfDB5/PotxnPWDaRrPs=", -+ "home-or-tmp": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", -+ "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", -+ "dev": true, -+ "requires": { -+ "os-homedir": "1.0.2", -+ "os-tmpdir": "1.0.2" -+ } -+ }, -+ "hosted-git-info": { -+ "version": "2.6.0", -+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", -+ "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==", - "dev": true - }, -- "mdurl": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", -- "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", -+ "htmlescape": { -+ "version": "1.1.1", -+ "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", -+ "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", - "dev": true - }, -- "meow": { -- "version": "4.0.1", -- "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", -- "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", -+ "htmlparser2": { -+ "version": "3.9.2", -+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz", -+ "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=", - "dev": true, - "requires": { -- "camelcase-keys": "4.2.0", -- "decamelize-keys": "1.1.0", -- "loud-rejection": "1.6.0", -- "minimist": "1.2.0", -- "minimist-options": "3.0.2", -- "normalize-package-data": "2.4.0", -- "read-pkg-up": "3.0.0", -- "redent": "2.0.0", -- "trim-newlines": "2.0.0" -- }, -+ "domelementtype": "1.3.0", -+ "domhandler": "2.4.1", -+ "domutils": "1.5.1", -+ "entities": "1.1.1", -+ "inherits": "2.0.3", -+ "readable-stream": "2.3.5" -+ }, - "dependencies": { -- "find-up": { -- "version": "2.1.0", -- "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", -- "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", -- "dev": true, -- "requires": { -- "locate-path": "2.0.0" -- } -- }, -- "load-json-file": { -- "version": "4.0.0", -- "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", -- "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", -- "dev": true, -- "requires": { -- "graceful-fs": "4.1.11", -- "parse-json": "4.0.0", -- "pify": "3.0.0", -- "strip-bom": "3.0.0" -- } -- }, -- "parse-json": { -- "version": "4.0.0", -- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", -- "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", -- "dev": true, -- "requires": { -- "error-ex": "1.3.1", -- "json-parse-better-errors": "1.0.2" -- } -- }, -- "path-type": { -- "version": "3.0.0", -- "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", -- "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", -- "dev": true, -- "requires": { -- "pify": "3.0.0" -- } -- }, -- "pify": { -- "version": "3.0.0", -- "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", -- "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", -+ "isarray": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", -+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, -- "read-pkg": { -- "version": "3.0.0", -- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", -- "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", -+ "readable-stream": { -+ "version": "2.3.5", -+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", -+ "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", - "dev": true, - "requires": { -- "load-json-file": "4.0.0", -- "normalize-package-data": "2.4.0", -- "path-type": "3.0.0" -+ "core-util-is": "1.0.2", -+ "inherits": "2.0.3", -+ "isarray": "1.0.0", -+ "process-nextick-args": "2.0.0", -+ "safe-buffer": "5.1.1", -+ "string_decoder": "1.0.3", -+ "util-deprecate": "1.0.2" - } - }, -- "read-pkg-up": { -- "version": "3.0.0", -- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", -- "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", -+ "string_decoder": { -+ "version": "1.0.3", -+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", -+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { -- "find-up": "2.1.0", -- "read-pkg": "3.0.0" -+ "safe-buffer": "5.1.1" - } -- }, -- "strip-bom": { -- "version": "3.0.0", -- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", -- "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", -- "dev": true - } - } - }, -- "micro": { -- "version": "9.3.1", -- "resolved": "https://registry.npmjs.org/micro/-/micro-9.3.1.tgz", -- "integrity": "sha512-83uimpPJqfwkfKvJl2WWontBlV3hmzrIgyJ+L2uhDXKNk7Ll+/ezK3zBz7TljubpKPqjM0JdT2Ker4MTPmhjgA==", -+ "http-signature": { -+ "version": "1.2.0", -+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", -+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { -- "arg": "2.0.0", -- "chalk": "2.4.0", -- "content-type": "1.0.4", -- "is-stream": "1.1.0", -- "raw-body": "2.3.2" -- }, -- "dependencies": { -- "ansi-styles": { -- "version": "3.2.1", -- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", -- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", -- "dev": true, -- "requires": { -- "color-convert": "1.9.1" -- } -- }, -- "chalk": { -- "version": "2.4.0", -- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.0.tgz", -- "integrity": "sha512-Wr/w0f4o9LuE7K53cD0qmbAMM+2XNLzR29vFn5hqko4sxGlUsyy363NvmyGIyk5tpe9cjTr9SJYbysEyPkRnFw==", -- "dev": true, -- "requires": { -- "ansi-styles": "3.2.1", -- "escape-string-regexp": "1.0.5", -- "supports-color": "5.4.0" -- } -- }, -- "has-flag": { -- "version": "3.0.0", -- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", -- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", -- "dev": true -- }, -- "supports-color": { -- "version": "5.4.0", -- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", -- "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", -- "dev": true, -- "requires": { -- "has-flag": "3.0.0" -- } -- } -+ "assert-plus": "1.0.0", -+ "jsprim": "1.4.1", -+ "sshpk": "1.14.1" - } - }, -- "micro-compress": { -- "version": "1.0.0", -- "resolved": "https://registry.npmjs.org/micro-compress/-/micro-compress-1.0.0.tgz", -- "integrity": "sha1-U/WoC0rQMgyhZaVZtuPfFF1PcE8=", -- "dev": true, -- "requires": { -- "compression": "1.7.3" -- } -+ "https-browserify": { -+ "version": "0.0.1", -+ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz", -+ "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=", -+ "dev": true - }, -- "micromatch": { -- "version": "2.3.11", -- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", -- "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", -+ "https-proxy-agent": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz", -+ "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=", - "dev": true, - "requires": { -- "arr-diff": "2.0.0", -- "array-unique": "0.2.1", -- "braces": "1.8.5", -- "expand-brackets": "0.1.5", -- "extglob": "0.3.2", -- "filename-regex": "2.0.1", -- "is-extglob": "1.0.0", -- "is-glob": "2.0.1", -- "kind-of": "3.2.2", -- "normalize-path": "2.1.1", -- "object.omit": "2.0.1", -- "parse-glob": "3.0.4", -- "regex-cache": "0.4.4" -+ "agent-base": "2.1.1", -+ "debug": "2.6.9", -+ "extend": "3.0.1" - } - }, -- "miller-rabin": { -- "version": "4.0.1", -- "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", -- "integrity": "sha1-8IA1HIZbDcViqEYpZtqlNUPHik0=", -+ "husky": { -+ "version": "0.14.3", -+ "resolved": "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz", -+ "integrity": "sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA==", - "dev": true, - "requires": { -- "bn.js": "4.11.8", -- "brorand": "1.1.0" -+ "is-ci": "1.1.0", -+ "normalize-path": "1.0.0", -+ "strip-indent": "2.0.0" -+ }, -+ "dependencies": { -+ "normalize-path": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz", -+ "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=", -+>>>>>>> .their -+ "dev": true -+ } - } - }, -- "mime": { -- "version": "1.6.0", -- "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", -- "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", -+<<<<<<< .our -+ "lodash": { -+ "version": "4.17.10", -+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", -+ "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", - "dev": true - }, -- "mime-db": { -- "version": "1.33.0", -- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", -- "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", -+ "lodash._reinterpolate": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", -+ "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, -- "mime-types": { -- "version": "2.1.18", -- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", -- "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", -- "dev": true, -- "requires": { -- "mime-db": "1.33.0" -- } -- }, -- "mimic-fn": { -- "version": "1.2.0", -- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", -- "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", -+ "lodash.assign": { -+ "version": "4.2.0", -+ "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", -+ "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", - "dev": true - }, -- "minimalistic-assert": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", -- "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", -+ "lodash.assignin": { -+ "version": "4.2.0", -+ "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", -+ "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=", - "dev": true - }, -- "minimalistic-crypto-utils": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", -- "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", -+ "lodash.bind": { -+ "version": "4.2.1", -+ "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", -+ "integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=", - "dev": true - }, -- "minimatch": { -- "version": "3.0.4", -- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", -- "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", -- "dev": true, -- "requires": { -- "brace-expansion": "1.1.11" -- } -- }, -- "minimist": { -- "version": "1.2.0", -- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", -- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", -+ "lodash.cond": { -+ "version": "4.5.2", -+ "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", -+ "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", - "dev": true - }, -- "minimist-options": { -- "version": "3.0.2", -- "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", -- "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", -- "dev": true, -- "requires": { -- "arrify": "1.0.1", -- "is-plain-obj": "1.1.0" -- } -- }, -- "minipass": { -- "version": "2.3.0", -- "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.0.tgz", -- "integrity": "sha512-jWC2Eg+Np4bxah7llu1IrUNSJQxtLz/J+pOjTM0nFpJXGAaV18XBWhUn031Q1tAA/TJtA1jgwnOe9S2PQa4Lbg==", -- "dev": true, -- "requires": { -- "safe-buffer": "5.1.2", -- "yallist": "3.0.2" -- } -- }, -- "minizlib": { -- "version": "1.1.0", -- "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz", -- "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", -- "dev": true, -- "requires": { -- "minipass": "2.3.0" -- } -+ "lodash.defaults": { -+ "version": "4.2.0", -+ "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", -+ "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", -+ "dev": true - }, -- "mkdirp": { -- "version": "0.5.1", -- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", -- "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", -- "dev": true, -- "requires": { -- "minimist": "0.0.8" -- }, -- "dependencies": { -- "minimist": { -- "version": "0.0.8", -- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", -- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", -- "dev": true -- } -- } -+ "lodash.filter": { -+ "version": "4.6.0", -+ "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", -+ "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=", -+ "dev": true - }, -- "mkpath": { -- "version": "0.1.0", -- "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz", -- "integrity": "sha1-dVSm+Nhxg0zJe1RisSLEwSTW3pE=", -+ "lodash.flatten": { -+ "version": "4.4.0", -+ "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", -+ "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, -- "mksnapshot": { -- "version": "0.3.1", -- "resolved": "https://registry.npmjs.org/mksnapshot/-/mksnapshot-0.3.1.tgz", -- "integrity": "sha1-JQHAVldDbXQs6Vik/5LHfkDdN+Y=", -- "dev": true, -- "requires": { -- "decompress-zip": "0.3.0", -- "fs-extra": "0.26.7", -- "request": "2.85.0" -- } -+ "lodash.foreach": { -+ "version": "4.5.0", -+ "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", -+ "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=", -+ "dev": true - }, -- "modify-values": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", -- "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", -+ "lodash.isempty": { -+ "version": "4.4.0", -+ "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", -+ "integrity": "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=", - "dev": true - }, -- "module-deps": { -- "version": "4.1.1", -- "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-4.1.1.tgz", -- "integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=", -- "dev": true, -- "requires": { -- "JSONStream": "1.3.2", -- "browser-resolve": "1.11.2", -- "cached-path-relative": "1.0.1", -- "concat-stream": "1.5.2", -- "defined": "1.0.0", -- "detective": "4.7.1", -- "duplexer2": "0.1.4", -- "inherits": "2.0.3", -- "parents": "1.0.1", -- "readable-stream": "2.3.6", -- "resolve": "1.7.1", -- "stream-combiner2": "1.1.1", -- "subarg": "1.0.0", -- "through2": "2.0.3", -- "xtend": "4.0.1" -- }, -- "dependencies": { -- "isarray": { -- "version": "1.0.0", -- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", -- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", -- "dev": true -- }, -- "readable-stream": { -- "version": "2.3.6", -- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", -- "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", -- "dev": true, -- "requires": { -- "core-util-is": "1.0.2", -- "inherits": "2.0.3", -- "isarray": "1.0.0", -- "process-nextick-args": "2.0.0", -- "safe-buffer": "5.1.2", -- "string_decoder": "1.1.1", -- "util-deprecate": "1.0.2" -- } -- }, -- "string_decoder": { -- "version": "1.1.1", -- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", -- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", -- "dev": true, -- "requires": { -- "safe-buffer": "5.1.2" -- } -- } -- } -+ "lodash.isplainobject": { -+ "version": "4.0.6", -+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", -+ "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", -+ "dev": true - }, -- "mri": { -- "version": "1.1.0", -- "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.0.tgz", -- "integrity": "sha1-XAo/KcjM/7ux7JQdzsCdcfoy82o=", -+ "lodash.map": { -+ "version": "4.6.0", -+ "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", -+ "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", - "dev": true - }, -- "ms": { -- "version": "2.0.0", -- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", -- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", -+ "lodash.memoize": { -+ "version": "3.0.4", -+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", -+ "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", - "dev": true - }, -- "mute-stream": { -- "version": "0.0.5", -- "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", -- "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", -+ "lodash.merge": { -+ "version": "4.6.1", -+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", -+ "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==", - "dev": true - }, -- "nan": { -- "version": "2.10.0", -- "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", -- "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", -- "dev": true, -- "optional": true -+ "lodash.pick": { -+ "version": "4.4.0", -+ "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", -+ "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", -+ "dev": true - }, -- "natural-compare": { -- "version": "1.4.0", -- "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", -- "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", -+ "lodash.range": { -+ "version": "3.2.0", -+ "resolved": "https://registry.npmjs.org/lodash.range/-/lodash.range-3.2.0.tgz", -+ "integrity": "sha1-9GHliPZmg/fq3q3lE+OKaaVloV0=", - "dev": true - }, -- "negotiator": { -- "version": "0.6.1", -- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", -- "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", -+ "lodash.reduce": { -+ "version": "4.6.0", -+ "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", -+ "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=", - "dev": true - }, -- "netrc": { -- "version": "0.1.4", -- "resolved": "https://registry.npmjs.org/netrc/-/netrc-0.1.4.tgz", -- "integrity": "sha1-a+lPysqNd63gqWcNxGCRTJRHJEQ=", -+ "lodash.reject": { -+ "version": "4.6.0", -+ "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", -+ "integrity": "sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU=", - "dev": true - }, -- "next-tick": { -- "version": "1.0.0", -- "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", -- "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", -+ "lodash.some": { -+ "version": "4.6.0", -+ "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", -+ "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", - "dev": true - }, -- "node-dir": { -- "version": "0.1.17", -- "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", -- "integrity": "sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=", -+ "lodash.template": { -+ "version": "4.4.0", -+ "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", -+ "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", - "dev": true, - "requires": { -- "minimatch": "3.0.4" -+ "lodash._reinterpolate": "3.0.0", -+ "lodash.templatesettings": "4.1.0" - } - }, -- "node-fetch": { -- "version": "2.1.2", -- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", -- "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=", -- "dev": true -+ "lodash.templatesettings": { -+ "version": "4.1.0", -+ "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", -+ "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", -+ "dev": true, -+ "requires": { -+ "lodash._reinterpolate": "3.0.0" -+ } - }, -- "node-version": { -- "version": "1.1.3", -- "resolved": "https://registry.npmjs.org/node-version/-/node-version-1.1.3.tgz", -- "integrity": "sha512-rEwE51JWn0yN3Wl5BXeGn5d52OGbSXzWiiXRjAQeuyvcGKyvuSILW2rb3G7Xh+nexzLwhTpek6Ehxd6IjvHePg==", -+ "lodash.transform": { -+ "version": "4.6.0", -+ "resolved": "https://registry.npmjs.org/lodash.transform/-/lodash.transform-4.6.0.tgz", -+ "integrity": "sha1-EjBkIvYzJK7YSD0/ODMrX2cFR6A=", - "dev": true - }, -- "nopt": { -- "version": "3.0.6", -- "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", -- "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", -+ "log-symbols": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", -+ "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", - "dev": true, - "requires": { -- "abbrev": "1.1.1" -+ "chalk": "1.1.3" - } - }, -- "normalize-package-data": { -- "version": "2.4.0", -- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", -- "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=", -- "dev": true, -- "requires": { -- "hosted-git-info": "2.6.0", -- "is-builtin-module": "1.0.0", -- "semver": "5.5.0", -- "validate-npm-package-license": "3.0.3" -- } -- }, -- "normalize-path": { -- "version": "2.1.1", -- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", -- "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", -- "dev": true, -- "requires": { -- "remove-trailing-separator": "1.1.0" -- } -- }, -- "npm-prefix": { -- "version": "1.2.0", -- "resolved": "https://registry.npmjs.org/npm-prefix/-/npm-prefix-1.2.0.tgz", -- "integrity": "sha1-5hlFX3B0ulTMZtbQ033Z8b5ry8A=", -- "dev": true, -- "requires": { -- "rc": "1.2.7", -- "shellsubstitute": "1.2.0", -- "untildify": "2.1.0" -- } -+ "longest": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", -+ "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", -+ "dev": true - }, -- "npm-run-path": { -+ "longest-streak": { - "version": "2.0.2", -- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", -- "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", -- "dev": true, -- "requires": { -- "path-key": "2.0.1" -- } -- }, -- "nth-check": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", -- "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", -- "dev": true, -- "requires": { -- "boolbase": "1.0.0" -- } -+ "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.2.tgz", -+ "integrity": "sha512-TmYTeEYxiAmSVdpbnQDXGtvYOIRsCMg89CVZzwzc2o7GFL1CjoiRPjH5ec0NFAVlAx3fVof9dX/t6KKRAo2OWA==", -+ "dev": true - }, -- "nugget": { -- "version": "2.0.1", -- "resolved": "https://registry.npmjs.org/nugget/-/nugget-2.0.1.tgz", -- "integrity": "sha1-IBCVpIfhrTYIGzQy+jytpPjQcbA=", -+ "loud-rejection": { -+ "version": "1.6.0", -+ "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", -+ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dev": true, - "requires": { -- "debug": "2.6.9", -- "minimist": "1.2.0", -- "pretty-bytes": "1.0.4", -- "progress-stream": "1.2.0", -- "request": "2.85.0", -- "single-line-log": "1.1.2", -- "throttleit": "0.0.2" -+ "currently-unhandled": "0.4.1", -+ "signal-exit": "3.0.2" - } - }, -- "number-is-nan": { -+ "lowercase-keys": { - "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", -- "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", -- "dev": true -- }, -- "nwmatcher": { -- "version": "1.4.4", -- "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz", -- "integrity": "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ==", -- "dev": true, -- "optional": true -- }, -- "oauth-sign": { -- "version": "0.8.2", -- "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", -- "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", -- "dev": true -- }, -- "object-assign": { -- "version": "4.1.1", -- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", -- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", -- "dev": true -- }, -- "object-keys": { -- "version": "0.4.0", -- "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", -- "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", -+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", -+ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true - }, -- "object.assign": { -- "version": "4.1.0", -- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", -- "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", -+ "lru-cache": { -+ "version": "4.1.3", -+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", -+ "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", - "dev": true, - "requires": { -- "define-properties": "1.1.2", -- "function-bind": "1.1.1", -- "has-symbols": "1.0.0", -- "object-keys": "1.0.11" -+ "pseudomap": "1.0.2", -+ "yallist": "2.1.2" - }, - "dependencies": { -- "object-keys": { -- "version": "1.0.11", -- "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", -- "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", -+ "yallist": { -+ "version": "2.1.2", -+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", -+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } - } - }, -- "object.omit": { -- "version": "2.0.1", -- "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", -- "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", -- "dev": true, -- "requires": { -- "for-own": "0.1.5", -- "is-extendable": "0.1.1" -- } -- }, -- "octicons": { -- "version": "7.3.0", -- "resolved": "https://registry.npmjs.org/octicons/-/octicons-7.3.0.tgz", -- "integrity": "sha512-UVjlkmUL15Ef/7Rd72Io634Bdl61QgSMasAZpvXPoR2XNFj1RelAyhl4QJuR1hBGlPWFDR7KFj2jEzsFax2IUg==", -- "dev": true, -- "requires": { -- "object-assign": "4.1.1" -- } -- }, -- "on-finished": { -- "version": "2.3.0", -- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", -- "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", -+ "make-dir": { -+ "version": "1.3.0", -+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", -+ "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { -- "ee-first": "1.1.1" -+ "pify": "3.0.0" -+ }, -+ "dependencies": { -+ "pify": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", -+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", -+ "dev": true -+ } - } - }, -- "on-headers": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", -- "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", -+ "map-obj": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", -+ "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", - "dev": true - }, -- "once": { -- "version": "1.4.0", -- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", -- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", -- "dev": true, -- "requires": { -- "wrappy": "1.0.2" -- } -- }, -- "onetime": { -- "version": "1.1.0", -- "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", -- "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", -+ "markdown-escapes": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.2.tgz", -+ "integrity": "sha512-lbRZ2mE3Q9RtLjxZBZ9+IMl68DKIXaVAhwvwn9pmjnPLS0h/6kyBMgNhqi1xFJ/2yv6cSyv0jbiZavZv93JkkA==", - "dev": true - }, -- "openssl-self-signed-certificate": { -- "version": "1.1.6", -- "resolved": "https://registry.npmjs.org/openssl-self-signed-certificate/-/openssl-self-signed-certificate-1.1.6.tgz", -- "integrity": "sha1-nTpHdrGlfphHNQOSEUrS+RWoPdQ=", -+ "markdown-extensions": { -+ "version": "1.1.1", -+ "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz", -+ "integrity": "sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==", - "dev": true - }, -- "opn": { -- "version": "5.3.0", -- "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz", -- "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", -+ "markdown-it": { -+ "version": "6.1.1", -+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-6.1.1.tgz", -+ "integrity": "sha1-ztA39Ec+6fUVOsQU933IPJG6knw=", - "dev": true, - "requires": { -- "is-wsl": "1.1.0" -+ "argparse": "1.0.10", -+ "entities": "1.1.1", -+ "linkify-it": "1.2.4", -+ "mdurl": "1.0.1", -+ "uc.micro": "1.0.5" - } - }, -- "optimist": { -- "version": "0.3.7", -- "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", -- "integrity": "sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=", -+ "markdown-it-named-headers": { -+ "version": "0.0.4", -+ "resolved": "https://registry.npmjs.org/markdown-it-named-headers/-/markdown-it-named-headers-0.0.4.tgz", -+ "integrity": "sha1-gu/CgyQkCmsed7mq5QF3HV81HB8=", - "dev": true, - "requires": { -- "wordwrap": "0.0.3" -+ "string": "3.3.3" - } - }, -- "optionator": { -- "version": "0.8.2", -- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", -- "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", -+ "markdown-table": { -+ "version": "1.1.2", -+ "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.2.tgz", -+ "integrity": "sha512-NcWuJFHDA8V3wkDgR/j4+gZx+YQwstPgfQDV8ndUeWWzta3dnDTBxpVzqS9lkmJAuV5YX35lmyojl6HO5JXAgw==", -+ "dev": true -+ }, -+ "marky-markdown-lite": { -+ "version": "1.2.0", -+ "resolved": "https://registry.npmjs.org/marky-markdown-lite/-/marky-markdown-lite-1.2.0.tgz", -+ "integrity": "sha1-dO2phLgTZVfe4QZO/RXkBhdAaZc=", - "dev": true, - "requires": { -- "deep-is": "0.1.3", -- "fast-levenshtein": "2.0.6", -- "levn": "0.3.0", -- "prelude-ls": "1.1.2", -- "type-check": "0.3.2", -- "wordwrap": "1.0.0" -+ "cheerio": "0.20.0", -+ "conventional-changelog-cli": "1.3.22", -+ "is-file": "1.0.0", -+ "markdown-it": "6.1.1", -+ "markdown-it-named-headers": "0.0.4" - }, - "dependencies": { -- "wordwrap": { -- "version": "1.0.0", -- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", -- "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", -- "dev": true -- } -- } -- }, -- "ora": { -- "version": "0.3.0", -- "resolved": "https://registry.npmjs.org/ora/-/ora-0.3.0.tgz", -- "integrity": "sha1-NnoHitJc+wltpQERXrW0AeB9dJU=", -- "dev": true, -- "requires": { -- "chalk": "1.1.3", -- "cli-cursor": "1.0.2", -- "cli-spinners": "0.2.0", -- "log-symbols": "1.0.2" -- }, -- "dependencies": { -- "cli-spinners": { -- "version": "0.2.0", -- "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.2.0.tgz", -- "integrity": "sha1-hQeHN5E7iA9uyf/ntl6D7Hd2KE8=", -- "dev": true -+ "cheerio": { -+ "version": "0.20.0", -+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.20.0.tgz", -+ "integrity": "sha1-XHEPK6uVZTJyhCugHG6mGzVF7DU=", -+ "dev": true, -+ "requires": { -+ "css-select": "1.2.0", -+ "dom-serializer": "0.1.0", -+ "entities": "1.1.1", -+ "htmlparser2": "3.8.3", -+ "jsdom": "7.2.2", -+ "lodash": "4.17.10" -+ } -+ }, -+ "domhandler": { -+ "version": "2.3.0", -+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", -+ "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", -+ "dev": true, -+ "requires": { -+ "domelementtype": "1.3.0" -+ } -+ }, -+ "htmlparser2": { -+ "version": "3.8.3", -+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", -+ "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", -+ "dev": true, -+ "requires": { -+ "domelementtype": "1.3.0", -+ "domhandler": "2.3.0", -+ "domutils": "1.5.1", -+ "entities": "1.0.0", -+ "readable-stream": "1.1.14" -+ }, -+ "dependencies": { -+ "entities": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", -+ "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", -+ "dev": true -+ } -+ } - } - } - }, -- "os-browserify": { -- "version": "0.1.2", -- "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.1.2.tgz", -- "integrity": "sha1-ScoCk+CxlZCl9d4Qx/JlphfY/lQ=", -- "dev": true -- }, -- "os-homedir": { -- "version": "1.0.2", -- "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", -- "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", -- "dev": true -- }, -- "os-locale": { -- "version": "1.4.0", -- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", -- "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", -- "dev": true, -- "requires": { -- "lcid": "1.0.0" -- } -- }, -- "os-tmpdir": { -- "version": "1.0.2", -- "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", -- "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", -- "dev": true -- }, -- "p-finally": { -- "version": "1.0.0", -- "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", -- "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", -- "dev": true -- }, -- "p-limit": { -- "version": "1.2.0", -- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", -- "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", -- "dev": true, -- "requires": { -- "p-try": "1.0.0" -- } -- }, -- "p-locate": { -- "version": "2.0.0", -- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", -- "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", -+ "matcher-collection": { -+ "version": "1.0.5", -+ "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-1.0.5.tgz", -+ "integrity": "sha1-LuCVQ4Nyy4iE8FgjQTjAXGROwzk=", - "dev": true, - "requires": { -- "p-limit": "1.2.0" -+ "minimatch": "3.0.4" - } - }, -- "p-try": { -- "version": "1.0.0", -- "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", -- "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", -+ "math-random": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", -+ "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", - "dev": true - }, -- "package-json": { -- "version": "4.0.1", -- "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", -- "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", -+ "md5.js": { -+ "version": "1.3.4", -+ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", -+ "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", - "dev": true, - "requires": { -- "got": "6.7.1", -- "registry-auth-token": "3.3.2", -- "registry-url": "3.1.0", -- "semver": "5.5.0" -+ "hash-base": "3.0.4", -+ "inherits": "2.0.3" - } - }, -- "pako": { -- "version": "0.2.9", -- "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", -- "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", -+ "mdast-comment-marker": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/mdast-comment-marker/-/mdast-comment-marker-1.0.2.tgz", -+ "integrity": "sha1-Hd8O+BH7UkOQF8jSwLkiA18rp0o=", - "dev": true - }, -- "parents": { -+ "mdast-util-compact": { - "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", -- "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", -+ "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.1.tgz", -+ "integrity": "sha1-zbX4TitqLTEU3zO9BdnLMuPECDo=", - "dev": true, - "requires": { -- "path-platform": "0.11.15" -+ "unist-util-modify-children": "1.1.2", -+ "unist-util-visit": "1.3.1" - } - }, -- "parse-asn1": { -- "version": "5.1.1", -- "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", -- "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", -- "dev": true, -- "requires": { -- "asn1.js": "4.10.1", -- "browserify-aes": "1.2.0", -- "create-hash": "1.2.0", -- "evp_bytestokey": "1.0.3", -- "pbkdf2": "3.0.16" -- } -+ "mdast-util-heading-style": { -+ "version": "1.0.3", -+ "resolved": "https://registry.npmjs.org/mdast-util-heading-style/-/mdast-util-heading-style-1.0.3.tgz", -+ "integrity": "sha1-77OQ28iqAWw89XegNJANsn7nJHw=", -+ "dev": true - }, -- "parse-entities": { -- "version": "1.1.2", -- "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.1.2.tgz", -- "integrity": "sha512-5N9lmQ7tmxfXf+hO3X6KRG6w7uYO/HL9fHalSySTdyn63C3WNvTM/1R8tn1u1larNcEbo3Slcy2bsVDQqvEpUg==", -- "dev": true, -- "requires": { -- "character-entities": "1.2.2", -- "character-entities-legacy": "1.1.2", -- "character-reference-invalid": "1.1.2", -- "is-alphanumerical": "1.0.2", -- "is-decimal": "1.0.2", -- "is-hexadecimal": "1.0.2" -- } -+ "mdast-util-to-string": { -+ "version": "1.0.4", -+ "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.0.4.tgz", -+ "integrity": "sha1-XEVch4yTVfDB5/PotxnPWDaRrPs=", -+ "dev": true - }, -- "parse-github-repo-url": { -- "version": "1.4.1", -- "resolved": "https://registry.npmjs.org/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz", -- "integrity": "sha1-nn2LslKmy2ukJZUGC3v23z28H1A=", -+ "mdurl": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", -+ "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", - "dev": true - }, -- "parse-gitignore": { -- "version": "0.4.0", -- "resolved": "https://registry.npmjs.org/parse-gitignore/-/parse-gitignore-0.4.0.tgz", -- "integrity": "sha1-q/cC5LkAUk//eQK2g4YoV7Y/k/4=", -+ "meow": { -+ "version": "4.0.1", -+ "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", -+ "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", - "dev": true, - "requires": { -- "array-unique": "0.3.2", -- "is-glob": "3.1.0" -+ "camelcase-keys": "4.2.0", -+ "decamelize-keys": "1.1.0", -+ "loud-rejection": "1.6.0", -+ "minimist": "1.2.0", -+ "minimist-options": "3.0.2", -+ "normalize-package-data": "2.4.0", -+ "read-pkg-up": "3.0.0", -+ "redent": "2.0.0", -+ "trim-newlines": "2.0.0" - }, - "dependencies": { -- "array-unique": { -- "version": "0.3.2", -- "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", -- "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", -- "dev": true -+ "find-up": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", -+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", -+ "dev": true, -+ "requires": { -+ "locate-path": "2.0.0" -+ } - }, -- "is-extglob": { -- "version": "2.1.1", -- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", -- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", -- "dev": true -+ "load-json-file": { -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", -+ "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", -+ "dev": true, -+ "requires": { -+ "graceful-fs": "4.1.11", -+ "parse-json": "4.0.0", -+ "pify": "3.0.0", -+ "strip-bom": "3.0.0" -+ } - }, -- "is-glob": { -- "version": "3.1.0", -- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", -- "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", -+ "parse-json": { -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", -+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { -- "is-extglob": "2.1.1" -+ "error-ex": "1.3.1", -+ "json-parse-better-errors": "1.0.2" - } -- } -- } -- }, -- "parse-glob": { -- "version": "3.0.4", -- "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", -- "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", -- "dev": true, -- "requires": { -- "glob-base": "0.3.0", -- "is-dotfile": "1.0.3", -- "is-extglob": "1.0.0", -- "is-glob": "2.0.1" -+ }, -+ "path-type": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", -+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", -+ "dev": true, -+ "requires": { -+ "pify": "3.0.0" -+ } -+ }, -+ "pify": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", -+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", -+ "dev": true -+ }, -+ "read-pkg": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", -+ "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", -+ "dev": true, -+ "requires": { -+ "load-json-file": "4.0.0", -+ "normalize-package-data": "2.4.0", -+ "path-type": "3.0.0" -+ } -+ }, -+ "read-pkg-up": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", -+ "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", -+ "dev": true, -+ "requires": { -+ "find-up": "2.1.0", -+ "read-pkg": "3.0.0" -+ } -+ }, -+ "strip-bom": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", -+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", -+ "dev": true -+ } - } - }, -- "parse-json": { -- "version": "2.2.0", -- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", -- "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", -+ "micro": { -+ "version": "9.3.1", -+ "resolved": "https://registry.npmjs.org/micro/-/micro-9.3.1.tgz", -+ "integrity": "sha512-83uimpPJqfwkfKvJl2WWontBlV3hmzrIgyJ+L2uhDXKNk7Ll+/ezK3zBz7TljubpKPqjM0JdT2Ker4MTPmhjgA==", - "dev": true, - "requires": { -- "error-ex": "1.3.1" -+ "arg": "2.0.0", -+ "chalk": "2.4.0", -+ "content-type": "1.0.4", -+ "is-stream": "1.1.0", -+ "raw-body": "2.3.2" -+ }, -+ "dependencies": { -+ "ansi-styles": { -+ "version": "3.2.1", -+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", -+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", -+ "dev": true, -+ "requires": { -+ "color-convert": "1.9.1" -+ } -+ }, -+ "chalk": { -+ "version": "2.4.0", -+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.0.tgz", -+ "integrity": "sha512-Wr/w0f4o9LuE7K53cD0qmbAMM+2XNLzR29vFn5hqko4sxGlUsyy363NvmyGIyk5tpe9cjTr9SJYbysEyPkRnFw==", -+ "dev": true, -+ "requires": { -+ "ansi-styles": "3.2.1", -+ "escape-string-regexp": "1.0.5", -+ "supports-color": "5.4.0" -+ } -+ }, -+ "has-flag": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", -+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", -+ "dev": true -+ }, -+ "supports-color": { -+ "version": "5.4.0", -+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", -+ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", -+ "dev": true, -+ "requires": { -+ "has-flag": "3.0.0" -+ } -+ } - } - }, -- "parse5": { -- "version": "1.5.1", -- "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", -- "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", -+ "micro-compress": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/micro-compress/-/micro-compress-1.0.0.tgz", -+ "integrity": "sha1-U/WoC0rQMgyhZaVZtuPfFF1PcE8=", - "dev": true, -- "optional": true -+ "requires": { -+ "compression": "1.7.3" -+ } - }, -- "path-browserify": { -- "version": "0.0.0", -- "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", -- "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", -- "dev": true -+ "micromatch": { -+ "version": "2.3.11", -+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", -+ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", -+ "dev": true, -+ "requires": { -+ "arr-diff": "2.0.0", -+ "array-unique": "0.2.1", -+ "braces": "1.8.5", -+ "expand-brackets": "0.1.5", -+ "extglob": "0.3.2", -+ "filename-regex": "2.0.1", -+ "is-extglob": "1.0.0", -+ "is-glob": "2.0.1", -+ "kind-of": "3.2.2", -+ "normalize-path": "2.1.1", -+ "object.omit": "2.0.1", -+ "parse-glob": "3.0.4", -+ "regex-cache": "0.4.4" -+ } - }, -- "path-exists": { -- "version": "2.1.0", -- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", -- "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", -+ "miller-rabin": { -+ "version": "4.0.1", -+ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", -+ "integrity": "sha1-8IA1HIZbDcViqEYpZtqlNUPHik0=", - "dev": true, - "requires": { -- "pinkie-promise": "2.0.1" -+ "bn.js": "4.11.8", -+ "brorand": "1.1.0" - } - }, -- "path-is-absolute": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", -- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", -+ "mime": { -+ "version": "1.6.0", -+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", -+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, -- "path-is-inside": { -- "version": "1.0.2", -- "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", -- "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", -+ "mime-db": { -+ "version": "1.33.0", -+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", -+ "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true - }, -- "path-key": { -- "version": "2.0.1", -- "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", -- "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", -+ "mime-types": { -+ "version": "2.1.18", -+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", -+ "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", -+ "dev": true, -+ "requires": { -+ "mime-db": "1.33.0" -+ } -+ }, -+ "mimic-fn": { -+ "version": "1.2.0", -+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", -+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, -- "path-parse": { -- "version": "1.0.5", -- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", -- "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", -+ "minimalistic-assert": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", -+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, -- "path-platform": { -- "version": "0.11.15", -- "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", -- "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", -+ "minimalistic-crypto-utils": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", -+ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, -- "path-type": { -- "version": "1.1.0", -- "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", -- "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", -+ "minimatch": { -+ "version": "3.0.4", -+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", -+ "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", - "dev": true, - "requires": { -- "graceful-fs": "4.1.11", -- "pify": "2.3.0", -- "pinkie-promise": "2.0.1" -+ "brace-expansion": "1.1.11" - } - }, -- "pbkdf2": { -- "version": "3.0.16", -- "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", -- "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", -+ "minimist": { -+ "version": "1.2.0", -+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", -+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", -+ "dev": true -+ }, -+ "minimist-options": { -+ "version": "3.0.2", -+ "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", -+ "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", - "dev": true, - "requires": { -- "create-hash": "1.2.0", -- "create-hmac": "1.1.7", -- "ripemd160": "2.0.2", -- "safe-buffer": "5.1.2", -- "sha.js": "2.4.11" -+ "arrify": "1.0.1", -+ "is-plain-obj": "1.1.0" - } - }, -- "peek-stream": { -- "version": "1.1.3", -- "resolved": "https://registry.npmjs.org/peek-stream/-/peek-stream-1.1.3.tgz", -- "integrity": "sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==", -+ "minipass": { -+ "version": "2.3.0", -+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.0.tgz", -+ "integrity": "sha512-jWC2Eg+Np4bxah7llu1IrUNSJQxtLz/J+pOjTM0nFpJXGAaV18XBWhUn031Q1tAA/TJtA1jgwnOe9S2PQa4Lbg==", - "dev": true, - "requires": { -- "buffer-from": "1.0.0", -- "duplexify": "3.6.0", -- "through2": "2.0.3" -+ "safe-buffer": "5.1.2", -+ "yallist": "3.0.2" - } - }, -- "performance-now": { -- "version": "2.1.0", -- "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", -- "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", -- "dev": true -+ "minizlib": { -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz", -+ "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", -+ "dev": true, -+ "requires": { -+ "minipass": "2.3.0" -+ } - }, -- "pify": { -- "version": "2.3.0", -- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", -- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", -+ "mkdirp": { -+ "version": "0.5.1", -+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", -+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", -+ "dev": true, -+ "requires": { -+ "minimist": "0.0.8" -+ }, -+ "dependencies": { -+ "minimist": { -+ "version": "0.0.8", -+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", -+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", -+======= -+ "ieee754": { -+ "version": "1.1.8", -+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", -+ "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", - "dev": true - }, -- "pinkie": { -- "version": "2.0.4", -- "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", -- "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", -+ "ignore": { -+ "version": "3.3.7", -+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", -+ "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", - "dev": true - }, -- "pinkie-promise": { -- "version": "2.0.1", -- "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", -- "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", -+ "import-lazy": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", -+ "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", -+ "dev": true -+ }, -+ "imurmurhash": { -+ "version": "0.1.4", -+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", -+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", -+ "dev": true -+ }, -+ "indent-string": { -+ "version": "3.2.0", -+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", -+ "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", -+ "dev": true -+ }, -+ "indexof": { -+ "version": "0.0.1", -+ "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", -+ "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", -+ "dev": true -+ }, -+ "inflight": { -+ "version": "1.0.6", -+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", -+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { -- "pinkie": "2.0.4" -+ "once": "1.4.0", -+ "wrappy": "1.0.2" - } - }, -- "pkg-conf": { -- "version": "2.1.0", -- "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", -- "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=", -+ "inherits": { -+ "version": "2.0.3", -+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", -+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", -+ "dev": true -+ }, -+ "ini": { -+ "version": "1.3.5", -+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", -+ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", -+ "dev": true -+ }, -+ "inline-source-map": { -+ "version": "0.6.2", -+ "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", -+ "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", - "dev": true, - "requires": { -- "find-up": "2.1.0", -- "load-json-file": "4.0.0" -+ "source-map": "0.5.7" -+ } -+ }, -+ "inquirer": { -+ "version": "0.12.0", -+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", -+ "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", -+ "dev": true, -+ "requires": { -+ "ansi-escapes": "1.4.0", -+ "ansi-regex": "2.1.1", -+ "chalk": "1.1.3", -+ "cli-cursor": "1.0.2", -+ "cli-width": "2.2.0", -+ "figures": "1.7.0", -+ "lodash": "4.17.5", -+ "readline2": "1.0.1", -+ "run-async": "0.1.0", -+ "rx-lite": "3.1.2", -+ "string-width": "1.0.2", -+ "strip-ansi": "3.0.1", -+ "through": "2.3.8" -+ } -+ }, -+ "insert-module-globals": { -+ "version": "7.0.2", -+ "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.2.tgz", -+ "integrity": "sha512-p3s7g96Nm62MbHRuj9ZXab0DuJNWD7qcmdUXCOQ/ZZn42DtDXfsLill7bq19lDCx3K3StypqUnuE3H2VmIJFUw==", -+ "dev": true, -+ "requires": { -+ "JSONStream": "1.3.2", -+ "combine-source-map": "0.7.2", -+ "concat-stream": "1.5.2", -+ "is-buffer": "1.1.6", -+ "lexical-scope": "1.2.0", -+ "process": "0.11.10", -+ "through2": "2.0.3", -+ "xtend": "4.0.1" - }, - "dependencies": { -- "find-up": { -- "version": "2.1.0", -- "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", -- "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", -- "dev": true, -- "requires": { -- "locate-path": "2.0.0" -- } -- }, -- "load-json-file": { -- "version": "4.0.0", -- "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", -- "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", -- "dev": true, -- "requires": { -- "graceful-fs": "4.1.11", -- "parse-json": "4.0.0", -- "pify": "3.0.0", -- "strip-bom": "3.0.0" -- } -- }, -- "parse-json": { -- "version": "4.0.0", -- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", -- "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", -+ "combine-source-map": { -+ "version": "0.7.2", -+ "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.7.2.tgz", -+ "integrity": "sha1-CHAxKFazB6h8xKxIbzqaYq7MwJ4=", - "dev": true, - "requires": { -- "error-ex": "1.3.1", -- "json-parse-better-errors": "1.0.2" -+ "convert-source-map": "1.1.3", -+ "inline-source-map": "0.6.2", -+ "lodash.memoize": "3.0.4", -+ "source-map": "0.5.7" - } -- }, -- "pify": { -- "version": "3.0.0", -- "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", -- "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", -- "dev": true -- }, -- "strip-bom": { -- "version": "3.0.0", -- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", -- "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", -- "dev": true - } - } - }, -- "pkg-config": { -- "version": "1.1.1", -- "resolved": "https://registry.npmjs.org/pkg-config/-/pkg-config-1.1.1.tgz", -- "integrity": "sha1-VX7yLXPaPIg3EHdmxS6tq94pj+Q=", -- "dev": true, -- "requires": { -- "debug-log": "1.0.1", -- "find-root": "1.1.0", -- "xtend": "4.0.1" -- } -+ "interpret": { -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", -+ "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", -+ "dev": true - }, -- "pkg-dir": { -+ "invert-kv": { - "version": "1.0.0", -- "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", -- "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", -- "dev": true, -- "requires": { -- "find-up": "1.1.2" -- } -+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", -+ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", -+ "dev": true - }, -- "pkg-up": { -+ "is-arrayish": { -+ "version": "0.2.1", -+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", -+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", -+ "dev": true -+ }, -+ "is-buffer": { -+ "version": "1.1.6", -+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", -+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", -+ "dev": true -+ }, -+ "is-builtin-module": { - "version": "1.0.0", -- "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", -- "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", -+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", -+ "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, - "requires": { -- "find-up": "1.1.2" -+ "builtin-modules": "1.1.1" - } - }, -- "plur": { -- "version": "2.1.2", -- "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", -- "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", -+ "is-callable": { -+ "version": "1.1.3", -+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", -+ "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", -+ "dev": true -+ }, -+ "is-ci": { -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz", -+ "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==", - "dev": true, - "requires": { -- "irregular-plurals": "1.4.0" -+ "ci-info": "1.1.3" - } - }, -- "pluralize": { -- "version": "1.2.1", -- "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", -- "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", -- "dev": true -- }, -- "prelude-ls": { -- "version": "1.1.2", -- "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", -- "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", -+ "is-date-object": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", -+ "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true - }, -- "prepend-http": { -- "version": "1.0.4", -- "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", -- "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", -+ "is-deflate": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/is-deflate/-/is-deflate-1.0.0.tgz", -+ "integrity": "sha1-yGKQHDwWH7CdrHzcfnhPgOmPLxQ=", - "dev": true - }, -- "preserve": { -- "version": "0.2.0", -- "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", -- "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", -+ "is-dotfile": { -+ "version": "1.0.3", -+ "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", -+ "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, -- "pretty-bytes": { -- "version": "1.0.4", -- "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz", -- "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", -+ "is-equal-shallow": { -+ "version": "0.1.3", -+ "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", -+ "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { -- "get-stdin": "4.0.1", -- "meow": "3.7.0" -- }, -- "dependencies": { -- "camelcase": { -- "version": "2.1.1", -- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", -- "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", -- "dev": true -- }, -- "camelcase-keys": { -- "version": "2.1.0", -- "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", -- "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", -- "dev": true, -- "requires": { -- "camelcase": "2.1.1", -- "map-obj": "1.0.1" -- } -- }, -- "indent-string": { -- "version": "2.1.0", -- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", -- "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", -- "dev": true, -- "requires": { -- "repeating": "2.0.1" -- } -- }, -- "map-obj": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", -- "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", -- "dev": true -- }, -- "meow": { -- "version": "3.7.0", -- "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", -- "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", -- "dev": true, -- "requires": { -- "camelcase-keys": "2.1.0", -- "decamelize": "1.2.0", -- "loud-rejection": "1.6.0", -- "map-obj": "1.0.1", -- "minimist": "1.2.0", -- "normalize-package-data": "2.4.0", -- "object-assign": "4.1.1", -- "read-pkg-up": "1.0.1", -- "redent": "1.0.0", -- "trim-newlines": "1.0.0" -- } -- }, -- "redent": { -- "version": "1.0.0", -- "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", -- "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", -- "dev": true, -- "requires": { -- "indent-string": "2.1.0", -- "strip-indent": "1.0.1" -- } -- }, -- "strip-indent": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", -- "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", -- "dev": true, -- "requires": { -- "get-stdin": "4.0.1" -- } -- }, -- "trim-newlines": { -- "version": "1.0.0", -- "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", -- "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", -- "dev": true -- } -+ "is-primitive": "2.0.0" - } - }, -- "process": { -- "version": "0.11.10", -- "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", -- "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", -+ "is-extendable": { -+ "version": "0.1.1", -+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", -+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, -- "process-nextick-args": { -- "version": "2.0.0", -- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", -- "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", -+ "is-extglob": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", -+ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, -- "progress": { -- "version": "2.0.0", -- "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", -- "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", -+ "is-file": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/is-file/-/is-file-1.0.0.tgz", -+ "integrity": "sha1-KKRM+9nT2xkwRfIrZfzo7fliBZY=", - "dev": true - }, -- "progress-stream": { -- "version": "1.2.0", -- "resolved": "https://registry.npmjs.org/progress-stream/-/progress-stream-1.2.0.tgz", -- "integrity": "sha1-LNPP6jO6OonJwSHsM0er6asSX3c=", -+ "is-finite": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", -+ "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { -- "speedometer": "0.1.4", -- "through2": "0.2.3" -- }, -- "dependencies": { -- "through2": { -- "version": "0.2.3", -- "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz", -- "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=", -- "dev": true, -- "requires": { -- "readable-stream": "1.1.14", -- "xtend": "2.1.2" -- } -- }, -- "xtend": { -- "version": "2.1.2", -- "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", -- "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", -- "dev": true, -- "requires": { -- "object-keys": "0.4.0" -- } -- } -+ "number-is-nan": "1.0.1" - } - }, -- "pseudomap": { -- "version": "1.0.2", -- "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", -- "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", -- "dev": true -- }, -- "public-encrypt": { -- "version": "4.0.2", -- "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", -- "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", -+ "is-fullwidth-code-point": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", -+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { -- "bn.js": "4.11.8", -- "browserify-rsa": "4.0.1", -- "create-hash": "1.2.0", -- "parse-asn1": "5.1.1", -- "randombytes": "2.0.6" -+ "number-is-nan": "1.0.1" - } - }, -- "pump": { -+ "is-glob": { - "version": "2.0.1", -- "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", -- "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", -+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", -+ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { -- "end-of-stream": "1.4.1", -- "once": "1.4.0" -+ "is-extglob": "1.0.0" - } - }, -- "pumpify": { -- "version": "1.5.0", -- "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.0.tgz", -- "integrity": "sha512-UWi0klDoq8xtVzlMRgENV9F7iCTZExaJQSQL187UXsxpk9NnrKGqTqqUNYAKGOzucSOxs2+jUnRNI+rLviPhJg==", -+ "is-gzip": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/is-gzip/-/is-gzip-1.0.0.tgz", -+ "integrity": "sha1-bKiwe5nHeZgCWQDlVc7Y7YCHmoM=", -+ "dev": true -+ }, -+ "is-installed-globally": { -+ "version": "0.1.0", -+ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", -+ "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", - "dev": true, - "requires": { -- "duplexify": "3.6.0", -- "inherits": "2.0.3", -- "pump": "2.0.1" -+ "global-dirs": "0.1.1", -+ "is-path-inside": "1.0.1" - } - }, -- "punycode": { -- "version": "1.4.1", -- "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", -- "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", -+ "is-my-ip-valid": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", -+ "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", - "dev": true - }, -- "q": { -- "version": "1.5.1", -- "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", -- "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", -- "dev": true -+ "is-my-json-valid": { -+ "version": "2.17.2", -+ "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz", -+ "integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==", -+ "dev": true, -+ "requires": { -+ "generate-function": "2.0.0", -+ "generate-object-property": "1.2.0", -+ "is-my-ip-valid": "1.0.0", -+ "jsonpointer": "4.0.1", -+ "xtend": "4.0.1" -+ } - }, -- "qs": { -- "version": "6.5.2", -- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", -- "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", -+ "is-npm": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", -+ "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", - "dev": true - }, -- "querystring": { -- "version": "0.2.0", -- "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", -- "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", -- "dev": true -+ "is-number": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", -+ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", -+ "dev": true, -+ "requires": { -+ "kind-of": "3.2.2" -+ } - }, -- "querystring-es3": { -- "version": "0.2.1", -- "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", -- "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", -+ "is-obj": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", -+ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "dev": true - }, -- "quick-lru": { -- "version": "1.1.0", -- "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", -- "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", -+ "is-path-cwd": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", -+ "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, -- "randomatic": { -- "version": "3.0.0", -- "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", -- "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", -+ "is-path-in-cwd": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", -+ "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", - "dev": true, - "requires": { -- "is-number": "4.0.0", -- "kind-of": "6.0.2", -- "math-random": "1.0.1" -- }, -- "dependencies": { -- "is-number": { -- "version": "4.0.0", -- "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", -- "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", -- "dev": true -- }, -- "kind-of": { -- "version": "6.0.2", -- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", -- "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", -- "dev": true -- } -+ "is-path-inside": "1.0.1" - } - }, -- "randombytes": { -- "version": "2.0.6", -- "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", -- "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", -+ "is-path-inside": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", -+ "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { -- "safe-buffer": "5.1.2" -+ "path-is-inside": "1.0.2" - } - }, -- "randomfill": { -+ "is-plain-obj": { -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", -+ "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", -+ "dev": true -+ }, -+ "is-posix-bracket": { -+ "version": "0.1.1", -+ "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", -+ "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", -+ "dev": true -+ }, -+ "is-primitive": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", -+ "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", -+ "dev": true -+ }, -+ "is-property": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", -+ "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", -+ "dev": true -+ }, -+ "is-redirect": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", -+ "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", -+ "dev": true -+ }, -+ "is-regex": { - "version": "1.0.4", -- "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", -- "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", -+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", -+ "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, - "requires": { -- "randombytes": "2.0.6", -- "safe-buffer": "5.1.2" -+ "has": "1.0.1" - } - }, -- "range-parser": { -- "version": "1.2.0", -- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", -- "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", -+ "is-resolvable": { -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", -+ "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, -- "raw-body": { -- "version": "2.3.2", -- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", -- "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", -- "dev": true, -- "requires": { -- "bytes": "3.0.0", -- "http-errors": "1.6.2", -- "iconv-lite": "0.4.19", -- "unpipe": "1.0.0" -- } -+ "is-retry-allowed": { -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", -+ "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", -+ "dev": true - }, -- "rc": { -- "version": "1.2.7", -- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.7.tgz", -- "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==", -+ "is-stream": { -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", -+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", -+ "dev": true -+ }, -+ "is-subset": { -+ "version": "0.1.1", -+ "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz", -+ "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=", -+ "dev": true -+ }, -+ "is-symbol": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", -+ "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", -+ "dev": true -+ }, -+ "is-text-path": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", -+ "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", - "dev": true, - "requires": { -- "deep-extend": "0.5.1", -- "ini": "1.3.5", -- "minimist": "1.2.0", -- "strip-json-comments": "2.0.1" -+ "text-extensions": "1.7.0" - } - }, -- "read-only-stream": { -+ "is-typedarray": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", -+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", -+ "dev": true -+ }, -+ "is-utf8": { -+ "version": "0.2.1", -+ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", -+ "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", -+ "dev": true -+ }, -+ "isarray": { -+ "version": "0.0.1", -+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", -+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", -+ "dev": true -+ }, -+ "isexe": { - "version": "2.0.0", -- "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", -- "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", -+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", -+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", -+ "dev": true -+ }, -+ "isobject": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", -+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { -- "readable-stream": "2.3.6" -+ "isarray": "1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", -+>>>>>>> .their - "dev": true -- }, -- "readable-stream": { -- "version": "2.3.6", -- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", -- "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", -- "dev": true, -- "requires": { -- "core-util-is": "1.0.2", -- "inherits": "2.0.3", -- "isarray": "1.0.0", -- "process-nextick-args": "2.0.0", -- "safe-buffer": "5.1.2", -- "string_decoder": "1.1.1", -- "util-deprecate": "1.0.2" -- } -- }, -- "string_decoder": { -- "version": "1.1.1", -- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", -- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", -- "dev": true, -- "requires": { -- "safe-buffer": "5.1.2" -- } - } - } - }, -- "read-pkg": { -- "version": "1.1.0", -- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", -- "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", -+<<<<<<< .our -+ "mkpath": { -+ "version": "0.1.0", -+ "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz", -+ "integrity": "sha1-dVSm+Nhxg0zJe1RisSLEwSTW3pE=", -+ "dev": true -+ }, -+ "mksnapshot": { -+ "version": "0.3.1", -+ "resolved": "https://registry.npmjs.org/mksnapshot/-/mksnapshot-0.3.1.tgz", -+ "integrity": "sha1-JQHAVldDbXQs6Vik/5LHfkDdN+Y=", - "dev": true, - "requires": { -- "load-json-file": "1.1.0", -- "normalize-package-data": "2.4.0", -- "path-type": "1.1.0" -+ "decompress-zip": "0.3.0", -+ "fs-extra": "0.26.7", -+ "request": "2.85.0" - } - }, -- "read-pkg-up": { -+ "modify-values": { - "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", -- "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", -- "dev": true, -- "requires": { -- "find-up": "1.1.2", -- "read-pkg": "1.1.0" -- } -+ "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", -+ "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", -+ "dev": true - }, -- "readable-stream": { -- "version": "1.1.14", -- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", -- "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", -+ "module-deps": { -+ "version": "4.1.1", -+ "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-4.1.1.tgz", -+ "integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=", - "dev": true, - "requires": { -- "core-util-is": "1.0.2", -+ "JSONStream": "1.3.2", -+ "browser-resolve": "1.11.2", -+ "cached-path-relative": "1.0.1", -+ "concat-stream": "1.5.2", -+ "defined": "1.0.0", -+ "detective": "4.7.1", -+ "duplexer2": "0.1.4", - "inherits": "2.0.3", -- "isarray": "0.0.1", -- "string_decoder": "0.10.31" -- } -- }, -- "readdirp": { -- "version": "2.1.0", -- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", -- "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", -- "dev": true, -- "requires": { -- "graceful-fs": "4.1.11", -- "minimatch": "3.0.4", -+ "parents": "1.0.1", - "readable-stream": "2.3.6", -- "set-immediate-shim": "1.0.1" -+ "resolve": "1.7.1", -+ "stream-combiner2": "1.1.1", -+ "subarg": "1.0.0", -+ "through2": "2.0.3", -+ "xtend": "4.0.1" - }, - "dependencies": { - "isarray": { -@@ -7214,717 +7940,3764 @@ - } - } - }, -- "readline2": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", -- "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", -- "dev": true, -- "requires": { -- "code-point-at": "1.1.0", -- "is-fullwidth-code-point": "1.0.0", -- "mute-stream": "0.0.5" -- } -+ "mri": { -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.0.tgz", -+ "integrity": "sha1-XAo/KcjM/7ux7JQdzsCdcfoy82o=", -+ "dev": true - }, -- "rechoir": { -- "version": "0.6.2", -- "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", -- "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", -- "dev": true, -- "requires": { -- "resolve": "1.7.1" -- } -- }, -- "redent": { -+ "ms": { - "version": "2.0.0", -- "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", -- "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", -+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", -+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", -+ "dev": true -+ }, -+ "mute-stream": { -+ "version": "0.0.5", -+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", -+ "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", -+ "dev": true -+ }, -+ "nan": { -+ "version": "2.10.0", -+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", -+ "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "dev": true, -- "requires": { -- "indent-string": "3.2.0", -- "strip-indent": "2.0.0" -- } -+ "optional": true - }, -- "regex-cache": { -- "version": "0.4.4", -- "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", -- "integrity": "sha1-db3FiioUls7EihKDW8VMjVYjNt0=", -+ "natural-compare": { -+ "version": "1.4.0", -+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", -+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", -+ "dev": true -+ }, -+ "negotiator": { -+ "version": "0.6.1", -+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", -+ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", -+ "dev": true -+ }, -+ "netrc": { -+ "version": "0.1.4", -+ "resolved": "https://registry.npmjs.org/netrc/-/netrc-0.1.4.tgz", -+ "integrity": "sha1-a+lPysqNd63gqWcNxGCRTJRHJEQ=", -+ "dev": true -+ }, -+ "next-tick": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", -+ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", -+ "dev": true -+ }, -+ "node-dir": { -+ "version": "0.1.17", -+ "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", -+ "integrity": "sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=", - "dev": true, - "requires": { -- "is-equal-shallow": "0.1.3" -+ "minimatch": "3.0.4" - } - }, -- "registry-auth-token": { -- "version": "3.3.2", -- "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", -- "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", -+ "node-fetch": { -+ "version": "2.1.2", -+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", -+ "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=", -+ "dev": true -+ }, -+ "node-version": { -+ "version": "1.1.3", -+ "resolved": "https://registry.npmjs.org/node-version/-/node-version-1.1.3.tgz", -+ "integrity": "sha512-rEwE51JWn0yN3Wl5BXeGn5d52OGbSXzWiiXRjAQeuyvcGKyvuSILW2rb3G7Xh+nexzLwhTpek6Ehxd6IjvHePg==", -+ "dev": true -+ }, -+ "nopt": { -+ "version": "3.0.6", -+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", -+ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "dev": true, - "requires": { -- "rc": "1.2.7", -- "safe-buffer": "5.1.2" -+ "abbrev": "1.1.1" - } - }, -- "registry-url": { -- "version": "3.1.0", -- "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", -- "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", -+ "normalize-package-data": { -+ "version": "2.4.0", -+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", -+ "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=", - "dev": true, - "requires": { -- "rc": "1.2.7" -+ "hosted-git-info": "2.6.0", -+ "is-builtin-module": "1.0.0", -+ "semver": "5.5.0", -+ "validate-npm-package-license": "3.0.3" - } - }, -- "remark": { -- "version": "8.0.0", -- "resolved": "https://registry.npmjs.org/remark/-/remark-8.0.0.tgz", -- "integrity": "sha512-K0PTsaZvJlXTl9DN6qYlvjTkqSZBFELhROZMrblm2rB+085flN84nz4g/BscKRMqDvhzlK1oQ/xnWQumdeNZYw==", -+ "normalize-path": { -+ "version": "2.1.1", -+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", -+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { -- "remark-parse": "4.0.0", -- "remark-stringify": "4.0.0", -- "unified": "6.2.0" -+ "remove-trailing-separator": "1.1.0" - } - }, -- "remark-cli": { -- "version": "4.0.0", -- "resolved": "https://registry.npmjs.org/remark-cli/-/remark-cli-4.0.0.tgz", -- "integrity": "sha512-q5GMjGypUS4rTZb3WfMQcGpClSC38A9Ogg1h/HB2GLsqypDetmAfy0X+tuJ6JeyCPVOXXCDgsDCQq4QPqKmxBA==", -+ "npm-prefix": { -+ "version": "1.2.0", -+ "resolved": "https://registry.npmjs.org/npm-prefix/-/npm-prefix-1.2.0.tgz", -+ "integrity": "sha1-5hlFX3B0ulTMZtbQ033Z8b5ry8A=", - "dev": true, - "requires": { -- "markdown-extensions": "1.1.1", -- "remark": "8.0.0", -- "unified-args": "4.0.0" -+ "rc": "1.2.7", -+ "shellsubstitute": "1.2.0", -+ "untildify": "2.1.0" - } - }, -- "remark-lint": { -- "version": "6.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-6.0.1.tgz", -- "integrity": "sha512-wvTTuB5O5pF8SxqahQjjrU3dtuhygYjaGcOZTw+4ACgSE4RBINDlNqN46HjcV3X0ib5GmObJUt5a2mmhtmuTqw==", -+ "npm-run-path": { -+ "version": "2.0.2", -+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", -+ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { -- "remark-message-control": "4.1.0" -+ "path-key": "2.0.1" - } - }, -- "remark-lint-blockquote-indentation": { -+ "nth-check": { - "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-1.0.1.tgz", -- "integrity": "sha512-YrP99MJ3+dQ5JXzq39fUOcYzwcumva/xEM1eFtD2TrQcSdlMLoqYa7gj+aEEhZCjlA5BssTiVoWWW0RjyPPGZw==", -+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", -+ "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", - "dev": true, - "requires": { -- "mdast-util-to-string": "1.0.4", -- "plur": "2.1.2", -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "boolbase": "1.0.0" - } - }, -- "remark-lint-code-block-style": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-1.0.1.tgz", -- "integrity": "sha512-FRUMhhKwCruH4vkatdMhVO4WlYpysV1NmMILVoK/k+/7uFLSfgvlqo66nzhpMdWL8TQHqdo0LhiXuetGC2WjsQ==", -+ "nugget": { -+ "version": "2.0.1", -+ "resolved": "https://registry.npmjs.org/nugget/-/nugget-2.0.1.tgz", -+ "integrity": "sha1-IBCVpIfhrTYIGzQy+jytpPjQcbA=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "debug": "2.6.9", -+ "minimist": "1.2.0", -+ "pretty-bytes": "1.0.4", -+ "progress-stream": "1.2.0", -+ "request": "2.85.0", -+ "single-line-log": "1.1.2", -+ "throttleit": "0.0.2" - } - }, -- "remark-lint-definition-case": { -+ "number-is-nan": { - "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-definition-case/-/remark-lint-definition-case-1.0.1.tgz", -- "integrity": "sha512-TxLye5KF4o/rKVTvmPRX5jS9itamFS02yy1IG8bIYcIAJvWsW3GlJaXq4ohK3hKwSQOhtCherEfD6XF9BHLNYQ==", -+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", -+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", -+ "dev": true -+ }, -+ "nwmatcher": { -+ "version": "1.4.4", -+ "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz", -+ "integrity": "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ==", - "dev": true, -- "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -- } -+ "optional": true - }, -- "remark-lint-definition-spacing": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-1.0.1.tgz", -- "integrity": "sha512-ewzdlFfpTSP11ZuiOln0yfz6Y03aWtgJmLVQNfF1spaT1gURaShjs8Hiilbo719bz96DgvXSZLP6UnkSiZL1vg==", -+ "oauth-sign": { -+ "version": "0.8.2", -+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", -+ "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", -+ "dev": true -+ }, -+ "object-assign": { -+ "version": "4.1.1", -+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", -+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", -+ "dev": true -+ }, -+ "object-keys": { -+ "version": "0.4.0", -+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", -+ "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", -+ "dev": true -+ }, -+ "object.assign": { -+ "version": "4.1.0", -+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", -+ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "define-properties": "1.1.2", -+ "function-bind": "1.1.1", -+ "has-symbols": "1.0.0", -+ "object-keys": "1.0.11" -+ }, -+ "dependencies": { -+ "object-keys": { -+ "version": "1.0.11", -+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", -+ "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", -+ "dev": true -+ } - } - }, -- "remark-lint-emphasis-marker": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-emphasis-marker/-/remark-lint-emphasis-marker-1.0.1.tgz", -- "integrity": "sha512-QyNsD6y8EZQqhechw0XFGybYMlxn6PFLSlFUO50KSQlJEOgkImN2yJfrNrET2GY4t/fc/uYmeI/q7auUIkLX2w==", -+ "object.omit": { -+ "version": "2.0.1", -+ "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", -+ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "for-own": "0.1.5", -+ "is-extendable": "0.1.1" - } - }, -- "remark-lint-fenced-code-flag": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-1.0.1.tgz", -- "integrity": "sha512-P24T9DRe/nnywPFRpE1UAXAVzN1CX6HmINr15UHbQZo1Cy8KYt7uV9YOR0/XzphtnO/AFenAqZyf7tchW5AUNQ==", -+ "octicons": { -+ "version": "7.3.0", -+ "resolved": "https://registry.npmjs.org/octicons/-/octicons-7.3.0.tgz", -+ "integrity": "sha512-UVjlkmUL15Ef/7Rd72Io634Bdl61QgSMasAZpvXPoR2XNFj1RelAyhl4QJuR1hBGlPWFDR7KFj2jEzsFax2IUg==", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "object-assign": "4.1.1" - } - }, -- "remark-lint-fenced-code-marker": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-1.0.1.tgz", -- "integrity": "sha512-mX7xAMl5m7xGX+YtOtyXIyv+egD4IQAm6DPGdfunI734QwODwcoBydtpTD56jrY+48nVcQ/anFYT1Blg3Xk3sQ==", -+ "on-finished": { -+ "version": "2.3.0", -+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", -+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "ee-first": "1.1.1" - } - }, -- "remark-lint-file-extension": { -+ "on-headers": { - "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-1.0.1.tgz", -- "integrity": "sha512-K1Pf5oviaFyCs0FhZqaNZ2odgd5KoV6AlA4nNAMxyylB0Y6t0mYpzECoLSS5Bgxf6f8Op9YbuM2cbjBAsv0dIA==", -+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", -+ "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", -+ "dev": true -+ }, -+ "once": { -+ "version": "1.4.0", -+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", -+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2" -+ "wrappy": "1.0.2" - } - }, -- "remark-lint-final-definition": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-1.0.1.tgz", -- "integrity": "sha512-DK6bphJdQ0xSOQAn+8wOyLIVc3SZW2+ZzCMCLkQnVtHiQ9GHMzFiCkeE3Cq+OClsMI5Yn8wFTHZHPUn58VhNEQ==", -+ "onetime": { -+ "version": "1.1.0", -+ "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", -+ "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", -+ "dev": true -+ }, -+ "openssl-self-signed-certificate": { -+ "version": "1.1.6", -+ "resolved": "https://registry.npmjs.org/openssl-self-signed-certificate/-/openssl-self-signed-certificate-1.1.6.tgz", -+ "integrity": "sha1-nTpHdrGlfphHNQOSEUrS+RWoPdQ=", -+ "dev": true -+ }, -+ "opn": { -+ "version": "5.3.0", -+ "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz", -+ "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "is-wsl": "1.1.0" - } - }, -- "remark-lint-hard-break-spaces": { -- "version": "1.0.2", -- "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-1.0.2.tgz", -- "integrity": "sha512-uh7LqHgRPCphiCvRzBVA4D0Ml2IqPaw89lWJdQ6HvYiV8ChB/OFLBapHi6OKW7NVVVPPJsElPMB/UPUsKFaPTg==", -+ "optimist": { -+ "version": "0.3.7", -+ "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", -+ "integrity": "sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "wordwrap": "0.0.3" - } - }, -- "remark-lint-heading-increment": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-heading-increment/-/remark-lint-heading-increment-1.0.1.tgz", -- "integrity": "sha512-jBAJacXAU5drUpvmymOoFmrdCCNDiz8bzGgJIMjpT0Vyjd0+qdXu2iyFMl/4RkkUli25rpUDXkTHTcxmNbh7Zw==", -+ "optionator": { -+ "version": "0.8.2", -+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", -+ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-visit": "1.3.1" -+ "deep-is": "0.1.3", -+ "fast-levenshtein": "2.0.6", -+ "levn": "0.3.0", -+ "prelude-ls": "1.1.2", -+ "type-check": "0.3.2", -+ "wordwrap": "1.0.0" -+ }, -+ "dependencies": { -+ "wordwrap": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", -+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", -+ "dev": true -+ } - } - }, -- "remark-lint-heading-style": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-1.0.1.tgz", -- "integrity": "sha512-m9Gqr091YdxUtG69xdXYH8fSd3+nsrsMamB/qSWpVSZuWQKZ1mRotr1LO9NphJh6vhw8IfBtG07wgEDn6b40sQ==", -+ "ora": { -+ "version": "0.3.0", -+ "resolved": "https://registry.npmjs.org/ora/-/ora-0.3.0.tgz", -+ "integrity": "sha1-NnoHitJc+wltpQERXrW0AeB9dJU=", - "dev": true, - "requires": { -- "mdast-util-heading-style": "1.0.3", -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-visit": "1.3.1" -- } -+ "chalk": "1.1.3", -+ "cli-cursor": "1.0.2", -+ "cli-spinners": "0.2.0", -+ "log-symbols": "1.0.2" -+ }, -+ "dependencies": { -+ "cli-spinners": { -+ "version": "0.2.0", -+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.2.0.tgz", -+ "integrity": "sha1-hQeHN5E7iA9uyf/ntl6D7Hd2KE8=", -+======= -+ "isstream": { -+ "version": "0.1.2", -+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", -+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", -+ "dev": true - }, -- "remark-lint-link-title-style": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-link-title-style/-/remark-lint-link-title-style-1.0.1.tgz", -- "integrity": "sha512-91MyqmZjokSzRbgvlKq5sLCJEFkM/MNKT1PDaWa3+GDLBGu7D4eMQGd2x49xX8IdJDEoWy5D8W+2Gb8XKWMUyw==", -+ "istanbul": { -+ "version": "0.4.5", -+ "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", -+ "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1", -- "vfile-location": "2.0.3" -+ "abbrev": "1.0.9", -+ "async": "1.5.2", -+ "escodegen": "1.8.1", -+ "esprima": "2.7.3", -+ "glob": "5.0.15", -+ "handlebars": "4.0.11", -+ "js-yaml": "3.11.0", -+ "mkdirp": "0.5.1", -+ "nopt": "3.0.6", -+ "once": "1.4.0", -+ "resolve": "1.1.7", -+ "supports-color": "3.2.3", -+ "which": "1.3.0", -+ "wordwrap": "1.0.0" -+ }, -+ "dependencies": { -+ "abbrev": { -+ "version": "1.0.9", -+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", -+ "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", -+ "dev": true -+ }, -+ "glob": { -+ "version": "5.0.15", -+ "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", -+ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", -+ "dev": true, -+ "requires": { -+ "inflight": "1.0.6", -+ "inherits": "2.0.3", -+ "minimatch": "3.0.4", -+ "once": "1.4.0", -+ "path-is-absolute": "1.0.1" -+ } -+ }, -+ "resolve": { -+ "version": "1.1.7", -+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", -+ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", -+ "dev": true -+ }, -+ "wordwrap": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", -+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", -+ "dev": true -+ } - } - }, -- "remark-lint-list-item-content-indent": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-list-item-content-indent/-/remark-lint-list-item-content-indent-1.0.1.tgz", -- "integrity": "sha512-R5cdXFFywoBcg+2UUcF9OJ/vt9oqJv+KmTKIQV9CFHWeAfMFiZbxazsSPNaCcO1fW9622hxPCawN/AofDTbP7Q==", -+ "js-tokens": { -+ "version": "3.0.2", -+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", -+ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", -+ "dev": true -+ }, -+ "js-yaml": { -+ "version": "3.11.0", -+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", -+ "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", - "dev": true, - "requires": { -- "plur": "2.1.2", -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "argparse": "1.0.10", -+ "esprima": "4.0.0" -+ }, -+ "dependencies": { -+ "esprima": { -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", -+ "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", -+ "dev": true -+ } - } - }, -- "remark-lint-list-item-indent": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-1.0.1.tgz", -- "integrity": "sha512-dSUFGQYtduuaos+5oXH89RTk0rGUe6DFf04q+rxQ7Z3YRbuXhAU2nYeY0/HENYiWJU1xFLteZkDvKMj0NfS3DQ==", -+ "jsbn": { -+ "version": "0.1.1", -+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", -+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, -- "requires": { -- "plur": "2.1.2", -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -- } -+ "optional": true - }, -- "remark-lint-list-item-spacing": { -- "version": "1.1.1", -- "resolved": "https://registry.npmjs.org/remark-lint-list-item-spacing/-/remark-lint-list-item-spacing-1.1.1.tgz", -- "integrity": "sha512-HlPEzRq4LJB6tQ72zgIZ42mOaOSX92O268BLolys/H1x6N29/JNMLfurWqLsrxZrxxHH3H7EUP4dNM2P1kDGBw==", -+ "jsdom": { -+ "version": "7.2.2", -+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-7.2.2.tgz", -+ "integrity": "sha1-QLQCdwwr2iNGkJa+6Rq2deOx/G4=", - "dev": true, -+ "optional": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "abab": "1.0.4", -+ "acorn": "2.7.0", -+ "acorn-globals": "1.0.9", -+ "cssom": "0.3.2", -+ "cssstyle": "0.2.37", -+ "escodegen": "1.8.1", -+ "nwmatcher": "1.4.3", -+ "parse5": "1.5.1", -+ "request": "2.85.0", -+ "sax": "1.2.4", -+ "symbol-tree": "3.2.2", -+ "tough-cookie": "2.3.4", -+ "webidl-conversions": "2.0.1", -+ "whatwg-url-compat": "0.6.5", -+ "xml-name-validator": "2.0.1" -+ }, -+ "dependencies": { -+ "acorn": { -+ "version": "2.7.0", -+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz", -+ "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc=", -+ "dev": true, -+ "optional": true -+ } - } - }, -- "remark-lint-maximum-heading-length": { -+ "json-parse-better-errors": { - "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-maximum-heading-length/-/remark-lint-maximum-heading-length-1.0.1.tgz", -- "integrity": "sha512-f8ChV9U238gncyvTqmzJ+UpCMj+hFyluWBjVYr2K8CNh+MdSivIxS4zw4170sBRoqNuS3gBxRHG9f4rmdqotJA==", -+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz", -+ "integrity": "sha512-xyQpxeWWMKyJps9CuGJYeng6ssI5bpqS9ltQpdVQ90t4ql6NdnxFKh95JcRt2cun/DjMVNrdjniLPuMA69xmCw==", -+ "dev": true -+ }, -+ "json-schema": { -+ "version": "0.2.3", -+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", -+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", -+ "dev": true -+ }, -+ "json-schema-traverse": { -+ "version": "0.3.1", -+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", -+ "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", -+ "dev": true -+ }, -+ "json-stable-stringify": { -+ "version": "0.0.1", -+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", -+ "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", - "dev": true, - "requires": { -- "mdast-util-to-string": "1.0.4", -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-visit": "1.3.1" -+ "jsonify": "0.0.0" - } - }, -- "remark-lint-maximum-line-length": { -- "version": "1.0.2", -- "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-1.0.2.tgz", -- "integrity": "sha512-M4UIXAAbtLgoQbTDVwdKOEFbTKtJSZ+pCW7ZqMFs+cbIN0Svm32LM9+xpVfVU0hLYt3Ypl++EAPfguBNe1PZEw==", -+ "json-stringify-safe": { -+ "version": "5.0.1", -+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", -+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", -+ "dev": true -+ }, -+ "jsonfile": { -+ "version": "2.4.0", -+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", -+ "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "graceful-fs": "4.1.11" - } - }, -- "remark-lint-no-auto-link-without-protocol": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-1.0.1.tgz", -- "integrity": "sha512-MHl0hNtF8Rc0lg6iuVP7/0rnp4uZadm3S07/1TiFeqzU22KFxxzcC8980Q4+I8oPZE0d1x80h9DmkNAVFwhDjQ==", -+ "jsonify": { -+ "version": "0.0.0", -+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", -+ "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", -+ "dev": true -+ }, -+ "jsonparse": { -+ "version": "1.3.1", -+ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", -+ "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", -+ "dev": true -+ }, -+ "jsonpointer": { -+ "version": "4.0.1", -+ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", -+ "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", -+ "dev": true -+ }, -+ "jsprim": { -+ "version": "1.4.1", -+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", -+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { -- "mdast-util-to-string": "1.0.4", -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "assert-plus": "1.0.0", -+ "extsprintf": "1.3.0", -+ "json-schema": "0.2.3", -+ "verror": "1.10.0" - } - }, -- "remark-lint-no-blockquote-without-marker": { -- "version": "2.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-2.0.1.tgz", -- "integrity": "sha512-8VTQ/MP3flvG4U0tFSD+DMVT7F/4u9SnQLb/jjeRC3DzgbsIagIUqpWYAKkc+yBz9S/lgftA92lLP5PrlOa5DA==", -+ "jsx-ast-utils": { -+ "version": "1.4.1", -+ "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz", -+ "integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=", -+ "dev": true -+ }, -+ "keyed-array": { -+ "version": "2.1.2", -+ "resolved": "https://registry.npmjs.org/keyed-array/-/keyed-array-2.1.2.tgz", -+ "integrity": "sha1-isE3thMi7V7Rx7Qbn5zQZmMcrOA=", -+ "dev": true -+ }, -+ "kind-of": { -+ "version": "3.2.2", -+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", -+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1", -- "vfile-location": "2.0.3" -+ "is-buffer": "1.1.6" - } - }, -- "remark-lint-no-consecutive-blank-lines": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-1.0.1.tgz", -- "integrity": "sha512-IhyUiGTpb/hjtusIVg10q963KeL5CyNfbWOfDZ1KtY2tvdoSPRGrrCuTKo6OG8r1qavM6bU0mtRuIBqNh4lIzA==", -+ "klaw": { -+ "version": "1.3.1", -+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", -+ "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "dev": true, - "requires": { -- "plur": "2.1.2", -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "graceful-fs": "4.1.11" - } - }, -- "remark-lint-no-duplicate-headings": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-headings/-/remark-lint-no-duplicate-headings-1.0.1.tgz", -- "integrity": "sha512-iZZxyZgwnjvDkydKZzqHBueJvIpGbxnITmgd8xN8TOLZoAg9/KGTQRAkotL1HXNRdkzwggfgB9ONxv/rWtYBmg==", -+ "labeled-stream-splicer": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz", -+ "integrity": "sha1-pS4dE4AkwAuGscDJH2d5GLiuClk=", - "dev": true, - "requires": { -- "mdast-util-to-string": "1.0.4", -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "inherits": "2.0.3", -+ "isarray": "0.0.1", -+ "stream-splicer": "2.0.0" - } - }, -- "remark-lint-no-emphasis-as-heading": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-no-emphasis-as-heading/-/remark-lint-no-emphasis-as-heading-1.0.1.tgz", -- "integrity": "sha512-+x17Hrjwne4Mhk2x/Zolnuv/sOclF1oYMDBSEYhBUpn/UAwxhXEXYKkeo0KkWA7Q3+UCLELJvzsk4cGNP6Sgow==", -+ "latest-version": { -+ "version": "3.1.0", -+ "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", -+ "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-visit": "1.3.1" -+ "package-json": "4.0.1" - } - }, -- "remark-lint-no-file-name-articles": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-1.0.1.tgz", -- "integrity": "sha512-SzebnFnilrsINA6QZP1YqPa3SrfSotrLkRWl5FUCoVshBvEFNKJFWXj6Xyt4NjWQ5tJWFtOMysAuHdGT+Odhjg==", -+ "lazy-cache": { -+ "version": "1.0.4", -+ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", -+ "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", -+ "dev": true, -+ "optional": true -+ }, -+ "lcid": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", -+ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2" -+ "invert-kv": "1.0.0" - } - }, -- "remark-lint-no-file-name-consecutive-dashes": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-1.0.1.tgz", -- "integrity": "sha512-YP2HBwA00yeD7phvxp4ftiqbfBPfYHPgPfcEcb8oNa1WlUh/58cs9DbSHWKsZG+XLkvEaheC6qUQG02jEKZHPA==", -+ "levn": { -+ "version": "0.3.0", -+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", -+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2" -+ "prelude-ls": "1.1.2", -+ "type-check": "0.3.2" - } - }, -- "remark-lint-no-file-name-irregular-characters": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-irregular-characters/-/remark-lint-no-file-name-irregular-characters-1.0.1.tgz", -- "integrity": "sha512-+ks/V6OVMGOPZKw+fe2E4DPvLoslGxvdgtqXq2Nyz0cEdYX8RP45kI79V4w95H7UCJAeOFM9mZzVLvmCY1sEbg==", -+ "lexical-scope": { -+ "version": "1.2.0", -+ "resolved": "https://registry.npmjs.org/lexical-scope/-/lexical-scope-1.2.0.tgz", -+ "integrity": "sha1-/Ope3HBKSzqHls3KQZw6CvryLfQ=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2" -+ "astw": "2.2.0" - } - }, -- "remark-lint-no-file-name-mixed-case": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-mixed-case/-/remark-lint-no-file-name-mixed-case-1.0.1.tgz", -- "integrity": "sha512-bcqPsow1C0LrsKII1YehUO7VPOER7nze6FzsZZ8/NP+d200OL7Y7VMCqN1kscAvG+PTJgjznyXuLEpy7KQnVFg==", -+ "linkify-it": { -+ "version": "1.2.4", -+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-1.2.4.tgz", -+ "integrity": "sha1-B3NSbDF8j9E71TTuHRgP+Iq/iBo=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2" -+ "uc.micro": "1.0.5" - } - }, -- "remark-lint-no-file-name-outer-dashes": { -- "version": "1.0.2", -- "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-1.0.2.tgz", -- "integrity": "sha512-BVEwLrA4kipalgKrxhncpgtmh6eUmHBH1ggC+X3csYR4X5vXv4vHQqpov4I1vMyWxMLMBnq7lTL3Iqp0CS4vwg==", -+ "load-json-file": { -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", -+ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2" -+ "graceful-fs": "4.1.11", -+ "parse-json": "2.2.0", -+ "pify": "2.3.0", -+ "pinkie-promise": "2.0.1", -+ "strip-bom": "2.0.0" - } - }, -- "remark-lint-no-heading-punctuation": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-no-heading-punctuation/-/remark-lint-no-heading-punctuation-1.0.1.tgz", -- "integrity": "sha512-/7kGRmPT+JLxEME1Z/rQn99mP8yr4qXFwcniKYsefR1jl8pCZciwCIp2Tq92Nn+FPELVrpk9sloRBb2JP3UB0A==", -+ "locate-path": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", -+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { -- "mdast-util-to-string": "1.0.4", -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-visit": "1.3.1" -+ "p-locate": "2.0.0", -+ "path-exists": "3.0.0" -+ }, -+ "dependencies": { -+ "path-exists": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", -+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", -+>>>>>>> .their -+ "dev": true -+ } - } - }, -- "remark-lint-no-inline-padding": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-1.0.1.tgz", -- "integrity": "sha512-nRl6vA45ZPdMz3/rVMZw7WRRqLFuMrzhdkrbrGLjwBovdIeD/IGCEbDA5NR60g2xT9V5dAmKogvHEH1bIr8SdQ==", -+<<<<<<< .our -+ "os-browserify": { -+ "version": "0.1.2", -+ "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.1.2.tgz", -+ "integrity": "sha1-ScoCk+CxlZCl9d4Qx/JlphfY/lQ=", -+ "dev": true -+ }, -+ "os-homedir": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", -+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", -+ "dev": true -+ }, -+ "os-locale": { -+ "version": "1.4.0", -+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", -+ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { -- "mdast-util-to-string": "1.0.4", -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-visit": "1.3.1" -+ "lcid": "1.0.0" - } - }, -- "remark-lint-no-literal-urls": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-1.0.1.tgz", -- "integrity": "sha512-YMsZFVYQDt9gvpc6THL76GzyhCR+cK79vjyEOEmX+O3tOjxQstbi0oW6Lngbl1WbpkCW5TWEzSKOorQowYI2wg==", -+ "os-tmpdir": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", -+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", -+ "dev": true -+ }, -+ "p-finally": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", -+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", -+ "dev": true -+ }, -+ "p-limit": { -+ "version": "1.2.0", -+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", -+ "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", - "dev": true, - "requires": { -- "mdast-util-to-string": "1.0.4", -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "p-try": "1.0.0" - } - }, -- "remark-lint-no-multiple-toplevel-headings": { -+ "p-locate": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", -+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", -+ "dev": true, -+ "requires": { -+ "p-limit": "1.2.0" -+ } -+ }, -+ "p-try": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", -+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", -+ "dev": true -+ }, -+ "package-json": { -+ "version": "4.0.1", -+ "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", -+ "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", -+ "dev": true, -+ "requires": { -+ "got": "6.7.1", -+ "registry-auth-token": "3.3.2", -+ "registry-url": "3.1.0", -+ "semver": "5.5.0" -+ } -+ }, -+ "pako": { -+ "version": "0.2.9", -+ "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", -+ "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", -+ "dev": true -+ }, -+ "parents": { - "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-1.0.1.tgz", -- "integrity": "sha512-LFfgjF3NKFkt0tGNnJ8Exf8+DrVcMRwek5qu5mvh2KrZnmSpm5flYWzUy2UnnIyicDL3CZYC/r3Fjz6CeBYgZA==", -+ "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", -+ "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "path-platform": "0.11.15" - } - }, -- "remark-lint-no-shell-dollars": { -+ "parse-asn1": { -+ "version": "5.1.1", -+ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", -+ "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", -+ "dev": true, -+ "requires": { -+ "asn1.js": "4.10.1", -+ "browserify-aes": "1.2.0", -+ "create-hash": "1.2.0", -+ "evp_bytestokey": "1.0.3", -+ "pbkdf2": "3.0.16" -+ } -+ }, -+ "parse-entities": { -+ "version": "1.1.2", -+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.1.2.tgz", -+ "integrity": "sha512-5N9lmQ7tmxfXf+hO3X6KRG6w7uYO/HL9fHalSySTdyn63C3WNvTM/1R8tn1u1larNcEbo3Slcy2bsVDQqvEpUg==", -+ "dev": true, -+ "requires": { -+ "character-entities": "1.2.2", -+ "character-entities-legacy": "1.1.2", -+ "character-reference-invalid": "1.1.2", -+ "is-alphanumerical": "1.0.2", -+ "is-decimal": "1.0.2", -+ "is-hexadecimal": "1.0.2" -+ } -+ }, -+ "parse-github-repo-url": { -+ "version": "1.4.1", -+ "resolved": "https://registry.npmjs.org/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz", -+ "integrity": "sha1-nn2LslKmy2ukJZUGC3v23z28H1A=", -+ "dev": true -+ }, -+ "parse-gitignore": { -+ "version": "0.4.0", -+ "resolved": "https://registry.npmjs.org/parse-gitignore/-/parse-gitignore-0.4.0.tgz", -+ "integrity": "sha1-q/cC5LkAUk//eQK2g4YoV7Y/k/4=", -+ "dev": true, -+ "requires": { -+ "array-unique": "0.3.2", -+ "is-glob": "3.1.0" -+ }, -+ "dependencies": { -+ "array-unique": { -+ "version": "0.3.2", -+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", -+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", -+ "dev": true -+ }, -+ "is-extglob": { -+ "version": "2.1.1", -+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", -+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", -+ "dev": true -+ }, -+ "is-glob": { -+ "version": "3.1.0", -+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", -+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", -+ "dev": true, -+ "requires": { -+ "is-extglob": "2.1.1" -+ } -+ } -+ } -+ }, -+ "parse-glob": { -+ "version": "3.0.4", -+ "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", -+ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", -+ "dev": true, -+ "requires": { -+ "glob-base": "0.3.0", -+ "is-dotfile": "1.0.3", -+ "is-extglob": "1.0.0", -+ "is-glob": "2.0.1" -+ } -+ }, -+ "parse-json": { -+ "version": "2.2.0", -+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", -+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", -+ "dev": true, -+ "requires": { -+ "error-ex": "1.3.1" -+ } -+ }, -+ "parse5": { -+ "version": "1.5.1", -+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", -+ "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", -+ "dev": true, -+ "optional": true -+ }, -+ "path-browserify": { -+ "version": "0.0.0", -+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", -+ "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", -+ "dev": true -+ }, -+ "path-exists": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", -+ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", -+ "dev": true, -+ "requires": { -+ "pinkie-promise": "2.0.1" -+ } -+ }, -+ "path-is-absolute": { - "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-1.0.1.tgz", -- "integrity": "sha512-YryHem73PTxjCkuC4HONJWHsmrLyXmF7r+cCH36Ys3vuWsfAbwkbOwpyuPB4KXn+6fHaTUfz/B5BPp3iwzJwyA==", -+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", -+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", -+ "dev": true -+ }, -+ "path-is-inside": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", -+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", -+ "dev": true -+ }, -+ "path-key": { -+ "version": "2.0.1", -+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", -+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", -+ "dev": true -+ }, -+ "path-parse": { -+ "version": "1.0.5", -+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", -+ "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", -+ "dev": true -+ }, -+ "path-platform": { -+ "version": "0.11.15", -+ "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", -+ "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", -+ "dev": true -+ }, -+ "path-type": { -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", -+ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", -+ "dev": true, -+ "requires": { -+ "graceful-fs": "4.1.11", -+ "pify": "2.3.0", -+ "pinkie-promise": "2.0.1" -+ } -+ }, -+ "pbkdf2": { -+ "version": "3.0.16", -+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", -+ "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", -+ "dev": true, -+ "requires": { -+ "create-hash": "1.2.0", -+ "create-hmac": "1.1.7", -+ "ripemd160": "2.0.2", -+ "safe-buffer": "5.1.2", -+ "sha.js": "2.4.11" -+ } -+ }, -+ "peek-stream": { -+ "version": "1.1.3", -+ "resolved": "https://registry.npmjs.org/peek-stream/-/peek-stream-1.1.3.tgz", -+ "integrity": "sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==", -+ "dev": true, -+ "requires": { -+ "buffer-from": "1.0.0", -+ "duplexify": "3.6.0", -+ "through2": "2.0.3" -+ } -+ }, -+ "performance-now": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", -+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", -+ "dev": true -+ }, -+ "pify": { -+ "version": "2.3.0", -+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", -+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", -+ "dev": true -+ }, -+ "pinkie": { -+ "version": "2.0.4", -+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", -+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", -+ "dev": true -+ }, -+ "pinkie-promise": { -+ "version": "2.0.1", -+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", -+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", -+ "dev": true, -+ "requires": { -+ "pinkie": "2.0.4" -+ } -+ }, -+ "pkg-conf": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", -+ "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=", -+ "dev": true, -+ "requires": { -+ "find-up": "2.1.0", -+ "load-json-file": "4.0.0" -+======= -+ "lodash": { -+ "version": "4.17.5", -+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", -+ "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", -+ "dev": true -+ }, -+ "lodash._reinterpolate": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", -+ "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", -+ "dev": true -+ }, -+ "lodash.assign": { -+ "version": "4.2.0", -+ "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", -+ "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", -+ "dev": true -+ }, -+ "lodash.assignin": { -+ "version": "4.2.0", -+ "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", -+ "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=", -+ "dev": true -+ }, -+ "lodash.bind": { -+ "version": "4.2.1", -+ "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", -+ "integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=", -+ "dev": true -+ }, -+ "lodash.cond": { -+ "version": "4.5.2", -+ "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", -+ "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", -+ "dev": true -+ }, -+ "lodash.defaults": { -+ "version": "4.2.0", -+ "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", -+ "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", -+ "dev": true -+ }, -+ "lodash.filter": { -+ "version": "4.6.0", -+ "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", -+ "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=", -+ "dev": true -+ }, -+ "lodash.flatten": { -+ "version": "4.4.0", -+ "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", -+ "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", -+ "dev": true -+ }, -+ "lodash.foreach": { -+ "version": "4.5.0", -+ "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", -+ "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=", -+ "dev": true -+ }, -+ "lodash.isempty": { -+ "version": "4.4.0", -+ "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", -+ "integrity": "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=", -+ "dev": true -+ }, -+ "lodash.isplainobject": { -+ "version": "4.0.6", -+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", -+ "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", -+ "dev": true -+ }, -+ "lodash.map": { -+ "version": "4.6.0", -+ "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", -+ "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", -+ "dev": true -+ }, -+ "lodash.memoize": { -+ "version": "3.0.4", -+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", -+ "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", -+ "dev": true -+ }, -+ "lodash.merge": { -+ "version": "4.6.1", -+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", -+ "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==", -+ "dev": true -+ }, -+ "lodash.pick": { -+ "version": "4.4.0", -+ "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", -+ "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", -+ "dev": true -+ }, -+ "lodash.range": { -+ "version": "3.2.0", -+ "resolved": "https://registry.npmjs.org/lodash.range/-/lodash.range-3.2.0.tgz", -+ "integrity": "sha1-9GHliPZmg/fq3q3lE+OKaaVloV0=", -+ "dev": true -+ }, -+ "lodash.reduce": { -+ "version": "4.6.0", -+ "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", -+ "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=", -+ "dev": true -+ }, -+ "lodash.reject": { -+ "version": "4.6.0", -+ "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", -+ "integrity": "sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU=", -+ "dev": true -+ }, -+ "lodash.some": { -+ "version": "4.6.0", -+ "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", -+ "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", -+ "dev": true -+ }, -+ "lodash.template": { -+ "version": "4.4.0", -+ "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", -+ "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", -+ "dev": true, -+ "requires": { -+ "lodash._reinterpolate": "3.0.0", -+ "lodash.templatesettings": "4.1.0" -+ } -+ }, -+ "lodash.templatesettings": { -+ "version": "4.1.0", -+ "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", -+ "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", -+ "dev": true, -+ "requires": { -+ "lodash._reinterpolate": "3.0.0" -+ } -+ }, -+ "lodash.transform": { -+ "version": "4.6.0", -+ "resolved": "https://registry.npmjs.org/lodash.transform/-/lodash.transform-4.6.0.tgz", -+ "integrity": "sha1-EjBkIvYzJK7YSD0/ODMrX2cFR6A=", -+ "dev": true -+ }, -+ "log-symbols": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", -+ "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", -+ "dev": true, -+ "requires": { -+ "chalk": "1.1.3" -+ } -+ }, -+ "longest": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", -+ "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", -+ "dev": true -+ }, -+ "loud-rejection": { -+ "version": "1.6.0", -+ "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", -+ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", -+ "dev": true, -+ "requires": { -+ "currently-unhandled": "0.4.1", -+ "signal-exit": "3.0.2" -+ } -+ }, -+ "lowercase-keys": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", -+ "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", -+ "dev": true -+ }, -+ "lru-cache": { -+ "version": "4.1.2", -+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.2.tgz", -+ "integrity": "sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ==", -+ "dev": true, -+ "requires": { -+ "pseudomap": "1.0.2", -+ "yallist": "2.1.2" -+ }, -+ "dependencies": { -+ "yallist": { -+ "version": "2.1.2", -+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", -+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", -+ "dev": true -+ } -+ } -+ }, -+ "make-dir": { -+ "version": "1.2.0", -+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz", -+ "integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==", -+ "dev": true, -+ "requires": { -+ "pify": "3.0.0" -+ }, -+ "dependencies": { -+ "pify": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", -+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", -+ "dev": true -+ } -+ } -+ }, -+ "map-obj": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", -+ "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", -+ "dev": true -+ }, -+ "markdown-it": { -+ "version": "6.1.1", -+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-6.1.1.tgz", -+ "integrity": "sha1-ztA39Ec+6fUVOsQU933IPJG6knw=", -+ "dev": true, -+ "requires": { -+ "argparse": "1.0.10", -+ "entities": "1.1.1", -+ "linkify-it": "1.2.4", -+ "mdurl": "1.0.1", -+ "uc.micro": "1.0.5" -+ } -+ }, -+ "markdown-it-named-headers": { -+ "version": "0.0.4", -+ "resolved": "https://registry.npmjs.org/markdown-it-named-headers/-/markdown-it-named-headers-0.0.4.tgz", -+ "integrity": "sha1-gu/CgyQkCmsed7mq5QF3HV81HB8=", -+ "dev": true, -+ "requires": { -+ "string": "3.3.3" -+ } -+ }, -+ "marky-markdown-lite": { -+ "version": "1.2.0", -+ "resolved": "https://registry.npmjs.org/marky-markdown-lite/-/marky-markdown-lite-1.2.0.tgz", -+ "integrity": "sha1-dO2phLgTZVfe4QZO/RXkBhdAaZc=", -+ "dev": true, -+ "requires": { -+ "cheerio": "0.20.0", -+ "conventional-changelog-cli": "1.3.16", -+ "is-file": "1.0.0", -+ "markdown-it": "6.1.1", -+ "markdown-it-named-headers": "0.0.4" -+ }, -+ "dependencies": { -+ "cheerio": { -+ "version": "0.20.0", -+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.20.0.tgz", -+ "integrity": "sha1-XHEPK6uVZTJyhCugHG6mGzVF7DU=", -+ "dev": true, -+ "requires": { -+ "css-select": "1.2.0", -+ "dom-serializer": "0.1.0", -+ "entities": "1.1.1", -+ "htmlparser2": "3.8.3", -+ "jsdom": "7.2.2", -+ "lodash": "4.17.5" -+ } -+ }, -+ "domhandler": { -+ "version": "2.3.0", -+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", -+ "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", -+ "dev": true, -+ "requires": { -+ "domelementtype": "1.3.0" -+ } -+ }, -+ "htmlparser2": { -+ "version": "3.8.3", -+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", -+ "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", -+ "dev": true, -+ "requires": { -+ "domelementtype": "1.3.0", -+ "domhandler": "2.3.0", -+ "domutils": "1.5.1", -+ "entities": "1.0.0", -+ "readable-stream": "1.1.14" -+ }, -+ "dependencies": { -+ "entities": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", -+ "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", -+ "dev": true -+ } -+ } -+ } -+ } -+ }, -+ "matcher-collection": { -+ "version": "1.0.5", -+ "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-1.0.5.tgz", -+ "integrity": "sha512-nUCmzKipcJEwYsBVAFh5P+d7JBuhJaW1xs85Hara9xuMLqtCVUrW6DSC0JVIkluxEH2W45nPBM/wjHtBXa/tYA==", -+ "dev": true, -+ "requires": { -+ "minimatch": "3.0.4" -+ } -+ }, -+ "md5.js": { -+ "version": "1.3.4", -+ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", -+ "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", -+ "dev": true, -+ "requires": { -+ "hash-base": "3.0.4", -+ "inherits": "2.0.3" -+ }, -+ "dependencies": { -+ "hash-base": { -+ "version": "3.0.4", -+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", -+ "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", -+ "dev": true, -+ "requires": { -+ "inherits": "2.0.3", -+ "safe-buffer": "5.1.1" -+ } -+ } -+ } -+ }, -+ "mdurl": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", -+ "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", -+ "dev": true -+ }, -+ "meow": { -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.0.tgz", -+ "integrity": "sha512-Me/kel335m6vMKmEmA6c87Z6DUFW3JqkINRnxkbC+A/PUm0D5Fl2dEBQrPKnqCL9Te/CIa1MUt/0InMJhuC/sw==", -+ "dev": true, -+ "requires": { -+ "camelcase-keys": "4.2.0", -+ "decamelize-keys": "1.1.0", -+ "loud-rejection": "1.6.0", -+ "minimist": "1.2.0", -+ "minimist-options": "3.0.2", -+ "normalize-package-data": "2.4.0", -+ "read-pkg-up": "3.0.0", -+ "redent": "2.0.0", -+ "trim-newlines": "2.0.0" -+>>>>>>> .their -+ }, -+ "dependencies": { -+ "find-up": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", -+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", -+ "dev": true, -+ "requires": { -+ "locate-path": "2.0.0" -+ } -+ }, -+ "load-json-file": { -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", -+ "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", -+ "dev": true, -+ "requires": { -+ "graceful-fs": "4.1.11", -+ "parse-json": "4.0.0", -+ "pify": "3.0.0", -+ "strip-bom": "3.0.0" -+ } -+ }, -+ "parse-json": { -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", -+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", -+ "dev": true, -+ "requires": { -+ "error-ex": "1.3.1", -+<<<<<<< .our -+ "json-parse-better-errors": "1.0.2" -+======= -+ "json-parse-better-errors": "1.0.1" -+ } -+ }, -+ "path-type": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", -+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", -+ "dev": true, -+ "requires": { -+ "pify": "3.0.0" -+>>>>>>> .their -+ } -+ }, -+ "pify": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", -+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", -+ "dev": true -+ }, -+<<<<<<< .our -+======= -+ "read-pkg": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", -+ "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", -+ "dev": true, -+ "requires": { -+ "load-json-file": "4.0.0", -+ "normalize-package-data": "2.4.0", -+ "path-type": "3.0.0" -+ } -+ }, -+ "read-pkg-up": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", -+ "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", -+ "dev": true, -+ "requires": { -+ "find-up": "2.1.0", -+ "read-pkg": "3.0.0" -+ } -+ }, -+>>>>>>> .their -+ "strip-bom": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", -+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", -+ "dev": true -+ } -+ } -+ }, -+<<<<<<< .our -+ "pkg-config": { -+ "version": "1.1.1", -+ "resolved": "https://registry.npmjs.org/pkg-config/-/pkg-config-1.1.1.tgz", -+ "integrity": "sha1-VX7yLXPaPIg3EHdmxS6tq94pj+Q=", -+ "dev": true, -+ "requires": { -+ "debug-log": "1.0.1", -+ "find-root": "1.1.0", -+ "xtend": "4.0.1" -+ } -+ }, -+ "pkg-dir": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", -+ "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", -+ "dev": true, -+ "requires": { -+ "find-up": "1.1.2" -+ } -+ }, -+ "pkg-up": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", -+ "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", -+ "dev": true, -+ "requires": { -+ "find-up": "1.1.2" -+ } -+ }, -+ "plur": { -+ "version": "2.1.2", -+ "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", -+ "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", -+ "dev": true, -+ "requires": { -+ "irregular-plurals": "1.4.0" -+ } -+ }, -+ "pluralize": { -+ "version": "1.2.1", -+ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", -+ "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", -+ "dev": true -+ }, -+ "prelude-ls": { -+ "version": "1.1.2", -+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", -+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", -+ "dev": true -+ }, -+ "prepend-http": { -+ "version": "1.0.4", -+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", -+ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", -+ "dev": true -+ }, -+ "preserve": { -+ "version": "0.2.0", -+ "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", -+ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", -+ "dev": true -+ }, -+ "pretty-bytes": { -+ "version": "1.0.4", -+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz", -+ "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", -+ "dev": true, -+ "requires": { -+ "get-stdin": "4.0.1", -+ "meow": "3.7.0" -+ }, -+ "dependencies": { -+ "camelcase": { -+ "version": "2.1.1", -+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", -+ "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", -+ "dev": true -+ }, -+ "camelcase-keys": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", -+ "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", -+ "dev": true, -+ "requires": { -+ "camelcase": "2.1.1", -+ "map-obj": "1.0.1" -+ } -+ }, -+ "indent-string": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", -+ "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", -+ "dev": true, -+ "requires": { -+ "repeating": "2.0.1" -+ } -+ }, -+ "map-obj": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", -+ "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", -+ "dev": true -+ }, -+ "meow": { -+ "version": "3.7.0", -+ "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", -+ "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", -+ "dev": true, -+ "requires": { -+ "camelcase-keys": "2.1.0", -+ "decamelize": "1.2.0", -+ "loud-rejection": "1.6.0", -+ "map-obj": "1.0.1", -+ "minimist": "1.2.0", -+ "normalize-package-data": "2.4.0", -+ "object-assign": "4.1.1", -+ "read-pkg-up": "1.0.1", -+ "redent": "1.0.0", -+ "trim-newlines": "1.0.0" -+ } -+ }, -+ "redent": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", -+ "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", -+ "dev": true, -+ "requires": { -+ "indent-string": "2.1.0", -+ "strip-indent": "1.0.1" -+ } -+ }, -+ "strip-indent": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", -+ "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", -+ "dev": true, -+ "requires": { -+ "get-stdin": "4.0.1" -+ } -+ }, -+ "trim-newlines": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", -+ "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", -+======= -+ "micromatch": { -+ "version": "2.3.11", -+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", -+ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", -+ "dev": true, -+ "requires": { -+ "arr-diff": "2.0.0", -+ "array-unique": "0.2.1", -+ "braces": "1.8.5", -+ "expand-brackets": "0.1.5", -+ "extglob": "0.3.2", -+ "filename-regex": "2.0.1", -+ "is-extglob": "1.0.0", -+ "is-glob": "2.0.1", -+ "kind-of": "3.2.2", -+ "normalize-path": "2.1.1", -+ "object.omit": "2.0.1", -+ "parse-glob": "3.0.4", -+ "regex-cache": "0.4.4" -+ } -+ }, -+ "miller-rabin": { -+ "version": "4.0.1", -+ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", -+ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", -+ "dev": true, -+ "requires": { -+ "bn.js": "4.11.8", -+ "brorand": "1.1.0" -+ } -+ }, -+ "mime": { -+ "version": "1.6.0", -+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", -+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", -+ "dev": true -+ }, -+ "mime-db": { -+ "version": "1.33.0", -+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", -+ "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", -+ "dev": true -+ }, -+ "mime-types": { -+ "version": "2.1.18", -+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", -+ "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", -+ "dev": true, -+ "requires": { -+ "mime-db": "1.33.0" -+ } -+ }, -+ "mimic-fn": { -+ "version": "1.2.0", -+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", -+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", -+ "dev": true -+ }, -+ "minimalistic-assert": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", -+ "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=", -+ "dev": true -+ }, -+ "minimalistic-crypto-utils": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", -+ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", -+ "dev": true -+ }, -+ "minimatch": { -+ "version": "3.0.4", -+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", -+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", -+ "dev": true, -+ "requires": { -+ "brace-expansion": "1.1.11" -+ } -+ }, -+ "minimist": { -+ "version": "1.2.0", -+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", -+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", -+ "dev": true -+ }, -+ "minimist-options": { -+ "version": "3.0.2", -+ "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", -+ "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", -+ "dev": true, -+ "requires": { -+ "arrify": "1.0.1", -+ "is-plain-obj": "1.1.0" -+ } -+ }, -+ "minipass": { -+ "version": "2.2.1", -+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.1.tgz", -+ "integrity": "sha512-u1aUllxPJUI07cOqzR7reGmQxmCqlH88uIIsf6XZFEWgw7gXKpJdR+5R9Y3KEDmWYkdIz9wXZs3C0jOPxejk/Q==", -+ "dev": true, -+ "requires": { -+ "yallist": "3.0.2" -+ } -+ }, -+ "minizlib": { -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz", -+ "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", -+ "dev": true, -+ "requires": { -+ "minipass": "2.2.1" -+ } -+ }, -+ "mkdirp": { -+ "version": "0.5.1", -+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", -+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", -+ "dev": true, -+ "requires": { -+ "minimist": "0.0.8" -+ }, -+ "dependencies": { -+ "minimist": { -+ "version": "0.0.8", -+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", -+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", -+>>>>>>> .their -+ "dev": true -+ } -+ } -+ }, -+<<<<<<< .our -+ "process": { -+ "version": "0.11.10", -+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", -+ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", -+ "dev": true -+ }, -+ "process-nextick-args": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", -+ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", -+ "dev": true -+ }, -+ "progress": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", -+ "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", -+ "dev": true -+ }, -+ "progress-stream": { -+ "version": "1.2.0", -+ "resolved": "https://registry.npmjs.org/progress-stream/-/progress-stream-1.2.0.tgz", -+ "integrity": "sha1-LNPP6jO6OonJwSHsM0er6asSX3c=", -+ "dev": true, -+ "requires": { -+ "speedometer": "0.1.4", -+ "through2": "0.2.3" -+ }, -+ "dependencies": { -+ "through2": { -+ "version": "0.2.3", -+ "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz", -+ "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=", -+ "dev": true, -+ "requires": { -+ "readable-stream": "1.1.14", -+ "xtend": "2.1.2" -+ } -+ }, -+ "xtend": { -+ "version": "2.1.2", -+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", -+ "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", -+ "dev": true, -+ "requires": { -+ "object-keys": "0.4.0" -+======= -+ "mkpath": { -+ "version": "0.1.0", -+ "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz", -+ "integrity": "sha1-dVSm+Nhxg0zJe1RisSLEwSTW3pE=", -+ "dev": true -+ }, -+ "mksnapshot": { -+ "version": "0.3.1", -+ "resolved": "https://registry.npmjs.org/mksnapshot/-/mksnapshot-0.3.1.tgz", -+ "integrity": "sha1-JQHAVldDbXQs6Vik/5LHfkDdN+Y=", -+ "dev": true, -+ "requires": { -+ "decompress-zip": "0.3.0", -+ "fs-extra": "0.26.7", -+ "request": "2.85.0" -+ } -+ }, -+ "modify-values": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.0.tgz", -+ "integrity": "sha1-4rbN65zhn5kxelNyLz2/XfXqqrI=", -+ "dev": true -+ }, -+ "module-deps": { -+ "version": "4.1.1", -+ "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-4.1.1.tgz", -+ "integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=", -+ "dev": true, -+ "requires": { -+ "JSONStream": "1.3.2", -+ "browser-resolve": "1.11.2", -+ "cached-path-relative": "1.0.1", -+ "concat-stream": "1.5.2", -+ "defined": "1.0.0", -+ "detective": "4.7.1", -+ "duplexer2": "0.1.4", -+ "inherits": "2.0.3", -+ "parents": "1.0.1", -+ "readable-stream": "2.3.5", -+ "resolve": "1.5.0", -+ "stream-combiner2": "1.1.1", -+ "subarg": "1.0.0", -+ "through2": "2.0.3", -+ "xtend": "4.0.1" -+ }, -+ "dependencies": { -+ "isarray": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", -+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", -+ "dev": true -+ }, -+ "readable-stream": { -+ "version": "2.3.5", -+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", -+ "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", -+ "dev": true, -+ "requires": { -+ "core-util-is": "1.0.2", -+ "inherits": "2.0.3", -+ "isarray": "1.0.0", -+ "process-nextick-args": "2.0.0", -+ "safe-buffer": "5.1.1", -+ "string_decoder": "1.0.3", -+ "util-deprecate": "1.0.2" -+ } -+ }, -+ "string_decoder": { -+ "version": "1.0.3", -+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", -+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", -+ "dev": true, -+ "requires": { -+ "safe-buffer": "5.1.1" -+>>>>>>> .their -+ } -+ } -+ } -+ }, -+<<<<<<< .our -+ "pseudomap": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", -+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", -+ "dev": true -+ }, -+ "public-encrypt": { -+ "version": "4.0.2", -+ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", -+ "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", -+ "dev": true, -+ "requires": { -+ "bn.js": "4.11.8", -+ "browserify-rsa": "4.0.1", -+ "create-hash": "1.2.0", -+ "parse-asn1": "5.1.1", -+ "randombytes": "2.0.6" -+ } -+ }, -+ "pump": { -+ "version": "2.0.1", -+ "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", -+ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", -+ "dev": true, -+ "requires": { -+ "end-of-stream": "1.4.1", -+ "once": "1.4.0" -+ } -+ }, -+ "pumpify": { -+ "version": "1.5.0", -+ "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.0.tgz", -+ "integrity": "sha512-UWi0klDoq8xtVzlMRgENV9F7iCTZExaJQSQL187UXsxpk9NnrKGqTqqUNYAKGOzucSOxs2+jUnRNI+rLviPhJg==", -+ "dev": true, -+ "requires": { -+ "duplexify": "3.6.0", -+ "inherits": "2.0.3", -+ "pump": "2.0.1" -+ } -+ }, -+ "punycode": { -+ "version": "1.4.1", -+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", -+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", -+ "dev": true -+ }, -+ "q": { -+ "version": "1.5.1", -+ "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", -+ "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", -+ "dev": true -+ }, -+ "qs": { -+ "version": "6.5.2", -+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", -+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", -+ "dev": true -+ }, -+ "querystring": { -+ "version": "0.2.0", -+ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", -+ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", -+ "dev": true -+ }, -+ "querystring-es3": { -+ "version": "0.2.1", -+ "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", -+ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", -+ "dev": true -+ }, -+ "quick-lru": { -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", -+ "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", -+ "dev": true -+ }, -+ "randomatic": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", -+ "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", -+ "dev": true, -+ "requires": { -+ "is-number": "4.0.0", -+ "kind-of": "6.0.2", -+ "math-random": "1.0.1" -+ }, -+ "dependencies": { -+ "is-number": { -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", -+ "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", -+ "dev": true -+ }, -+ "kind-of": { -+ "version": "6.0.2", -+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", -+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", -+======= -+ "ms": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", -+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", -+ "dev": true -+ }, -+ "mute-stream": { -+ "version": "0.0.5", -+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", -+ "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", -+ "dev": true -+ }, -+ "natural-compare": { -+ "version": "1.4.0", -+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", -+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", -+ "dev": true -+ }, -+ "netrc": { -+ "version": "0.1.4", -+ "resolved": "https://registry.npmjs.org/netrc/-/netrc-0.1.4.tgz", -+ "integrity": "sha1-a+lPysqNd63gqWcNxGCRTJRHJEQ=", -+ "dev": true -+ }, -+ "node-dir": { -+ "version": "0.1.17", -+ "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", -+ "integrity": "sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=", -+ "dev": true, -+ "requires": { -+ "minimatch": "3.0.4" -+ } -+ }, -+ "nopt": { -+ "version": "3.0.6", -+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", -+ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", -+ "dev": true, -+ "requires": { -+ "abbrev": "1.1.1" -+ } -+ }, -+ "normalize-package-data": { -+ "version": "2.4.0", -+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", -+ "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", -+ "dev": true, -+ "requires": { -+ "hosted-git-info": "2.6.0", -+ "is-builtin-module": "1.0.0", -+ "semver": "5.5.0", -+ "validate-npm-package-license": "3.0.3" -+ } -+ }, -+ "normalize-path": { -+ "version": "2.1.1", -+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", -+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", -+ "dev": true, -+ "requires": { -+ "remove-trailing-separator": "1.1.0" -+ } -+ }, -+ "npm-run-path": { -+ "version": "2.0.2", -+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", -+ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", -+ "dev": true, -+ "requires": { -+ "path-key": "2.0.1" -+ } -+ }, -+ "nth-check": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", -+ "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", -+ "dev": true, -+ "requires": { -+ "boolbase": "1.0.0" -+ } -+ }, -+ "nugget": { -+ "version": "2.0.1", -+ "resolved": "https://registry.npmjs.org/nugget/-/nugget-2.0.1.tgz", -+ "integrity": "sha1-IBCVpIfhrTYIGzQy+jytpPjQcbA=", -+ "dev": true, -+ "requires": { -+ "debug": "2.6.9", -+ "minimist": "1.2.0", -+ "pretty-bytes": "1.0.4", -+ "progress-stream": "1.2.0", -+ "request": "2.85.0", -+ "single-line-log": "1.1.2", -+ "throttleit": "0.0.2" -+ } -+ }, -+ "number-is-nan": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", -+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", -+ "dev": true -+ }, -+ "nwmatcher": { -+ "version": "1.4.3", -+ "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.3.tgz", -+ "integrity": "sha512-IKdSTiDWCarf2JTS5e9e2+5tPZGdkRJ79XjYV0pzK8Q9BpsFyBq1RGKxzs7Q8UBushGw7m6TzVKz6fcY99iSWw==", -+ "dev": true, -+ "optional": true -+ }, -+ "oauth-sign": { -+ "version": "0.8.2", -+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", -+ "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", -+ "dev": true -+ }, -+ "object-assign": { -+ "version": "4.1.1", -+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", -+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", -+ "dev": true -+ }, -+ "object-keys": { -+ "version": "0.4.0", -+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", -+ "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", -+ "dev": true -+ }, -+ "object.assign": { -+ "version": "4.1.0", -+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", -+ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", -+ "dev": true, -+ "requires": { -+ "define-properties": "1.1.2", -+ "function-bind": "1.1.1", -+ "has-symbols": "1.0.0", -+ "object-keys": "1.0.11" -+ }, -+ "dependencies": { -+ "object-keys": { -+ "version": "1.0.11", -+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", -+ "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", -+>>>>>>> .their -+ "dev": true -+ } -+ } -+ }, -+<<<<<<< .our -+ "randombytes": { -+ "version": "2.0.6", -+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", -+ "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", -+ "dev": true, -+ "requires": { -+ "safe-buffer": "5.1.2" -+ } -+ }, -+ "randomfill": { -+ "version": "1.0.4", -+ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", -+ "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", -+ "dev": true, -+ "requires": { -+ "randombytes": "2.0.6", -+ "safe-buffer": "5.1.2" -+ } -+ }, -+ "range-parser": { -+ "version": "1.2.0", -+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", -+ "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", -+ "dev": true -+ }, -+ "raw-body": { -+ "version": "2.3.2", -+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", -+ "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", -+ "dev": true, -+ "requires": { -+ "bytes": "3.0.0", -+ "http-errors": "1.6.2", -+ "iconv-lite": "0.4.19", -+ "unpipe": "1.0.0" -+ } -+ }, -+ "rc": { -+ "version": "1.2.7", -+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.7.tgz", -+ "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==", -+ "dev": true, -+ "requires": { -+ "deep-extend": "0.5.1", -+ "ini": "1.3.5", -+ "minimist": "1.2.0", -+ "strip-json-comments": "2.0.1" -+ } -+ }, -+ "read-only-stream": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", -+ "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", -+ "dev": true, -+ "requires": { -+ "readable-stream": "2.3.6" -+ }, -+ "dependencies": { -+ "isarray": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", -+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", -+ "dev": true -+ }, -+ "readable-stream": { -+ "version": "2.3.6", -+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", -+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", -+ "dev": true, -+ "requires": { -+ "core-util-is": "1.0.2", -+ "inherits": "2.0.3", -+ "isarray": "1.0.0", -+ "process-nextick-args": "2.0.0", -+ "safe-buffer": "5.1.2", -+ "string_decoder": "1.1.1", -+ "util-deprecate": "1.0.2" -+ } -+ }, -+ "string_decoder": { -+ "version": "1.1.1", -+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", -+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", -+ "dev": true, -+ "requires": { -+ "safe-buffer": "5.1.2" -+ } -+ } -+ } -+ }, -+ "read-pkg": { -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", -+ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", -+ "dev": true, -+ "requires": { -+ "load-json-file": "1.1.0", -+ "normalize-package-data": "2.4.0", -+ "path-type": "1.1.0" -+ } -+ }, -+ "read-pkg-up": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", -+ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", -+ "dev": true, -+ "requires": { -+ "find-up": "1.1.2", -+ "read-pkg": "1.1.0" -+ } -+ }, -+ "readable-stream": { -+ "version": "1.1.14", -+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", -+ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", -+ "dev": true, -+ "requires": { -+ "core-util-is": "1.0.2", -+ "inherits": "2.0.3", -+ "isarray": "0.0.1", -+ "string_decoder": "0.10.31" -+ } -+ }, -+ "readdirp": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", -+ "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", -+ "dev": true, -+ "requires": { -+ "graceful-fs": "4.1.11", -+ "minimatch": "3.0.4", -+ "readable-stream": "2.3.6", -+ "set-immediate-shim": "1.0.1" -+ }, -+ "dependencies": { -+ "isarray": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", -+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", -+ "dev": true -+ }, -+ "readable-stream": { -+ "version": "2.3.6", -+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", -+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", -+ "dev": true, -+ "requires": { -+ "core-util-is": "1.0.2", -+ "inherits": "2.0.3", -+ "isarray": "1.0.0", -+ "process-nextick-args": "2.0.0", -+ "safe-buffer": "5.1.2", -+ "string_decoder": "1.1.1", -+ "util-deprecate": "1.0.2" -+ } -+ }, -+ "string_decoder": { -+ "version": "1.1.1", -+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", -+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", -+ "dev": true, -+ "requires": { -+ "safe-buffer": "5.1.2" -+ } -+ } -+ } -+ }, -+ "readline2": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", -+ "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", -+ "dev": true, -+ "requires": { -+ "code-point-at": "1.1.0", -+ "is-fullwidth-code-point": "1.0.0", -+ "mute-stream": "0.0.5" -+ } -+ }, -+ "rechoir": { -+ "version": "0.6.2", -+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", -+ "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", -+ "dev": true, -+ "requires": { -+ "resolve": "1.7.1" -+ } -+ }, -+ "redent": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", -+ "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", -+ "dev": true, -+ "requires": { -+ "indent-string": "3.2.0", -+ "strip-indent": "2.0.0" -+ } -+ }, -+ "regex-cache": { -+ "version": "0.4.4", -+ "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", -+ "integrity": "sha1-db3FiioUls7EihKDW8VMjVYjNt0=", -+ "dev": true, -+ "requires": { -+ "is-equal-shallow": "0.1.3" -+ } -+ }, -+ "registry-auth-token": { -+ "version": "3.3.2", -+ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", -+ "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", -+ "dev": true, -+ "requires": { -+ "rc": "1.2.7", -+ "safe-buffer": "5.1.2" -+ } -+ }, -+ "registry-url": { -+ "version": "3.1.0", -+ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", -+ "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", -+ "dev": true, -+ "requires": { -+ "rc": "1.2.7" -+ } -+ }, -+ "remark": { -+ "version": "8.0.0", -+ "resolved": "https://registry.npmjs.org/remark/-/remark-8.0.0.tgz", -+ "integrity": "sha512-K0PTsaZvJlXTl9DN6qYlvjTkqSZBFELhROZMrblm2rB+085flN84nz4g/BscKRMqDvhzlK1oQ/xnWQumdeNZYw==", -+ "dev": true, -+ "requires": { -+ "remark-parse": "4.0.0", -+ "remark-stringify": "4.0.0", -+ "unified": "6.2.0" -+ } -+ }, -+ "remark-cli": { -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/remark-cli/-/remark-cli-4.0.0.tgz", -+ "integrity": "sha512-q5GMjGypUS4rTZb3WfMQcGpClSC38A9Ogg1h/HB2GLsqypDetmAfy0X+tuJ6JeyCPVOXXCDgsDCQq4QPqKmxBA==", -+ "dev": true, -+ "requires": { -+ "markdown-extensions": "1.1.1", -+ "remark": "8.0.0", -+ "unified-args": "4.0.0" -+ } -+ }, -+ "remark-lint": { -+ "version": "6.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-6.0.1.tgz", -+ "integrity": "sha512-wvTTuB5O5pF8SxqahQjjrU3dtuhygYjaGcOZTw+4ACgSE4RBINDlNqN46HjcV3X0ib5GmObJUt5a2mmhtmuTqw==", -+ "dev": true, -+ "requires": { -+ "remark-message-control": "4.1.0" -+ } -+ }, -+ "remark-lint-blockquote-indentation": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-1.0.1.tgz", -+ "integrity": "sha512-YrP99MJ3+dQ5JXzq39fUOcYzwcumva/xEM1eFtD2TrQcSdlMLoqYa7gj+aEEhZCjlA5BssTiVoWWW0RjyPPGZw==", -+ "dev": true, -+ "requires": { -+ "mdast-util-to-string": "1.0.4", -+ "plur": "2.1.2", -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-code-block-style": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-1.0.1.tgz", -+ "integrity": "sha512-FRUMhhKwCruH4vkatdMhVO4WlYpysV1NmMILVoK/k+/7uFLSfgvlqo66nzhpMdWL8TQHqdo0LhiXuetGC2WjsQ==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-definition-case": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-definition-case/-/remark-lint-definition-case-1.0.1.tgz", -+ "integrity": "sha512-TxLye5KF4o/rKVTvmPRX5jS9itamFS02yy1IG8bIYcIAJvWsW3GlJaXq4ohK3hKwSQOhtCherEfD6XF9BHLNYQ==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-definition-spacing": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-1.0.1.tgz", -+ "integrity": "sha512-ewzdlFfpTSP11ZuiOln0yfz6Y03aWtgJmLVQNfF1spaT1gURaShjs8Hiilbo719bz96DgvXSZLP6UnkSiZL1vg==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-emphasis-marker": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-emphasis-marker/-/remark-lint-emphasis-marker-1.0.1.tgz", -+ "integrity": "sha512-QyNsD6y8EZQqhechw0XFGybYMlxn6PFLSlFUO50KSQlJEOgkImN2yJfrNrET2GY4t/fc/uYmeI/q7auUIkLX2w==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-fenced-code-flag": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-1.0.1.tgz", -+ "integrity": "sha512-P24T9DRe/nnywPFRpE1UAXAVzN1CX6HmINr15UHbQZo1Cy8KYt7uV9YOR0/XzphtnO/AFenAqZyf7tchW5AUNQ==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-fenced-code-marker": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-1.0.1.tgz", -+ "integrity": "sha512-mX7xAMl5m7xGX+YtOtyXIyv+egD4IQAm6DPGdfunI734QwODwcoBydtpTD56jrY+48nVcQ/anFYT1Blg3Xk3sQ==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-file-extension": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-1.0.1.tgz", -+ "integrity": "sha512-K1Pf5oviaFyCs0FhZqaNZ2odgd5KoV6AlA4nNAMxyylB0Y6t0mYpzECoLSS5Bgxf6f8Op9YbuM2cbjBAsv0dIA==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2" -+ } -+ }, -+ "remark-lint-final-definition": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-1.0.1.tgz", -+ "integrity": "sha512-DK6bphJdQ0xSOQAn+8wOyLIVc3SZW2+ZzCMCLkQnVtHiQ9GHMzFiCkeE3Cq+OClsMI5Yn8wFTHZHPUn58VhNEQ==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-hard-break-spaces": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-1.0.2.tgz", -+ "integrity": "sha512-uh7LqHgRPCphiCvRzBVA4D0Ml2IqPaw89lWJdQ6HvYiV8ChB/OFLBapHi6OKW7NVVVPPJsElPMB/UPUsKFaPTg==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-heading-increment": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-heading-increment/-/remark-lint-heading-increment-1.0.1.tgz", -+ "integrity": "sha512-jBAJacXAU5drUpvmymOoFmrdCCNDiz8bzGgJIMjpT0Vyjd0+qdXu2iyFMl/4RkkUli25rpUDXkTHTcxmNbh7Zw==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-heading-style": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-1.0.1.tgz", -+ "integrity": "sha512-m9Gqr091YdxUtG69xdXYH8fSd3+nsrsMamB/qSWpVSZuWQKZ1mRotr1LO9NphJh6vhw8IfBtG07wgEDn6b40sQ==", -+ "dev": true, -+ "requires": { -+ "mdast-util-heading-style": "1.0.3", -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-link-title-style": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-link-title-style/-/remark-lint-link-title-style-1.0.1.tgz", -+ "integrity": "sha512-91MyqmZjokSzRbgvlKq5sLCJEFkM/MNKT1PDaWa3+GDLBGu7D4eMQGd2x49xX8IdJDEoWy5D8W+2Gb8XKWMUyw==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1", -+ "vfile-location": "2.0.3" -+ } -+ }, -+ "remark-lint-list-item-content-indent": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-list-item-content-indent/-/remark-lint-list-item-content-indent-1.0.1.tgz", -+ "integrity": "sha512-R5cdXFFywoBcg+2UUcF9OJ/vt9oqJv+KmTKIQV9CFHWeAfMFiZbxazsSPNaCcO1fW9622hxPCawN/AofDTbP7Q==", -+ "dev": true, -+ "requires": { -+ "plur": "2.1.2", -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-list-item-indent": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-1.0.1.tgz", -+ "integrity": "sha512-dSUFGQYtduuaos+5oXH89RTk0rGUe6DFf04q+rxQ7Z3YRbuXhAU2nYeY0/HENYiWJU1xFLteZkDvKMj0NfS3DQ==", -+ "dev": true, -+ "requires": { -+ "plur": "2.1.2", -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-list-item-spacing": { -+ "version": "1.1.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-list-item-spacing/-/remark-lint-list-item-spacing-1.1.1.tgz", -+ "integrity": "sha512-HlPEzRq4LJB6tQ72zgIZ42mOaOSX92O268BLolys/H1x6N29/JNMLfurWqLsrxZrxxHH3H7EUP4dNM2P1kDGBw==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-maximum-heading-length": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-maximum-heading-length/-/remark-lint-maximum-heading-length-1.0.1.tgz", -+ "integrity": "sha512-f8ChV9U238gncyvTqmzJ+UpCMj+hFyluWBjVYr2K8CNh+MdSivIxS4zw4170sBRoqNuS3gBxRHG9f4rmdqotJA==", -+ "dev": true, -+ "requires": { -+ "mdast-util-to-string": "1.0.4", -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-maximum-line-length": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-1.0.2.tgz", -+ "integrity": "sha512-M4UIXAAbtLgoQbTDVwdKOEFbTKtJSZ+pCW7ZqMFs+cbIN0Svm32LM9+xpVfVU0hLYt3Ypl++EAPfguBNe1PZEw==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-no-auto-link-without-protocol": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-1.0.1.tgz", -+ "integrity": "sha512-MHl0hNtF8Rc0lg6iuVP7/0rnp4uZadm3S07/1TiFeqzU22KFxxzcC8980Q4+I8oPZE0d1x80h9DmkNAVFwhDjQ==", -+ "dev": true, -+ "requires": { -+ "mdast-util-to-string": "1.0.4", -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-no-blockquote-without-marker": { -+ "version": "2.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-2.0.1.tgz", -+ "integrity": "sha512-8VTQ/MP3flvG4U0tFSD+DMVT7F/4u9SnQLb/jjeRC3DzgbsIagIUqpWYAKkc+yBz9S/lgftA92lLP5PrlOa5DA==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1", -+ "vfile-location": "2.0.3" -+ } -+ }, -+ "remark-lint-no-consecutive-blank-lines": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-1.0.1.tgz", -+ "integrity": "sha512-IhyUiGTpb/hjtusIVg10q963KeL5CyNfbWOfDZ1KtY2tvdoSPRGrrCuTKo6OG8r1qavM6bU0mtRuIBqNh4lIzA==", -+ "dev": true, -+ "requires": { -+ "plur": "2.1.2", -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-no-duplicate-headings": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-headings/-/remark-lint-no-duplicate-headings-1.0.1.tgz", -+ "integrity": "sha512-iZZxyZgwnjvDkydKZzqHBueJvIpGbxnITmgd8xN8TOLZoAg9/KGTQRAkotL1HXNRdkzwggfgB9ONxv/rWtYBmg==", -+ "dev": true, -+ "requires": { -+ "mdast-util-to-string": "1.0.4", -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-no-emphasis-as-heading": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-no-emphasis-as-heading/-/remark-lint-no-emphasis-as-heading-1.0.1.tgz", -+ "integrity": "sha512-+x17Hrjwne4Mhk2x/Zolnuv/sOclF1oYMDBSEYhBUpn/UAwxhXEXYKkeo0KkWA7Q3+UCLELJvzsk4cGNP6Sgow==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-no-file-name-articles": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-1.0.1.tgz", -+ "integrity": "sha512-SzebnFnilrsINA6QZP1YqPa3SrfSotrLkRWl5FUCoVshBvEFNKJFWXj6Xyt4NjWQ5tJWFtOMysAuHdGT+Odhjg==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2" -+ } -+ }, -+ "remark-lint-no-file-name-consecutive-dashes": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-1.0.1.tgz", -+ "integrity": "sha512-YP2HBwA00yeD7phvxp4ftiqbfBPfYHPgPfcEcb8oNa1WlUh/58cs9DbSHWKsZG+XLkvEaheC6qUQG02jEKZHPA==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2" -+ } -+ }, -+ "remark-lint-no-file-name-irregular-characters": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-irregular-characters/-/remark-lint-no-file-name-irregular-characters-1.0.1.tgz", -+ "integrity": "sha512-+ks/V6OVMGOPZKw+fe2E4DPvLoslGxvdgtqXq2Nyz0cEdYX8RP45kI79V4w95H7UCJAeOFM9mZzVLvmCY1sEbg==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2" -+ } -+ }, -+ "remark-lint-no-file-name-mixed-case": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-mixed-case/-/remark-lint-no-file-name-mixed-case-1.0.1.tgz", -+ "integrity": "sha512-bcqPsow1C0LrsKII1YehUO7VPOER7nze6FzsZZ8/NP+d200OL7Y7VMCqN1kscAvG+PTJgjznyXuLEpy7KQnVFg==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2" -+ } -+ }, -+ "remark-lint-no-file-name-outer-dashes": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-1.0.2.tgz", -+ "integrity": "sha512-BVEwLrA4kipalgKrxhncpgtmh6eUmHBH1ggC+X3csYR4X5vXv4vHQqpov4I1vMyWxMLMBnq7lTL3Iqp0CS4vwg==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2" -+ } -+ }, -+ "remark-lint-no-heading-punctuation": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-no-heading-punctuation/-/remark-lint-no-heading-punctuation-1.0.1.tgz", -+ "integrity": "sha512-/7kGRmPT+JLxEME1Z/rQn99mP8yr4qXFwcniKYsefR1jl8pCZciwCIp2Tq92Nn+FPELVrpk9sloRBb2JP3UB0A==", -+ "dev": true, -+ "requires": { -+ "mdast-util-to-string": "1.0.4", -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-no-inline-padding": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-1.0.1.tgz", -+ "integrity": "sha512-nRl6vA45ZPdMz3/rVMZw7WRRqLFuMrzhdkrbrGLjwBovdIeD/IGCEbDA5NR60g2xT9V5dAmKogvHEH1bIr8SdQ==", -+ "dev": true, -+ "requires": { -+ "mdast-util-to-string": "1.0.4", -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-no-literal-urls": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-1.0.1.tgz", -+ "integrity": "sha512-YMsZFVYQDt9gvpc6THL76GzyhCR+cK79vjyEOEmX+O3tOjxQstbi0oW6Lngbl1WbpkCW5TWEzSKOorQowYI2wg==", -+ "dev": true, -+ "requires": { -+ "mdast-util-to-string": "1.0.4", -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-no-multiple-toplevel-headings": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-1.0.1.tgz", -+ "integrity": "sha512-LFfgjF3NKFkt0tGNnJ8Exf8+DrVcMRwek5qu5mvh2KrZnmSpm5flYWzUy2UnnIyicDL3CZYC/r3Fjz6CeBYgZA==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-no-shell-dollars": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-1.0.1.tgz", -+ "integrity": "sha512-YryHem73PTxjCkuC4HONJWHsmrLyXmF7r+cCH36Ys3vuWsfAbwkbOwpyuPB4KXn+6fHaTUfz/B5BPp3iwzJwyA==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-no-shortcut-reference-image": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-1.0.1.tgz", -+ "integrity": "sha512-nUQ+4xB5hKZTCl9gvg7c+W1T3ddsnjgu4zwRza2Bn+21cKmUzx+z9dvlZ4aVuNGmxuWHbKI8/ZkKuB8Eu27vJw==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-no-shortcut-reference-link": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-1.0.2.tgz", -+ "integrity": "sha512-A6ZexZ6XyQ7fXebrj5WgW5FkSJ81GobjWyMFVmBxgxPd9GH2BkRsZ10aFSkQQvfKSrqbnOL2vrigGMgbiERRxA==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-no-table-indentation": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-1.0.1.tgz", -+ "integrity": "sha512-QrtT1GvJmAoNsWh+gmHFajFlM+ubm9rd3Cbz2OYPix8ZM6g907aIfG2NusJFXL9D8/CExQWYhlBvelFBbHgqbQ==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-ordered-list-marker-style": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-1.0.1.tgz", -+ "integrity": "sha512-LJICUZIxqHHi360EP90zbDP+2QQIVVgPGlz0AatuR9ifd7xqAzraQKxsQajAZpuOepZgjBMTOz9L9W0Znx7ujA==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-ordered-list-marker-value": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-value/-/remark-lint-ordered-list-marker-value-1.0.1.tgz", -+ "integrity": "sha512-P6fYui3MvuB21+6AYH8Lbe7SVZ2VQL+FVJUuDCBhe01bgx6SajGmQ/f4Iqt0gCHEAaKw7e2B7tdwd36ifbs1EA==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-rule-style": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-1.0.1.tgz", -+ "integrity": "sha512-dzH+K6DcPIIMBq6LUQgE4dR9TiQGZrQOoULD7m0Y0lIb2EoR2FK5Zd4TgZg/LnvTs6fid37t0xFoaY4/lXV/5Q==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-strong-marker": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-1.0.1.tgz", -+ "integrity": "sha512-+bwWKWAqDwqd21Vw+ndqVFh5V27Dp4MKhk9AUlKmcvgJYHuvQ8UfWQdpZcP218ps/4EbwTfyi33TaPyXqOTlXA==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-table-cell-padding": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-1.0.1.tgz", -+ "integrity": "sha512-o3WwC9YysXbQKf0D5nvhhJPcLagqedLwGdifukdgyaKvuIQVbtWbNv1/UOdB3LL+D+2fUrwrCmnQ8J3E1r0lBw==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-table-pipe-alignment": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-table-pipe-alignment/-/remark-lint-table-pipe-alignment-1.0.1.tgz", -+ "integrity": "sha512-lYfK2gWGN45hYfAOZw5gscQ4uDaO9bJLp+H64jvrTQzBV+OCvB9kRQwI0oIrJAa4XMmipAZR+2XhjNSCfQ0fRA==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-table-pipes": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-1.0.1.tgz", -+ "integrity": "sha512-VHfDRvcovLBl/cvSjwDoA0xRizdZU33A6F2qFD9A5hu1sDWgGxMLg5m2MOvFlRkUVxSwUv47cuD0/yxB4THYXQ==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-lint-unordered-list-marker-style": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-1.0.1.tgz", -+ "integrity": "sha512-dHYD9cHM9ZJ7BKUZ1nEPGfLAHgUmYxccXtms1GSEM/uyUtR2SU/ao1RwZZ+LvacZFCNZ1yG2yKCJhGI/5U/GrA==", -+ "dev": true, -+ "requires": { -+ "unified-lint-rule": "1.0.2", -+ "unist-util-generated": "1.1.2", -+ "unist-util-position": "3.0.1", -+ "unist-util-visit": "1.3.1" -+ } -+ }, -+ "remark-message-control": { -+ "version": "4.1.0", -+ "resolved": "https://registry.npmjs.org/remark-message-control/-/remark-message-control-4.1.0.tgz", -+ "integrity": "sha512-e1dszks4YKY7hLAkhS2367jBjBpAfvi+kVgSN/tOFrdp3qxITjiNR5fOFnyYF8vvorkQ9uxlKJoZUOW8T7rKDg==", -+ "dev": true, -+ "requires": { -+ "mdast-comment-marker": "1.0.2", -+ "unified-message-control": "1.0.4", -+ "xtend": "4.0.1" -+ } -+ }, -+ "remark-parse": { -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-4.0.0.tgz", -+ "integrity": "sha512-XZgICP2gJ1MHU7+vQaRM+VA9HEL3X253uwUM/BGgx3iv6TH2B3bF3B8q00DKcyP9YrJV+/7WOWEWBFF/u8cIsw==", -+ "dev": true, -+ "requires": { -+ "collapse-white-space": "1.0.4", -+ "is-alphabetical": "1.0.2", -+ "is-decimal": "1.0.2", -+ "is-whitespace-character": "1.0.2", -+ "is-word-character": "1.0.2", -+ "markdown-escapes": "1.0.2", -+ "parse-entities": "1.1.2", -+ "repeat-string": "1.6.1", -+ "state-toggle": "1.0.1", -+ "trim": "0.0.1", -+ "trim-trailing-lines": "1.1.1", -+ "unherit": "1.1.1", -+ "unist-util-remove-position": "1.1.2", -+ "vfile-location": "2.0.3", -+ "xtend": "4.0.1" -+ } -+ }, -+ "remark-preset-lint-markdown-style-guide": { -+ "version": "2.1.1", -+ "resolved": "https://registry.npmjs.org/remark-preset-lint-markdown-style-guide/-/remark-preset-lint-markdown-style-guide-2.1.1.tgz", -+ "integrity": "sha512-Ao6fB63WuGtz1fa4rjoI+u1EOu21rWVGPmJlUKZlCICPPB6I815nJ52V0sLYjaw2cs+ZiXsXhdVinN7UpVgXcQ==", -+ "dev": true, -+ "requires": { -+ "remark-lint": "6.0.1", -+ "remark-lint-blockquote-indentation": "1.0.1", -+ "remark-lint-code-block-style": "1.0.1", -+ "remark-lint-definition-case": "1.0.1", -+ "remark-lint-definition-spacing": "1.0.1", -+ "remark-lint-emphasis-marker": "1.0.1", -+ "remark-lint-fenced-code-flag": "1.0.1", -+ "remark-lint-fenced-code-marker": "1.0.1", -+ "remark-lint-file-extension": "1.0.1", -+ "remark-lint-final-definition": "1.0.1", -+ "remark-lint-hard-break-spaces": "1.0.2", -+ "remark-lint-heading-increment": "1.0.1", -+ "remark-lint-heading-style": "1.0.1", -+ "remark-lint-link-title-style": "1.0.1", -+ "remark-lint-list-item-content-indent": "1.0.1", -+ "remark-lint-list-item-indent": "1.0.1", -+ "remark-lint-list-item-spacing": "1.1.1", -+ "remark-lint-maximum-heading-length": "1.0.1", -+ "remark-lint-maximum-line-length": "1.0.2", -+ "remark-lint-no-auto-link-without-protocol": "1.0.1", -+ "remark-lint-no-blockquote-without-marker": "2.0.1", -+ "remark-lint-no-consecutive-blank-lines": "1.0.1", -+ "remark-lint-no-duplicate-headings": "1.0.1", -+ "remark-lint-no-emphasis-as-heading": "1.0.1", -+ "remark-lint-no-file-name-articles": "1.0.1", -+ "remark-lint-no-file-name-consecutive-dashes": "1.0.1", -+ "remark-lint-no-file-name-irregular-characters": "1.0.1", -+ "remark-lint-no-file-name-mixed-case": "1.0.1", -+ "remark-lint-no-file-name-outer-dashes": "1.0.2", -+ "remark-lint-no-heading-punctuation": "1.0.1", -+ "remark-lint-no-inline-padding": "1.0.1", -+ "remark-lint-no-literal-urls": "1.0.1", -+ "remark-lint-no-multiple-toplevel-headings": "1.0.1", -+ "remark-lint-no-shell-dollars": "1.0.1", -+ "remark-lint-no-shortcut-reference-image": "1.0.1", -+ "remark-lint-no-shortcut-reference-link": "1.0.2", -+ "remark-lint-no-table-indentation": "1.0.1", -+ "remark-lint-ordered-list-marker-style": "1.0.1", -+ "remark-lint-ordered-list-marker-value": "1.0.1", -+ "remark-lint-rule-style": "1.0.1", -+ "remark-lint-strong-marker": "1.0.1", -+ "remark-lint-table-cell-padding": "1.0.1", -+ "remark-lint-table-pipe-alignment": "1.0.1", -+ "remark-lint-table-pipes": "1.0.1", -+ "remark-lint-unordered-list-marker-style": "1.0.1" -+ } -+ }, -+ "remark-stringify": { -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-4.0.0.tgz", -+ "integrity": "sha512-xLuyKTnuQer3ke9hkU38SUYLiTmS078QOnoFavztmbt/pAJtNSkNtFgR0U//uCcmG0qnyxao+PDuatQav46F1w==", -+ "dev": true, -+ "requires": { -+ "ccount": "1.0.3", -+ "is-alphanumeric": "1.0.0", -+ "is-decimal": "1.0.2", -+ "is-whitespace-character": "1.0.2", -+ "longest-streak": "2.0.2", -+ "markdown-escapes": "1.0.2", -+ "markdown-table": "1.1.2", -+ "mdast-util-compact": "1.0.1", -+ "parse-entities": "1.1.2", -+ "repeat-string": "1.6.1", -+ "state-toggle": "1.0.1", -+ "stringify-entities": "1.3.2", -+ "unherit": "1.1.1", -+ "xtend": "4.0.1" -+======= -+ "object.omit": { -+ "version": "2.0.1", -+ "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", -+ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", -+ "dev": true, -+ "requires": { -+ "for-own": "0.1.5", -+ "is-extendable": "0.1.1" -+ } -+ }, -+ "once": { -+ "version": "1.4.0", -+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", -+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", -+ "dev": true, -+ "requires": { -+ "wrappy": "1.0.2" -+ } -+ }, -+ "onetime": { -+ "version": "1.1.0", -+ "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", -+ "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", -+ "dev": true -+ }, -+ "optimist": { -+ "version": "0.3.7", -+ "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", -+ "integrity": "sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=", -+ "dev": true, -+ "requires": { -+ "wordwrap": "0.0.3" -+ } -+ }, -+ "optionator": { -+ "version": "0.8.2", -+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", -+ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", -+ "dev": true, -+ "requires": { -+ "deep-is": "0.1.3", -+ "fast-levenshtein": "2.0.6", -+ "levn": "0.3.0", -+ "prelude-ls": "1.1.2", -+ "type-check": "0.3.2", -+ "wordwrap": "1.0.0" -+ }, -+ "dependencies": { -+ "wordwrap": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", -+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", -+ "dev": true -+ } -+ } -+ }, -+ "ora": { -+ "version": "0.3.0", -+ "resolved": "https://registry.npmjs.org/ora/-/ora-0.3.0.tgz", -+ "integrity": "sha1-NnoHitJc+wltpQERXrW0AeB9dJU=", -+ "dev": true, -+ "requires": { -+ "chalk": "1.1.3", -+ "cli-cursor": "1.0.2", -+ "cli-spinners": "0.2.0", -+ "log-symbols": "1.0.2" -+ }, -+ "dependencies": { -+ "cli-spinners": { -+ "version": "0.2.0", -+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.2.0.tgz", -+ "integrity": "sha1-hQeHN5E7iA9uyf/ntl6D7Hd2KE8=", -+ "dev": true -+ } -+ } -+ }, -+ "os-browserify": { -+ "version": "0.1.2", -+ "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.1.2.tgz", -+ "integrity": "sha1-ScoCk+CxlZCl9d4Qx/JlphfY/lQ=", -+ "dev": true -+ }, -+ "os-homedir": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", -+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", -+ "dev": true -+ }, -+ "os-locale": { -+ "version": "1.4.0", -+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", -+ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", -+ "dev": true, -+ "requires": { -+ "lcid": "1.0.0" -+ } -+ }, -+ "os-tmpdir": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", -+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", -+ "dev": true -+ }, -+ "p-finally": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", -+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", -+ "dev": true -+ }, -+ "p-limit": { -+ "version": "1.2.0", -+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", -+ "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", -+ "dev": true, -+ "requires": { -+ "p-try": "1.0.0" -+ } -+ }, -+ "p-locate": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", -+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", -+ "dev": true, -+ "requires": { -+ "p-limit": "1.2.0" -+ } -+ }, -+ "p-try": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", -+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", -+ "dev": true -+ }, -+ "package-json": { -+ "version": "4.0.1", -+ "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", -+ "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", -+ "dev": true, -+ "requires": { -+ "got": "6.7.1", -+ "registry-auth-token": "3.3.2", -+ "registry-url": "3.1.0", -+ "semver": "5.5.0" -+ } -+ }, -+ "pako": { -+ "version": "0.2.9", -+ "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", -+ "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", -+ "dev": true -+ }, -+ "parents": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", -+ "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", -+ "dev": true, -+ "requires": { -+ "path-platform": "0.11.15" -+ } -+ }, -+ "parse-asn1": { -+ "version": "5.1.0", -+ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", -+ "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", -+ "dev": true, -+ "requires": { -+ "asn1.js": "4.10.1", -+ "browserify-aes": "1.1.1", -+ "create-hash": "1.1.3", -+ "evp_bytestokey": "1.0.3", -+ "pbkdf2": "3.0.14" -+ } -+ }, -+ "parse-github-repo-url": { -+ "version": "1.4.1", -+ "resolved": "https://registry.npmjs.org/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz", -+ "integrity": "sha1-nn2LslKmy2ukJZUGC3v23z28H1A=", -+ "dev": true -+ }, -+ "parse-gitignore": { -+ "version": "0.4.0", -+ "resolved": "https://registry.npmjs.org/parse-gitignore/-/parse-gitignore-0.4.0.tgz", -+ "integrity": "sha1-q/cC5LkAUk//eQK2g4YoV7Y/k/4=", -+ "dev": true, -+ "requires": { -+ "array-unique": "0.3.2", -+ "is-glob": "3.1.0" -+ }, -+ "dependencies": { -+ "array-unique": { -+ "version": "0.3.2", -+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", -+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", -+ "dev": true -+ }, -+ "is-extglob": { -+ "version": "2.1.1", -+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", -+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", -+ "dev": true -+ }, -+ "is-glob": { -+ "version": "3.1.0", -+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", -+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", -+ "dev": true, -+ "requires": { -+ "is-extglob": "2.1.1" -+ } -+ } -+ } -+ }, -+ "parse-glob": { -+ "version": "3.0.4", -+ "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", -+ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", -+ "dev": true, -+ "requires": { -+ "glob-base": "0.3.0", -+ "is-dotfile": "1.0.3", -+ "is-extglob": "1.0.0", -+ "is-glob": "2.0.1" -+ } -+ }, -+ "parse-json": { -+ "version": "2.2.0", -+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", -+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", -+ "dev": true, -+ "requires": { -+ "error-ex": "1.3.1" -+ } -+ }, -+ "parse5": { -+ "version": "1.5.1", -+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", -+ "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", -+ "dev": true, -+ "optional": true -+ }, -+ "path-browserify": { -+ "version": "0.0.0", -+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", -+ "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", -+ "dev": true -+ }, -+ "path-exists": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", -+ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", -+ "dev": true, -+ "requires": { -+ "pinkie-promise": "2.0.1" -+ } -+ }, -+ "path-is-absolute": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", -+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", -+ "dev": true -+ }, -+ "path-is-inside": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", -+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", -+ "dev": true -+ }, -+ "path-key": { -+ "version": "2.0.1", -+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", -+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", -+ "dev": true -+ }, -+ "path-parse": { -+ "version": "1.0.5", -+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", -+ "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", -+ "dev": true -+ }, -+ "path-platform": { -+ "version": "0.11.15", -+ "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", -+ "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", -+ "dev": true -+ }, -+ "path-type": { -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", -+ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", -+ "dev": true, -+ "requires": { -+ "graceful-fs": "4.1.11", -+ "pify": "2.3.0", -+ "pinkie-promise": "2.0.1" -+ } -+ }, -+ "pbkdf2": { -+ "version": "3.0.14", -+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", -+ "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", -+ "dev": true, -+ "requires": { -+ "create-hash": "1.1.3", -+ "create-hmac": "1.1.6", -+ "ripemd160": "2.0.1", -+ "safe-buffer": "5.1.1", -+ "sha.js": "2.4.10" -+ } -+ }, -+ "peek-stream": { -+ "version": "1.1.2", -+ "resolved": "https://registry.npmjs.org/peek-stream/-/peek-stream-1.1.2.tgz", -+ "integrity": "sha1-l+t2NlvP2MieKH9VyLadTD6bzFI=", -+ "dev": true, -+ "requires": { -+ "duplexify": "3.5.4", -+ "through2": "2.0.3" -+ } -+ }, -+ "performance-now": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", -+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", -+ "dev": true -+ }, -+ "pify": { -+ "version": "2.3.0", -+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", -+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", -+ "dev": true -+ }, -+ "pinkie": { -+ "version": "2.0.4", -+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", -+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", -+ "dev": true -+ }, -+ "pinkie-promise": { -+ "version": "2.0.1", -+ "resolved": "http://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", -+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", -+ "dev": true, -+ "requires": { -+ "pinkie": "2.0.4" -+ } -+ }, -+ "pkg-conf": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", -+ "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=", -+ "dev": true, -+ "requires": { -+ "find-up": "2.1.0", -+ "load-json-file": "4.0.0" -+ }, -+ "dependencies": { -+ "find-up": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", -+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", -+ "dev": true, -+ "requires": { -+ "locate-path": "2.0.0" -+ } -+ }, -+ "load-json-file": { -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", -+ "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", -+ "dev": true, -+ "requires": { -+ "graceful-fs": "4.1.11", -+ "parse-json": "4.0.0", -+ "pify": "3.0.0", -+ "strip-bom": "3.0.0" -+ } -+ }, -+ "parse-json": { -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", -+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", -+ "dev": true, -+ "requires": { -+ "error-ex": "1.3.1", -+ "json-parse-better-errors": "1.0.1" -+ } -+ }, -+ "pify": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", -+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", -+ "dev": true -+ }, -+ "strip-bom": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", -+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", -+ "dev": true -+ } -+ } -+ }, -+ "pkg-config": { -+ "version": "1.1.1", -+ "resolved": "https://registry.npmjs.org/pkg-config/-/pkg-config-1.1.1.tgz", -+ "integrity": "sha1-VX7yLXPaPIg3EHdmxS6tq94pj+Q=", -+ "dev": true, -+ "requires": { -+ "debug-log": "1.0.1", -+ "find-root": "1.1.0", -+ "xtend": "4.0.1" -+ } -+ }, -+ "pkg-dir": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", -+ "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", -+ "dev": true, -+ "requires": { -+ "find-up": "1.1.2" -+ } -+ }, -+ "pkg-up": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", -+ "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", -+ "dev": true, -+ "requires": { -+ "find-up": "1.1.2" -+ } -+ }, -+ "pluralize": { -+ "version": "1.2.1", -+ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", -+ "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", -+ "dev": true -+ }, -+ "prelude-ls": { -+ "version": "1.1.2", -+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", -+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", -+ "dev": true -+ }, -+ "prepend-http": { -+ "version": "1.0.4", -+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", -+ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", -+ "dev": true -+ }, -+ "preserve": { -+ "version": "0.2.0", -+ "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", -+ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", -+ "dev": true -+ }, -+ "pretty-bytes": { -+ "version": "1.0.4", -+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz", -+ "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", -+ "dev": true, -+ "requires": { -+ "get-stdin": "4.0.1", -+ "meow": "3.7.0" -+ }, -+ "dependencies": { -+ "camelcase": { -+ "version": "2.1.1", -+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", -+ "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", -+ "dev": true -+ }, -+ "camelcase-keys": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", -+ "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", -+ "dev": true, -+ "requires": { -+ "camelcase": "2.1.1", -+ "map-obj": "1.0.1" -+ } -+ }, -+ "indent-string": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", -+ "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", -+ "dev": true, -+ "requires": { -+ "repeating": "2.0.1" -+ } -+ }, -+ "map-obj": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", -+ "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", -+ "dev": true -+ }, -+ "meow": { -+ "version": "3.7.0", -+ "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", -+ "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", -+ "dev": true, -+ "requires": { -+ "camelcase-keys": "2.1.0", -+ "decamelize": "1.2.0", -+ "loud-rejection": "1.6.0", -+ "map-obj": "1.0.1", -+ "minimist": "1.2.0", -+ "normalize-package-data": "2.4.0", -+ "object-assign": "4.1.1", -+ "read-pkg-up": "1.0.1", -+ "redent": "1.0.0", -+ "trim-newlines": "1.0.0" -+ } -+ }, -+ "redent": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", -+ "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", -+ "dev": true, -+ "requires": { -+ "indent-string": "2.1.0", -+ "strip-indent": "1.0.1" -+ } -+ }, -+ "strip-indent": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", -+ "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", -+ "dev": true, -+ "requires": { -+ "get-stdin": "4.0.1" -+ } -+ }, -+ "trim-newlines": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", -+ "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", -+ "dev": true -+ } -+ } -+ }, -+ "process": { -+ "version": "0.11.10", -+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", -+ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", -+ "dev": true -+ }, -+ "process-nextick-args": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", -+ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", -+ "dev": true -+ }, -+ "progress": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", -+ "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", -+ "dev": true -+ }, -+ "progress-stream": { -+ "version": "1.2.0", -+ "resolved": "https://registry.npmjs.org/progress-stream/-/progress-stream-1.2.0.tgz", -+ "integrity": "sha1-LNPP6jO6OonJwSHsM0er6asSX3c=", -+ "dev": true, -+ "requires": { -+ "speedometer": "0.1.4", -+ "through2": "0.2.3" -+ }, -+ "dependencies": { -+ "through2": { -+ "version": "0.2.3", -+ "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz", -+ "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=", -+ "dev": true, -+ "requires": { -+ "readable-stream": "1.1.14", -+ "xtend": "2.1.2" -+ } -+ }, -+ "xtend": { -+ "version": "2.1.2", -+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", -+ "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", -+ "dev": true, -+ "requires": { -+ "object-keys": "0.4.0" -+ } -+ } -+ } -+ }, -+ "pseudomap": { -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", -+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", -+ "dev": true -+ }, -+ "public-encrypt": { -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", -+ "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", -+ "dev": true, -+ "requires": { -+ "bn.js": "4.11.8", -+ "browserify-rsa": "4.0.1", -+ "create-hash": "1.1.3", -+ "parse-asn1": "5.1.0", -+ "randombytes": "2.0.6" -+ } -+ }, -+ "pump": { -+ "version": "2.0.1", -+ "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", -+ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-visit": "1.3.1" -+ "end-of-stream": "1.4.1", -+ "once": "1.4.0" - } - }, -- "remark-lint-no-shortcut-reference-image": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-1.0.1.tgz", -- "integrity": "sha512-nUQ+4xB5hKZTCl9gvg7c+W1T3ddsnjgu4zwRza2Bn+21cKmUzx+z9dvlZ4aVuNGmxuWHbKI8/ZkKuB8Eu27vJw==", -+ "pumpify": { -+ "version": "1.4.0", -+ "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.4.0.tgz", -+ "integrity": "sha512-2kmNR9ry+Pf45opRVirpNuIFotsxUGLaYqxIwuR77AYrYRMuFCz9eryHBS52L360O+NcR383CL4QYlMKPq4zYA==", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-visit": "1.3.1" -+ "duplexify": "3.5.4", -+ "inherits": "2.0.3", -+ "pump": "2.0.1" - } - }, -- "remark-lint-no-shortcut-reference-link": { -- "version": "1.0.2", -- "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-1.0.2.tgz", -- "integrity": "sha512-A6ZexZ6XyQ7fXebrj5WgW5FkSJ81GobjWyMFVmBxgxPd9GH2BkRsZ10aFSkQQvfKSrqbnOL2vrigGMgbiERRxA==", -+ "punycode": { -+ "version": "1.4.1", -+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", -+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", -+ "dev": true -+ }, -+ "q": { -+ "version": "1.5.1", -+ "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", -+ "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", -+ "dev": true -+ }, -+ "qs": { -+ "version": "6.5.1", -+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", -+ "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", -+ "dev": true -+ }, -+ "querystring": { -+ "version": "0.2.0", -+ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", -+ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", -+ "dev": true -+ }, -+ "querystring-es3": { -+ "version": "0.2.1", -+ "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", -+ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", -+ "dev": true -+ }, -+ "quick-lru": { -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", -+ "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", -+ "dev": true -+ }, -+ "randomatic": { -+ "version": "1.1.7", -+ "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", -+ "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-visit": "1.3.1" -+ "is-number": "3.0.0", -+ "kind-of": "4.0.0" -+ }, -+ "dependencies": { -+ "is-number": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", -+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", -+ "dev": true, -+ "requires": { -+ "kind-of": "3.2.2" -+ }, -+ "dependencies": { -+ "kind-of": { -+ "version": "3.2.2", -+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", -+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", -+ "dev": true, -+ "requires": { -+ "is-buffer": "1.1.6" -+ } -+ } -+ } -+ }, -+ "kind-of": { -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", -+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", -+ "dev": true, -+ "requires": { -+ "is-buffer": "1.1.6" -+ } -+ } - } - }, -- "remark-lint-no-table-indentation": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-1.0.1.tgz", -- "integrity": "sha512-QrtT1GvJmAoNsWh+gmHFajFlM+ubm9rd3Cbz2OYPix8ZM6g907aIfG2NusJFXL9D8/CExQWYhlBvelFBbHgqbQ==", -+ "randombytes": { -+ "version": "2.0.6", -+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", -+ "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "safe-buffer": "5.1.1" - } - }, -- "remark-lint-ordered-list-marker-style": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-1.0.1.tgz", -- "integrity": "sha512-LJICUZIxqHHi360EP90zbDP+2QQIVVgPGlz0AatuR9ifd7xqAzraQKxsQajAZpuOepZgjBMTOz9L9W0Znx7ujA==", -+ "randomfill": { -+ "version": "1.0.4", -+ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", -+ "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "randombytes": "2.0.6", -+ "safe-buffer": "5.1.1" - } - }, -- "remark-lint-ordered-list-marker-value": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-value/-/remark-lint-ordered-list-marker-value-1.0.1.tgz", -- "integrity": "sha512-P6fYui3MvuB21+6AYH8Lbe7SVZ2VQL+FVJUuDCBhe01bgx6SajGmQ/f4Iqt0gCHEAaKw7e2B7tdwd36ifbs1EA==", -+ "rc": { -+ "version": "1.2.6", -+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.6.tgz", -+ "integrity": "sha1-6xiYnG1PTxYsOZ953dKfODVWgJI=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "deep-extend": "0.4.2", -+ "ini": "1.3.5", -+ "minimist": "1.2.0", -+ "strip-json-comments": "2.0.1" - } - }, -- "remark-lint-rule-style": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-1.0.1.tgz", -- "integrity": "sha512-dzH+K6DcPIIMBq6LUQgE4dR9TiQGZrQOoULD7m0Y0lIb2EoR2FK5Zd4TgZg/LnvTs6fid37t0xFoaY4/lXV/5Q==", -+ "read-only-stream": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", -+ "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "readable-stream": "2.3.5" -+ }, -+ "dependencies": { -+ "isarray": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", -+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", -+ "dev": true -+ }, -+ "readable-stream": { -+ "version": "2.3.5", -+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", -+ "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", -+ "dev": true, -+ "requires": { -+ "core-util-is": "1.0.2", -+ "inherits": "2.0.3", -+ "isarray": "1.0.0", -+ "process-nextick-args": "2.0.0", -+ "safe-buffer": "5.1.1", -+ "string_decoder": "1.0.3", -+ "util-deprecate": "1.0.2" -+ } -+ }, -+ "string_decoder": { -+ "version": "1.0.3", -+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", -+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", -+ "dev": true, -+ "requires": { -+ "safe-buffer": "5.1.1" -+ } -+ } - } - }, -- "remark-lint-strong-marker": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-1.0.1.tgz", -- "integrity": "sha512-+bwWKWAqDwqd21Vw+ndqVFh5V27Dp4MKhk9AUlKmcvgJYHuvQ8UfWQdpZcP218ps/4EbwTfyi33TaPyXqOTlXA==", -+ "read-pkg": { -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", -+ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "load-json-file": "1.1.0", -+ "normalize-package-data": "2.4.0", -+ "path-type": "1.1.0" - } - }, -- "remark-lint-table-cell-padding": { -+ "read-pkg-up": { - "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-1.0.1.tgz", -- "integrity": "sha512-o3WwC9YysXbQKf0D5nvhhJPcLagqedLwGdifukdgyaKvuIQVbtWbNv1/UOdB3LL+D+2fUrwrCmnQ8J3E1r0lBw==", -+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", -+ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "find-up": "1.1.2", -+ "read-pkg": "1.1.0" - } - }, -- "remark-lint-table-pipe-alignment": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-table-pipe-alignment/-/remark-lint-table-pipe-alignment-1.0.1.tgz", -- "integrity": "sha512-lYfK2gWGN45hYfAOZw5gscQ4uDaO9bJLp+H64jvrTQzBV+OCvB9kRQwI0oIrJAa4XMmipAZR+2XhjNSCfQ0fRA==", -+ "readable-stream": { -+ "version": "1.1.14", -+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", -+ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "core-util-is": "1.0.2", -+ "inherits": "2.0.3", -+ "isarray": "0.0.1", -+ "string_decoder": "0.10.31" - } - }, -- "remark-lint-table-pipes": { -+ "readline2": { - "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-1.0.1.tgz", -- "integrity": "sha512-VHfDRvcovLBl/cvSjwDoA0xRizdZU33A6F2qFD9A5hu1sDWgGxMLg5m2MOvFlRkUVxSwUv47cuD0/yxB4THYXQ==", -+ "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", -+ "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "code-point-at": "1.1.0", -+ "is-fullwidth-code-point": "1.0.0", -+ "mute-stream": "0.0.5" - } - }, -- "remark-lint-unordered-list-marker-style": { -- "version": "1.0.1", -- "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-1.0.1.tgz", -- "integrity": "sha512-dHYD9cHM9ZJ7BKUZ1nEPGfLAHgUmYxccXtms1GSEM/uyUtR2SU/ao1RwZZ+LvacZFCNZ1yG2yKCJhGI/5U/GrA==", -+ "rechoir": { -+ "version": "0.6.2", -+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", -+ "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { -- "unified-lint-rule": "1.0.2", -- "unist-util-generated": "1.1.2", -- "unist-util-position": "3.0.1", -- "unist-util-visit": "1.3.1" -+ "resolve": "1.5.0" - } - }, -- "remark-message-control": { -- "version": "4.1.0", -- "resolved": "https://registry.npmjs.org/remark-message-control/-/remark-message-control-4.1.0.tgz", -- "integrity": "sha512-e1dszks4YKY7hLAkhS2367jBjBpAfvi+kVgSN/tOFrdp3qxITjiNR5fOFnyYF8vvorkQ9uxlKJoZUOW8T7rKDg==", -+ "redent": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", -+ "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", - "dev": true, - "requires": { -- "mdast-comment-marker": "1.0.2", -- "unified-message-control": "1.0.4", -- "xtend": "4.0.1" -+ "indent-string": "3.2.0", -+ "strip-indent": "2.0.0" - } - }, -- "remark-parse": { -- "version": "4.0.0", -- "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-4.0.0.tgz", -- "integrity": "sha512-XZgICP2gJ1MHU7+vQaRM+VA9HEL3X253uwUM/BGgx3iv6TH2B3bF3B8q00DKcyP9YrJV+/7WOWEWBFF/u8cIsw==", -- "dev": true, -- "requires": { -- "collapse-white-space": "1.0.4", -- "is-alphabetical": "1.0.2", -- "is-decimal": "1.0.2", -- "is-whitespace-character": "1.0.2", -- "is-word-character": "1.0.2", -- "markdown-escapes": "1.0.2", -- "parse-entities": "1.1.2", -- "repeat-string": "1.6.1", -- "state-toggle": "1.0.1", -- "trim": "0.0.1", -- "trim-trailing-lines": "1.1.1", -- "unherit": "1.1.1", -- "unist-util-remove-position": "1.1.2", -- "vfile-location": "2.0.3", -- "xtend": "4.0.1" -+ "regex-cache": { -+ "version": "0.4.4", -+ "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", -+ "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", -+ "dev": true, -+ "requires": { -+ "is-equal-shallow": "0.1.3" - } - }, -- "remark-preset-lint-markdown-style-guide": { -- "version": "2.1.1", -- "resolved": "https://registry.npmjs.org/remark-preset-lint-markdown-style-guide/-/remark-preset-lint-markdown-style-guide-2.1.1.tgz", -- "integrity": "sha512-Ao6fB63WuGtz1fa4rjoI+u1EOu21rWVGPmJlUKZlCICPPB6I815nJ52V0sLYjaw2cs+ZiXsXhdVinN7UpVgXcQ==", -+ "registry-auth-token": { -+ "version": "3.3.2", -+ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", -+ "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", - "dev": true, - "requires": { -- "remark-lint": "6.0.1", -- "remark-lint-blockquote-indentation": "1.0.1", -- "remark-lint-code-block-style": "1.0.1", -- "remark-lint-definition-case": "1.0.1", -- "remark-lint-definition-spacing": "1.0.1", -- "remark-lint-emphasis-marker": "1.0.1", -- "remark-lint-fenced-code-flag": "1.0.1", -- "remark-lint-fenced-code-marker": "1.0.1", -- "remark-lint-file-extension": "1.0.1", -- "remark-lint-final-definition": "1.0.1", -- "remark-lint-hard-break-spaces": "1.0.2", -- "remark-lint-heading-increment": "1.0.1", -- "remark-lint-heading-style": "1.0.1", -- "remark-lint-link-title-style": "1.0.1", -- "remark-lint-list-item-content-indent": "1.0.1", -- "remark-lint-list-item-indent": "1.0.1", -- "remark-lint-list-item-spacing": "1.1.1", -- "remark-lint-maximum-heading-length": "1.0.1", -- "remark-lint-maximum-line-length": "1.0.2", -- "remark-lint-no-auto-link-without-protocol": "1.0.1", -- "remark-lint-no-blockquote-without-marker": "2.0.1", -- "remark-lint-no-consecutive-blank-lines": "1.0.1", -- "remark-lint-no-duplicate-headings": "1.0.1", -- "remark-lint-no-emphasis-as-heading": "1.0.1", -- "remark-lint-no-file-name-articles": "1.0.1", -- "remark-lint-no-file-name-consecutive-dashes": "1.0.1", -- "remark-lint-no-file-name-irregular-characters": "1.0.1", -- "remark-lint-no-file-name-mixed-case": "1.0.1", -- "remark-lint-no-file-name-outer-dashes": "1.0.2", -- "remark-lint-no-heading-punctuation": "1.0.1", -- "remark-lint-no-inline-padding": "1.0.1", -- "remark-lint-no-literal-urls": "1.0.1", -- "remark-lint-no-multiple-toplevel-headings": "1.0.1", -- "remark-lint-no-shell-dollars": "1.0.1", -- "remark-lint-no-shortcut-reference-image": "1.0.1", -- "remark-lint-no-shortcut-reference-link": "1.0.2", -- "remark-lint-no-table-indentation": "1.0.1", -- "remark-lint-ordered-list-marker-style": "1.0.1", -- "remark-lint-ordered-list-marker-value": "1.0.1", -- "remark-lint-rule-style": "1.0.1", -- "remark-lint-strong-marker": "1.0.1", -- "remark-lint-table-cell-padding": "1.0.1", -- "remark-lint-table-pipe-alignment": "1.0.1", -- "remark-lint-table-pipes": "1.0.1", -- "remark-lint-unordered-list-marker-style": "1.0.1" -+ "rc": "1.2.6", -+ "safe-buffer": "5.1.1" - } - }, -- "remark-stringify": { -- "version": "4.0.0", -- "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-4.0.0.tgz", -- "integrity": "sha512-xLuyKTnuQer3ke9hkU38SUYLiTmS078QOnoFavztmbt/pAJtNSkNtFgR0U//uCcmG0qnyxao+PDuatQav46F1w==", -+ "registry-url": { -+ "version": "3.1.0", -+ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", -+ "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", - "dev": true, - "requires": { -- "ccount": "1.0.3", -- "is-alphanumeric": "1.0.0", -- "is-decimal": "1.0.2", -- "is-whitespace-character": "1.0.2", -- "longest-streak": "2.0.2", -- "markdown-escapes": "1.0.2", -- "markdown-table": "1.1.2", -- "mdast-util-compact": "1.0.1", -- "parse-entities": "1.1.2", -- "repeat-string": "1.6.1", -- "state-toggle": "1.0.1", -- "stringify-entities": "1.3.2", -- "unherit": "1.1.1", -- "xtend": "4.0.1" -+ "rc": "1.2.6" -+>>>>>>> .their - } - }, - "remove-trailing-separator": { -@@ -7954,12 +11727,15 @@ - "is-finite": "1.0.2" - } - }, -+<<<<<<< .our - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", - "dev": true - }, -+======= -+>>>>>>> .their - "request": { - "version": "2.85.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz", -@@ -7967,7 +11743,11 @@ - "dev": true, - "requires": { - "aws-sign2": "0.7.0", -+<<<<<<< .our - "aws4": "1.7.0", -+======= -+ "aws4": "1.6.0", -+>>>>>>> .their - "caseless": "0.12.0", - "combined-stream": "1.0.6", - "extend": "3.0.1", -@@ -7982,9 +11762,15 @@ - "mime-types": "2.1.18", - "oauth-sign": "0.8.2", - "performance-now": "2.1.0", -+<<<<<<< .our - "qs": "6.5.2", - "safe-buffer": "5.1.2", - "stringstream": "0.0.6", -+======= -+ "qs": "6.5.1", -+ "safe-buffer": "5.1.1", -+ "stringstream": "0.0.5", -+>>>>>>> .their - "tough-cookie": "2.3.4", - "tunnel-agent": "0.6.0", - "uuid": "3.2.1" -@@ -8010,6 +11796,7 @@ - "requires": { - "caller-path": "0.1.0", - "resolve-from": "1.0.1" -+<<<<<<< .our - }, - "dependencies": { - "resolve-from": { -@@ -8024,15 +11811,29 @@ - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", - "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", -+======= -+ } -+ }, -+ "resolve": { -+ "version": "1.5.0", -+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", -+ "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", -+>>>>>>> .their - "dev": true, - "requires": { - "path-parse": "1.0.5" - } - }, - "resolve-from": { -+<<<<<<< .our - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", -+======= -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", -+ "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", -+>>>>>>> .their - "dev": true - }, - "restore-cursor": { -@@ -8064,7 +11865,11 @@ - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", -+<<<<<<< .our - "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=", -+======= -+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", -+>>>>>>> .their - "dev": true, - "requires": { - "glob": "7.1.2" -@@ -8073,7 +11878,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -8087,12 +11896,21 @@ - } - }, - "ripemd160": { -+<<<<<<< .our - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "3.0.4", -+======= -+ "version": "2.0.1", -+ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", -+ "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", -+ "dev": true, -+ "requires": { -+ "hash-base": "2.0.2", -+>>>>>>> .their - "inherits": "2.0.3" - } - }, -@@ -8106,9 +11924,15 @@ - } - }, - "run-parallel": { -+<<<<<<< .our - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", -+======= -+ "version": "1.1.7", -+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.7.tgz", -+ "integrity": "sha512-nB641a6enJOh0fdsFHR9SiVCiOlAyjMplImDdjV3kWCzJZw9rwzvGwmpGuPmfX//Yxblh0pkzPcFcxA81iwmxA==", -+>>>>>>> .their - "dev": true - }, - "rx-lite": { -@@ -8118,15 +11942,25 @@ - "dev": true - }, - "safe-buffer": { -+<<<<<<< .our - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", -+======= -+ "version": "5.1.1", -+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", -+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", -+>>>>>>> .their - "dev": true - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", -+<<<<<<< .our - "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk=", -+======= -+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", -+>>>>>>> .their - "dev": true, - "optional": true - }, -@@ -8145,6 +11979,7 @@ - "semver": "5.5.0" - } - }, -+<<<<<<< .our - "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", -@@ -8294,12 +12129,15 @@ - } - } - }, -+======= -+>>>>>>> .their - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, -+<<<<<<< .our - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", -@@ -8320,6 +12158,16 @@ - "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.2" -+======= -+ "sha.js": { -+ "version": "2.4.10", -+ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.10.tgz", -+ "integrity": "sha512-vnwmrFDlOExK4Nm16J2KMWHLrp14lBrjxMxBJpu++EnsuBmpiYaM/MEs46Vxxm/4FvdP5yTwuCTO9it5FSjrqA==", -+ "dev": true, -+ "requires": { -+ "inherits": "2.0.3", -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - }, - "shasum": { -@@ -8329,7 +12177,11 @@ - "dev": true, - "requires": { - "json-stable-stringify": "0.0.1", -+<<<<<<< .our - "sha.js": "2.4.11" -+======= -+ "sha.js": "2.4.10" -+>>>>>>> .their - } - }, - "shebang-command": { -@@ -8373,7 +12225,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -8386,12 +12242,15 @@ - } - } - }, -+<<<<<<< .our - "shellsubstitute": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shellsubstitute/-/shellsubstitute-1.2.0.tgz", - "integrity": "sha1-5PcCpQxRiw9v6YRRiQ1wWvKba3A=", - "dev": true - }, -+======= -+>>>>>>> .their - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", -@@ -8413,12 +12272,15 @@ - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true - }, -+<<<<<<< .our - "sliced": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", - "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=", - "dev": true - }, -+======= -+>>>>>>> .their - "sntp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", -@@ -8475,7 +12337,11 @@ - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", -+<<<<<<< .our - "integrity": "sha1-YFvZvjA6pZ+zX5Ip++oN3snqB9k=", -+======= -+ "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", -+>>>>>>> .their - "dev": true, - "requires": { - "through": "2.3.8" -@@ -8484,7 +12350,11 @@ - "split2": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", -+<<<<<<< .our - "integrity": "sha1-GGsldbz4PoW30YRldWI47k7kJJM=", -+======= -+ "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", -+>>>>>>> .their - "dev": true, - "requires": { - "through2": "2.0.3" -@@ -8513,6 +12383,7 @@ - } - }, - "standard": { -+<<<<<<< .our - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/standard/-/standard-10.0.3.tgz", - "integrity": "sha512-JURZ+85ExKLQULckDFijdX5WHzN6RC7fgiZNSV4jFQVo+3tPoQGHyBrGekye/yf0aOfb4210EM5qPNlc2cRh4w==", -@@ -8539,6 +12410,34 @@ - "get-stdin": "5.0.1", - "minimist": "1.2.0", - "pkg-conf": "2.1.0" -+======= -+ "version": "8.6.0", -+ "resolved": "https://registry.npmjs.org/standard/-/standard-8.6.0.tgz", -+ "integrity": "sha1-Y1Eyvnv7VnwpIQBfMPnjUOR1Kq0=", -+ "dev": true, -+ "requires": { -+ "eslint": "3.10.2", -+ "eslint-config-standard": "6.2.1", -+ "eslint-config-standard-jsx": "3.2.0", -+ "eslint-plugin-promise": "3.4.2", -+ "eslint-plugin-react": "6.7.1", -+ "eslint-plugin-standard": "2.0.1", -+ "standard-engine": "5.2.0" -+ } -+ }, -+ "standard-engine": { -+ "version": "5.2.0", -+ "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-5.2.0.tgz", -+ "integrity": "sha1-QAZgrlrM6K/U22D/IhSpGQrXkKM=", -+ "dev": true, -+ "requires": { -+ "deglob": "2.1.0", -+ "find-root": "1.1.0", -+ "get-stdin": "5.0.1", -+ "home-or-tmp": "2.0.0", -+ "minimist": "1.2.0", -+ "pkg-config": "1.1.1" -+>>>>>>> .their - }, - "dependencies": { - "get-stdin": { -@@ -8552,11 +12451,19 @@ - "standard-markdown": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/standard-markdown/-/standard-markdown-4.0.2.tgz", -+<<<<<<< .our - "integrity": "sha1-NaC1bLtX5JzuLXQ9ocmERMNK1Lg=", - "dev": true, - "requires": { - "async": "2.6.0", - "commander": "2.15.1", -+======= -+ "integrity": "sha512-h+WTmoGN0qmse8I1VX8VD6V5JeVLXZOPQltvxQP9FfSpSl6RmKYMLTUQ2j/QhdmsdxQKDqulZF/Bf8oEnttIQA==", -+ "dev": true, -+ "requires": { -+ "async": "2.6.0", -+ "commander": "2.15.0", -+>>>>>>> .their - "globby": "6.1.0", - "lodash.flatten": "4.4.0", - "lodash.range": "3.2.0", -@@ -8579,6 +12486,7 @@ - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "dev": true, - "requires": { -+<<<<<<< .our - "lodash": "4.17.10" - } - }, -@@ -8586,11 +12494,24 @@ - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", -+======= -+ "lodash": "4.17.5" -+ } -+ }, -+ "chalk": { -+ "version": "2.3.2", -+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", -+ "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", -+<<<<<<< .our - "supports-color": "5.4.0" -+======= -+ "supports-color": "5.3.0" -+>>>>>>> .their - } - }, - "cli-cursor": { -@@ -8603,15 +12524,165 @@ - } - }, - "cli-spinners": { -+<<<<<<< .our - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.3.1.tgz", - "integrity": "sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg==", -+======= -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.1.0.tgz", -+ "integrity": "sha1-8YR7FohE2RemceudFH499JfJDQY=", -+ "dev": true -+ }, -+ "doctrine": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", -+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", -+ "dev": true, -+ "requires": { -+ "esutils": "2.0.2" -+ } -+ }, -+ "eslint": { -+ "version": "3.19.0", -+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", -+ "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", -+ "dev": true, -+ "requires": { -+ "babel-code-frame": "6.26.0", -+ "chalk": "1.1.3", -+ "concat-stream": "1.5.2", -+ "debug": "2.6.9", -+ "doctrine": "2.1.0", -+ "escope": "3.6.0", -+ "espree": "3.5.4", -+ "esquery": "1.0.0", -+ "estraverse": "4.2.0", -+ "esutils": "2.0.2", -+ "file-entry-cache": "2.0.0", -+ "glob": "7.1.2", -+ "globals": "9.18.0", -+ "ignore": "3.3.7", -+ "imurmurhash": "0.1.4", -+ "inquirer": "0.12.0", -+ "is-my-json-valid": "2.17.2", -+ "is-resolvable": "1.1.0", -+ "js-yaml": "3.11.0", -+ "json-stable-stringify": "1.0.1", -+ "levn": "0.3.0", -+ "lodash": "4.17.5", -+ "mkdirp": "0.5.1", -+ "natural-compare": "1.4.0", -+ "optionator": "0.8.2", -+ "path-is-inside": "1.0.2", -+ "pluralize": "1.2.1", -+ "progress": "1.1.8", -+ "require-uncached": "1.0.3", -+ "shelljs": "0.7.8", -+ "strip-bom": "3.0.0", -+ "strip-json-comments": "2.0.1", -+ "table": "3.8.3", -+ "text-table": "0.2.0", -+ "user-home": "2.0.0" -+ }, -+ "dependencies": { -+ "ansi-styles": { -+ "version": "2.2.1", -+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", -+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", -+ "dev": true -+ }, -+ "chalk": { -+ "version": "1.1.3", -+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", -+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", -+ "dev": true, -+ "requires": { -+ "ansi-styles": "2.2.1", -+ "escape-string-regexp": "1.0.5", -+ "has-ansi": "2.0.0", -+ "strip-ansi": "3.0.1", -+ "supports-color": "2.0.0" -+ } -+ }, -+ "supports-color": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", -+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", -+ "dev": true -+ } -+ } -+ }, -+ "eslint-config-standard": { -+ "version": "10.2.1", -+ "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz", -+ "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=", -+ "dev": true -+ }, -+ "eslint-config-standard-jsx": { -+ "version": "4.0.2", -+ "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-4.0.2.tgz", -+ "integrity": "sha512-F8fRh2WFnTek7dZH9ZaE0PCBwdVGkwVWZmizla/DDNOmg7Tx6B/IlK5+oYpiX29jpu73LszeJj5i1axEZv6VMw==", -+ "dev": true -+ }, -+ "eslint-plugin-promise": { -+ "version": "3.5.0", -+ "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz", -+ "integrity": "sha1-ePu2/+BHIBYnVp6FpsU3OvKmj8o=", -+ "dev": true -+ }, -+ "eslint-plugin-react": { -+ "version": "6.10.3", -+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz", -+ "integrity": "sha1-xUNb6wZ3ThLH2y9qut3L+QDNP3g=", -+ "dev": true, -+ "requires": { -+ "array.prototype.find": "2.0.4", -+ "doctrine": "1.5.0", -+ "has": "1.0.1", -+ "jsx-ast-utils": "1.4.1", -+ "object.assign": "4.1.0" -+ }, -+ "dependencies": { -+ "doctrine": { -+ "version": "1.5.0", -+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", -+ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", -+ "dev": true, -+ "requires": { -+ "esutils": "2.0.2", -+ "isarray": "1.0.0" -+ } -+ } -+ } -+ }, -+ "eslint-plugin-standard": { -+ "version": "3.0.1", -+ "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz", -+ "integrity": "sha1-NNDJFbRe3G8BA5PH7vOCOwhWXPI=", -+ "dev": true -+ }, -+ "estraverse": { -+ "version": "4.2.0", -+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", -+ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", -+ "dev": true -+ }, -+ "get-stdin": { -+ "version": "5.0.1", -+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", -+ "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=", -+>>>>>>> .their - "dev": true - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -8641,13 +12712,35 @@ - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, -+<<<<<<< .our -+======= -+ "isarray": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", -+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", -+ "dev": true -+ }, -+ "json-stable-stringify": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", -+ "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", -+ "dev": true, -+ "requires": { -+ "jsonify": "0.0.0" -+ } -+ }, -+>>>>>>> .their - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { -+<<<<<<< .our - "chalk": "2.4.1" -+======= -+ "chalk": "2.3.2" -+>>>>>>> .their - } - }, - "onetime": { -@@ -8665,12 +12758,27 @@ - "integrity": "sha512-iMK1DOQxzzh2MBlVsU42G80mnrvUhqsMh74phHtDlrcTZPK0pH6o7l7DRshK+0YsxDyEuaOkziVdvM3T0QTzpw==", - "dev": true, - "requires": { -+<<<<<<< .our - "chalk": "2.4.1", - "cli-cursor": "2.1.0", - "cli-spinners": "1.3.1", - "log-symbols": "2.2.0" - } - }, -+======= -+ "chalk": "2.3.2", -+ "cli-cursor": "2.1.0", -+ "cli-spinners": "1.1.0", -+ "log-symbols": "2.2.0" -+ } -+ }, -+ "progress": { -+ "version": "1.1.8", -+ "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", -+ "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", -+ "dev": true -+ }, -+>>>>>>> .their - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", -@@ -8681,10 +12789,52 @@ - "signal-exit": "3.0.2" - } - }, -+<<<<<<< .our - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", -+======= -+ "standard": { -+ "version": "10.0.3", -+ "resolved": "https://registry.npmjs.org/standard/-/standard-10.0.3.tgz", -+ "integrity": "sha512-JURZ+85ExKLQULckDFijdX5WHzN6RC7fgiZNSV4jFQVo+3tPoQGHyBrGekye/yf0aOfb4210EM5qPNlc2cRh4w==", -+ "dev": true, -+ "requires": { -+ "eslint": "3.19.0", -+ "eslint-config-standard": "10.2.1", -+ "eslint-config-standard-jsx": "4.0.2", -+ "eslint-plugin-import": "2.2.0", -+ "eslint-plugin-node": "4.2.3", -+ "eslint-plugin-promise": "3.5.0", -+ "eslint-plugin-react": "6.10.3", -+ "eslint-plugin-standard": "3.0.1", -+ "standard-engine": "7.0.0" -+ } -+ }, -+ "standard-engine": { -+ "version": "7.0.0", -+ "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-7.0.0.tgz", -+ "integrity": "sha1-67d7nI/CyBZf+jU72Rug3/Qa9pA=", -+ "dev": true, -+ "requires": { -+ "deglob": "2.1.0", -+ "get-stdin": "5.0.1", -+ "minimist": "1.2.0", -+ "pkg-conf": "2.1.0" -+ } -+ }, -+ "strip-bom": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", -+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", -+ "dev": true -+ }, -+ "supports-color": { -+ "version": "5.3.0", -+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", -+ "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", -+>>>>>>> .their - "dev": true, - "requires": { - "has-flag": "3.0.0" -@@ -8692,6 +12842,7 @@ - } - } - }, -+<<<<<<< .our - "state-toggle": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.1.tgz", -@@ -8704,6 +12855,8 @@ - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - }, -+======= -+>>>>>>> .their - "stream-browserify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", -@@ -8711,7 +12864,11 @@ - "dev": true, - "requires": { - "inherits": "2.0.3", -+<<<<<<< .our - "readable-stream": "2.3.6" -+======= -+ "readable-stream": "2.3.5" -+>>>>>>> .their - }, - "dependencies": { - "isarray": { -@@ -8721,27 +12878,47 @@ - "dev": true - }, - "readable-stream": { -+<<<<<<< .our - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", -+======= -+ "version": "2.3.5", -+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", -+ "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", -+>>>>>>> .their - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", -+======= -+ "safe-buffer": "5.1.1", -+ "string_decoder": "1.0.3", -+>>>>>>> .their - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { -+<<<<<<< .our - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" -+======= -+ "version": "1.0.3", -+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", -+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", -+ "dev": true, -+ "requires": { -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -8753,7 +12930,11 @@ - "dev": true, - "requires": { - "duplexer2": "0.1.4", -+<<<<<<< .our - "readable-stream": "2.3.6" -+======= -+ "readable-stream": "2.3.5" -+>>>>>>> .their - }, - "dependencies": { - "isarray": { -@@ -8763,27 +12944,47 @@ - "dev": true - }, - "readable-stream": { -+<<<<<<< .our - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", -+======= -+ "version": "2.3.5", -+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", -+ "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", -+>>>>>>> .their - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", -+======= -+ "safe-buffer": "5.1.1", -+ "string_decoder": "1.0.3", -+>>>>>>> .their - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { -+<<<<<<< .our - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" -+======= -+ "version": "1.0.3", -+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", -+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", -+ "dev": true, -+ "requires": { -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -8795,14 +12996,24 @@ - "dev": true - }, - "stream-http": { -+<<<<<<< .our - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.2.tgz", - "integrity": "sha512-QllfrBhqF1DPcz46WxKTs6Mz1Bpc+8Qm6vbqOpVav5odAXwbyzwnEczoWqtxrsmlO+cJqtPrp/8gWKWjaKLLlA==", -+======= -+ "version": "2.8.1", -+ "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.1.tgz", -+ "integrity": "sha512-cQ0jo17BLca2r0GfRdZKYAGLU6JRoIWxqSOakUMuKOT6MOK7AAlE856L33QuDmAy/eeOrhLee3dZKX0Uadu93A==", -+>>>>>>> .their - "dev": true, - "requires": { - "builtin-status-codes": "3.0.0", - "inherits": "2.0.3", -+<<<<<<< .our - "readable-stream": "2.3.6", -+======= -+ "readable-stream": "2.3.5", -+>>>>>>> .their - "to-arraybuffer": "1.0.1", - "xtend": "4.0.1" - }, -@@ -8814,27 +13025,47 @@ - "dev": true - }, - "readable-stream": { -+<<<<<<< .our - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", -+======= -+ "version": "2.3.5", -+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", -+ "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", -+>>>>>>> .their - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", -+======= -+ "safe-buffer": "5.1.1", -+ "string_decoder": "1.0.3", -+>>>>>>> .their - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { -+<<<<<<< .our - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" -+======= -+ "version": "1.0.3", -+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", -+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", -+ "dev": true, -+ "requires": { -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -8852,7 +13083,11 @@ - "dev": true, - "requires": { - "inherits": "2.0.3", -+<<<<<<< .our - "readable-stream": "2.3.6" -+======= -+ "readable-stream": "2.3.5" -+>>>>>>> .their - }, - "dependencies": { - "isarray": { -@@ -8862,27 +13097,47 @@ - "dev": true - }, - "readable-stream": { -+<<<<<<< .our - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", -+======= -+ "version": "2.3.5", -+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", -+ "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", -+>>>>>>> .their - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", -+======= -+ "safe-buffer": "5.1.1", -+ "string_decoder": "1.0.3", -+>>>>>>> .their - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { -+<<<<<<< .our - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" -+======= -+ "version": "1.0.3", -+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", -+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", -+ "dev": true, -+ "requires": { -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -8910,6 +13165,7 @@ - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, -+<<<<<<< .our - "stringify-entities": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz", -@@ -8926,6 +13182,12 @@ - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", - "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", -+======= -+ "stringstream": { -+ "version": "0.0.5", -+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", -+ "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", -+>>>>>>> .their - "dev": true - }, - "strip-ansi": { -@@ -9016,7 +13278,11 @@ - "ajv": "4.11.8", - "ajv-keywords": "1.5.1", - "chalk": "1.1.3", -+<<<<<<< .our - "lodash": "4.17.10", -+======= -+ "lodash": "4.17.5", -+>>>>>>> .their - "slice-ansi": "0.0.4", - "string-width": "2.1.1" - }, -@@ -9055,7 +13321,11 @@ - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", -+<<<<<<< .our - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", -+======= -+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", -+>>>>>>> .their - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", -@@ -9074,30 +13344,52 @@ - } - }, - "tar": { -+<<<<<<< .our - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.2.tgz", - "integrity": "sha512-BfkE9CciGGgDsATqkikUHrQrraBCO+ke/1f6SFAEMnxyyfN9lxC+nW1NFWMpqH865DhHIy9vQi682gk1X7friw==", -+======= -+ "version": "4.4.0", -+ "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.0.tgz", -+ "integrity": "sha512-gJlTiiErwo96K904FnoYWl+5+FBgS+FimU6GMh66XLdLa55al8+d4jeDfPoGwSNHdtWI5FJP6xurmVqhBuGJpQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "chownr": "1.0.1", - "fs-minipass": "1.2.5", -+<<<<<<< .our - "minipass": "2.3.0", - "minizlib": "1.1.0", - "mkdirp": "0.5.1", - "safe-buffer": "5.1.2", -+======= -+ "minipass": "2.2.1", -+ "minizlib": "1.1.0", -+ "mkdirp": "0.5.1", -+>>>>>>> .their - "yallist": "3.0.2" - } - }, - "tar-fs": { -+<<<<<<< .our - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.2.tgz", - "integrity": "sha512-LdknWjPEiZC1nOBwhv0JBzfJBGPJar08dZg2rwZe0ZTLQoRGEzgrl7vF3qUEkCHpI/wN9e7RyCuDhMsJUCLPPQ==", -+======= -+ "version": "1.16.0", -+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.0.tgz", -+ "integrity": "sha512-I9rb6v7mjWLtOfCau9eH5L7sLJyU2BnxtEZRQ5Mt+eRKmf1F0ohXmT/Jc3fr52kDvjJ/HV5MH3soQfPL5bQ0Yg==", -+>>>>>>> .their - "dev": true, - "requires": { - "chownr": "1.0.1", - "mkdirp": "0.5.1", - "pump": "1.0.3", -+<<<<<<< .our - "tar-stream": "1.6.0" -+======= -+ "tar-stream": "1.5.5" -+>>>>>>> .their - }, - "dependencies": { - "pump": { -@@ -9113,6 +13405,7 @@ - } - }, - "tar-stream": { -+<<<<<<< .our - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.0.tgz", - "integrity": "sha512-lh2iAPG/BHNmN6WB9Ybdynk9rEJ5GD/dy4zscHmVlwa1dq2tpE+BH78i5vjYwYVWEaOXGBjzxr89aVACF17Cpw==", -@@ -9124,6 +13417,16 @@ - "fs-constants": "1.0.0", - "readable-stream": "2.3.6", - "to-buffer": "1.1.1", -+======= -+ "version": "1.5.5", -+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz", -+ "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==", -+ "dev": true, -+ "requires": { -+ "bl": "1.2.1", -+ "end-of-stream": "1.4.1", -+ "readable-stream": "2.3.5", -+>>>>>>> .their - "xtend": "4.0.1" - }, - "dependencies": { -@@ -9134,27 +13437,47 @@ - "dev": true - }, - "readable-stream": { -+<<<<<<< .our - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", -+======= -+ "version": "2.3.5", -+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", -+ "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", -+>>>>>>> .their - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", -+======= -+ "safe-buffer": "5.1.1", -+ "string_decoder": "1.0.3", -+>>>>>>> .their - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { -+<<<<<<< .our - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" -+======= -+ "version": "1.0.3", -+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", -+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", -+ "dev": true, -+ "requires": { -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -9207,7 +13530,11 @@ - "text-extensions": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.7.0.tgz", -+<<<<<<< .our - "integrity": "sha1-+qq6JiXtdG1WiiPk0KrNm/CKizk=", -+======= -+ "integrity": "sha512-AKXZeDq230UaSzaO5s3qQUZOaC7iKbzq0jOFL614R7d9R593HLqAOL0cYoqLdkNrjBSOdmoQI06yigq1TSBXAg==", -+>>>>>>> .their - "dev": true - }, - "text-table": { -@@ -9234,7 +13561,11 @@ - "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", - "dev": true, - "requires": { -+<<<<<<< .our - "readable-stream": "2.3.6", -+======= -+ "readable-stream": "2.3.5", -+>>>>>>> .their - "xtend": "4.0.1" - }, - "dependencies": { -@@ -9245,27 +13576,47 @@ - "dev": true - }, - "readable-stream": { -+<<<<<<< .our - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", -+======= -+ "version": "2.3.5", -+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", -+ "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", -+>>>>>>> .their - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", - "string_decoder": "1.1.1", -+======= -+ "safe-buffer": "5.1.1", -+ "string_decoder": "1.0.3", -+>>>>>>> .their - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { -+<<<<<<< .our - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" -+======= -+ "version": "1.0.3", -+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", -+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", -+ "dev": true, -+ "requires": { -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -9300,6 +13651,7 @@ - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, -+<<<<<<< .our - "to-buffer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", -@@ -9317,6 +13669,8 @@ - "x-is-function": "1.0.4" - } - }, -+======= -+>>>>>>> .their - "touch": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/touch/-/touch-0.0.3.tgz", -@@ -9359,12 +13713,15 @@ - "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", - "dev": true - }, -+<<<<<<< .our - "trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", - "dev": true - }, -+======= -+>>>>>>> .their - "trim-newlines": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", -@@ -9377,6 +13734,7 @@ - "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", - "dev": true - }, -+<<<<<<< .our - "trim-trailing-lines": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.1.tgz", -@@ -9389,6 +13747,8 @@ - "integrity": "sha512-FHkoUZvG6Egrv9XZAyYGKEyb1JMsFphgPjoczkZC2y6W93U1jswcVURB8MUvtsahEPEVACyxD47JAL63vF4JsQ==", - "dev": true - }, -+======= -+>>>>>>> .their - "tslint": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-4.5.1.tgz", -@@ -9396,20 +13756,34 @@ - "dev": true, - "requires": { - "babel-code-frame": "6.26.0", -+<<<<<<< .our - "colors": "1.2.5", -+======= -+ "colors": "1.2.1", -+>>>>>>> .their - "diff": "3.5.0", - "findup-sync": "0.3.0", - "glob": "7.1.2", - "optimist": "0.6.1", -+<<<<<<< .our - "resolve": "1.7.1", - "tsutils": "1.9.1", - "update-notifier": "2.5.0" -+======= -+ "resolve": "1.5.0", -+ "tsutils": "1.9.1", -+ "update-notifier": "2.3.0" -+>>>>>>> .their - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -9456,7 +13830,11 @@ - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - }, - "tweetnacl": { -@@ -9482,9 +13860,15 @@ - "dev": true - }, - "typescript": { -+<<<<<<< .our - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", - "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", -+======= -+ "version": "2.7.2", -+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.2.tgz", -+ "integrity": "sha512-p5TCYZDAO0m4G344hD+wx/LATebLWZNkkh2asWUFqSsD2OrDNhbAHuSjobrmsUmdzjJjEeZVU9g1h3O6vpstnw==", -+>>>>>>> .their - "dev": true - }, - "uc.micro": { -@@ -9533,6 +13917,7 @@ - "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", - "dev": true - }, -+<<<<<<< .our - "unherit": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.1.tgz", -@@ -9677,6 +14062,8 @@ - "vfile-location": "2.0.3" - } - }, -+======= -+>>>>>>> .their - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", -@@ -9692,6 +14079,7 @@ - "crypto-random-string": "1.0.0" - } - }, -+<<<<<<< .our - "unist-util-generated": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.2.tgz", -@@ -9764,12 +14152,15 @@ - "os-homedir": "1.0.2" - } - }, -+======= -+>>>>>>> .their - "unzip-response": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", - "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", - "dev": true - }, -+<<<<<<< .our - "update-check": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.1.tgz", -@@ -9791,6 +14182,18 @@ - "configstore": "3.1.2", - "import-lazy": "2.1.0", - "is-ci": "1.1.0", -+======= -+ "update-notifier": { -+ "version": "2.3.0", -+ "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.3.0.tgz", -+ "integrity": "sha1-TognpruRUUCrCTVZ1wFOPruDdFE=", -+ "dev": true, -+ "requires": { -+ "boxen": "1.3.0", -+ "chalk": "2.3.2", -+ "configstore": "3.1.1", -+ "import-lazy": "2.1.0", -+>>>>>>> .their - "is-installed-globally": "0.1.0", - "is-npm": "1.0.0", - "latest-version": "3.1.0", -@@ -9808,14 +14211,24 @@ - } - }, - "chalk": { -+<<<<<<< .our - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", -+======= -+ "version": "2.3.2", -+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", -+ "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", -+<<<<<<< .our - "supports-color": "5.4.0" -+======= -+ "supports-color": "5.3.0" -+>>>>>>> .their - } - }, - "has-flag": { -@@ -9825,9 +14238,15 @@ - "dev": true - }, - "supports-color": { -+<<<<<<< .our - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", -+======= -+ "version": "5.3.0", -+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", -+ "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", -+>>>>>>> .their - "dev": true, - "requires": { - "has-flag": "3.0.0" -@@ -9910,12 +14329,15 @@ - "spdx-expression-parse": "3.0.0" - } - }, -+<<<<<<< .our - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, -+======= -+>>>>>>> .their - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", -@@ -9927,6 +14349,7 @@ - "extsprintf": "1.3.0" - } - }, -+<<<<<<< .our - "vfile": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz", -@@ -9990,6 +14413,8 @@ - "integrity": "sha512-dxUM6IYvGChHuwMT3dseyU5BHprNRXzAV0OHx1A769lVGsTiT50kU7BbpRFV+IE6oWmU+PwHdsTKfXhnDIRIgQ==", - "dev": true - }, -+======= -+>>>>>>> .their - "vm-browserify": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", -@@ -10002,7 +14427,11 @@ - "walk-sync": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-0.3.2.tgz", -+<<<<<<< .our - "integrity": "sha1-SCcoCvxC0OA1NnxKTjHurA0Tb3U=", -+======= -+ "integrity": "sha512-FMB5VqpLqOCcqrzA9okZFc0wq0Qbmdm396qJxvQZhDpyu0W95G9JCmp74tx7iyYnyOcBtUuKJsgIKAqjozvmmQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "ensure-posix-path": "1.0.2", -@@ -10029,7 +14458,11 @@ - "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", -+<<<<<<< .our - "integrity": "sha1-/wS9/AEO5UfXgL7DjhrBwnd9JTo=", -+======= -+ "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", -+>>>>>>> .their - "dev": true, - "requires": { - "isexe": "2.0.0" -@@ -10106,6 +14539,7 @@ - "strip-ansi": "3.0.1" - } - }, -+<<<<<<< .our - "wrapped": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wrapped/-/wrapped-1.0.1.tgz", -@@ -10124,6 +14558,8 @@ - } - } - }, -+======= -+>>>>>>> .their - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", -@@ -10142,7 +14578,11 @@ - "write-file-atomic": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", -+<<<<<<< .our - "integrity": "sha1-H/YVdcLipOjlENb6TiQ8zhg5mas=", -+======= -+ "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", -+>>>>>>> .their - "dev": true, - "requires": { - "graceful-fs": "4.1.11", -@@ -10150,6 +14590,7 @@ - "signal-exit": "3.0.2" - } - }, -+<<<<<<< .our - "x-is-function": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/x-is-function/-/x-is-function-1.0.4.tgz", -@@ -10162,6 +14603,8 @@ - "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", - "dev": true - }, -+======= -+>>>>>>> .their - "xdg-basedir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", -changed in both - base 100644 570c63f4e7915198292dae1cd9e84e7ecd725386 package.json - our 100644 c081cd89450cd50efba1ec280ff1349a96ea3ce0 package.json - their 100644 87167f4bd3a967da3e673237ba91da87f2a452f1 package.json -@@ -1,17 +1,25 @@ - { - "name": "electron", -+<<<<<<< .our - "version": "4.0.0-nightly.20180821", -+======= -+ "version": "1.7.16", -+>>>>>>> .their - "repository": "https://github.com/electron/electron", - "description": "Build cross platform desktop apps with JavaScript, HTML, and CSS", - "devDependencies": { - "asar": "^0.11.0", - "browserify": "^13.1.0", - "check-for-leaks": "^1.0.2", -+<<<<<<< .our - "clang-format": "^1.2.3", -+======= -+>>>>>>> .their - "colors": "^1.1.2", - "dotenv-safe": "^4.0.4", - "dugite": "^1.45.0", - "electabul": "~0.0.4", -+<<<<<<< .our - "electron-docs-linter": "^2.3.4", - "electron-typescript-definitions": "^1.3.6", - "github": "^9.2.0", -@@ -24,6 +32,15 @@ - "octicons": "^7.3.0", - "remark-cli": "^4.0.0", - "remark-preset-lint-markdown-style-guide": "^2.1.1", -+======= -+ "electron-docs-linter": "^2.3.3", -+ "electron-typescript-definitions": "~1.2.11", -+ "github": "^9.2.0", -+ "heads": "^1.3.0", -+ "husky": "^0.14.3", -+ "minimist": "^1.2.0", -+ "nugget": "^2.0.1", -+>>>>>>> .their - "request": "^2.68.0", - "semver": "^5.5.0", - "serve": "^6.5.8", -@@ -69,6 +86,10 @@ - "lint:js-in-markdown": "standard-markdown docs", - "create-api-json": "electron-docs-linter docs --outfile=out/electron-api.json --version=$npm_package_version", - "create-typescript-definitions": "npm run create-api-json && electron-typescript-definitions --in=out/electron-api.json --out=out/electron.d.ts", -+<<<<<<< .our -+======= -+ "merge-release": "node ./script/merge-release.js", -+>>>>>>> .their - "mock-release": "node ./script/ci-release-build.js", - "preinstall": "node -e 'process.exit(0)'", - "publish-to-npm": "node ./script/publish-to-npm.js", -changed in both - base 100755 4db30b71fca9996003fe44a71fa9d81499677bd2 script/bump-version.py - our 100755 564adb2116312b0f6d0351096bd89cb373cd3bab script/bump-version.py - their 100755 28424aaa8ee614b0dfffc7468adb2266f05440cb script/bump-version.py -@@ -12,6 +12,7 @@ - SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) - - def main(): -+<<<<<<< .our - - parser = argparse.ArgumentParser( - description='Bump version numbers. Must specify at least one of the three' -@@ -94,6 +95,77 @@ - if args.dry_run: - print 'new version number would be: {0}\n'.format(version + suffix) - return 0 -+======= -+ -+ parser = argparse.ArgumentParser( -+ description='Bump version numbers. Must specify at least one of the three' -+ +' options:\n' -+ +' --bump=patch to increment patch version, or\n' -+ +' --stable to promote current beta to stable, or\n' -+ +' --version={version} to set version number directly\n' -+ +'Note that you can use both --bump and --stable ' -+ +'simultaneously.', -+ formatter_class=argparse.RawTextHelpFormatter -+ ) -+ parser.add_argument( -+ '--version', -+ default=None, -+ dest='new_version', -+ help='new version number' -+ ) -+ parser.add_argument( -+ '--bump', -+ action='store', -+ default=None, -+ dest='bump', -+ help='increment [major | minor | patch | beta]' -+ ) -+ parser.add_argument( -+ '--stable', -+ action='store_true', -+ default= False, -+ dest='stable', -+ help='promote to stable (i.e. remove `-beta.x` suffix)' -+ ) -+ parser.add_argument( -+ '--dry-run', -+ action='store_true', -+ default= False, -+ dest='dry_run', -+ help='just to check that version number is correct' -+ ) -+ -+ args = parser.parse_args() -+ -+ if args.new_version == None and args.bump == None and args.stable == False: -+ parser.print_help() -+ return 1 -+ -+ increments = ['major', 'minor', 'patch', 'beta'] -+ -+ curr_version = get_electron_version() -+ versions = parse_version(re.sub('-beta', '', curr_version)) -+ -+ if args.bump in increments: -+ versions = increase_version(versions, increments.index(args.bump)) -+ if versions[3] == '0': -+ # beta starts at 1 -+ versions = increase_version(versions, increments.index('beta')) -+ -+ if args.stable == True: -+ versions[3] = '0' -+ -+ if args.new_version != None: -+ versions = parse_version(re.sub('-beta', '', args.new_version)) -+ -+ version = '.'.join(versions[:3]) -+ suffix = '' if versions[3] == '0' else '-beta.' + versions[3] -+ -+ if args.dry_run: -+ print 'new version number would be: {0}\n'.format(version + suffix) -+ return 0 -+ -+>>>>>>> .their - - with scoped_cwd(SOURCE_ROOT): - update_electron_gyp(version, suffix) -@@ -104,9 +176,12 @@ - tag_version(version, suffix) - - print 'Bumped to version: {0}'.format(version + suffix) -+<<<<<<< .our - - def not_reached(): - raise Exception('Unreachable code was reached') -+======= -+>>>>>>> .their - - def increase_version(versions, index): - for i in range(index + 1, 4): -@@ -116,8 +191,12 @@ - - - def update_electron_gyp(version, suffix): -+<<<<<<< .our - pattern = re.compile(" *'version%' *: *'[0-9.]+(-beta[0-9.]*)?(-dev)?" - + "(-nightly[0-9.]*)?'") -+======= -+ pattern = re.compile(" *'version%' *: *'[0-9.]+(-beta[0-9.]*)?'") -+>>>>>>> .their - with open('electron.gyp', 'r') as f: - lines = f.readlines() - -@@ -209,6 +288,7 @@ - - - def tag_version(version, suffix): -+<<<<<<< .our - execute([ - 'git', - 'commit', -@@ -217,6 +297,9 @@ - 'Bump v{0}'.format(version + suffix), - '-n' - ]) -+======= -+ execute(['git', 'commit', '-a', '-m', 'Bump v{0}'.format(version + suffix)]) -+>>>>>>> .their - - - if __name__ == '__main__': -added in both - our 100644 be9f9597387f5f8b7bfddc61c202f32ce4c6d478 script/ci-release-build.js - their 100644 eb37ece8a892e696dbcc1815c3b9a2ccca79437b script/ci-release-build.js -@@ -1,3 +1,4 @@ -+<<<<<<< .our - require('dotenv-safe').load() - - const assert = require('assert') -@@ -23,6 +24,18 @@ - 'electron-release-osx-x64' - ] - -+======= -+const assert = require('assert') -+const request = require('request') -+const buildAppVeyorURL = 'https://windows-ci.electronjs.org/api/builds' -+ -+const circleCIJobs = [ -+ 'electron-linux-arm', -+ 'electron-linux-ia32', -+ 'electron-linux-x64' -+] -+ -+>>>>>>> .their - async function makeRequest (requestOptions, parseResponse) { - return new Promise((resolve, reject) => { - request(requestOptions, (err, res, body) => { -@@ -34,6 +47,7 @@ - resolve(body) - } - } else { -+<<<<<<< .our - console.error('Error occurred while requesting:', requestOptions.url) - if (parseResponse) { - try { -@@ -41,6 +55,10 @@ - } catch (err) { - console.log('Error: ', `(status ${res.statusCode})`, err || res.body, requestOptions) - } -+======= -+ if (parseResponse) { -+ console.log('Error: ', `(status ${res.statusCode})`, err || JSON.parse(res.body), requestOptions) -+>>>>>>> .their - } else { - console.log('Error: ', `(status ${res.statusCode})`, err || res.body, requestOptions) - } -@@ -50,7 +68,12 @@ - }) - } - -+<<<<<<< .our - async function circleCIcall (buildUrl, targetBranch, job, options) { -+======= -+async function circleCIcall (buildUrl, targetBranch, job, ghRelease) { -+ assert(process.env.CIRCLE_TOKEN, 'CIRCLE_TOKEN not found in environment') -+>>>>>>> .their - console.log(`Triggering CircleCI to run build job: ${job} on branch: ${targetBranch} with release flag.`) - let buildRequest = { - 'build_parameters': { -@@ -58,16 +81,23 @@ - } - } - -+<<<<<<< .our - if (options.ghRelease) { -+======= -+ if (ghRelease) { -+>>>>>>> .their - buildRequest.build_parameters.ELECTRON_RELEASE = 1 - } else { - buildRequest.build_parameters.RUN_RELEASE_BUILD = 'true' - } - -+<<<<<<< .our - if (options.automaticRelease) { - buildRequest.build_parameters.AUTO_RELEASE = 'true' - } - -+======= -+>>>>>>> .their - let circleResponse = await makeRequest({ - method: 'POST', - url: buildUrl, -@@ -79,6 +109,7 @@ - }, true).catch(err => { - console.log('Error calling CircleCI:', err) - }) -+<<<<<<< .our - console.log(`CircleCI release build request for ${job} successful. Check ${circleResponse.build_url} for status.`) - } - -@@ -97,15 +128,29 @@ - let environmentVariables = {} - - if (options.ghRelease) { -+======= -+ console.log(`Check ${circleResponse.build_url} for status. (${job})`) -+} -+ -+async function buildAppVeyor (targetBranch, ghRelease) { -+ console.log(`Triggering AppVeyor to run build on branch: ${targetBranch} with release flag.`) -+ assert(process.env.APPVEYOR_TOKEN, 'APPVEYOR_TOKEN not found in environment') -+ let environmentVariables = {} -+ -+ if (ghRelease) { -+>>>>>>> .their - environmentVariables.ELECTRON_RELEASE = 1 - } else { - environmentVariables.RUN_RELEASE_BUILD = 'true' - } - -+<<<<<<< .our - if (options.automaticRelease) { - environmentVariables.AUTO_RELEASE = 'true' - } - -+======= -+>>>>>>> .their - const requestOpts = { - url: buildAppVeyorURL, - auth: { -@@ -116,7 +161,11 @@ - }, - body: JSON.stringify({ - accountName: 'AppVeyor', -+<<<<<<< .our - projectSlug: appVeyorJobs[job], -+======= -+ projectSlug: 'electron', -+>>>>>>> .their - branch: targetBranch, - environmentVariables - }), -@@ -125,6 +174,7 @@ - let appVeyorResponse = await makeRequest(requestOpts, true).catch(err => { - console.log('Error calling AppVeyor:', err) - }) -+<<<<<<< .our - const buildUrl = `https://windows-ci.electronjs.org/project/AppVeyor/${appVeyorJobs[job]}/build/${appVeyorResponse.version}` - console.log(`AppVeyor release build request for ${job} successful. Check build status at ${buildUrl}`) - } -@@ -202,10 +252,27 @@ - console.log(`VSTS release build request for ${build.name} successful. Check ${vstsResponse._links.web.href} for status.`) - } - -+======= -+ const buildUrl = `https://windows-ci.electronjs.org/project/AppVeyor/electron/build/${appVeyorResponse.version}` -+ console.log(`AppVeyor release build request successful. Check build status at ${buildUrl}`) -+} -+ -+function buildCircleCI (targetBranch, ghRelease, job) { -+ const circleBuildUrl = `https://circleci.com/api/v1.1/project/github/electron/electron/tree/${targetBranch}?circle-token=${process.env.CIRCLE_TOKEN}` -+ if (job) { -+ assert(circleCIJobs.includes(job), `Unknown CI job name: ${job}.`) -+ circleCIcall(circleBuildUrl, targetBranch, job, ghRelease) -+ } else { -+ circleCIJobs.forEach((job) => circleCIcall(circleBuildUrl, targetBranch, job, ghRelease)) -+ } -+} -+ -+>>>>>>> .their - function runRelease (targetBranch, options) { - if (options.ci) { - switch (options.ci) { - case 'CircleCI': { -+<<<<<<< .our - buildCircleCI(targetBranch, options) - break - } -@@ -226,12 +293,26 @@ - buildCircleCI(targetBranch, options) - buildAppVeyor(targetBranch, options) - buildVSTS(targetBranch, options) -+======= -+ buildCircleCI(targetBranch, options.ghRelease, options.job) -+ break -+ } -+ case 'AppVeyor': { -+ buildAppVeyor(targetBranch, options.ghRelease) -+ break -+ } -+ } -+ } else { -+ buildCircleCI(targetBranch, options.ghRelease, options.job) -+ buildAppVeyor(targetBranch, options.ghRelease) -+>>>>>>> .their - } - } - - module.exports = runRelease - - if (require.main === module) { -+<<<<<<< .our - const args = require('minimist')(process.argv.slice(2), { - boolean: ['ghRelease', 'automaticRelease'] - }) -@@ -239,6 +320,13 @@ - if (args._.length < 1) { - console.log(`Trigger CI to build release builds of electron. - Usage: ci-release-build.js [--job=CI_JOB_NAME] [--ci=CircleCI|AppVeyor|VSTS] [--ghRelease] [--automaticRelease] TARGET_BRANCH -+======= -+ const args = require('minimist')(process.argv.slice(2)) -+ const targetBranch = args._[0] -+ if (args._.length < 1) { -+ console.log(`Trigger CI to build release builds of electron. -+ Usage: ci-release-build.js [--job=CI_JOB_NAME] [--ci=CircleCI|AppVeyor] [--ghRelease] TARGET_BRANCH -+>>>>>>> .their - `) - process.exit(0) - } -changed in both - base 100755 96e6ea2e751eea50df6e4d1014c5ce9ce9e726bb script/cibuild - our 100755 758dc2c794e642430ab6a0d966e7a41863be947c script/cibuild - their 100755 36e9e13fe98bce5d93a28e9711b36ae96d909fd6 script/cibuild -@@ -57,6 +57,20 @@ - if os.environ.has_key('TARGET_ARCH'): - target_arch = os.environ['TARGET_ARCH'] - -+<<<<<<< .our -+======= -+ is_travis = (os.getenv('TRAVIS') == 'true') -+ if is_travis and PLATFORM == 'linux': -+ print 'Setup travis CI' -+ execute(['sudo', 'apt-get', 'update']) -+ deps = LINUX_DEPS -+ if target_arch == 'arm': -+ deps += LINUX_DEPS_ARM -+ else: -+ deps += LINUX_DEPS_NO_ARM -+ execute(['sudo', 'apt-get', 'install'] + deps) -+ -+>>>>>>> .their - if PLATFORM == 'linux' and target_arch == 'x64': - os.environ['DISPLAY'] = ':99.0' - execute(['sh', '-e', '/etc/init.d/xvfb', 'start']) -added in remote - their 100755 a33a208c32e4395a09cec65b121991443af1f373 script/merge-release.js -@@ -0,0 +1,116 @@ -+#!/usr/bin/env node -+ -+require('colors') -+const assert = require('assert') -+const branchToRelease = process.argv[2] -+const fail = '\u2717'.red -+const { GitProcess, GitError } = require('dugite') -+const pass = '\u2713'.green -+const path = require('path') -+const pkg = require('../package.json') -+ -+assert(process.env.ELECTRON_GITHUB_TOKEN, 'ELECTRON_GITHUB_TOKEN not found in environment') -+if (!branchToRelease) { -+ console.log(`Usage: merge-release branch`) -+ process.exit(1) -+} -+const gitDir = path.resolve(__dirname, '..') -+ -+async function callGit (args, errorMessage, successMessage) { -+ let gitResult = await GitProcess.exec(args, gitDir) -+ if (gitResult.exitCode === 0) { -+ console.log(`${pass} ${successMessage}`) -+ return true -+ } else { -+ console.log(`${fail} ${errorMessage} ${gitResult.stderr}`) -+ process.exit(1) -+ } -+} -+ -+async function checkoutBranch (branchName) { -+ console.log(`Checking out ${branchName}.`) -+ let errorMessage = `Error checking out branch ${branchName}:` -+ let successMessage = `Successfully checked out branch ${branchName}.` -+ return callGit(['checkout', branchName], errorMessage, successMessage) -+} -+ -+async function commitMerge () { -+ console.log(`Committing the merge for v${pkg.version}`) -+ let errorMessage = `Error committing merge:` -+ let successMessage = `Successfully committed the merge for v${pkg.version}` -+ let gitArgs = ['commit', '-m', `v${pkg.version}`] -+ return callGit(gitArgs, errorMessage, successMessage) -+} -+ -+async function mergeReleaseIntoBranch (branchName) { -+ console.log(`Merging release branch into ${branchName}.`) -+ let mergeArgs = ['merge', 'release-1-7-x', '--squash'] -+ let mergeDetails = await GitProcess.exec(mergeArgs, gitDir) -+ if (mergeDetails.exitCode === 0) { -+ return true -+ } else { -+ const error = GitProcess.parseError(mergeDetails.stderr) -+ if (error === GitError.MergeConflicts) { -+ console.log(`${fail} Could not merge release branch into ${branchName} ` + -+ `due to merge conflicts.`) -+ return false -+ } else { -+ console.log(`${fail} Could not merge release branch into ${branchName} ` + -+ `due to an error: ${mergeDetails.stderr}.`) -+ process.exit(1) -+ } -+ } -+} -+ -+async function pushBranch (branchName) { -+ console.log(`Pushing branch ${branchName}.`) -+ let pushArgs = ['push', 'origin', branchName] -+ let errorMessage = `Could not push branch ${branchName} due to an error:` -+ let successMessage = `Successfully pushed branch ${branchName}.` -+ return callGit(pushArgs, errorMessage, successMessage) -+} -+ -+async function pull () { -+ console.log(`Performing a git pull`) -+ let errorMessage = `Could not pull due to an error:` -+ let successMessage = `Successfully performed a git pull` -+ return callGit(['pull'], errorMessage, successMessage) -+} -+ -+async function rebase (targetBranch) { -+ console.log(`Rebasing release branch from ${targetBranch}`) -+ let errorMessage = `Could not rebase due to an error:` -+ let successMessage = `Successfully rebased release branch from ` + -+ `${targetBranch}` -+ return callGit(['rebase', targetBranch], errorMessage, successMessage) -+} -+ -+async function mergeRelease () { -+ await checkoutBranch(branchToRelease) -+ let mergeSuccess = await mergeReleaseIntoBranch(branchToRelease) -+ if (mergeSuccess) { -+ console.log(`${pass} Successfully merged release branch into ` + -+ `${branchToRelease}.`) -+ await commitMerge() -+ let pushSuccess = await pushBranch(branchToRelease) -+ if (pushSuccess) { -+ console.log(`${pass} Success!!! ${branchToRelease} now has the latest release!`) -+ } -+ } else { -+ console.log(`Trying rebase of ${branchToRelease} into release branch.`) -+ await pull() -+ await checkoutBranch('release-1-7-x') -+ let rebaseResult = await rebase(branchToRelease) -+ if (rebaseResult) { -+ let pushResult = pushBranch('HEAD') -+ if (pushResult) { -+ console.log(`Rebase of ${branchToRelease} into release branch was ` + -+ `successful. Let release builds run and then try this step again.`) -+ } -+ // Exit as failure so release doesn't continue -+ process.exit(1) -+ } -+ } -+} -+ -+mergeRelease() -added in both - our 100755 72a28b719bf1ff7770692caef86c76746c4d8edf script/prepare-release.js - their 100755 3e7baefd0cc37db804c6019b597200c02a281c1e script/prepare-release.js -@@ -1,5 +1,6 @@ - #!/usr/bin/env node - -+<<<<<<< .our - if (!process.env.CI) require('dotenv-safe').load() - require('colors') - const args = require('minimist')(process.argv.slice(2), { -@@ -9,20 +10,39 @@ - const { execSync } = require('child_process') - const fail = '\u2717'.red - const { GitProcess } = require('dugite') -+======= -+require('colors') -+const args = require('minimist')(process.argv.slice(2)) -+const assert = require('assert') -+const ciReleaseBuild = require('./ci-release-build') -+const { execSync } = require('child_process') -+const fail = '\u2717'.red -+const { GitProcess, GitError } = require('dugite') -+>>>>>>> .their - const GitHub = require('github') - const pass = '\u2713'.green - const path = require('path') - const pkg = require('../package.json') - const readline = require('readline') - const versionType = args._[0] -+<<<<<<< .our - const targetRepo = versionType === 'nightly' ? 'nightlies' : 'electron' -+======= -+>>>>>>> .their - - // TODO (future) automatically determine version based on conventional commits - // via conventional-recommended-bump - -+<<<<<<< .our - if (!versionType && !args.notesOnly) { - console.log(`Usage: prepare-release versionType [stable | beta | nightly]` + - ` (--stable) (--notesOnly) (--automaticRelease) (--branch)`) -+======= -+assert(process.env.ELECTRON_GITHUB_TOKEN, 'ELECTRON_GITHUB_TOKEN not found in environment') -+if (!versionType && !args.notesOnly) { -+ console.log(`Usage: prepare-release versionType [major | minor | patch | beta]` + -+ ` (--stable) (--notesOnly)`) -+>>>>>>> .their - process.exit(1) - } - -@@ -30,12 +50,37 @@ - const gitDir = path.resolve(__dirname, '..') - github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN}) - -+<<<<<<< .our - async function getNewVersion (dryRun) { - if (!dryRun) { - console.log(`Bumping for new "${versionType}" version.`) - } - let bumpScript = path.join(__dirname, 'bump-version.py') - let scriptArgs = [bumpScript, '--bump', versionType] -+======= -+async function createReleaseBranch () { -+ console.log(`Creating release branch.`) -+ let checkoutDetails = await GitProcess.exec([ 'checkout', '-b', 'release-1-7-x' ], gitDir) -+ if (checkoutDetails.exitCode === 0) { -+ console.log(`${pass} Successfully created the release branch.`) -+ } else { -+ const error = GitProcess.parseError(checkoutDetails.stderr) -+ if (error === GitError.BranchAlreadyExists) { -+ console.log(`${fail} Release branch already exists, aborting prepare ` + -+ `release process.`) -+ } else { -+ console.log(`${fail} Error creating release branch: ` + -+ `${checkoutDetails.stderr}`) -+ } -+ process.exit(1) -+ } -+} -+ -+function getNewVersion (dryRun) { -+ console.log(`Bumping for new "${versionType}" version.`) -+ let bumpScript = path.join(__dirname, 'bump-version.py') -+ let scriptArgs = [bumpScript, `--bump ${versionType}`] -+>>>>>>> .their - if (args.stable) { - scriptArgs.push('--stable') - } -@@ -52,7 +97,10 @@ - return newVersion - } catch (err) { - console.log(`${fail} Could not bump version, error was:`, err) -+<<<<<<< .our - throw err -+======= -+>>>>>>> .their - } - } - -@@ -74,6 +122,7 @@ - } - - async function getReleaseNotes (currentBranch) { -+<<<<<<< .our - if (versionType === 'nightly') { - return 'Nightlies do not get release notes, please compare tags for info' - } -@@ -81,6 +130,12 @@ - let githubOpts = { - owner: 'electron', - repo: targetRepo, -+======= -+ console.log(`Generating release notes for ${currentBranch}.`) -+ let githubOpts = { -+ owner: 'electron', -+ repo: 'electron', -+>>>>>>> .their - base: `v${pkg.version}`, - head: currentBranch - } -@@ -142,11 +197,18 @@ - - async function createRelease (branchToTarget, isBeta) { - let releaseNotes = await getReleaseNotes(branchToTarget) -+<<<<<<< .our - let newVersion = await getNewVersion() - await tagRelease(newVersion) - const githubOpts = { - owner: 'electron', - repo: targetRepo -+======= -+ let newVersion = getNewVersion() -+ const githubOpts = { -+ owner: 'electron', -+ repo: 'electron' -+>>>>>>> .their - } - console.log(`Checking for existing draft release.`) - let releases = await github.repos.getReleases(githubOpts) -@@ -164,6 +226,7 @@ - githubOpts.draft = true - githubOpts.name = `electron ${newVersion}` - if (isBeta) { -+<<<<<<< .our - if (newVersion.indexOf('nightly') > 0) { - githubOpts.body = `Note: This is a nightly release. Please file new issues ` + - `for any bugs you find in it.\n \n This release is published to npm ` + -@@ -175,13 +238,23 @@ - `under the beta tag and can be installed via npm install electron@beta, ` + - `or npm i electron@${newVersion.substr(1)}.\n \n ${releaseNotes}` - } -+======= -+ githubOpts.body = `Note: This is a beta release. Please file new issues ` + -+ `for any bugs you find in it.\n \n This release is published to npm ` + -+ `under the beta tag and can be installed via npm install electron@beta, ` + -+ `or npm i electron@${newVersion.substr(1)}.\n \n ${releaseNotes}` -+>>>>>>> .their - githubOpts.name = `${githubOpts.name}` - githubOpts.prerelease = true - } else { - githubOpts.body = releaseNotes - } - githubOpts.tag_name = newVersion -+<<<<<<< .our - githubOpts.target_commitish = newVersion.indexOf('nightly') !== -1 ? 'master' : branchToTarget -+======= -+ githubOpts.target_commitish = branchToTarget -+>>>>>>> .their - await github.repos.createRelease(githubOpts) - .catch(err => { - console.log(`${fail} Error creating new release: `, err) -@@ -190,6 +263,7 @@ - console.log(`${pass} Draft release for ${newVersion} has been created.`) - } - -+<<<<<<< .our - async function pushRelease (branch) { - let pushDetails = await GitProcess.exec(['push', 'origin', `HEAD:${branch}`, '--follow-tags'], gitDir) - if (pushDetails.exitCode === 0) { -@@ -197,11 +271,21 @@ - `release builds to finish before running "npm run release".`) - } else { - console.log(`${fail} Error pushing the release: ` + -+======= -+async function pushRelease () { -+ let pushDetails = await GitProcess.exec(['push', 'origin', 'HEAD'], gitDir) -+ if (pushDetails.exitCode === 0) { -+ console.log(`${pass} Successfully pushed the release branch. Wait for ` + -+ `release builds to finish before running "npm run release".`) -+ } else { -+ console.log(`${fail} Error pushing the release branch: ` + -+>>>>>>> .their - `${pushDetails.stderr}`) - process.exit(1) - } - } - -+<<<<<<< .our - async function runReleaseBuilds (branch) { - await ciReleaseBuild(branch, { - ghRelease: true, -@@ -229,6 +313,17 @@ - } else { - response = await promptForVersion(newVersion) - } -+======= -+async function runReleaseBuilds () { -+ await ciReleaseBuild('release-1-7-x', { -+ ghRelease: true -+ }) -+} -+ -+async function verifyNewVersion () { -+ let newVersion = await getNewVersion(true) -+ let response = await promptForVersion(newVersion) -+>>>>>>> .their - if (response.match(/^y/i)) { - console.log(`${pass} Starting release of ${newVersion}`) - } else { -@@ -250,6 +345,7 @@ - }) - } - -+<<<<<<< .our - // function to determine if there have been commits to master since the last release - async function changesToRelease () { - let lastCommitWasRelease = new RegExp(`^Bump v[0-9.]*(-beta[0-9.]*)?(-nightly[0-9.]*)?$`, 'g') -@@ -278,6 +374,19 @@ - process.exit(1) - } - } -+======= -+async function prepareRelease (isBeta, notesOnly) { -+ let currentBranch = await getCurrentBranch(gitDir) -+ if (notesOnly) { -+ let releaseNotes = await getReleaseNotes(currentBranch) -+ console.log(`Draft release notes are: ${releaseNotes}`) -+ } else { -+ await verifyNewVersion() -+ await createReleaseBranch() -+ await createRelease(currentBranch, isBeta) -+ await pushRelease() -+ await runReleaseBuilds() -+>>>>>>> .their - } - } - -added in remote - their 100755 78b63933009cf47cc50130dabaa8fe6f5f73b30f script/prerelease.js -@@ -0,0 +1,112 @@ -+#!/usr/bin/env node -+ -+require('colors') -+const assert = require('assert') -+const GitHub = require('github') -+const heads = require('heads') -+const pkg = require('../package.json') -+const pass = '\u2713'.green -+const fail = '\u2717'.red -+let failureCount = 0 -+ -+assert(process.env.ELECTRON_GITHUB_TOKEN, 'ELECTRON_GITHUB_TOKEN not found in environment') -+ -+const github = new GitHub() -+github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN}) -+github.repos.getReleases({owner: 'electron', repo: 'electron'}) -+ .then(res => { -+ const releases = res.data -+ const drafts = releases -+ .filter(release => release.draft) // comment out for testing -+ // .filter(release => release.tag_name === 'v1.7.5') // uncomment for testing -+ -+ check(drafts.length === 1, 'one draft exists', true) -+ const draft = drafts[0] -+ -+ check(draft.tag_name === `v${pkg.version}`, `draft release version matches local package.json (v${pkg.version})`) -+ check(draft.prerelease, 'draft is a prerelease') -+ check(draft.body.length > 50 && !draft.body.includes('(placeholder)'), 'draft has release notes') -+ -+ const requiredAssets = assetsForVersion(draft.tag_name).sort() -+ const extantAssets = draft.assets.map(asset => asset.name).sort() -+ -+ requiredAssets.forEach(asset => { -+ check(extantAssets.includes(asset), asset) -+ }) -+ -+ const s3Urls = s3UrlsForVersion(draft.tag_name) -+ heads(s3Urls) -+ .then(results => { -+ results.forEach((result, i) => { -+ check(result === 200, s3Urls[i]) -+ }) -+ -+ process.exit(failureCount > 0 ? 1 : 0) -+ }) -+ .catch(err => { -+ console.error('Error making HEAD requests for S3 assets') -+ console.error(err) -+ process.exit(1) -+ }) -+ }) -+ -+function check (condition, statement, exitIfFail = false) { -+ if (condition) { -+ console.log(`${pass} ${statement}`) -+ } else { -+ failureCount++ -+ console.log(`${fail} ${statement}`) -+ if (exitIfFail) process.exit(1) -+ } -+} -+ -+function assetsForVersion (version) { -+ const patterns = [ -+ 'electron-{{VERSION}}-darwin-x64-dsym.zip', -+ 'electron-{{VERSION}}-darwin-x64-symbols.zip', -+ 'electron-{{VERSION}}-darwin-x64.zip', -+ 'electron-{{VERSION}}-linux-arm-symbols.zip', -+ 'electron-{{VERSION}}-linux-arm.zip', -+ 'electron-{{VERSION}}-linux-armv7l-symbols.zip', -+ 'electron-{{VERSION}}-linux-armv7l.zip', -+ 'electron-{{VERSION}}-linux-ia32-symbols.zip', -+ 'electron-{{VERSION}}-linux-ia32.zip', -+ 'electron-{{VERSION}}-linux-x64-symbols.zip', -+ 'electron-{{VERSION}}-linux-x64.zip', -+ 'electron-{{VERSION}}-mas-x64-dsym.zip', -+ 'electron-{{VERSION}}-mas-x64-symbols.zip', -+ 'electron-{{VERSION}}-mas-x64.zip', -+ 'electron-{{VERSION}}-win32-ia32-pdb.zip', -+ 'electron-{{VERSION}}-win32-ia32-symbols.zip', -+ 'electron-{{VERSION}}-win32-ia32.zip', -+ 'electron-{{VERSION}}-win32-x64-pdb.zip', -+ 'electron-{{VERSION}}-win32-x64-symbols.zip', -+ 'electron-{{VERSION}}-win32-x64.zip', -+ 'electron-api.json', -+ 'electron.d.ts', -+ 'ffmpeg-{{VERSION}}-darwin-x64.zip', -+ 'ffmpeg-{{VERSION}}-linux-arm.zip', -+ 'ffmpeg-{{VERSION}}-linux-armv7l.zip', -+ 'ffmpeg-{{VERSION}}-linux-ia32.zip', -+ 'ffmpeg-{{VERSION}}-linux-x64.zip', -+ 'ffmpeg-{{VERSION}}-mas-x64.zip', -+ 'ffmpeg-{{VERSION}}-win32-ia32.zip', -+ 'ffmpeg-{{VERSION}}-win32-x64.zip' -+ ] -+ return patterns.map(pattern => pattern.replace(/{{VERSION}}/g, version)) -+} -+ -+function s3UrlsForVersion (version) { -+ const bucket = 'https://gh-contractor-zcbenz.s3.amazonaws.com/' -+ const patterns = [ -+ 'atom-shell/dist/{{VERSION}}/iojs-{{VERSION}}-headers.tar.gz', -+ 'atom-shell/dist/{{VERSION}}/iojs-{{VERSION}}.tar.gz', -+ 'atom-shell/dist/{{VERSION}}/node-{{VERSION}}.tar.gz', -+ 'atom-shell/dist/{{VERSION}}/node.lib', -+ 'atom-shell/dist/{{VERSION}}/win-x64/iojs.lib', -+ 'atom-shell/dist/{{VERSION}}/win-x86/iojs.lib', -+ 'atom-shell/dist/{{VERSION}}/x64/node.lib', -+ 'atom-shell/dist/index.json' -+ ] -+ return patterns.map(pattern => bucket + pattern.replace(/{{VERSION}}/g, version)) -+} -added in both - our 100755 84e00ad4f309201f151c3f8fcbaf9ee536c9b6cb script/release.js - their 100755 54379f8ff9ea9fc19a0ba3349c0019f23383b94f script/release.js -@@ -1,8 +1,14 @@ - #!/usr/bin/env node - -+<<<<<<< .our - if (!process.env.CI) require('dotenv-safe').load() - require('colors') - const args = require('minimist')(process.argv.slice(2)) -+======= -+require('colors') -+const args = require('minimist')(process.argv.slice(2)) -+const assert = require('assert') -+>>>>>>> .their - const fs = require('fs') - const { execSync } = require('child_process') - const GitHub = require('github') -@@ -16,16 +22,30 @@ - const sumchecker = require('sumchecker') - const temp = require('temp').track() - const { URL } = require('url') -+<<<<<<< .our - const targetRepo = pkgVersion.indexOf('nightly') > 0 ? 'nightlies' : 'electron' - let failureCount = 0 - -+======= -+let failureCount = 0 -+ -+assert(process.env.ELECTRON_GITHUB_TOKEN, 'ELECTRON_GITHUB_TOKEN not found in environment') -+ -+>>>>>>> .their - const github = new GitHub({ - followRedirects: false - }) - github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN}) -+<<<<<<< .our - - async function getDraftRelease (version, skipValidation) { - let releaseInfo = await github.repos.getReleases({owner: 'electron', repo: targetRepo}) -+======= -+const gitDir = path.resolve(__dirname, '..') -+ -+async function getDraftRelease (version, skipValidation) { -+ let releaseInfo = await github.repos.getReleases({owner: 'electron', repo: 'electron'}) -+>>>>>>> .their - let drafts - let versionToCheck - if (version) { -@@ -49,8 +69,13 @@ - return draft - } - -+<<<<<<< .our - async function validateReleaseAssets (release, validatingRelease) { - const requiredAssets = assetsForVersion(release.tag_name, validatingRelease).sort() -+======= -+async function validateReleaseAssets (release) { -+ const requiredAssets = assetsForVersion(release.tag_name).sort() -+>>>>>>> .their - const extantAssets = release.assets.map(asset => asset.name).sort() - const downloadUrls = release.assets.map(asset => asset.browser_download_url).sort() - -@@ -60,6 +85,7 @@ - }) - check((failureCount === 0), `All required GitHub assets exist for release`, true) - -+<<<<<<< .our - if (!validatingRelease || !release.draft) { - if (release.draft) { - await verifyAssets(release) -@@ -72,6 +98,18 @@ - const s3Urls = s3UrlsForVersion(release.tag_name) - await verifyShasums(s3Urls, true) - } -+======= -+ if (release.draft) { -+ await verifyAssets(release) -+ } else { -+ await verifyShasums(downloadUrls) -+ .catch(err => { -+ console.log(`${fail} error verifyingShasums`, err) -+ }) -+ } -+ const s3Urls = s3UrlsForVersion(release.tag_name) -+ await verifyShasums(s3Urls, true) -+>>>>>>> .their - } - - function check (condition, statement, exitIfFail = false) { -@@ -84,13 +122,22 @@ - } - } - -+<<<<<<< .our - function assetsForVersion (version, validatingRelease) { -+======= -+function assetsForVersion (version) { -+>>>>>>> .their - const patterns = [ - `electron-${version}-darwin-x64-dsym.zip`, - `electron-${version}-darwin-x64-symbols.zip`, - `electron-${version}-darwin-x64.zip`, -+<<<<<<< .our - `electron-${version}-linux-arm64-symbols.zip`, - `electron-${version}-linux-arm64.zip`, -+======= -+ `electron-${version}-linux-arm-symbols.zip`, -+ `electron-${version}-linux-arm.zip`, -+>>>>>>> .their - `electron-${version}-linux-armv7l-symbols.zip`, - `electron-${version}-linux-armv7l.zip`, - `electron-${version}-linux-ia32-symbols.zip`, -@@ -109,17 +156,27 @@ - `electron-api.json`, - `electron.d.ts`, - `ffmpeg-${version}-darwin-x64.zip`, -+<<<<<<< .our - `ffmpeg-${version}-linux-arm64.zip`, -+======= -+ `ffmpeg-${version}-linux-arm.zip`, -+>>>>>>> .their - `ffmpeg-${version}-linux-armv7l.zip`, - `ffmpeg-${version}-linux-ia32.zip`, - `ffmpeg-${version}-linux-x64.zip`, - `ffmpeg-${version}-mas-x64.zip`, - `ffmpeg-${version}-win32-ia32.zip`, -+<<<<<<< .our - `ffmpeg-${version}-win32-x64.zip` - ] - if (!validatingRelease) { - patterns.push('SHASUMS256.txt') - } -+======= -+ `ffmpeg-${version}-win32-x64.zip`, -+ `SHASUMS256.txt` -+ ] -+>>>>>>> .their - return patterns - } - -@@ -141,6 +198,7 @@ - } - - function checkVersion () { -+<<<<<<< .our - if (args.skipVersionCheck) return - - console.log(`Verifying that app version matches package version ${pkgVersion}.`) -@@ -150,6 +208,11 @@ - scriptArgs.unshift('-R') - } - let appVersion = runScript(startScript, scriptArgs).trim() -+======= -+ console.log(`Verifying that app version matches package version ${pkgVersion}.`) -+ let startScript = path.join(__dirname, 'start.py') -+ let appVersion = runScript(startScript, ['--version']).trim() -+>>>>>>> .their - check((pkgVersion.indexOf(appVersion) === 0), `App version ${appVersion} matches ` + - `package version ${pkgVersion}.`, true) - } -@@ -180,7 +243,11 @@ - function uploadIndexJson () { - console.log('Uploading index.json to S3.') - let scriptPath = path.join(__dirname, 'upload-index-json.py') -+<<<<<<< .our - runScript(scriptPath, [pkgVersion]) -+======= -+ runScript(scriptPath, []) -+>>>>>>> .their - console.log(`${pass} Done uploading index.json to S3.`) - } - -@@ -191,7 +258,11 @@ - console.log(`${fileName} already exists on GitHub; deleting before creating new file.`) - await github.repos.deleteAsset({ - owner: 'electron', -+<<<<<<< .our - repo: targetRepo, -+======= -+ repo: 'electron', -+>>>>>>> .their - id: existingAssets[0].id - }).catch(err => { - console.log(`${fail} Error deleting ${fileName} on GitHub:`, err) -@@ -210,7 +281,11 @@ - async function uploadShasumFile (filePath, fileName, release) { - let githubOpts = { - owner: 'electron', -+<<<<<<< .our - repo: targetRepo, -+======= -+ repo: 'electron', -+>>>>>>> .their - id: release.id, - filePath, - name: fileName -@@ -245,7 +320,11 @@ - async function publishRelease (release) { - let githubOpts = { - owner: 'electron', -+<<<<<<< .our - repo: targetRepo, -+======= -+ repo: 'electron', -+>>>>>>> .their - id: release.id, - tag_name: release.tag_name, - draft: false -@@ -259,6 +338,7 @@ - - async function makeRelease (releaseToValidate) { - if (releaseToValidate) { -+<<<<<<< .our - if (releaseToValidate === true) { - releaseToValidate = pkgVersion - } else { -@@ -267,18 +347,31 @@ - console.log(`Validating release ${releaseToValidate}`) - let release = await getDraftRelease(releaseToValidate) - await validateReleaseAssets(release, true) -+======= -+ console.log(`Validating release ${args.validateRelease}`) -+ let release = await getDraftRelease(args.validateRelease) -+ await validateReleaseAssets(release) -+>>>>>>> .their - } else { - checkVersion() - let draftRelease = await getDraftRelease() - uploadNodeShasums() - uploadIndexJson() -+<<<<<<< .our - -+======= -+>>>>>>> .their - await createReleaseShasums(draftRelease) - // Fetch latest version of release before verifying - draftRelease = await getDraftRelease(pkgVersion, true) - await validateReleaseAssets(draftRelease) -+<<<<<<< .our - await tagLibCC() - await publishRelease(draftRelease) -+======= -+ await publishRelease(draftRelease) -+ await cleanupReleaseBranch() -+>>>>>>> .their - console.log(`${pass} SUCCESS!!! Release has been published. Please run ` + - `"npm run publish-to-npm" to publish release to npm.`) - } -@@ -300,7 +393,11 @@ - let downloadDir = await makeTempDir() - let githubOpts = { - owner: 'electron', -+<<<<<<< .our - repo: targetRepo, -+======= -+ repo: 'electron', -+>>>>>>> .their - headers: { - Accept: 'application/octet-stream' - } -@@ -446,6 +543,7 @@ - `shasums defined in ${validationArgs.shaSumFile}.`) - } - -+<<<<<<< .our - async function tagLibCC () { - const tag = `electron-${pkg.version}` - const libccDir = path.join(path.resolve(__dirname, '..'), 'vendor', 'libchromiumcontent') -@@ -462,6 +560,26 @@ - } else { - console.log(`${fail} Error tagging libchromiumcontent with ${tag}: ` + - `${tagDetails.stderr}`) -+======= -+async function cleanupReleaseBranch () { -+ console.log(`Cleaning up release branch.`) -+ let errorMessage = `Could not delete local release branch.` -+ let successMessage = `Successfully deleted local release branch.` -+ await callGit(['branch', '-D', 'release-1-7-x'], errorMessage, successMessage) -+ errorMessage = `Could not delete remote release branch.` -+ successMessage = `Successfully deleted remote release branch.` -+ return callGit(['push', 'origin', ':release'], errorMessage, successMessage) -+} -+ -+async function callGit (args, errorMessage, successMessage) { -+ let gitResult = await GitProcess.exec(args, gitDir) -+ if (gitResult.exitCode === 0) { -+ console.log(`${pass} ${successMessage}`) -+ return true -+ } else { -+ console.log(`${fail} ${errorMessage} ${gitResult.stderr}`) -+ process.exit(1) -+>>>>>>> .their - } - } - -changed in both - base 100755 94cdb4e9ce644b87fbe0d18ea8c7ad5234486250 script/update-external-binaries.py - our 100755 0bc9d0f632057f4a17aa811340ba21631433f173 script/update-external-binaries.py - their 100755 a207ad3a1a15e5b01eb85ba382267aa2594dbd98 script/update-external-binaries.py -@@ -8,7 +8,12 @@ - from lib.util import add_exec_bit, download, extract_zip, rm_rf, \ - safe_mkdir, tempdir - -+<<<<<<< .our - VERSION = 'v1.4.0' -+======= -+ -+VERSION = 'v1.2.2' -+>>>>>>> .their - SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) - FRAMEWORKS_URL = 'http://github.com/electron/electron-frameworks/releases' \ - '/download/' + VERSION -added in both - our 100644 2facda2daa1b8a8ccb63a28198a15b7e7ecb0880 script/upload-to-github.js - their 100644 7c3f8d9c11ce7b75f307850663efd2e571e8644a script/upload-to-github.js -@@ -1,16 +1,24 @@ -+<<<<<<< .our - if (!process.env.CI) require('dotenv-safe').load() - -+======= -+>>>>>>> .their - const GitHub = require('github') - const github = new GitHub() - github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN}) - -+<<<<<<< .our - if (process.argv.length < 6) { -+======= -+if (process.argv.length < 5) { -+>>>>>>> .their - console.log('Usage: upload-to-github filePath fileName releaseId') - process.exit(1) - } - let filePath = process.argv[2] - let fileName = process.argv[3] - let releaseId = process.argv[4] -+<<<<<<< .our - let releaseVersion = process.argv[5] - - const targetRepo = releaseVersion.indexOf('nightly') > 0 ? 'nightlies' : 'electron' -@@ -18,6 +26,12 @@ - let githubOpts = { - owner: 'electron', - repo: targetRepo, -+======= -+ -+let githubOpts = { -+ owner: 'electron', -+ repo: 'electron', -+>>>>>>> .their - id: releaseId, - filePath: filePath, - name: fileName -@@ -39,7 +53,11 @@ - console.log(`${fileName} already exists; will delete before retrying upload.`) - github.repos.deleteAsset({ - owner: 'electron', -+<<<<<<< .our - repo: targetRepo, -+======= -+ repo: 'electron', -+>>>>>>> .their - id: existingAssets[0].id - }).then(uploadToGitHub).catch(uploadToGitHub) - } else { -changed in both - base 100755 455ed789e0a081bc411adb02b75995bede18c25f script/upload.py - our 100755 2d9eaa201265971ca01acaea6e84a440e5db0532 script/upload.py - their 100755 4da630433812b51ff0ebbdf89f68c71d90ab8046 script/upload.py -@@ -51,6 +51,7 @@ - return 1 - - tag_exists = False -+<<<<<<< .our - release = get_release(args.version) - if not release['draft']: - tag_exists = True -@@ -84,6 +85,55 @@ - # Upload the x64 binary for arm/arm64 mksnapshot - mksnapshot = get_zip_name('mksnapshot', ELECTRON_VERSION, 'x64') - upload_electron(release, os.path.join(DIST_DIR, mksnapshot), args) -+======= -+ for r in releases: -+ if not r['draft'] and r['tag_name'] == args.version: -+ release = r -+ tag_exists = True -+ break -+ -+ if not args.upload_to_s3: -+ assert tag_exists == args.overwrite, \ -+ 'You have to pass --overwrite to overwrite a published release' -+ if not args.overwrite: -+ release = create_or_get_release_draft(github, releases, args.version, -+ tag_exists) -+ -+ # Upload Electron with GitHub Releases API. -+ upload_electron(github, release, os.path.join(DIST_DIR, DIST_NAME), -+ args.upload_to_s3) -+ if get_target_arch() != 'mips64el': -+ upload_electron(github, release, os.path.join(DIST_DIR, SYMBOLS_NAME), -+ args.upload_to_s3) -+ if PLATFORM == 'darwin': -+ upload_electron(github, release, os.path.join(DIST_DIR, -+ 'electron-api.json'), args.upload_to_s3) -+ upload_electron(github, release, os.path.join(DIST_DIR, 'electron.d.ts'), -+ args.upload_to_s3) -+ upload_electron(github, release, os.path.join(DIST_DIR, DSYM_NAME), -+ args.upload_to_s3) -+ elif PLATFORM == 'win32': -+ upload_electron(github, release, os.path.join(DIST_DIR, PDB_NAME), -+ args.upload_to_s3) -+ -+ # Upload free version of ffmpeg. -+ ffmpeg = get_zip_name('ffmpeg', ELECTRON_VERSION) -+ upload_electron(github, release, os.path.join(DIST_DIR, ffmpeg), -+ args.upload_to_s3) -+ -+ # Upload chromedriver and mksnapshot for minor version update. -+ if parse_version(args.version)[2] == '0': -+ chromedriver = get_zip_name('chromedriver', ELECTRON_VERSION) -+ upload_electron(github, release, os.path.join(DIST_DIR, chromedriver), -+ args.upload_to_s3) -+ mksnapshot = get_zip_name('mksnapshot', ELECTRON_VERSION) -+ upload_electron(github, release, os.path.join(DIST_DIR, mksnapshot), -+ args.upload_to_s3) -+ -+ if PLATFORM == 'win32' and not tag_exists and not args.upload_to_s3: -+ # Upload PDBs to Windows symbol server. -+ run_python_script('upload-windows-pdb.py') -+>>>>>>> .their - - if not tag_exists and not args.upload_to_s3: - # Upload symbols to symbol server. -@@ -149,7 +199,66 @@ - return dist_time > int(head_time) - - -+<<<<<<< .our - def upload_electron(release, file_path, args): -+======= -+def get_text_with_editor(name): -+ editor = os.environ.get('EDITOR', 'nano') -+ initial_message = '\n# Please enter the body of your release note for %s.' \ -+ % name -+ -+ t = tempfile.NamedTemporaryFile(suffix='.tmp', delete=False) -+ t.write(initial_message) -+ t.close() -+ subprocess.call([editor, t.name]) -+ -+ text = '' -+ for line in open(t.name, 'r'): -+ if len(line) == 0 or line[0] != '#': -+ text += line -+ -+ os.unlink(t.name) -+ return text -+ -+def create_or_get_release_draft(github, releases, tag, tag_exists): -+ # Search for existing draft. -+ for release in releases: -+ if release['draft'] and release['tag_name'] == tag: -+ return release -+ -+ if tag_exists: -+ tag = 'do-not-publish-me' -+ return create_release_draft(github, tag) -+ -+ -+def create_release_draft(github, tag): -+ name = '{0} {1} beta'.format(PROJECT_NAME, tag) -+ if os.environ.has_key('CI'): -+ body = '(placeholder)' -+ else: -+ body = get_text_with_editor(name) -+ if body == '': -+ sys.stderr.write('Quit due to empty release note.\n') -+ sys.exit(0) -+ -+ data = dict(tag_name=tag, name=name, body=body, draft=True, prerelease=True) -+ r = github.repos(ELECTRON_REPO).releases.post(data=data) -+ return r -+ -+ -+def upload_electron(github, release, file_path, upload_to_s3): -+ -+ # if upload_to_s3 is set, skip github upload. -+ if upload_to_s3: -+ bucket, access_key, secret_key = s3_config() -+ key_prefix = 'electron-artifacts/{0}'.format(release['tag_name']) -+ s3put(bucket, access_key, secret_key, os.path.dirname(file_path), -+ key_prefix, [file_path]) -+ upload_sha256_checksum(release['tag_name'], file_path, key_prefix) -+ return -+ -+ # Delete the original file before uploading in CI. -+>>>>>>> .their - filename = os.path.basename(file_path) - - # if upload_to_s3 is set, skip github upload. -@@ -165,6 +274,7 @@ - return - - # Upload the file. -+<<<<<<< .our - upload_io_to_github(release, filename, file_path, args.version) - - # Upload the checksum file. -@@ -177,6 +287,27 @@ - script_path = os.path.join(SOURCE_ROOT, 'script', 'upload-to-github.js') - execute(['node', script_path, filepath, filename, str(release['id']), - version]) -+======= -+ upload_io_to_github(release, filename, file_path) -+ -+ # Upload the checksum file. -+ upload_sha256_checksum(release['tag_name'], file_path) -+ -+ # Upload ARM assets without the v7l suffix for backwards compatibility -+ # TODO Remove for 2.0 -+ if 'armv7l' in filename: -+ arm_filename = filename.replace('armv7l', 'arm') -+ arm_file_path = os.path.join(os.path.dirname(file_path), arm_filename) -+ shutil.copy2(file_path, arm_file_path) -+ upload_electron(github, release, arm_file_path, upload_to_s3) -+ -+ -+def upload_io_to_github(release, filename, filepath): -+ print 'Uploading %s to Github' % \ -+ (filename) -+ script_path = os.path.join(SOURCE_ROOT, 'script', 'upload-to-github.js') -+ execute(['node', script_path, filepath, filename, str(release['id'])]) -+>>>>>>> .their - - - def upload_sha256_checksum(version, file_path, key_prefix=None): -changed in both - base 100644 1df816807ddb0fb20d91f9a6536381126ff9ebb7 spec/api-app-spec.js - our 100644 d224eda2989332c18d655cef05a8bacc2eb6d4b8 spec/api-app-spec.js - their 100644 a8c288e771ecb3f1fd8807f7dc9a776769395b03 spec/api-app-spec.js -@@ -196,6 +196,7 @@ - }) - }) - -+<<<<<<< .our - // TODO(MarshallOfSound) - Remove in 4.0.0 - describe('app.makeSingleInstance', () => { - it('prevents the second launch of app', function (done) { -@@ -233,11 +234,41 @@ - expect(code).to.equal(1) - done() - }) -+======= -+ describe('app.makeSingleInstance', function () { -+ it('prevents the second launch of app', function (done) { -+ this.timeout(120000) -+ const appPath = path.join(__dirname, 'fixtures', 'api', 'singleton') -+ // First launch should exit with 0. -+ let secondLaunched = false -+ const first = ChildProcess.spawn(remote.process.execPath, [appPath]) -+ let launchOnce = true -+ first.stdout.on('data', (data) => { -+ if (data.toString().trim() === 'launched' && launchOnce) { -+ launchOnce = false -+ // Second launch should exit with 1. -+ const second = ChildProcess.spawn(remote.process.execPath, [appPath]) -+ second.once('exit', (code) => { -+ assert.ok(!secondLaunched) -+ assert.equal(code, 1) -+ secondLaunched = true -+ }) -+ } -+ }) -+ first.once('exit', (code) => { -+ assert.ok(secondLaunched) -+ assert.equal(code, 0) -+ done() -+>>>>>>> .their - }) - }) - }) - -+<<<<<<< .our - describe('app.relaunch', () => { -+======= -+ describe('app.relaunch', function () { -+>>>>>>> .their - let server = null - const socketPath = process.platform === 'win32' ? '\\\\.\\pipe\\electron-app-relaunch' : '/tmp/electron-app-relaunch' - -@@ -294,8 +325,16 @@ - }) - }) - -+<<<<<<< .our - xdescribe('app.importCertificate', () => { - let w = null -+======= -+ xdescribe('app.importCertificate', function () { -+ if (process.platform !== 'linux') return -+ -+ this.timeout(120000) -+ var w = null -+>>>>>>> .their - - before(function () { - if (process.platform !== 'linux') { -@@ -535,7 +574,11 @@ - }) - }) - -+<<<<<<< .our - describe('select-client-certificate event', () => { -+======= -+ xdescribe('select-client-certificate event', function () { -+>>>>>>> .their - let w = null - - before(function () { -@@ -688,6 +731,54 @@ - this.skip() - } - }) -+<<<<<<< .our -+======= -+ -+ it('does not launch for blacklisted argument', function (done) { -+ const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app') -+ // App should exit with non 123 code. -+ const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'electron-test://?', '--no-sandbox', '--gpu-launcher=cmd.exe /c start calc']) -+ first.once('exit', (code) => { -+ assert.notEqual(code, 123) -+ done() -+ }) -+ }) -+ -+ it('launches successfully for multiple uris in cmd args', function (done) { -+ const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app') -+ // App should exit with code 123. -+ const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'http://electronjs.org', 'electron-test://testdata']) -+ first.once('exit', (code) => { -+ assert.equal(code, 123) -+ done() -+ }) -+ }) -+ -+ it('does not launch for encoded space', function (done) { -+ const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app') -+ // App should exit with non 123 code. -+ const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'electron-test://?', '--no-sandbox', '--gpu-launcher%20"cmd.exe /c start calc']) -+ first.once('exit', (code) => { -+ assert.notEqual(code, 123) -+ done() -+ }) -+ }) -+ -+ it('launches successfully for argnames similar to blacklisted ones', function (done) { -+ const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app') -+ // inspect is blacklisted, but inspector should work, and app launch should succeed -+ const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'electron-test://?', '--inspector']) -+ first.once('exit', (code) => { -+ assert.equal(code, 123) -+ done() -+ }) -+ }) -+ }) -+ -+ describe('getFileIcon() API', function () { -+ // FIXME Get these specs running on Linux CI -+ if (process.platform === 'linux' && isCI) return -+>>>>>>> .their - - it('does not launch for argument following a URL', done => { - const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app') -changed in both - base 100644 52c9b5fb47e3f559785104958b65824d511fa986 spec/api-browser-window-spec.js - our 100644 f4cba12ec19d224bc46fca898db42a99baf4972e spec/api-browser-window-spec.js - their 100644 f4222145dba6f9e773d7d657cc688ad9efb55afa spec/api-browser-window-spec.js -changed in both - base 100644 2f9f2b2795adbe396b683ed9854c6675a50d6ba4 spec/chromium-spec.js - our 100644 d90269769d269e4054d25cba4b6c4ac8a1929aa6 spec/chromium-spec.js - their 100644 e18b1a141eac068348eb34d064a357929b243a5f spec/chromium-spec.js -@@ -319,8 +319,12 @@ - b = window.open(windowUrl, '', 'nodeIntegration=no,show=no') - }) - -+<<<<<<< .our - // TODO(codebytere): re-enable this test - xit('disables node integration when it is disabled on the parent window for chrome devtools URLs', (done) => { -+======= -+ it('disables node integration when it is disabled on the parent window for chrome devtools URLs', (done) => { -+>>>>>>> .their - let b - app.once('web-contents-created', (event, contents) => { - contents.once('did-finish-load', () => { -added in both - our 100644 3202a7a180d6d48c70706d5ef244652872b24bbc spec/fixtures/api/singleton/main.js - their 100644 665987c8400f1183d009e3aad3bfab0860529de1 spec/fixtures/api/singleton/main.js -@@ -1,5 +1,6 @@ - const {app} = require('electron') - -+<<<<<<< .our - app.once('ready', () => { - console.log('started') // ping parent - }) -@@ -11,5 +12,18 @@ - }) - - if (!gotTheLock) { -+======= -+console.log('launched') -+ -+process.on('uncaughtException', () => { -+ app.exit(2) -+}) -+ -+const shouldExit = app.makeSingleInstance(() => { -+ process.nextTick(() => app.exit(0)) -+}) -+ -+if (shouldExit) { -+>>>>>>> .their - app.exit(1) - } -changed in both - base 100644 1211b3ea8bb8f45b69c4479ce9c4ce42a2d84373 spec/package.json - our 100644 37dec32f876cbe6a0b07b78922140397947a818a spec/package.json - their 100644 0bedddc69f0b1c930b90ced3f38726649e82fe49 spec/package.json -@@ -13,11 +13,19 @@ - "dirty-chai": "^2.0.1", - "graceful-fs": "^4.1.11", - "mkdirp": "^0.5.1", -+<<<<<<< .our - "mocha": "^5.2.0", - "mocha-junit-reporter": "^1.17.0", - "multiparty": "^4.1.4", - "q": "^1.5.1", - "send": "^0.16.2", -+======= -+ "mocha": "^3.1.0", -+ "mocha-junit-reporter": "^1.14.0", -+ "multiparty": "^4.1.3", -+ "q": "^1.4.1", -+ "send": "^0.14.1", -+>>>>>>> .their - "temp": "^0.8.3", - "walkdir": "0.0.12", - "winreg": "^1.2.4", -changed in both - base 100644 74a9e6d278e9e96968d8e3b75303456b4a756825 spec/static/index.html - our 100644 fc1e153c0af2908cf7ee4c3ea4f05522de04f0f8 spec/static/index.html - their 100644 39f523f7d96b322ce39323040426ef517ee3c261 spec/static/index.html -@@ -44,12 +44,24 @@ - const { Coverage } = require('electabul') - const Mocha = require('mocha') - -+<<<<<<< .our - const mocha = new Mocha(process.env.MOCHA_REPORTER - ? { reporter: process.env.MOCHA_REPORTER } - : undefined) - - if (!process.env.MOCHA_REPORTER) { - mocha.ui('bdd').reporter(isCi ? 'tap' : 'html') -+======= -+ var Mocha = require('mocha'); -+ var mochaOpts = {}; -+ if (process.env.MOCHA_REPORTER) { -+ mochaOpts.reporter = process.env.MOCHA_REPORTER; -+ } -+ var mocha = new Mocha(mochaOpts); -+ -+ if (!process.env.MOCHA_REPORTER) { -+ mocha.ui('bdd').reporter(isCi ? 'tap' : 'html'); -+>>>>>>> .their - } - mocha.timeout(isCi ? 30000 : 10000) - -changed in both - base 160000 92e2d6a9657444dfbdcb89f986c8705bdda3dccf vendor/libchromiumcontent - our 160000 c85470a1c379b1c4bedb372c146521bc4be9b75d vendor/libchromiumcontent - their 160000 4a4acde5522c21fe2f0a21f5ca29f99e90b03adc vendor/libchromiumcontent -changed in both - base 160000 dfa72e2c73e0442d27746e0f8716d0427f7f9b27 vendor/node - our 160000 ece0a06ac8147efb5b5af431c21f312f1884616e vendor/node - their 160000 a992f2ff412b85606ec1d4c1eb00ad832fa1e640 vendor/node -added in both - our 100644 84bd69c2b2868ac23bc30061aa208ad38fbb9506 vsts.yml - their 100644 aaee2e6522650cd470f09e43b74b4d0a126c2128 vsts.yml -@@ -59,7 +59,11 @@ - - bash: | - echo 'Verifying ffmpeg on build' - if [ "$ELECTRON_RELEASE" == "1" ]; then -+<<<<<<< .our - script/verify-ffmpeg.py -c R -+======= -+ script/verify-ffmpeg.py -R -+>>>>>>> .their - else - script/verify-ffmpeg.py - fi -@@ -69,6 +73,7 @@ - - task: PublishTestResults@2 - displayName: Publish Test Results - inputs: -+<<<<<<< .our - testResultsFiles: '**/test-*.xml' - condition: and(always(), eq(variables['MOCHA_FILE'], 'test-results.xml')) - -@@ -93,5 +98,18 @@ - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/out' - ArtifactName: out -+======= -+ testResultsFiles: 'test-results.xml' -+ searchFolder: junit -+ condition: and(always(), ne(variables['ELECTRON_RELEASE'], '1')) -+ -+- task: kasunkodagoda.slack-notification.slack-notification-task.SlackNotification@3 -+ displayName: Post Slack Notification -+ inputs: -+ SlackApiToken: '$(slack_token)' -+ Channel: '#bot-nightly-releases' -+ Message: '$(Build.DefinitionName)-$(Build.BuildNumber) finished with a $(Agent.JobStatus) status.' -+ condition: and(always(), eq(variables['Build.Reason'], 'Schedule')) -+>>>>>>> .their - - - task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3 diff --git a/app/test/fixtures/merge-parser/electron/merge-1-8-x-into-master.txt b/app/test/fixtures/merge-parser/electron/merge-1-8-x-into-master.txt deleted file mode 100644 index df79003098f..00000000000 --- a/app/test/fixtures/merge-parser/electron/merge-1-8-x-into-master.txt +++ /dev/null @@ -1,11139 +0,0 @@ -changed in both - base 100644 e3a808718b918ad0b158ee4e8d0fdbb811fbf191 .circleci/config.yml - our 100644 6d44d618aabcce04c60344f2274dec5b0c2a1f68 .circleci/config.yml - their 100644 0563a8274cd113b56243a76f5057013bfafb7118 .circleci/config.yml -@@ -352,6 +352,7 @@ - version: 2 - jobs: - electron-linux-arm: -+<<<<<<< .our - environment: - TARGET_ARCH: arm - <<: *build-defaults -@@ -359,6 +360,13 @@ - - electron-linux-arm-test: - machine: true -+======= -+ docker: -+ - image: electronbuilds/electron:0.0.7 -+ environment: -+ TARGET_ARCH: arm -+ resource_class: 2xlarge -+>>>>>>> .their - steps: - - attach_workspace: - at: /tmp/workspace/project/out -@@ -391,6 +399,7 @@ - resource_class: 2xlarge - - electron-linux-arm64: -+<<<<<<< .our - environment: - TARGET_ARCH: arm64 - <<: *build-defaults -@@ -398,6 +407,13 @@ - - electron-linux-arm64-test: - machine: true -+======= -+ docker: -+ - image: electronbuilds/electron:0.0.7 -+ environment: -+ TARGET_ARCH: arm64 -+ resource_class: 2xlarge -+>>>>>>> .their - steps: - - attach_workspace: - at: /tmp/workspace/project/out -@@ -430,12 +446,19 @@ - resource_class: 2xlarge - - electron-linux-ia32: -+<<<<<<< .our - environment: - TARGET_ARCH: ia32 - DISPLAY: ':99.0' - RUN_TESTS: true - RUN_HEADLESS_TESTS: true - <<: *build-defaults -+======= -+ docker: -+ - image: electronbuilds/electron:0.0.7 -+ environment: -+ TARGET_ARCH: ia32 -+>>>>>>> .their - resource_class: xlarge - - electron-linux-ia32-release-nightly: -@@ -447,12 +470,20 @@ - resource_class: xlarge - - electron-linux-mips64el: -+<<<<<<< .our - environment: - TARGET_ARCH: mips64el - <<: *build-defaults -+======= -+ docker: -+ - image: electronbuilds/electron:0.0.7 -+ environment: -+ TARGET_ARCH: mips64el -+>>>>>>> .their - resource_class: xlarge - - electron-linux-x64: -+<<<<<<< .our - environment: - TARGET_ARCH: x64 - DISPLAY: ':99.0' -@@ -469,10 +500,107 @@ - NIGHTLY_BUILD: true - <<: *build-defaults - resource_class: xlarge -+======= -+ docker: -+ - image: electronbuilds/electron:0.0.7 -+ environment: -+ TARGET_ARCH: x64 -+ DISPLAY: ':99.0' -+ resource_class: 2xlarge -+ steps: -+ - checkout -+ - run: -+ name: Setup for headless testing -+ command: sh -e /etc/init.d/xvfb start -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ no_output_timeout: 30m -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Test -+ environment: -+ MOCHA_FILE: junit/test-results.xml -+ MOCHA_REPORTER: mocha-junit-reporter -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Testing Electron debug build' -+ mkdir junit -+ script/test.py --ci --rebuild_native_modules -+ else -+ echo 'Skipping testing on release build' -+ fi -+ - run: -+ name: Verify FFmpeg -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Verifying ffmpeg on debug build' -+ script/verify-ffmpeg.py -+ else -+ echo 'Skipping verify ffmpeg on release build' -+ fi -+ - run: -+ name: Generate Typescript Definitions -+ command: npm run create-typescript-definitions -+ - store_test_results: -+ path: junit -+ - store_artifacts: -+ path: junit -+ - store_artifacts: -+ path: out/electron.d.ts -+ - store_artifacts: -+ path: out/electron-api.json -+>>>>>>> .their - - electron-osx-x64: - environment: - TARGET_ARCH: x64 -+<<<<<<< .our - RUN_TESTS: true - INSTALL_MACOS_NODE: true - macos: -@@ -488,11 +616,109 @@ - macos: - xcode: "8.3.3" - <<: *build-steps -+======= -+ macos: -+ xcode: "9.0" -+ resource_class: 2xlarge -+ steps: -+ - checkout -+ - run: -+ name: Reclaim disk space -+ command: | -+ df -h -+ sudo rm -rf /Library/Developer/CoreSimulator -+ df -h -+ sysctl -n hw.ncpu -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ no_output_timeout: 30m -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Test -+ environment: -+ MOCHA_FILE: junit/test-results.xml -+ MOCHA_REPORTER: mocha-junit-reporter -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Testing Electron debug build' -+ mkdir junit -+ script/test.py --ci --rebuild_native_modules -+ else -+ echo 'Skipping testing on release build' -+ fi -+ - run: -+ name: Verify FFmpeg -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Verifying ffmpeg on debug build' -+ script/verify-ffmpeg.py -+ else -+ echo 'Skipping verify ffmpeg on release build' -+ fi -+ - run: -+ name: Generate Typescript Definitions -+ command: npm run create-typescript-definitions -+ - store_test_results: -+ path: junit -+ - store_artifacts: -+ path: junit -+ - store_artifacts: -+ path: out/electron.d.ts -+ - store_artifacts: -+ path: out/electron-api.json -+>>>>>>> .their - - electron-mas-x64: - environment: - TARGET_ARCH: x64 - MAS_BUILD: 1 -+<<<<<<< .our - RUN_TESTS: true - INSTALL_MACOS_NODE: true - macos: -@@ -668,6 +894,103 @@ - GN_EXTRA_ARGS: 'is_mas_build = true' - <<: *gn-mac-build-machine - <<: *gn-mac-build-steps -+======= -+ macos: -+ xcode: "9.0" -+ resource_class: 2xlarge -+ steps: -+ - checkout -+ - run: -+ name: Reclaim disk space -+ command: | -+ df -h -+ sudo rm -rf /Library/Developer/CoreSimulator -+ df -h -+ sysctl -n hw.ncpu -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ no_output_timeout: 30m -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Test -+ environment: -+ MOCHA_FILE: junit/test-results.xml -+ MOCHA_REPORTER: mocha-junit-reporter -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Testing Electron debug build' -+ mkdir junit -+ script/test.py --ci --rebuild_native_modules -+ else -+ echo 'Skipping testing on release build' -+ fi -+ - run: -+ name: Verify FFmpeg -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Verifying ffmpeg on debug build' -+ script/verify-ffmpeg.py -+ else -+ echo 'Skipping verify ffmpeg on release build' -+ fi -+ - run: -+ name: Generate Typescript Definitions -+ command: npm run create-typescript-definitions -+ - store_test_results: -+ path: junit -+ - store_artifacts: -+ path: junit -+ - store_artifacts: -+ path: out/electron.d.ts -+ - store_artifacts: -+ path: out/electron-api.json -+>>>>>>> .their - - workflows: - version: 2 -@@ -689,12 +1012,19 @@ - build-x64: - jobs: - - electron-linux-x64 -+<<<<<<< .our -+======= -+ build-mips64el: -+ jobs: -+ - electron-linux-mips64el -+>>>>>>> .their - build-osx-x64: - jobs: - - electron-osx-x64 - build-mas-x64: - jobs: - - electron-mas-x64 -+<<<<<<< .our - build-gn-linux: - jobs: - - electron-gn-linux-x64-debug-fyi -@@ -745,3 +1075,5 @@ - - electron-gn-linux-arm64-release-fyi - - electron-gn-mas-release-fyi - - electron-gn-osx-release-fyi -+======= -+>>>>>>> .their -changed in both - base 100644 eb045368b7a5ce226368c7c2955db1fe1ac676e5 .gitignore - our 100644 f393b1cdcef87b41bb3ed47ebae59757fed3a780 .gitignore - their 100644 97d35686044a0257a78fc58ed5fa2f096a6aec66 .gitignore -@@ -27,6 +27,7 @@ - /external_binaries/ - /out/ - /vendor/.gclient -+<<<<<<< .our - /vendor/debian_jessie_mips64-sysroot/ - /vendor/debian_stretch_amd64-sysroot/ - /vendor/debian_stretch_arm-sysroot/ -@@ -34,6 +35,17 @@ - /vendor/debian_stretch_i386-sysroot/ - /vendor/gcc-4.8.3-d197-n64-loongson/ - /vendor/readme-gcc483-loongson.txt -+======= -+/vendor/cross-gcc-4.9.3-n64-loongson-rc5.4 -+/vendor/debian_jessie_amd64-sysroot/ -+/vendor/debian_jessie_arm-sysroot/ -+/vendor/debian_jessie_arm64-sysroot/ -+/vendor/debian_jessie_i386-sysroot/ -+/vendor/debian_jessie_mips64-sysroot/ -+/vendor/debian_wheezy_amd64-sysroot/ -+/vendor/debian_wheezy_arm-sysroot/ -+/vendor/debian_wheezy_i386-sysroot/ -+>>>>>>> .their - /vendor/download/ - /vendor/llvm-build/ - /vendor/llvm/ -changed in both - base 100644 bff9a648f5bd1180cc5b1c9a2bc6fc080c09b616 CONTRIBUTING.md - our 100644 414f83db905db904728facf3b40e70e7b7973193 CONTRIBUTING.md - their 100644 fffa69e5aad572e7922eb83858572198cee0e453 CONTRIBUTING.md -changed in both - base 100644 58da91e125094253096e1317eb10b2fc33901860 Dockerfile - our 100644 74e5eeedea9bea87cd7a98ac2cb63f4376275a2a Dockerfile - their 100644 526603ec9bac3e465ee378d22a49fa0abe72cee4 Dockerfile -@@ -7,8 +7,13 @@ - RUN chmod a+rwx /home - - # Install node.js -+<<<<<<< .our - RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - - RUN apt-get install -y nodejs -+======= -+RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - -+RUN apt-get update && apt-get install -y --force-yes nodejs -+>>>>>>> .their - - # Install wget used by crash reporter - RUN apt-get install -y wget -added in both - our 100644 a95dcfb73ddc8dcb4db9c8a82655e49580135dd9 Dockerfile.arm64v8 - their 100644 6272c9d16cf63ecbda6dae80592939a100233302 Dockerfile.arm64v8 -@@ -42,6 +42,10 @@ - python-setuptools \ - python-pip \ - python-dbusmock \ -+<<<<<<< .our -+======= -+ unzip \ -+>>>>>>> .their - wget \ - xvfb - -changed in both - base 100644 3c3a610ecab99f40e7db8441414a3089fabef045 Dockerfile.circleci - our 100644 d369c8c640161fc3ba65935297aec7dd27eb1e9f Dockerfile.circleci - their 100644 a186769291fa9010ffa4456ec08ab84f57aee9f8 Dockerfile.circleci -@@ -3,8 +3,13 @@ - USER root - - # Install node.js -+<<<<<<< .our - RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - - RUN apt-get install -y nodejs -+======= -+RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - -+RUN apt-get update && apt-get install -y --force-yes nodejs -+>>>>>>> .their - - # Install wget used by crash reporter - RUN apt-get install -y wget -added in remote - their 100644 1567ad810092ec3eb4efae628c38403a775e4d65 Jenkinsfile.arm64 -@@ -0,0 +1,36 @@ -+pipeline { -+ agent { -+ docker { -+ image 'electronbuilds/arm64v8:0.0.3' -+ args '--privileged' -+ } -+ } -+ environment { -+ TARGET_ARCH='arm64' -+ DISPLAY=':99.0' -+ MOCHA_TIMEOUT='60000' -+ } -+ stages { -+ stage('Bootstrap') { -+ steps { -+ sh 'script/bootstrap.py -v --dev --target_arch=$TARGET_ARCH' -+ } -+ } -+ stage('Build') { -+ steps { -+ sh 'script/build.py -c D --ninja-path /usr/local/ninja/ninja' -+ } -+ } -+ stage('Test') { -+ steps { -+ sh '/etc/init.d/xvfb start' -+ sh 'script/test.py --ci' -+ } -+ } -+ } -+ post { -+ always { -+ cleanWs() -+ } -+ } -+} -changed in both - base 100644 d9ad098a6aca95172956ff4ed66b9542346e0771 README.md - our 100644 ec09364417b767ac59b2d970fee5e2ab2db2173b README.md - their 100644 1ea1ec27294ad3d8e85092b13dbd9cacfcdf38d0 README.md -changed in both - base 100644 ff2f1018423a244508c90ad7554ca278d2b2a66a SECURITY.md - our 100644 c113ff00e06f0fd2d5025b7fd87fa8d6bc9fcf74 SECURITY.md - their 100644 a0d18da90d90d51745e3f9405991f9d8d067058e SECURITY.md -changed in both - base 100644 ce0baaf989bdbd6897fa333d3af88d1d573a2bd2 appveyor.yml - our 100644 67a2b2124619d866f67d849f57f3548ba28be26a appveyor.yml - their 100644 5ee73c661b1079e9bf252868b31814d3aa4c2760 appveyor.yml -@@ -1,3 +1,4 @@ -+<<<<<<< .our - version: 1.0.{build} - branches: - except: -@@ -6,6 +7,10 @@ - image: electron-16-vs2017-15.4.5 - environment: - DISABLE_CRASH_REPORTER_TESTS: true -+======= -+build_cloud: electron-16 -+image: electron-16-vs2015 -+>>>>>>> .their - build_script: - - ps: >- - if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) { -@@ -61,6 +66,7 @@ - - path: test-results.xml - name: test-results.xml - deploy_script: -+<<<<<<< .our - - ps: >- - if (Test-Path Env:\ELECTRON_RELEASE) { - if (Test-Path Env:\RUN_RELEASE_BUILD) { -@@ -71,3 +77,6 @@ - & python script\upload.py - } - } -+======= -+- ps: "if (Test-Path Env:\\ELECTRON_RELEASE) {\n if (Test-Path Env:\\RUN_RELEASE_BUILD) {\n Write-Output \"Uploading Electron release distribution to s3\"\n & python script\\upload.py --upload_to_s3\n } else {\n Write-Output \"Uploading Electron release distribution to github releases\"\n & python script\\upload.py\n }\n} else {\n Write-Output \"Skipping upload distribution because build is not for release\"\n}" -+>>>>>>> .their -changed in both - base 100644 e1603fa5942f7b000c3385648530255032e775a2 atom/app/atom_library_main.h - our 100644 2c7a27caa20a411558010c3c58bd78e7850c0737 atom/app/atom_library_main.h - their 100644 63d285bb5e4838578d23505d7738c9ac88575df1 atom/app/atom_library_main.h -@@ -9,7 +9,12 @@ - - #if defined(OS_MACOSX) - extern "C" { -+<<<<<<< .our - __attribute__((visibility("default"))) int AtomMain(int argc, char* argv[]); -+======= -+__attribute__((visibility("default"))) -+int AtomMain(int argc, char* argv[]); -+>>>>>>> .their - - #ifdef ENABLE_RUN_AS_NODE - __attribute__((visibility("default"))) int AtomInitializeICUandStartNode( -changed in both - base 100644 7ee7522934689937f7be7b0f866134bf611c7d69 atom/app/atom_library_main.mm - our 100644 57a519fcd0db28548ea75034cf92191161183385 atom/app/atom_library_main.mm - their 100644 ae096acd4a931d397e285643d36580625dde14bf atom/app/atom_library_main.mm -@@ -14,6 +14,10 @@ - #include "brightray/common/mac/main_application_bundle.h" - #include "content/public/app/content_main.h" - -+<<<<<<< .our -+======= -+#if defined(OS_MACOSX) -+>>>>>>> .their - int AtomMain(int argc, char* argv[]) { - atom::AtomMainDelegate delegate; - content::ContentMainParams params(&delegate); -changed in both - base 100644 fa854ca1637a677332f4b01fdede12b23b945720 atom/app/atom_main.cc - our 100644 fc77100d9acb58221c35f364c4db7866a44d347d atom/app/atom_main.cc - their 100644 5fd93a88d60c926ebd50c4b453693b5ce066c20d atom/app/atom_main.cc -@@ -93,11 +93,15 @@ - } - #endif - -+<<<<<<< .our - #ifdef ENABLE_RUN_AS_NODE - bool run_as_node = IsEnvSet(kRunAsNode); - #else - bool run_as_node = false; - #endif -+======= -+ bool run_as_node = IsEnvSet(kRunAsNode); -+>>>>>>> .their - - // Make sure the output is printed to console. - if (run_as_node || !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE")) -@@ -132,10 +136,14 @@ - auto ret = atom::NodeMain(argv.size(), argv.data()); - std::for_each(argv.begin(), argv.end(), free); - return ret; -+<<<<<<< .our - } - #endif - - if (IsEnvSet("ELECTRON_INTERNAL_CRASH_SERVICE")) { -+======= -+ } else if (IsEnvSet("ELECTRON_INTERNAL_CRASH_SERVICE")) { -+>>>>>>> .their - return crash_service::Main(cmd); - } - -@@ -156,7 +164,10 @@ - #elif defined(OS_LINUX) // defined(OS_WIN) - - int main(int argc, char* argv[]) { -+<<<<<<< .our - #ifdef ENABLE_RUN_AS_NODE -+======= -+>>>>>>> .their - if (IsEnvSet(kRunAsNode)) { - base::i18n::InitializeICU(); - base::AtExitManager atexit_manager; -@@ -175,7 +186,10 @@ - #else // defined(OS_LINUX) - - int main(int argc, char* argv[]) { -+<<<<<<< .our - #ifdef ENABLE_RUN_AS_NODE -+======= -+>>>>>>> .their - if (IsEnvSet(kRunAsNode)) { - return AtomInitializeICUandStartNode(argc, argv); - } -added in both - our 100644 23e870cf4a32aecfc246a81edad46971b4456a55 atom/app/command_line_args.cc - their 100644 82edd15b4ac52e5b14effdd8ff7e112f4331293b atom/app/command_line_args.cc -@@ -2,15 +2,30 @@ - // Use of this source code is governed by the MIT license that can be - // found in the LICENSE file. - -+<<<<<<< .our - #include "atom/app/command_line_args.h" - -+======= -+#include <string> -+ -+#include "atom/app/command_line_args.h" -+ -+#include "base/strings/string_util.h" -+#include "base/strings/utf_string_conversions.h" -+#include "content/public/common/content_switches.h" -+ -+>>>>>>> .their - namespace { - - bool IsUrlArg(const base::CommandLine::CharType* arg) { - // the first character must be a letter for this to be a URL - auto c = *arg; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) { -+<<<<<<< .our - for (auto* p = arg + 1; *p; ++p) { -+======= -+ for (auto p = arg + 1; *p; ++p) { -+>>>>>>> .their - c = *p; - - // colon indicates that the argument starts with a URI scheme -@@ -31,12 +46,1345 @@ - return false; - } - -+<<<<<<< .our -+======= -+const char* blacklist[] = { -+ // node -+ "inspect", -+ "inspect-brk", -+ -+ // chromium switches: -+ // find ./ \( -name "*switches.cc" -o -name "*switch_list.h" \) \ -+ // | xargs grep -P --no-filename '"\S+"[);]$' \ -+ // | perl -pe 's|^.*?"(\S+)"[);]$| "$1",|'; \ -+ // | LANG="C" sort | uniq -+ "/prefetch:1", -+ "/prefetch:2", -+ "/prefetch:3", -+ "/prefetch:4", -+ "/prefetch:5", -+ "/prefetch:6", -+ "/prefetch:8", -+ "0", -+ "?", -+ "BlacklistOnly", -+ "ChromeOSMemoryPressureHandling", -+ "Disabled", -+ "OnlineCheckOnly", -+ "SafeSites", -+ "accept-resource-provider", -+ "adaboost", -+ "aec-refined-adaptive-filter", -+ "agc-startup-min-volume", -+ "aggressive", -+ "aggressive-cache-discard", -+ "aggressive-tab-discard", -+ "all-toolchains", -+ "allow-cross-origin-auth-prompt", -+ "allow-external-pages", -+ "allow-failed-policy-fetch-for-test", -+ "allow-file-access-from-files", -+ "allow-hidden-media-playback", -+ "allow-http-background-page", -+ "allow-http-screen-capture", -+ "allow-insecure-localhost", -+ "allow-legacy-extension-manifests", -+ "allow-loopback-in-peer-connection", -+ "allow-nacl-crxfs-api", -+ "allow-nacl-file-handle-api", -+ "allow-nacl-socket-api", -+ "allow-no-sandbox-job", -+ "allow-outdated-plugins", -+ "allow-ra-in-dev-mode", -+ "allow-running-insecure-content", -+ "allow-sandbox-debugging", -+ "allow-silent-push", -+ "alsa-check-close-timeout", -+ "alsa-enable-upsampling", -+ "alsa-fixed-output-sample-rate", -+ "alsa-input-device", -+ "alsa-mute-device-name", -+ "alsa-mute-element-name", -+ "alsa-output-avail-min", -+ "alsa-output-buffer-size", -+ "alsa-output-device", -+ "alsa-output-period-size", -+ "alsa-output-start-threshold", -+ "alsa-volume-device-name", -+ "alsa-volume-element-name", -+ "also-emit-success-logs", -+ "always-authorize-plugins", -+ "always-on", -+ "always-use-complex-text", -+ "alwaystrue", -+ "android-fonts-path", -+ "android-stderr-port", -+ "android-stdin-port", -+ "android-stdout-port", -+ "angle", -+ "app", -+ "app-auto-launched", -+ "app-id", -+ "app-mode-auth-code", -+ "app-mode-oauth-token", -+ "app-mode-oem-manifest", -+ "app-shell-allow-roaming", -+ "app-shell-host-window-size", -+ "app-shell-preferred-network", -+ "app-shell-refresh-token", -+ "app-shell-user", -+ "apple", -+ "apps-gallery-download-url", -+ "apps-gallery-update-url", -+ "apps-gallery-url", -+ "apps-keep-chrome-alive-in-tests", -+ "arc-always-start", -+ "arc-availability", -+ "arc-available", -+ "args", -+ "artifacts-dir", -+ "ash-adjustable-large-cursor", -+ "ash-animate-from-boot-splash-screen", -+ "ash-constrain-pointer-to-root", -+ "ash-copy-host-background-at-boot", -+ "ash-debug-shortcuts", -+ "ash-dev-shortcuts", -+ "ash-disable-maximize-mode-window-backdrop", -+ "ash-disable-screen-orientation-lock", -+ "ash-disable-touch-exploration-mode", -+ "ash-enable-magnifier-key-scroller", -+ "ash-enable-mirrored-screen", -+ "ash-enable-palette-on-all-displays", -+ "ash-enable-smooth-screen-rotation", -+ "ash-enable-software-mirroring", -+ "ash-enable-unified-desktop", -+ "ash-estimated-presentation-delay", -+ "ash-force-enable-palette", -+ "ash-hide-notifications-for-factory", -+ "ash-host-window-bounds", -+ "ash-shelf-color", -+ "ash-shelf-color-scheme", -+ "ash-touch-hud", -+ "ash-webui-init", -+ "attestation-server", -+ "audio-buffer-size", -+ "aura-legacy-power-button", -+ "auth-ext-path", -+ "auth-server-whitelist", -+ "auth-spnego-account-type", -+ "auto", -+ "auto-open-devtools-for-tabs", -+ "auto-select-desktop-capture-source", -+ "blink-settings", -+ "bootstrap", -+ "browser-subprocess-path", -+ "browser-test", -+ "bwsi", -+ "bypass-app-banner-engagement-checks", -+ "canvas-msaa-sample-count", -+ "cast-initial-screen-height", -+ "cast-initial-screen-width", -+ "cc-layer-tree-test-long-timeout", -+ "cc-layer-tree-test-no-timeout", -+ "cc-rebaseline-pixeltests", -+ "cellular-first", -+ "cellular-only", -+ "check-for-update-interval", -+ "check-layout-test-sys-deps", -+ "child-process", -+ "child-wallpaper-large", -+ "child-wallpaper-small", -+ "cipher-suite-blacklist", -+ "clamshell", -+ "class", -+ "clear-token-service", -+ "cloud-print-file", -+ "cloud-print-file-type", -+ "cloud-print-job-title", -+ "cloud-print-print-ticket", -+ "cloud-print-setup-proxy", -+ "cloud-print-url", -+ "cloud-print-xmpp-endpoint", -+ "color", -+ "compensate-for-unstable-pinch-zoom", -+ "compile-shader-always-succeeds", -+ "component-updater", -+ "connectivity-check-url", -+ "conservative", -+ "content-image-texture-target", -+ "content-shell-host-window-size", -+ "controller", -+ "crash-dumps-dir", -+ "crash-on-failure", -+ "crash-on-hang-threads", -+ "crash-server-url", -+ "crash-test", -+ "crashpad-handler", -+ "create-browser-on-startup-for-tests", -+ "create-default-gl-context", -+ "cros-region", -+ "cros-regions-mode", -+ "crosh-command", -+ "cryptauth-http-host", -+ "custom-devtools-frontend", -+ "custom-launcher-page", -+ "custom_summary", -+ "d3d11", -+ "d3d9", -+ "daemon", -+ "dark_muted", -+ "dark_vibrant", -+ "data-path", -+ "data-reduction-proxy-config-url", -+ "data-reduction-proxy-experiment", -+ "data-reduction-proxy-http-proxies", -+ "data-reduction-proxy-lo-fi", -+ "data-reduction-proxy-pingback-url", -+ "data-reduction-proxy-secure-proxy-check-url", -+ "data-reduction-proxy-server-experiments-disabled", -+ "data-reduction-proxy-warmup-url", -+ "dbus-stub", -+ "debug-devtools", -+ "debug-enable-frame-toggle", -+ "debug-packed-apps", -+ "debug-print", -+ "default", -+ "default-background-color", -+ "default-tile-height", -+ "default-tile-width", -+ "default-wallpaper-is-oem", -+ "default-wallpaper-large", -+ "default-wallpaper-small", -+ "demo", -+ "derelict-detection-timeout", -+ "derelict-idle-timeout", -+ "desktop", -+ "desktop-window-1080p", -+ "deterministic-fetch", -+ "device-management-url", -+ "device-scale-factor", -+ "devtools-flags", -+ "diagnostics", -+ "diagnostics-format", -+ "diagnostics-recovery", -+ "disable", -+ "disable-2d-canvas-clip-aa", -+ "disable-2d-canvas-image-chromium", -+ "disable-3d-apis", -+ "disable-accelerated-2d-canvas", -+ "disable-accelerated-jpeg-decoding", -+ "disable-accelerated-mjpeg-decode", -+ "disable-accelerated-video-decode", -+ "disable-add-to-shelf", -+ "disable-app-info-dialog-mac", -+ "disable-app-list-dismiss-on-blur", -+ "disable-app-window-cycling", -+ "disable-appcontainer", -+ "disable-arc-data-wipe", -+ "disable-arc-opt-in-verification", -+ "disable-audio-support-for-desktop-share", -+ "disable-autofill-keyboard-accessory-view", -+ "disable-avfoundation-overlays", -+ "disable-background-networking", -+ "disable-background-timer-throttling", -+ "disable-backgrounding-occluded-windows", -+ "disable-backing-store-limit", -+ "disable-blink-features", -+ "disable-boot-animation", -+ "disable-breakpad", -+ "disable-browser-task-scheduler", -+ "disable-bundled-ppapi-flash", -+ "disable-canvas-aa", -+ "disable-captive-portal-bypass-proxy", -+ "disable-cast-streaming-hw-encoding", -+ "disable-clear-browsing-data-counters", -+ "disable-client-side-phishing-detection", -+ "disable-cloud-import", -+ "disable-component-cloud-policy", -+ "disable-component-extensions-with-background-pages", -+ "disable-component-update", -+ "disable-composited-antialiasing", -+ "disable-contextual-search", -+ "disable-d3d11", -+ "disable-databases", -+ "disable-datasaver-prompt", -+ "disable-default-apps", -+ "disable-demo-mode", -+ "disable-device-disabling", -+ "disable-device-discovery-notifications", -+ "disable-dinosaur-easter-egg", -+ "disable-direct-composition", -+ "disable-direct-composition-layers", -+ "disable-directwrite-for-ui", -+ "disable-display-color-calibration", -+ "disable-display-list-2d-canvas", -+ "disable-distance-field-text", -+ "disable-domain-blocking-for-3d-apis", -+ "disable-domain-reliability", -+ "disable-download-image-renaming", -+ "disable-drive-search-in-app-launcher", -+ "disable-dwm-composition", -+ "disable-encryption-migration", -+ "disable-eol-notification", -+ "disable-es3-apis", -+ "disable-es3-gl-context", -+ "disable-extensions", -+ "disable-extensions-except", -+ "disable-extensions-file-access-check", -+ "disable-extensions-http-throttling", -+ "disable-fast-web-scroll-view-insets", -+ "disable-features", -+ "disable-field-trial-config", -+ "disable-file-system", -+ "disable-flash-3d", -+ "disable-flash-stage3d", -+ "disable-fullscreen-low-power-mode", -+ "disable-fullscreen-tab-detaching", -+ "disable-gaia-services", -+ "disable-gesture-editing", -+ "disable-gesture-requirement-for-media-playback", -+ "disable-gesture-requirement-for-presentation", -+ "disable-gesture-typing", -+ "disable-gl-drawing-for-tests", -+ "disable-gl-error-limit", -+ "disable-gl-extensions", -+ "disable-glsl-translator", -+ "disable-gpu", -+ "disable-gpu-async-worker-context", -+ "disable-gpu-compositing", -+ "disable-gpu-driver-bug-workarounds", -+ "disable-gpu-early-init", -+ "disable-gpu-memory-buffer-compositor-resources", -+ "disable-gpu-memory-buffer-video-frames", -+ "disable-gpu-process-crash-limit", -+ "disable-gpu-program-cache", -+ "disable-gpu-rasterization", -+ "disable-gpu-sandbox", -+ "disable-gpu-shader-disk-cache", -+ "disable-gpu-vsync", -+ "disable-gpu-watchdog", -+ "disable-hang-monitor", -+ "disable-hid-detection-on-oobe", -+ "disable-hide-inactive-stacked-tab-close-buttons", -+ "disable-histogram-customizer", -+ "disable-hosted-app-shim-creation", -+ "disable-hosted-apps-in-windows", -+ "disable-http2", -+ "disable-in-process-stack-traces", -+ "disable-infobars", -+ "disable-input-ime-api", -+ "disable-input-view", -+ "disable-ios-password-generation", -+ "disable-ios-password-suggestions", -+ "disable-ios-physical-web", -+ "disable-javascript-harmony-shipping", -+ "disable-kill-after-bad-ipc", -+ "disable-lcd-text", -+ "disable-legacy-window", -+ "disable-local-storage", -+ "disable-logging", -+ "disable-login-animations", -+ "disable-low-end-device-mode", -+ "disable-low-latency-dxva", -+ "disable-low-res-tiling", -+ "disable-lru-snapshot-cache", -+ "disable-mac-overlays", -+ "disable-mac-views-native-app-windows", -+ "disable-main-frame-before-activation", -+ "disable-md-oobe", -+ "disable-media-session-api", -+ "disable-media-suspend", -+ "disable-merge-key-char-events", -+ "disable-minimize-on-second-launcher-item-click", -+ "disable-mojo-renderer", -+ "disable-mtp-write-support", -+ "disable-multi-display-layout", -+ "disable-namespace-sandbox", -+ "disable-native-cups", -+ "disable-native-gpu-memory-buffers", -+ "disable-network-portal-notification", -+ "disable-new-channel-switcher-ui", -+ "disable-new-kiosk-ui", -+ "disable-new-korean-ime", -+ "disable-new-zip-unpacker", -+ "disable-notifications", -+ "disable-ntp-popular-sites", -+ "disable-nv12-dxgi-video", -+ "disable-offer-store-unmasked-wallet-cards", -+ "disable-offer-upload-credit-cards", -+ "disable-office-editing-component-extension", -+ "disable-offline-auto-reload", -+ "disable-offline-auto-reload-visible-only", -+ "disable-overscroll-edge-effect", -+ "disable-panel-fitting", -+ "disable-partial-raster", -+ "disable-password-generation", -+ "disable-payment-request", -+ "disable-pepper-3d", -+ "disable-pepper-3d-image-chromium", -+ "disable-per-monitor-dpi", -+ "disable-permission-action-reporting", -+ "disable-permissions-api", -+ "disable-physical-keyboard-autocorrect", -+ "disable-pinch", -+ "disable-pnacl-crash-throttling", -+ "disable-popup-blocking", -+ "disable-prefer-compositing-to-lcd-text", -+ "disable-presentation-api", -+ "disable-print-preview", -+ "disable-prompt-on-repost", -+ "disable-pull-to-refresh-effect", -+ "disable-push-api-background-mode", -+ "disable-quic", -+ "disable-reading-from-canvas", -+ "disable-remote-core-animation", -+ "disable-remote-fonts", -+ "disable-remote-playback-api", -+ "disable-renderer-accessibility", -+ "disable-renderer-backgrounding", -+ "disable-renderer-priority-management", -+ "disable-resize-lock", -+ "disable-rgba-4444-textures", -+ "disable-rollback-option", -+ "disable-rtc-smoothness-algorithm", -+ "disable-screen-orientation-lock", -+ "disable-search-geolocation-disclosure", -+ "disable-seccomp-filter-sandbox", -+ "disable-settings-window", -+ "disable-setuid-sandbox", -+ "disable-shader-name-hashing", -+ "disable-shared-workers", -+ "disable-signin-promo", -+ "disable-signin-scoped-device-id", -+ "disable-single-click-autofill", -+ "disable-slimming-paint-invalidation", -+ "disable-smart-virtual-keyboard", -+ "disable-smooth-scrolling", -+ "disable-software-rasterizer", -+ "disable-speech-api", -+ "disable-suggestions-ui", -+ "disable-sync", -+ "disable-sync-app-list", -+ "disable-sync-types", -+ "disable-system-timezone-automatic-detection", -+ "disable-tab-for-desktop-share", -+ "disable-tab-strip-autoscroll-new-tabs", -+ "disable-threaded-animation", -+ "disable-threaded-compositing", -+ "disable-threaded-scrolling", -+ "disable-touch-adjustment", -+ "disable-touch-drag-drop", -+ "disable-translate", -+ "disable-translate-new-ux", -+ "disable-usb-keyboard-detect", -+ "disable-v8-idle-tasks", -+ "disable-vaapi-accelerated-video-encode", -+ "disable-views-rect-based-targeting", -+ "disable-virtual-keyboard-overscroll", -+ "disable-voice-input", -+ "disable-volume-adjust-sound", -+ "disable-wake-on-wifi", -+ "disable-web-notification-custom-layouts", -+ "disable-web-security", -+ "disable-webgl", -+ "disable-webgl-image-chromium", -+ "disable-webrtc-encryption", -+ "disable-webrtc-hw-decoding", -+ "disable-webrtc-hw-encoding", -+ "disable-webrtc-hw-vp8-encoding", -+ "disable-win32k-lockdown", -+ "disable-xss-auditor", -+ "disable-zero-browsers-open-for-tests", -+ "disable-zero-copy", -+ "disable-zero-copy-dxgi-video", -+ "disabled", -+ "disk-cache-dir", -+ "disk-cache-size", -+ "display", -+ "dmg-device", -+ "dns-log-details", -+ "dom-automation", -+ "dotfile", -+ "draw-view-bounds-rects", -+ "duck-flash", -+ "dump-browser-histograms", -+ "dump-dom", -+ "eafe-path", -+ "eafe-url", -+ "early-tracing", -+ "easy-unlock-app-path", -+ "edge-touch-filtering", -+ "egl", -+ "elevate", -+ "embedded-extension-options", -+ "emphasize-titles-in-omnibox-dropdown", -+ "emulate-shader-precision", -+ "enable-accelerated-2d-canvas", -+ "enable-accelerated-vpx-decode", -+ "enable-accessibility-tab-switcher", -+ "enable-account-consistency", -+ "enable-adaptive-selection-handle-orientation", -+ "enable-add-to-shelf", -+ "enable-aggressive-domstorage-flushing", -+ "enable-android-wallpapers-app", -+ "enable-app-info-dialog-mac", -+ "enable-app-list", -+ "enable-app-window-cycling", -+ "enable-appcontainer", -+ "enable-arc", -+ "enable-arc-oobe-optin", -+ "enable-audio-debug-recordings-from-extension", -+ "enable-autofill-keyboard-accessory-view", -+ "enable-automation", -+ "enable-benchmarking", -+ "enable-ble-advertising-in-apps", -+ "enable-blink-features", -+ "enable-bookmark-undo", -+ "enable-browser-side-navigation", -+ "enable-browser-task-scheduler", -+ "enable-canvas-2d-dynamic-rendering-mode-switching", -+ "enable-checker-imaging", -+ "enable-chromevox-arc-support", -+ "enable-clear-browsing-data-counters", -+ "enable-cloud-print-proxy", -+ "enable-cloud-print-xps", -+ "enable-color-correct-rendering", -+ "enable-color-correct-rendering-default-mode", -+ "enable-consumer-kiosk", -+ "enable-contextual-search", -+ "enable-crash-reporter", -+ "enable-crash-reporter-for-testing", -+ "enable-crx-hash-check", -+ "enable-data-reduction-proxy-bypass-warning", -+ "enable-data-reduction-proxy-carrier-test", -+ "enable-data-reduction-proxy-force-pingback", -+ "enable-data-reduction-proxy-lite-page", -+ "enable-data-reduction-proxy-savings-promo", -+ "enable-datasaver-prompt", -+ "enable-default-media-session", -+ "enable-device-discovery-notifications", -+ "enable-devtools-experiments", -+ "enable-direct-composition-layers", -+ "enable-display-list-2d-canvas", -+ "enable-distance-field-text", -+ "enable-distillability-service", -+ "enable-dom-distiller", -+ "enable-domain-reliability", -+ "enable-download-image-renaming", -+ "enable-drive-search-in-app-launcher", -+ "enable-drm-atomic", -+ "enable-embedded-extension-options", -+ "enable-encryption-migration", -+ "enable-es3-apis", -+ "enable-exclusive-audio", -+ "enable-experimental-accessibility-features", -+ "enable-experimental-canvas-features", -+ "enable-experimental-extension-apis", -+ "enable-experimental-input-view-features", -+ "enable-experimental-web-platform-features", -+ "enable-extension-activity-log-testing", -+ "enable-extension-activity-logging", -+ "enable-extension-assets-sharing", -+ "enable-fast-unload", -+ "enable-fast-web-scroll-view-insets", -+ "enable-features", -+ "enable-first-run-ui-transitions", -+ "enable-floating-virtual-keyboard", -+ "enable-font-antialiasing", -+ "enable-fullscreen-tab-detaching", -+ "enable-fullscreen-toolbar-reveal", -+ "enable-google-branded-context-menu", -+ "enable-gpu-async-worker-context", -+ "enable-gpu-benchmarking", -+ "enable-gpu-client-logging", -+ "enable-gpu-client-tracing", -+ "enable-gpu-command-logging", -+ "enable-gpu-debugging", -+ "enable-gpu-driver-debug-logging", -+ "enable-gpu-memory-buffer-compositor-resources", -+ "enable-gpu-memory-buffer-video-frames", -+ "enable-gpu-rasterization", -+ "enable-gpu-service-logging", -+ "enable-gpu-service-tracing", -+ "enable-grouped-history", -+ "enable-hardware-overlays", -+ "enable-harfbuzz-rendertext", -+ "enable-hdr", -+ "enable-heap-profiling", -+ "enable-hosted-app-quit-notification", -+ "enable-hosted-apps-in-windows", -+ "enable-hosted-mode", -+ "enable-hotword-hardware", -+ "enable-hung-renderer-infobar", -+ "enable-inband-text-tracks", -+ "enable-input-ime-api", -+ "enable-ios-handoff-to-other-devices", -+ "enable-ios-password-generation", -+ "enable-ios-physical-web", -+ "enable-kiosk-mode", -+ "enable-layer-lists", -+ "enable-lcd-text", -+ "enable-leak-detection", -+ "enable-local-file-accesses", -+ "enable-local-sync-backend", -+ "enable-logging", -+ "enable-login-screen-apps", -+ "enable-longpress-drag-selection", -+ "enable-low-end-device-mode", -+ "enable-low-res-tiling", -+ "enable-lru-snapshot-cache", -+ "enable-mac-views-native-app-windows", -+ "enable-main-frame-before-activation", -+ "enable-md-feedback", -+ "enable-md-policy-page", -+ "enable-media-suspend", -+ "enable-merge-key-char-events", -+ "enable-message-center-always-scroll-up-upon-notification-removal", -+ "enable-nacl", -+ "enable-nacl-debug", -+ "enable-nacl-nonsfi-mode", -+ "enable-native-gpu-memory-buffers", -+ "enable-natural-scroll-default", -+ "enable-navigation-tracing", -+ "enable-net-benchmarking", -+ "enable-network-information", -+ "enable-network-portal-notification", -+ "enable-network-service", -+ "enable-new-vp9-codec-string", -+ "enable-ntp-popular-sites", -+ "enable-ntp-search-engine-country-detection", -+ "enable-offer-store-unmasked-wallet-cards", -+ "enable-offer-upload-credit-cards", -+ "enable-offline-auto-reload", -+ "enable-offline-auto-reload-visible-only", -+ "enable-osk-overscroll", -+ "enable-override-bookmarks-ui", -+ "enable-partial-raster", -+ "enable-password-generation", -+ "enable-payment-request", -+ "enable-pepper-testing", -+ "enable-per-monitor-dpi", -+ "enable-permission-action-reporting", -+ "enable-physical-keyboard-autocorrect", -+ "enable-pinch", -+ "enable-pixel-output-in-tests", -+ "enable-plugin-placeholder-testing", -+ "enable-potentially-annoying-security-features", -+ "enable-power-overlay", -+ "enable-precache", -+ "enable-precise-memory-info", -+ "enable-prefer-compositing-to-lcd-text", -+ "enable-print-browser", -+ "enable-print-preview-register-promos", -+ "enable-profile-shortcut-manager", -+ "enable-profiling", -+ "enable-proximity-auth-bluetooth-low-energy-discovery", -+ "enable-proximity-auth-proximity-detection", -+ "enable-push-api-background-mode", -+ "enable-quic", -+ "enable-reader-mode-toolbar-icon", -+ "enable-refresh-token-annotation-request", -+ "enable-request-tablet-site", -+ "enable-rgba-4444-textures", -+ "enable-sandbox", -+ "enable-sandbox-logging", -+ "enable-screenshot-testing-with-mode", -+ "enable-scripts-require-action", -+ "enable-scroll-prediction", -+ "enable-service-manager-tracing", -+ "enable-settings-window", -+ "enable-sgi-video-sync", -+ "enable-signin-promo", -+ "enable-single-click-autofill", -+ "enable-site-engagement-eviction-policy", -+ "enable-site-settings", -+ "enable-skia-benchmarking", -+ "enable-slimming-paint-invalidation", -+ "enable-slimming-paint-v2", -+ "enable-smooth-scrolling", -+ "enable-spatial-navigation", -+ "enable-spdy-proxy-auth", -+ "enable-speech-dispatcher", -+ "enable-spelling-feedback-field-trial", -+ "enable-spotlight-actions", -+ "enable-stats-collection-bindings", -+ "enable-stats-table", -+ "enable-strict-mixed-content-checking", -+ "enable-strict-powerful-feature-restrictions", -+ "enable-suggestions-ui", -+ "enable-suggestions-with-substring-match", -+ "enable-supervised-user-managed-bookmarks-folder", -+ "enable-surface-synchronization", -+ "enable-swap-buffers-with-bounds", -+ "enable-sync-app-list", -+ "enable-sync-articles", -+ "enable-tab-audio-muting", -+ "enable-tcp-fastopen", -+ "enable-tether", -+ "enable-threaded-compositing", -+ "enable-threaded-texture-mailboxes", -+ "enable-thumbnail-retargeting", -+ "enable-tile-compression", -+ "enable-touch-calibration-setting", -+ "enable-touch-drag-drop", -+ "enable-touch-support-for-screen-magnifier", -+ "enable-touchpad-three-finger-click", -+ "enable-touchview", -+ "enable-trace-app-source", -+ "enable-tracing", -+ "enable-tracing-output", -+ "enable-translate-new-ux", -+ "enable-ui-devtools", -+ "enable-use-zoom-for-dsf", -+ "enable-user-controlled-alternate-protocol-ports", -+ "enable-user-metrics", -+ "enable-usermedia-screen-capturing", -+ "enable-video-player-chromecast-support", -+ "enable-viewport", -+ "enable-virtual-keyboard", -+ "enable-voice-interaction", -+ "enable-vp9-in-mp4", -+ "enable-vtune-support", -+ "enable-vulkan", -+ "enable-wayland-server", -+ "enable-web-notification-custom-layouts", -+ "enable-webfonts-intervention-trigger", -+ "enable-webfonts-intervention-v2", -+ "enable-webgl-draft-extensions", -+ "enable-webgl-image-chromium", -+ "enable-webrtc-event-logging-from-extension", -+ "enable-webrtc-srtp-aes-gcm", -+ "enable-webrtc-stun-origin", -+ "enable-webvr", -+ "enable-wifi-credential-sync", -+ "enable-win7-webrtc-hw-h264-decoding", -+ "enable-zero-copy", -+ "enable-zip-archiver-on-file-manager", -+ "enabled", -+ "enabled-2g", -+ "enabled-3g", -+ "enabled-slow2g", -+ "encode-binary", -+ "enforce", -+ "enforce-gl-minimums", -+ "enforce-webrtc-ip-permission-check", -+ "enforce_strict", -+ "enterprise-disable-arc", -+ "enterprise-enable-forced-re-enrollment", -+ "enterprise-enable-zero-touch-enrollment", -+ "enterprise-enrollment-initial-modulus", -+ "enterprise-enrollment-modulus-limit", -+ "error-console", -+ "explicitly-allowed-ports", -+ "expose-internals-for-testing", -+ "extension-content-verification", -+ "extension-process", -+ "extensions-install-verification", -+ "extensions-multi-account", -+ "extensions-not-webstore", -+ "extensions-on-chrome-urls", -+ "extensions-update-frequency", -+ "extra-search-query-params", -+ "fail-on-unused-args", -+ "fake-variations-channel", -+ "false", -+ "fast", -+ "fast-start", -+ "feedback-server", -+ "field-trial-handle", -+ "first-exec-after-boot", -+ "flag-switches-begin", -+ "flag-switches-end", -+ "font-cache-shared-handle", -+ "force-android-app-mode", -+ "force-app-mode", -+ "force-desktop-ios-promotion", -+ "force-dev-mode-highlighting", -+ "force-device-scale-factor", -+ "force-display-list-2d-canvas", -+ "force-fieldtrial-params", -+ "force-fieldtrials", -+ "force-first-run", -+ "force-first-run-ui", -+ "force-gpu-mem-available-mb", -+ "force-gpu-rasterization", -+ "force-happiness-tracking-system", -+ "force-load-easy-unlock-app-in-tests", -+ "force-local-ntp", -+ "force-login-manager-in-tests", -+ "force-mediafoundation", -+ "force-overlay-fullscreen-video", -+ "force-pnacl-subzero", -+ "force-renderer-accessibility", -+ "force-show-update-menu-badge", -+ "force-show-update-menu-item", -+ "force-system-compositor-mode", -+ "force-tablet-mode", -+ "force-ui-direction", -+ "force-variation-ids", -+ "force-video-overlays", -+ "force-wave-audio", -+ "force-webrtc-ip-handling-policy", -+ "full-memory-crash-report", -+ "gaia-url", -+ "gcm-checkin-url", -+ "gcm-mcs-endpoint", -+ "gcm-registration-url", -+ "generate-accessibility-test-expectations", -+ "gl", -+ "gl-composited-texture-quad-border", -+ "gl-shader-interm-output", -+ "gles", -+ "golden-screenshots-dir", -+ "google-apis-url", -+ "google-base-url", -+ "google-doodle-url", -+ "google-url", -+ "gpu-active-device-id", -+ "gpu-active-vendor-id", -+ "gpu-device-id", -+ "gpu-driver-bug-workarounds", -+ "gpu-driver-date", -+ "gpu-driver-vendor", -+ "gpu-driver-version", -+ "gpu-launcher", -+ "gpu-no-complete-info-collection", -+ "gpu-no-context-lost", -+ "gpu-process", -+ "gpu-program-cache-size-kb", -+ "gpu-rasterization-msaa-sample-count", -+ "gpu-sandbox-allow-sysv-shm", -+ "gpu-sandbox-failures-fatal", -+ "gpu-sandbox-start-early", -+ "gpu-secondary-device-ids", -+ "gpu-secondary-vendor-ids", -+ "gpu-startup-dialog", -+ "gpu-testing-device-id", -+ "gpu-testing-driver-date", -+ "gpu-testing-gl-renderer", -+ "gpu-testing-gl-vendor", -+ "gpu-testing-gl-version", -+ "gpu-testing-os-version", -+ "gpu-testing-secondary-device-ids", -+ "gpu-testing-secondary-vendor-ids", -+ "gpu-testing-vendor-id", -+ "gpu-vendor-id", -+ "guest-wallpaper-large", -+ "guest-wallpaper-small", -+ "h", -+ "has-chromeos-diamond-key", -+ "headless", -+ "help", -+ "hide", -+ "hide-icons", -+ "hide-scrollbars", -+ "history-entry-requires-user-gesture", -+ "homedir", -+ "homepage", -+ "host", -+ "host-pairing-oobe", -+ "host-resolver-retry-attempts", -+ "host-resolver-rules", -+ "host-rules", -+ "icu-data-dir", -+ "ignore-autocomplete-off-autofill", -+ "ignore-certificate-errors", -+ "ignore-gpu-blacklist", -+ "ignore-urlfetcher-cert-requests", -+ "ignore-user-profile-mapping-for-tests", -+ "in-process-gpu", -+ "incognito", -+ "inert-visual-viewport", -+ "input", -+ "inspect", -+ "inspect-brk", -+ "install-chrome-app", -+ "install-supervised-user-whitelists", -+ "instant-process", -+ "interests-url", -+ "invalidation-use-gcm-channel", -+ "ipc-connection-timeout", -+ "ipc-dump-directory", -+ "ipc-fuzzer-testcase", -+ "is-running-in-mash", -+ "isolate-extensions", -+ "isolate-sites-for-testing", -+ "javascript-harmony", -+ "js-flags", -+ "keep-alive-for-test", -+ "kiosk", -+ "kiosk-printing", -+ "lang", -+ "last-launched-app", -+ "layer", -+ "light_muted", -+ "light_vibrant", -+ "load-and-launch-app", -+ "load-apps", -+ "load-extension", -+ "load-media-router-component-extension", -+ "local-heuristics-only-for-password-generation", -+ "local-ntp-reload", -+ "local-sync-backend-dir", -+ "log-gpu-control-list-decisions", -+ "log-level", -+ "log-net-log", -+ "login-manager", -+ "login-profile", -+ "login-user", -+ "lso-url", -+ "ltr", -+ "main-frame-resizes-are-orientation-changes", -+ "make-chrome-default", -+ "make-default-browser", -+ "managed-user-id", -+ "managed-user-sync-token", -+ "mark-non-secure-as", -+ "markdown", -+ "market-url-for-testing", -+ "mash", -+ "material", -+ "material-design-ink-drop-animation-speed", -+ "material-hybrid", -+ "max-gum-fps", -+ "max-output-volume-dba1m", -+ "max-untiled-layer-height", -+ "max-untiled-layer-width", -+ "media-cache-size", -+ "mem-pressure-system-reserved-kb", -+ "memory-metrics", -+ "memory-pressure-off", -+ "memory-pressure-thresholds", -+ "memory-pressure-thresholds-mb", -+ "message-center-changes-while-open", -+ "metrics-client-id", -+ "metrics-recording-only", -+ "mhtml-generator-option", -+ "mock", -+ "mojo-channel-token", -+ "mojo-local-storage", -+ "mojo-pipe-token", -+ "monitoring-destination-id", -+ "mse-audio-buffer-size-limit", -+ "mse-video-buffer-size-limit", -+ "mus", -+ "mus-config", -+ "mute-audio", -+ "nacl-broker", -+ "nacl-dangerous-no-sandbox-nonsfi", -+ "nacl-debug-mask", -+ "nacl-gdb", -+ "nacl-gdb-script", -+ "nacl-loader", -+ "nacl-loader-nonsfi", -+ "native", -+ "native-crx-bindings", -+ "net-log-capture-mode", -+ "netifs-to-ignore", -+ "network-country-iso", -+ "new-window", -+ "no-default-browser-check", -+ "no-experiments", -+ "no-first-run", -+ "no-managed-user-acknowledgment-check", -+ "no-network-profile-warning", -+ "no-pings", -+ "no-proxy-server", -+ "no-referrers", -+ "no-sandbox", -+ "no-service-autorun", -+ "no-startup-window", -+ "no-wifi", -+ "no-zygote", -+ "nocolor", -+ "noerrdialogs", -+ "non-material", -+ "non-secure", -+ "none", -+ "normal_muted", -+ "normal_vibrant", -+ "note-taking-app-ids", -+ "ntp-snippets-add-incomplete", -+ "ntp-switch-to-existing-tab", -+ "null", -+ "num-pac-threads", -+ "num-raster-threads", -+ "oauth2-client-id", -+ "oauth2-client-secret", -+ "off", -+ "on", -+ "oobe-bootstrapping-master", -+ "oobe-guest-session", -+ "oobe-skip-postlogin", -+ "oobe-timer-interval", -+ "open-ash", -+ "opengraph", -+ "origin-to-force-quic-on", -+ "origin-trial-disabled-features", -+ "origin-trial-disabled-tokens", -+ "origin-trial-public-key", -+ "original-process-start-time", -+ "osmesa", -+ "output", -+ "override", -+ "override-metrics-upload-url", -+ "override-plugin-power-saver-for-testing", -+ "override-use-software-gl-for-tests", -+ "overscroll-history-navigation", -+ "overscroll-start-threshold", -+ "ozone-dump-file", -+ "ozone-platform", -+ "pack-extension", -+ "pack-extension-key", -+ "parent-profile", -+ "parent-window", -+ "passive-listeners-default", -+ "password-store", -+ "permission-request-api-scope", -+ "permission-request-api-url", -+ "power-stub", -+ "ppapi", -+ "ppapi-antialiased-text-enabled", -+ "ppapi-broker", -+ "ppapi-flash-args", -+ "ppapi-flash-path", -+ "ppapi-flash-version", -+ "ppapi-in-process", -+ "ppapi-plugin-launcher", -+ "ppapi-startup-dialog", -+ "ppapi-subpixel-rendering-setting", -+ "precache-config-settings-url", -+ "precache-manifest-url-prefix", -+ "prerender-from-omnibox", -+ "previous-app", -+ "primary", -+ "primordial-pipe-token", -+ "print-to-pdf", -+ "privet-ipv6-only", -+ "process-per-site", -+ "process-per-tab", -+ "process-service-name", -+ "product-version", -+ "profile-directory", -+ "profiler-timing", -+ "profiling-at-start", -+ "profiling-file", -+ "profiling-flush", -+ "progress-bar-animation", -+ "progress-bar-completion", -+ "prompt-for-external-extensions", -+ "proxy-auto-detect", -+ "proxy-bypass-list", -+ "proxy-pac-url", -+ "proxy-server", -+ "q", -+ "quic-connection-options", -+ "quic-host-whitelist", -+ "quic-max-packet-length", -+ "quic-version", -+ "rdp_desktop_session", -+ "reader-mode-feedback", -+ "reader-mode-heuristics", -+ "rebaseline-pixel-tests", -+ "reduce-security-for-testing", -+ "reduced-referrer-granularity", -+ "register-font-files", -+ "register-pepper-plugins", -+ "relauncher", -+ "remote-debugging-address", -+ "remote-debugging-port", -+ "remote-debugging-socket-name", -+ "remote-debugging-targets", -+ "renderer", -+ "renderer-client-id", -+ "renderer-cmd-prefix", -+ "renderer-process-limit", -+ "renderer-startup-dialog", -+ "renderer-wait-for-java-debugger", -+ "renderpass", -+ "repl", -+ "report-vp9-as-an-unsupported-mime-type", -+ "require-audio-hardware-for-testing", -+ "reset-app-list-install-state", -+ "reset-variation-state", -+ "restore-last-session", -+ "root", -+ "root-layer-scrolls", -+ "rtl", -+ "run-layout-test", -+ "runtime-deps-list-file", -+ "safebrowsing-disable-auto-update", -+ "safebrowsing-disable-download-protection", -+ "safebrowsing-disable-extension-blacklist", -+ "safebrowsing-manual-download-blacklist", -+ "sandbox-ipc", -+ "save-page-as-mhtml", -+ "saveas-menu-label", -+ "screen-config", -+ "screenshot", -+ "script-executable", -+ "scripts-require-action", -+ "scroll-end-effect", -+ "secondary", -+ "secondary-display-layout", -+ "secondary-ui-md", -+ "service", -+ "service-overrides", -+ "service-request-channel-token", -+ "shared-files", -+ "shill-stub", -+ "show-app-list", -+ "show-autofill-signatures", -+ "show-autofill-type-predictions", -+ "show-component-extension-options", -+ "show-composited-layer-borders", -+ "show-fps-counter", -+ "show-icons", -+ "show-layer-animation-bounds", -+ "show-mac-overlay-borders", -+ "show-overdraw-feedback", -+ "show-paint-rects", -+ "show-property-changed-rects", -+ "show-saved-copy", -+ "show-screenspace-rects", -+ "show-surface-damage-rects", -+ "show_summary", -+ "silent-debugger-extension-api", -+ "silent-launch", -+ "simulate-critical-update", -+ "simulate-elevated-recovery", -+ "simulate-outdated", -+ "simulate-outdated-no-au", -+ "simulate-upgrade", -+ "single-process", -+ "site-per-process", -+ "skip-gpu-data-loading", -+ "skip-nostore-all", -+ "skip-nostore-main", -+ "skip-reencoding-on-skp-capture", -+ "slow", -+ "slow-connections-only", -+ "slow-down-raster-scale-factor", -+ "sms-test-messages", -+ "spdy-proxy-auth-fallback", -+ "spdy-proxy-auth-origin", -+ "spdy-proxy-auth-value", -+ "spelling-service-feedback-interval-seconds", -+ "spelling-service-feedback-url", -+ "ssl-key-log-file", -+ "ssl-version-max", -+ "ssl-version-min", -+ "stable-release-mode", -+ "start-fullscreen", -+ "start-maximized", -+ "start-stack-profiler", -+ "started", -+ "stub", -+ "stub-cros-settings", -+ "supports-dual-gpus", -+ "surface", -+ "swiftshader", -+ "swiftshader-webgl", -+ "sync-allow-insecure-xmpp-connection", -+ "sync-deferred-startup-timeout-seconds", -+ "sync-disable-deferred-startup", -+ "sync-enable-get-update-avoidance", -+ "sync-notification-host-port", -+ "sync-on-draw-hardware", -+ "sync-short-initial-retry-override", -+ "sync-short-nudge-delay-for-test", -+ "sync-url", -+ "system-developer-mode", -+ "system-log-upload-frequency", -+ "tab-management-experiment-type-disabled", -+ "tab-management-experiment-type-elderberry", -+ "task-profiler", -+ "team-drives", -+ "test-auto-update-ui", -+ "test-child-process", -+ "test-cros-gaia-id-migration", -+ "test-do-not-initialize-icu", -+ "test-encryption-migration-ui", -+ "test-gl-lib", -+ "test-launcher-batch-limit", -+ "test-launcher-bot-mode", -+ "test-launcher-debug-launcher", -+ "test-launcher-filter-file", -+ "test-launcher-force-run-broken-tests", -+ "test-launcher-jobs", -+ "test-launcher-list-tests", -+ "test-launcher-output", -+ "test-launcher-print-test-stdio", -+ "test-launcher-print-writable-path", -+ "test-launcher-retry-limit", -+ "test-launcher-shard-index", -+ "test-launcher-summary-output", -+ "test-launcher-timeout", -+ "test-launcher-total-shards", -+ "test-launcher-trace", -+ "test-name", -+ "test-tiny-timeout", -+ "test-type", -+ "testing-fixed-http-port", -+ "testing-fixed-https-port", -+ "threads", -+ "time", -+ "timeout", -+ "tls1", -+ "tls1.1", -+ "tls1.2", -+ "tls1.3", -+ "top-chrome-md", -+ "top-controls-hide-threshold", -+ "top-controls-show-threshold", -+ "top-document-isolation", -+ "touch-calibration", -+ "touch-devices", -+ "touch-events", -+ "touch-noise-filtering", -+ "touch-selection-strategy", -+ "touch_view", -+ "trace-config-file", -+ "trace-export-events-to-etw", -+ "trace-shutdown", -+ "trace-shutdown-file", -+ "trace-startup", -+ "trace-startup-duration", -+ "trace-startup-file", -+ "trace-to-console", -+ "trace-to-file", -+ "trace-to-file-name", -+ "trace-upload-url", -+ "tracelog", -+ "translate-ranker-model-url", -+ "translate-script-url", -+ "translate-security-origin", -+ "true", -+ "try-chrome-again", -+ "try-supported-channel-layouts", -+ "type", -+ "ui-disable-partial-swap", -+ "ui-enable-layer-lists", -+ "ui-enable-rgba-4444-textures", -+ "ui-enable-zero-copy", -+ "ui-prioritize-in-gpu-process", -+ "ui-show-fps-counter", -+ "ui-show-layer-animation-bounds", -+ "ui-show-layer-borders", -+ "ui-show-paint-rects", -+ "ui-show-property-changed-rects", -+ "ui-show-screenspace-rects", -+ "ui-show-surface-damage-rects", -+ "ui-slow-animations", -+ "ui-test-action-max-timeout", -+ "ui-test-action-timeout", -+ "uninstall", -+ "unlimited-storage", -+ "unsafe-pac-url", -+ "unsafely-allow-protected-media-identifier-for-domain", -+ "unsafely-treat-insecure-origin-as-secure", -+ "use-angle", -+ "use-cras", -+ "use-double-buffering", -+ "use-fake-device-for-media-stream", -+ "use-fake-jpeg-decode-accelerator", -+ "use-fake-ui-for-media-stream", -+ "use-file-for-fake-audio-capture", -+ "use-file-for-fake-video-capture", -+ "use-first-display-as-internal", -+ "use-gl", -+ "use-gpu-in-tests", -+ "use-mobile-user-agent", -+ "use-mock-keychain", -+ "use-new-virtual-keyboard-behavior", -+ "use-passthrough-cmd-decoder", -+ "use-simple-cache-backend", -+ "use-test-config", -+ "use_new_features_summary", -+ "user-agent", -+ "user-always-affiliated", -+ "user-data-dir", -+ "utility", -+ "utility-allowed-dir", -+ "utility-cmd-prefix", -+ "utility-run-elevated", -+ "v", -+ "v8-cache-options", -+ "v8-cache-strategies-for-cache-storage", -+ "validate-crx", -+ "validate-input-event-stream", -+ "variations-server-url", -+ "version", -+ "video-image-texture-target", -+ "video-threads", -+ "video-underflow-threshold-ms", -+ "viewer-launch-via-appid", -+ "virtual-time-budget", -+ "vmodule", -+ "wait-for-debugger", -+ "wait-for-debugger-children", -+ "wake-on-wifi-packet", -+ "wallet-service-use-sandbox", -+ "watcher", -+ "waveout-buffers", -+ "webapk-server-url", -+ "webrtc-max-cpu-consumption-percentage", -+ "webrtc-stun-probe-trial", -+ "webview-enable-safebrowsing-support", -+ "webview-sandboxed-renderer", -+ "whitelisted-extension-id", -+ "win-jumplist-action", -+ "window-position", -+ "window-size", -+ "window-workspace", -+ "windows10-custom-titlebar", -+ "windows8-search", -+ "winhttp-proxy-resolver", -+ "wm-window-animations-disabled", -+ "yield-between-content-script-runs", -+ "zygote", -+ "zygote-cmd-prefix" -+}; -+ -+bool IsBlacklistedArg(const base::CommandLine::CharType* arg) { -+#if defined(OS_WIN) -+ const auto converted = base::WideToUTF8(arg); -+ const char* a = converted.c_str(); -+#else -+ const char* a = arg; -+#endif -+ -+ static const char* prefixes[] = {"--", "-", "/"}; -+ -+ int prefix_length = 0; -+ for (auto& prefix : prefixes) { -+ if (base::StartsWith(a, prefix, base::CompareCase::SENSITIVE)) { -+ prefix_length = strlen(prefix); -+ break; -+ } -+ } -+ -+ if (prefix_length > 0) { -+ a += prefix_length; -+ std::string switch_name = -+ base::ToLowerASCII(base::StringPiece(a, strcspn(a, "="))); -+ for (auto& item : blacklist) { -+ if (switch_name == item) -+ return true; -+ } -+ } -+ -+ return false; -+} -+ -+>>>>>>> .their - } // namespace - - namespace atom { - - bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv) { - const base::CommandLine::StringType dashdash(2, '-'); -+<<<<<<< .our - bool block_args = false; - for (int i = 0; i < argc; ++i) { - if (argv[i] == dashdash) -@@ -45,6 +1393,17 @@ - return false; - } else if (IsUrlArg(argv[i])) { - block_args = true; -+======= -+ bool block_blacklisted_args = false; -+ for (int i = 0; i < argc; ++i) { -+ if (argv[i] == dashdash) -+ break; -+ if (block_blacklisted_args) { -+ if (IsBlacklistedArg(argv[i])) -+ return false; -+ } else if (IsUrlArg(argv[i])) { -+ block_blacklisted_args = true; -+>>>>>>> .their - } - } - return true; -added in both - our 100644 2c0acc1648ff3b4bc574f000643069f8ef8e94bb atom/app/command_line_args.h - their 100644 1f5fd756868898e7a304c754d89625059d36441f atom/app/command_line_args.h -@@ -14,3 +14,7 @@ - } // namespace atom - - #endif // ATOM_APP_COMMAND_LINE_ARGS_H_ -+<<<<<<< .our -+======= -+ -+>>>>>>> .their -changed in both - base 100644 1534f648498f991dbf16f53a1f8b7f816fc8fd27 atom/browser/api/atom_api_app.cc - our 100644 089a2b63d1bae3afebea925582a3aac81ddeaa4f atom/browser/api/atom_api_app.cc - their 100644 b3d79045c0d482495618f47801492d8f04c81af2 atom/browser/api/atom_api_app.cc -changed in both - base 100644 4bd88a5a43c03ceba308ec06fdf0cbadeddcaae3 atom/browser/api/atom_api_browser_view.cc - our 100644 bd83208694c61c4d7c43ce4be26939c2682b2a13 atom/browser/api/atom_api_browser_view.cc - their 100644 41f0e99cdd79bf1ad2c4c8c0db5aaa97ac5e1297 atom/browser/api/atom_api_browser_view.cc -changed in both - base 100644 79feb7520b0d8209b1b024f17261161a350f09a3 atom/browser/api/atom_api_desktop_capturer.cc - our 100644 135b4edd11048a4635f9017f569f4b4ae644a09c atom/browser/api/atom_api_desktop_capturer.cc - their 100644 7a7c41503e22572cdfddc4be915d1f7ab2b77ef7 atom/browser/api/atom_api_desktop_capturer.cc -@@ -62,6 +62,7 @@ - const gfx::Size& thumbnail_size, - atom::api::DesktopCapturer* cap) { - #if defined(OS_WIN) -+<<<<<<< .our - if (content::desktop_capture::CreateDesktopCaptureOptions() - .allow_directx_capturer()) { - // DxgiDuplicatorController should be alive in this scope according to -@@ -71,6 +72,18 @@ - webrtc::ScreenCapturerWinDirectx::IsSupported(); - } - #endif // defined(OS_WIN) -+======= -+ // On windows, desktop effects (e.g. Aero) will be disabled when the Desktop -+ // capture API is active by default. -+ // We keep the desktop effects in most times. Howerver, the screen still -+ // fickers when the API is capturing the window due to limitation of current -+ // implemetation. This is a known and wontFix issue in webrtc (see: -+ // http://code.google.com/p/webrtc/issues/detail?id=3373) -+ options.set_disable_effects(false); -+ options.set_allow_directx_capturer(true); -+#endif -+ -+>>>>>>> .their - std::unique_ptr<webrtc::DesktopCapturer> screen_capturer( - capture_screen ? content::desktop_capture::CreateScreenCapturer() - : nullptr); -changed in both - base 100644 59fdac39491ceaae7340d08164c091dafdb8a388 atom/browser/api/atom_api_menu_views.cc - our 100644 3da7dc2842fa4561e037aa67f290d0cc6ca71014 atom/browser/api/atom_api_menu_views.cc - their 100644 66adeb8271d8720aad9f9974242f26db583e10cc atom/browser/api/atom_api_menu_views.cc -@@ -19,11 +19,16 @@ - - MenuViews::~MenuViews() = default; - -+<<<<<<< .our - void MenuViews::PopupAt(TopLevelWindow* window, - int x, - int y, - int positioning_item, - const base::Closure& callback) { -+======= -+void MenuViews::PopupAt( -+ Window* window, int x, int y, int positioning_item, bool async) { -+>>>>>>> .their - auto* native_window = static_cast<NativeWindowViews*>(window->window()); - if (!native_window) - return; -@@ -45,12 +50,24 @@ - // Show the menu. - int32_t window_id = window->weak_map_id(); - auto close_callback = base::Bind( -+<<<<<<< .our - &MenuViews::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback); - menu_runners_[window_id] = - std::make_unique<MenuRunner>(model(), flags, close_callback); - menu_runners_[window_id]->RunMenuAt( - native_window->widget(), NULL, gfx::Rect(location, gfx::Size()), - views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE); -+======= -+ &MenuViews::ClosePopupAt, weak_factory_.GetWeakPtr(), window_id); -+ menu_runners_[window_id] = std::unique_ptr<MenuRunner>(new MenuRunner( -+ model(), flags, close_callback)); -+ ignore_result(menu_runners_[window_id]->RunMenuAt( -+ native_window->widget(), -+ NULL, -+ gfx::Rect(location, gfx::Size()), -+ views::MENU_ANCHOR_TOPLEFT, -+ ui::MENU_SOURCE_MOUSE)); -+>>>>>>> .their - } - - void MenuViews::ClosePopupAt(int32_t window_id) { -changed in both - base 100644 40dc30600f936e9a89fc8b201e1a9816a94b721e atom/browser/api/atom_api_protocol.h - our 100644 deaf680c996ce0dd74af45e7c7c95f711884bb07 atom/browser/api/atom_api_protocol.h - their 100644 dfc32be6bc57cb9c9c18803ff13e2045ce7f6caa atom/browser/api/atom_api_protocol.h -changed in both - base 100644 7df905a8ee9decfc0406db717c0149655e399234 atom/browser/api/atom_api_web_contents.cc - our 100644 20a1ac2e672f08ffea528b6e094ba530ff8083d1 atom/browser/api/atom_api_web_contents.cc - their 100644 1aa7878fd435a355575cac8034a19e40e021c422 atom/browser/api/atom_api_web_contents.cc -@@ -280,7 +280,12 @@ - - // Called when CapturePage is done. - void OnCapturePageDone(const base::Callback<void(const gfx::Image&)>& callback, -+<<<<<<< .our - const SkBitmap& bitmap) { -+======= -+ const SkBitmap& bitmap, -+ content::ReadbackResponse response) { -+>>>>>>> .their - // Hack to enable transparency in captured image - // TODO(nitsakh) Remove hack once fixed in chromium - const_cast<SkBitmap&>(bitmap).setAlphaType(kPremul_SkAlphaType); -@@ -397,8 +402,8 @@ - options.Get("transparent", &transparent); - - content::WebContents::CreateParams params(session->browser_context()); -- auto* view = new OffScreenWebContentsView( -- transparent, base::Bind(&WebContents::OnPaint, base::Unretained(this))); -+ auto* view = new OffScreenWebContentsView(transparent, -+ base::Bind(&WebContents::OnPaint, base::Unretained(this))); - params.view = view; - params.delegate_view = view; - -@@ -1742,7 +1747,12 @@ - return; - - #if defined(ENABLE_OSR) -+<<<<<<< .our - auto* osr_wcv = GetOffScreenWebContentsView(); -+======= -+ const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents()); -+ auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView()); -+>>>>>>> .their - if (osr_wcv) - osr_wcv->SetPainting(true); - #endif -@@ -1753,7 +1763,12 @@ - return; - - #if defined(ENABLE_OSR) -+<<<<<<< .our - auto* osr_wcv = GetOffScreenWebContentsView(); -+======= -+ const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents()); -+ auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView()); -+>>>>>>> .their - if (osr_wcv) - osr_wcv->SetPainting(false); - #endif -@@ -1764,7 +1779,13 @@ - return false; - - #if defined(ENABLE_OSR) -+<<<<<<< .our - auto* osr_wcv = GetOffScreenWebContentsView(); -+======= -+ const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents()); -+ auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView()); -+ -+>>>>>>> .their - return osr_wcv && osr_wcv->IsPainting(); - #else - return false; -@@ -1776,7 +1797,13 @@ - return; - - #if defined(ENABLE_OSR) -+<<<<<<< .our - auto* osr_wcv = GetOffScreenWebContentsView(); -+======= -+ const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents()); -+ auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView()); -+ -+>>>>>>> .their - if (osr_wcv) - osr_wcv->SetFrameRate(frame_rate); - #endif -@@ -1787,7 +1814,13 @@ - return 0; - - #if defined(ENABLE_OSR) -+<<<<<<< .our - auto* osr_wcv = GetOffScreenWebContentsView(); -+======= -+ const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents()); -+ auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView()); -+ -+>>>>>>> .their - return osr_wcv ? osr_wcv->GetFrameRate() : 0; - #else - return 0; -@@ -1871,6 +1904,7 @@ - return mate::ConvertToV8(isolate, *web_preferences->preference()); - } - -+<<<<<<< .our - v8::Local<v8::Value> WebContents::GetLastWebPreferences( - v8::Isolate* isolate) const { - auto* web_preferences = WebContentsPreferences::From(web_contents()); -@@ -1880,6 +1914,17 @@ - } - - v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() const { -+======= -+v8::Local<v8::Value> WebContents::GetLastWebPreferences(v8::Isolate* isolate) { -+ WebContentsPreferences* web_preferences = -+ WebContentsPreferences::FromWebContents(web_contents()); -+ if (!web_preferences) -+ return v8::Null(isolate); -+ return mate::ConvertToV8(isolate, *web_preferences->last_web_preferences()); -+} -+ -+v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() { -+>>>>>>> .their - if (owner_window()) - return BrowserWindow::From(isolate(), owner_window()); - else -changed in both - base 100644 ffeb8f7241802ba1bd188752b3b3ef9a81c7dd66 atom/browser/api/atom_api_web_contents.h - our 100644 7939f8268aa8c3371623e0c15f3b6001d7f1efa4 atom/browser/api/atom_api_web_contents.h - their 100644 a5b96adb94fa384f8ba50737be07f05f2074580f atom/browser/api/atom_api_web_contents.h -@@ -234,8 +234,13 @@ - v8::Local<v8::Value> GetPreloadPath(v8::Isolate* isolate) const; - - // Returns the web preferences of current WebContents. -+<<<<<<< .our - v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate) const; - v8::Local<v8::Value> GetLastWebPreferences(v8::Isolate* isolate) const; -+======= -+ v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate); -+ v8::Local<v8::Value> GetLastWebPreferences(v8::Isolate* isolate); -+>>>>>>> .their - - // Returns the owner window. - v8::Local<v8::Value> GetOwnerBrowserWindow() const; -removed in local - base 100644 bb7060adb76d9f7993f18774be599c2bd604cb9f atom/browser/api/atom_api_window.cc - their 100644 5a135ea522d56f89a8d56f41814ca483040ed62f atom/browser/api/atom_api_window.cc -changed in both - base 100644 61c97f2c35ce3c9e76cee59f9e4becd9649c993b atom/browser/atom_browser_client.cc - our 100644 57c4ee582405e6d501ec23940ccb10689ecd64a1 atom/browser/atom_browser_client.cc - their 100644 49c8656c882a5aedf27649504c65d4f64f0ae416 atom/browser/atom_browser_client.cc -@@ -296,6 +296,7 @@ - base::CommandLine* command_line, - int process_id) { - // Make sure we're about to launch a known executable -+<<<<<<< .our - { - base::FilePath child_path; - PathService::Get(content::CHILD_PROCESS_EXE, &child_path); -@@ -303,6 +304,11 @@ - base::ThreadRestrictions::ScopedAllowIO allow_io; - CHECK(base::MakeAbsoluteFilePath(command_line->GetProgram()) == child_path); - } -+======= -+ base::FilePath child_path; -+ PathService::Get(content::CHILD_PROCESS_EXE, &child_path); -+ CHECK(base::MakeAbsoluteFilePath(command_line->GetProgram()) == child_path); -+>>>>>>> .their - - std::string process_type = - command_line->GetSwitchValueASCII(::switches::kProcessType); -changed in both - base 100644 7c154b60b00e25c42847ceefb98723b50ea03dd0 atom/browser/native_browser_view.h - our 100644 56937e4c8c69e3605d2b6cc71a0877b74ff4e83d atom/browser/native_browser_view.h - their 100644 cab6980fa2cf035c1a5ca6b4aee822a0ee604fd4 atom/browser/native_browser_view.h -changed in both - base 100644 17b0a1ee9006dd70888165a9209076fd7065f3cc atom/browser/native_browser_view_mac.mm - our 100644 0416e26e89f1e0f37366ef1798b4359da0729225 atom/browser/native_browser_view_mac.mm - their 100644 86df632638ef7772270569824515b251470d0c08 atom/browser/native_browser_view_mac.mm -changed in both - base 100644 08a8123bcaef664aa660d1bea6d6baf783b78e89 atom/browser/native_browser_view_views.cc - our 100644 6414005a1e40d80ae86102b12edee0255cab9adb atom/browser/native_browser_view_views.cc - their 100644 3e7df488c73e98ba2870c913542f478865e15575 atom/browser/native_browser_view_views.cc -changed in both - base 100644 5dcda13447cde098fccaf8782fefb97d861d47f4 atom/browser/native_browser_view_views.h - our 100644 8f8e860292baddad1156c50ae7cfaa0fd6e87d99 atom/browser/native_browser_view_views.h - their 100644 abf47178302ad7527c1640a3f41492f871f137e5 atom/browser/native_browser_view_views.h -changed in both - base 100644 1e02a37fc07da1616026915cea6c61f467a4751d atom/browser/native_window.h - our 100644 35b67e2dd230692c415a32aae5f0a5e99ab74ac0 atom/browser/native_window.h - their 100644 d2e1ff876c1678dc2749b5d98a8cc46e948bb2dc atom/browser/native_window.h -@@ -221,6 +221,8 @@ - content::WebContents*, - const content::NativeWebKeyboardEvent& event) {} - -+ virtual void UpdateDraggableRegionViews() {} -+ - // Public API used by platform-dependent delegates and observers to send UI - // related notifications. - void NotifyWindowRequestPreferredWith(int* width); -changed in both - base 100644 24d9a0aab87837e39a4c1e1368cfb3a724dd0410 atom/browser/native_window_mac.h - our 100644 44a78198f44cdba9875e3fb27c8e2c87eaa6f33b atom/browser/native_window_mac.h - their 100644 e0c548a2d616d90c5ac3de0a879bcd7943e503b0 atom/browser/native_window_mac.h -@@ -130,8 +130,19 @@ - gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) const override; - gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) const override; - -+<<<<<<< .our - // Use a custom content view instead of Chromium's BridgedContentView. - void OverrideNSWindowContentView(); -+======= -+ // content::WebContentsObserver: -+ void RenderViewHostChanged(content::RenderViewHost* old_host, -+ content::RenderViewHost* new_host) override; -+ -+ // Refresh the DraggableRegion views. -+ void UpdateDraggableRegionViews() override { -+ UpdateDraggableRegionViews(draggable_regions_); -+ } -+>>>>>>> .their - - // Set the attribute of NSWindow while work around a bug of zoom button. - void SetStyleMask(bool on, NSUInteger flag); -changed in both - base 100644 59301fc7a982605ca204bb541410ac74a872e127 atom/browser/native_window_mac.mm - our 100644 004263ec127709067e903ffbf31003b8844226b4 atom/browser/native_window_mac.mm - their 100644 1db35693d8ae2b9ade1d13d0f28631ee5b8417cc atom/browser/native_window_mac.mm -@@ -1387,6 +1387,7 @@ - [parent->GetNativeWindow() addChildWindow:window_ ordered:NSWindowAbove]; - } - -+<<<<<<< .our - void NativeWindowMac::ShowWindowButton(NSWindowButton button) { - auto view = [window_ standardWindowButton:button]; - [view.superview addSubview:view positioned:NSWindowAbove relativeTo:nil]; -@@ -1395,6 +1396,35 @@ - void NativeWindowMac::SetForwardMouseMessages(bool forward) { - [window_ setAcceptsMouseMovedEvents:forward]; - } -+======= -+ // Remove all ControlRegionViews that are added last time. -+ // Note that [webView subviews] returns the view's mutable internal array and -+ // it should be copied to avoid mutating the original array while enumerating -+ // it. -+ base::scoped_nsobject<NSArray> subviews([[webView subviews] copy]); -+ for (NSView* subview in subviews.get()) -+ if ([subview isKindOfClass:[ControlRegionView class]]) -+ [subview removeFromSuperview]; -+ -+ // Draggable regions is implemented by having the whole web view draggable -+ // (mouseDownCanMoveWindow) and overlaying regions that are not draggable. -+ std::vector<gfx::Rect> drag_exclude_rects = -+ CalculateNonDraggableRegions(regions, webViewWidth, webViewHeight); -+ -+ if (browser_view_) { -+ browser_view_->UpdateDraggableRegions(drag_exclude_rects); -+ } -+ -+ // Create and add a ControlRegionView for each region that needs to be -+ // excluded from the dragging. -+ for (const auto& rect : drag_exclude_rects) { -+ base::scoped_nsobject<NSView> controlRegion( -+ [[ControlRegionView alloc] initWithFrame:NSZeroRect]); -+ [controlRegion setFrame:NSMakeRect(rect.x(), webViewHeight - rect.bottom(), -+ rect.width(), rect.height())]; -+ [webView addSubview:controlRegion]; -+ } -+>>>>>>> .their - - void NativeWindowMac::OverrideNSWindowContentView() { - // When using `views::Widget` to hold WebContents, Chromium would use -changed in both - base 100644 0ae5092b4397fbf999ada9007eaadcd3e9c4b43a atom/browser/native_window_views.cc - our 100644 0dba39942f92d54ba34db7709b73012055680d94 atom/browser/native_window_views.cc - their 100644 26f1a926ac94a6838eeba2208a15e37ebd1e4019 atom/browser/native_window_views.cc -@@ -55,6 +55,7 @@ - #include "atom/browser/ui/views/win_frame_view.h" - #include "atom/browser/ui/win/atom_desktop_native_widget_aura.h" - #include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h" -+#include "content/public/browser/gpu_data_manager.h" - #include "skia/ext/skia_utils_win.h" - #include "ui/base/win/shell.h" - #include "ui/display/display.h" -@@ -247,7 +248,16 @@ - ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style); - } - -+ bool hardware_accelerated = -+ content::GpuDataManager::GetInstance()->HardwareAccelerationEnabled(); - LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); -+<<<<<<< .our -+======= -+ // Window without thick frame has to have WS_EX_COMPOSITED style when GPU -+ // acceleration is enabled. -+ if (!thick_frame_ && hardware_accelerated) -+ ex_style |= WS_EX_COMPOSITED; -+>>>>>>> .their - if (window_type == "toolbar") - ex_style |= WS_EX_TOOLWINDOW; - ::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style); -@@ -1237,9 +1247,141 @@ - void NativeWindowViews::HandleKeyboardEvent( - content::WebContents*, - const content::NativeWebKeyboardEvent& event) { -+<<<<<<< .our - keyboard_event_handler_->HandleKeyboardEvent(event, - root_view_->GetFocusManager()); - root_view_->HandleKeyEvent(event); -+======= -+ keyboard_event_handler_->HandleKeyboardEvent(event, GetFocusManager()); -+ -+ if (!menu_bar_) -+ return; -+ -+ // Show accelerator when "Alt" is pressed. -+ if (menu_bar_visible_ && IsAltKey(event)) -+ menu_bar_->SetAcceleratorVisibility( -+ event.GetType() == blink::WebInputEvent::kRawKeyDown); -+ -+ // Show the submenu when "Alt+Key" is pressed. -+ if (event.GetType() == blink::WebInputEvent::kRawKeyDown && -+ !IsAltKey(event) && IsAltModifier(event)) { -+ if (!menu_bar_visible_ && -+ (menu_bar_->GetAcceleratorIndex(event.windows_key_code) != -1)) -+ SetMenuBarVisibility(true); -+ menu_bar_->ActivateAccelerator(event.windows_key_code); -+ return; -+ } -+ -+ if (!menu_bar_autohide_) -+ return; -+ -+ // Toggle the menu bar only when a single Alt is released. -+ if (event.GetType() == blink::WebInputEvent::kRawKeyDown && IsAltKey(event)) { -+ // When a single Alt is pressed: -+ menu_bar_alt_pressed_ = true; -+ } else if (event.GetType() == blink::WebInputEvent::kKeyUp && -+ IsAltKey(event) && menu_bar_alt_pressed_) { -+ // When a single Alt is released right after a Alt is pressed: -+ menu_bar_alt_pressed_ = false; -+ SetMenuBarVisibility(!menu_bar_visible_); -+ } else { -+ // When any other keys except single Alt have been pressed/released: -+ menu_bar_alt_pressed_ = false; -+ } -+} -+ -+void NativeWindowViews::ShowAutofillPopup( -+ content::RenderFrameHost* frame_host, -+ content::WebContents* web_contents, -+ const gfx::RectF& bounds, -+ const std::vector<base::string16>& values, -+ const std::vector<base::string16>& labels) { -+ bool is_offsceen = false; -+ bool is_embedder_offscreen = false; -+ -+ auto* web_contents_preferences = -+ WebContentsPreferences::FromWebContents(web_contents); -+ if (web_contents_preferences) { -+ const auto* web_preferences = web_contents_preferences->web_preferences(); -+ -+ web_preferences->GetBoolean("offscreen", &is_offsceen); -+ int guest_instance_id = 0; -+ web_preferences->GetInteger(options::kGuestInstanceID, &guest_instance_id); -+ -+ if (guest_instance_id) { -+ auto manager = WebViewManager::GetWebViewManager(web_contents); -+ if (manager) { -+ auto embedder = manager->GetEmbedder(guest_instance_id); -+ if (embedder) { -+ is_embedder_offscreen = WebContentsPreferences::IsPreferenceEnabled( -+ "offscreen", embedder); -+ } -+ } -+ } -+ } -+ -+ autofill_popup_->CreateView( -+ frame_host, -+ is_offsceen || is_embedder_offscreen, -+ widget(), -+ bounds); -+ autofill_popup_->SetItems(values, labels); -+ autofill_popup_->UpdatePopupBounds(menu_bar_visible_ ? 0 : kMenuBarHeight); -+} -+ -+void NativeWindowViews::HideAutofillPopup( -+ content::RenderFrameHost* frame_host) { -+ autofill_popup_->Hide(); -+} -+ -+void NativeWindowViews::Layout() { -+ const auto size = GetContentsBounds().size(); -+ const auto menu_bar_bounds = -+ menu_bar_visible_ ? gfx::Rect(0, 0, size.width(), kMenuBarHeight) -+ : gfx::Rect(); -+ if (menu_bar_) { -+ menu_bar_->SetBoundsRect(menu_bar_bounds); -+ } -+ -+ if (web_view_) { -+ web_view_->SetBoundsRect( -+ gfx::Rect(0, menu_bar_bounds.height(), size.width(), -+ size.height() - menu_bar_bounds.height())); -+ } -+ -+ if (autofill_popup_.get()) -+ autofill_popup_->UpdatePopupBounds(menu_bar_visible_ ? 0 : kMenuBarHeight); -+} -+ -+gfx::Size NativeWindowViews::GetMinimumSize() const { -+ return NativeWindow::GetMinimumSize(); -+} -+ -+gfx::Size NativeWindowViews::GetMaximumSize() const { -+ return NativeWindow::GetMaximumSize(); -+} -+ -+bool NativeWindowViews::AcceleratorPressed(const ui::Accelerator& accelerator) { -+ return accelerator_util::TriggerAcceleratorTableCommand( -+ &accelerator_table_, accelerator); -+} -+ -+void NativeWindowViews::RegisterAccelerators(AtomMenuModel* menu_model) { -+ // Clear previous accelerators. -+ views::FocusManager* focus_manager = GetFocusManager(); -+ accelerator_table_.clear(); -+ focus_manager->UnregisterAccelerators(this); -+ -+ // Register accelerators with focus manager. -+ accelerator_util::GenerateAcceleratorTable(&accelerator_table_, menu_model); -+ accelerator_util::AcceleratorTable::const_iterator iter; -+ for (iter = accelerator_table_.begin(); -+ iter != accelerator_table_.end(); -+ ++iter) { -+ focus_manager->RegisterAccelerator( -+ iter->first, ui::AcceleratorManager::kNormalPriority, this); -+ } -+>>>>>>> .their - } - - ui::WindowShowState NativeWindowViews::GetRestoredState() { -changed in both - base 100644 ad02ed620d6d94ba15e7f8d154063a0968178110 atom/browser/net/asar/url_request_asar_job.cc - our 100644 85eb2e1dd142b6d64aafb5350ae47603db989e8f atom/browser/net/asar/url_request_asar_job.cc - their 100644 5c4472a315911a6c2da533b35d489f8f9da5cd53 atom/browser/net/asar/url_request_asar_job.cc -@@ -243,6 +243,24 @@ - meta_info->mime_type_result = net::GetWellKnownMimeTypeFromExtension( - file_extension.substr(1), &meta_info->mime_type); - } -+<<<<<<< .our -+======= -+ -+ // We use GetWellKnownMimeTypeFromExtension() to ensure that configurations -+ // that may have been set by other programs on a user's machine don't affect -+ // the mime type returned (in particular, JS should always be -+ // (application/javascript). See https://crbug.com/797712. Using an accurate -+ // mime type is necessary at least for modules and sw, which enforce strict -+ // mime type requirements. -+ // TODO(deepak1556): Revert this when sw support is removed for file scheme. -+ base::FilePath::StringType file_extension = file_path.Extension(); -+ if (file_extension.empty()) { -+ meta_info->mime_type_result = false; -+ } else { -+ meta_info->mime_type_result = net::GetWellKnownMimeTypeFromExtension( -+ file_extension.substr(1), &meta_info->mime_type); -+ } -+>>>>>>> .their - } - - void URLRequestAsarJob::DidFetchMetaInfo(const FileMetaInfo* meta_info) { -changed in both - base 100644 9400f361f11a2e709b4cb0837ff638219aa519a7 atom/browser/net/atom_url_request.cc - our 100644 5ffbfd65a48b4459b2ebca66a5c2259f18ed80a8 atom/browser/net/atom_url_request.cc - their 100644 f259889edab7c64ac8c682e2bd68a778463135e0 atom/browser/net/atom_url_request.cc -changed in both - base 100644 79dd80b586600cb5e3b98d03f69f9bd8aed4a526 atom/browser/net/atom_url_request_job_factory.cc - our 100644 7047f7a6f7f83e782121f2a849a621fb836ad534 atom/browser/net/atom_url_request_job_factory.cc - their 100644 20680adf7da826e94e555865d4f023d8a9217eab atom/browser/net/atom_url_request_job_factory.cc -changed in both - base 100644 56f979c2ff60b06aea1c62f5cefa78b1a9df6e21 atom/browser/net/atom_url_request_job_factory.h - our 100644 c0e26568fdea57dd473f917d597624ab10efe129 atom/browser/net/atom_url_request_job_factory.h - their 100644 a560839b68e0ccd00f414deff245bc237de9deba atom/browser/net/atom_url_request_job_factory.h -changed in both - base 100644 be3d76bc047d1723eaed3db1bfac827baa063009 atom/browser/node_debugger.cc - our 100644 56e68e2b8b817aae2786775e3977977474420cc2 atom/browser/node_debugger.cc - their 100644 a0d0b0dc42b913937bedbb08d1e344dc00ba26c7 atom/browser/node_debugger.cc -@@ -31,11 +31,27 @@ - #endif - } - -+<<<<<<< .our - // Set process._debugWaitConnect if --inspect-brk was specified to stop - // the debugger on the first line - if (options.wait_for_connect()) { - mate::Dictionary process(env_->isolate(), env_->process_object()); - process.Set("_breakFirstLine", true); -+======= -+ if (options.inspector_enabled()) { -+ // Use custom platform since the gin platform does not work correctly -+ // with node's inspector agent -+ platform_.reset(v8::platform::CreateDefaultPlatform()); -+ -+ // Set process._debugWaitConnect if --inspect-brk was specified to stop -+ // the debugger on the first line -+ if (options.wait_for_connect()) { -+ mate::Dictionary process(env_->isolate(), env_->process_object()); -+ process.Set("_breakFirstLine", true); -+ } -+ -+ inspector->Start(platform_.get(), nullptr, options); -+>>>>>>> .their - } - - inspector->Start(static_cast<node::NodePlatform*>(platform), nullptr, -changed in both - base 100644 42d3b7792e3b17eb2b1c508f2e433e9dbd945452 atom/browser/osr/osr_render_widget_host_view.cc - our 100644 4a2a0747fe2e6bf38c8999b80dbfea31e52a17fd atom/browser/osr/osr_render_widget_host_view.cc - their 100644 80a13ef96656b3fe7820b8412aacad0b005526e1 atom/browser/osr/osr_render_widget_host_view.cc -@@ -259,12 +259,29 @@ - native_window_(native_window), - transparent_(transparent), - callback_(callback), -+<<<<<<< .our - frame_rate_(frame_rate), -+======= -+ parent_callback_(nullptr), -+ frame_rate_(frame_rate), -+ frame_rate_threshold_us_(0), -+ last_time_(base::Time::Now()), -+>>>>>>> .their - scale_factor_(kDefaultScaleFactor), - size_(native_window->GetSize()), - painting_(painting), - is_showing_(!render_widget_host_->is_hidden()), -+<<<<<<< .our - mouse_wheel_phase_handler_(render_widget_host_, this), -+======= -+ is_destroyed_(false), -+ popup_position_(gfx::Rect()), -+ hold_resize_(false), -+ pending_resize_(false), -+ paint_callback_running_(false), -+ renderer_compositor_frame_sink_(nullptr), -+ background_color_(SkColor()), -+>>>>>>> .their - weak_ptr_factory_(this) { - DCHECK(render_widget_host_); - bool is_guest_view_hack = parent_host_view_ != nullptr; -@@ -292,9 +309,13 @@ - compositor_.reset( - new ui::Compositor(context_factory_private->AllocateFrameSinkId(), - content::GetContextFactory(), context_factory_private, -+<<<<<<< .our - base::ThreadTaskRunnerHandle::Get(), - features::IsSurfaceSynchronizationEnabled(), - false /* enable_pixel_canvas */)); -+======= -+ base::ThreadTaskRunnerHandle::Get())); -+>>>>>>> .their - compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget); - compositor_->SetRootLayer(root_layer_.get()); - #endif -@@ -713,8 +734,18 @@ - } - - return new OffScreenRenderWidgetHostView( -+<<<<<<< .our - transparent_, true, embedder_host_view->GetFrameRate(), callback_, - render_widget_host, embedder_host_view, native_window_); -+======= -+ transparent_, -+ true, -+ embedder_host_view->GetFrameRate(), -+ callback_, -+ render_widget_host, -+ embedder_host_view, -+ native_window_); -+>>>>>>> .their - } - - #if !defined(OS_MACOSX) -@@ -1204,7 +1235,11 @@ - - SetupFrameRate(true); - -+<<<<<<< .our - for (auto* guest_host_view : guest_host_views_) -+======= -+ for (auto guest_host_view : guest_host_views_) -+>>>>>>> .their - guest_host_view->SetFrameRate(frame_rate); - } - -@@ -1233,10 +1268,15 @@ - - frame_rate_threshold_us_ = 1000000 / frame_rate_; - -+<<<<<<< .our - if (GetCompositor()) { - GetCompositor()->SetAuthoritativeVSyncInterval( - base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_)); - } -+======= -+ GetCompositor()->SetAuthoritativeVSyncInterval( -+ base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_)); -+>>>>>>> .their - - if (copy_frame_generator_.get()) { - copy_frame_generator_->set_frame_rate_threshold_us( -changed in both - base 100644 23549838c335b37b479b2f154eaab29d86abbc4a atom/browser/osr/osr_render_widget_host_view.h - our 100644 b81f6310f864c00fea50b1aac49dc89173eaa302 atom/browser/osr/osr_render_widget_host_view.h - their 100644 ed0c46f6b41a044e9f4f224b3fe9322efe1937b3 atom/browser/osr/osr_render_widget_host_view.h -@@ -317,6 +317,8 @@ - viz::LocalSurfaceId local_surface_id_; - viz::ParentLocalSurfaceIdAllocator local_surface_id_allocator_; - -+ bool paint_callback_running_; -+ - std::unique_ptr<ui::Layer> root_layer_; - std::unique_ptr<ui::Compositor> compositor_; - std::unique_ptr<content::DelegatedFrameHost> delegated_frame_host_; -changed in both - base 100644 0e10abf6a034ab604f51553eb905b18e18f45552 atom/browser/osr/osr_web_contents_view.cc - our 100644 c8223df0d8c6f3436d323059686e42684ff98462 atom/browser/osr/osr_web_contents_view.cc - their 100644 4cbc6a5c42f9762b81fc4d601ebb534dedcd4914 atom/browser/osr/osr_web_contents_view.cc -@@ -13,9 +13,18 @@ - namespace atom { - - OffScreenWebContentsView::OffScreenWebContentsView( -+<<<<<<< .our - bool transparent, - const OnPaintCallback& callback) - : transparent_(transparent), callback_(callback) { -+======= -+ bool transparent, const OnPaintCallback& callback) -+ : transparent_(transparent), -+ painting_(true), -+ frame_rate_(60), -+ callback_(callback), -+ web_contents_(nullptr) { -+>>>>>>> .their - #if defined(OS_MACOSX) - PlatformCreate(); - #endif -@@ -104,8 +113,18 @@ - - auto* relay = NativeWindowRelay::FromWebContents(web_contents_); - return new OffScreenRenderWidgetHostView( -+<<<<<<< .our - transparent_, painting_, GetFrameRate(), callback_, render_widget_host, - nullptr, relay->window.get()); -+======= -+ transparent_, -+ painting_, -+ GetFrameRate(), -+ callback_, -+ render_widget_host, -+ nullptr, -+ relay->window.get()); -+>>>>>>> .their - } - - content::RenderWidgetHostViewBase* -@@ -124,8 +143,18 @@ - : web_contents_impl->GetRenderWidgetHostView()); - - return new OffScreenRenderWidgetHostView( -+<<<<<<< .our - transparent_, true, view->GetFrameRate(), callback_, render_widget_host, - view, relay->window.get()); -+======= -+ transparent_, -+ true, -+ view->GetFrameRate(), -+ callback_, -+ render_widget_host, -+ view, -+ relay->window.get()); -+>>>>>>> .their - } - - void OffScreenWebContentsView::SetPageTitle(const base::string16& title) {} -@@ -209,6 +238,42 @@ - } - } - -+void OffScreenWebContentsView::SetPainting(bool painting) { -+ auto* view = GetView(); -+ if (view != nullptr) { -+ view->SetPainting(painting); -+ } else { -+ painting_ = painting; -+ } -+} -+ -+bool OffScreenWebContentsView::IsPainting() const { -+ auto* view = GetView(); -+ if (view != nullptr) { -+ return view->IsPainting(); -+ } else { -+ return painting_; -+ } -+} -+ -+void OffScreenWebContentsView::SetFrameRate(int frame_rate) { -+ auto* view = GetView(); -+ if (view != nullptr) { -+ view->SetFrameRate(frame_rate); -+ } else { -+ frame_rate_ = frame_rate; -+ } -+} -+ -+int OffScreenWebContentsView::GetFrameRate() const { -+ auto* view = GetView(); -+ if (view != nullptr) { -+ return view->GetFrameRate(); -+ } else { -+ return frame_rate_; -+ } -+} -+ - OffScreenRenderWidgetHostView* OffScreenWebContentsView::GetView() const { - if (web_contents_) { - return static_cast<OffScreenRenderWidgetHostView*>( -changed in both - base 100644 ffb3b38619c4521f9947fe29e3871ed06d97978e atom/browser/osr/osr_web_contents_view.h - our 100644 206ab9dd3421af522a12aba615c6f040ba176ba4 atom/browser/osr/osr_web_contents_view.h - their 100644 788e55bf316d8069811fc026bf610ad231371fce atom/browser/osr/osr_web_contents_view.h -@@ -83,8 +83,13 @@ - OffScreenRenderWidgetHostView* GetView() const; - - const bool transparent_; -+<<<<<<< .our - bool painting_ = true; - int frame_rate_ = 60; -+======= -+ bool painting_; -+ int frame_rate_; -+>>>>>>> .their - OnPaintCallback callback_; - - // Weak refs. -changed in both - base 100644 9610d80693b1670f696f82812442419504d61454 atom/browser/relauncher.cc - our 100644 35c6785e3d87d21eaea27ad5818434d870326047 atom/browser/relauncher.cc - their 100644 9dfb6edd06661f302ca7498a2ba34f0ce70c938b atom/browser/relauncher.cc -changed in both - base 100644 3313eba36bb903426778fac6cd18258a95fec677 atom/browser/resources/mac/Info.plist - our 100644 9094f0f7335edf833d51f688851e6a105de60433 atom/browser/resources/mac/Info.plist - their 100644 a9ccf0ef539f713789b79e05d83092561a96fc80 atom/browser/resources/mac/Info.plist -@@ -17,9 +17,15 @@ - <key>CFBundleIconFile</key> - <string>electron.icns</string> - <key>CFBundleVersion</key> -+<<<<<<< .our - <string>4.0.0</string> - <key>CFBundleShortVersionString</key> - <string>4.0.0</string> -+======= -+ <string>1.8.8</string> -+ <key>CFBundleShortVersionString</key> -+ <string>1.8.8</string> -+>>>>>>> .their - <key>LSApplicationCategoryType</key> - <string>public.app-category.developer-tools</string> - <key>LSMinimumSystemVersion</key> -changed in both - base 100644 c349f99d712ff69960d35b18587ddb6c417f7cd5 atom/browser/resources/win/atom.rc - our 100644 c0bd831e8bddf10180f75cd40694831e2e98622d atom/browser/resources/win/atom.rc - their 100644 cd274bfcb0537b6f7830ef0a0fd6958ce06aec45 atom/browser/resources/win/atom.rc -@@ -56,8 +56,13 @@ - // - - VS_VERSION_INFO VERSIONINFO -+<<<<<<< .our - FILEVERSION 4,0,0,20180821 - PRODUCTVERSION 4,0,0,20180821 -+======= -+ FILEVERSION 1,8,8,0 -+ PRODUCTVERSION 1,8,8,0 -+>>>>>>> .their - FILEFLAGSMASK 0x3fL - #ifdef _DEBUG - FILEFLAGS 0x1L -@@ -74,12 +79,20 @@ - BEGIN - VALUE "CompanyName", "GitHub, Inc." - VALUE "FileDescription", "Electron" -+<<<<<<< .our - VALUE "FileVersion", "4.0.0" -+======= -+ VALUE "FileVersion", "1.8.8" -+>>>>>>> .their - VALUE "InternalName", "electron.exe" - VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." - VALUE "OriginalFilename", "electron.exe" - VALUE "ProductName", "Electron" -+<<<<<<< .our - VALUE "ProductVersion", "4.0.0" -+======= -+ VALUE "ProductVersion", "1.8.8" -+>>>>>>> .their - VALUE "SquirrelAwareVersion", "1" - END - END -changed in both - base 100644 276f782ce0d25b7c24fdf829b74074ead01cf7d8 atom/browser/ui/file_dialog_mac.mm - our 100644 18b18a8b240cda5512ae49e0afde5c749bdf75c0 atom/browser/ui/file_dialog_mac.mm - their 100644 295d9a57b895db9c6f66c64fd4d94d0d8f365e4c atom/browser/ui/file_dialog_mac.mm -@@ -282,6 +282,7 @@ - return true; - } - -+<<<<<<< .our - void OpenDialogCompletion(int chosen, - NSOpenPanel* dialog, - const DialogSettings& settings, -@@ -307,6 +308,17 @@ - ReadDialogPaths(dialog, &paths); - callback.Run(true, paths); - #endif -+======= -+void OpenDialogCompletion(int chosen, NSOpenPanel* dialog, -+ const DialogSettings& settings, -+ const OpenDialogCallback& callback) { -+ if (chosen == NSFileHandlingPanelCancelButton) { -+ callback.Run(false, std::vector<base::FilePath>()); -+ } else { -+ std::vector<base::FilePath> paths; -+ ReadDialogPaths(dialog, &paths); -+ callback.Run(true, paths); -+>>>>>>> .their - } - } - -@@ -330,8 +342,13 @@ - NSWindow* window = settings.parent_window->GetNativeWindow(); - [dialog beginSheetModalForWindow:window - completionHandler:^(NSInteger chosen) { -+<<<<<<< .our - OpenDialogCompletion(chosen, dialog, settings, callback); - }]; -+======= -+ OpenDialogCompletion(chosen, dialog, settings, callback); -+ }]; -+>>>>>>> .their - } - } - -@@ -349,6 +366,7 @@ - return true; - } - -+<<<<<<< .our - void SaveDialogCompletion(int chosen, - NSSavePanel* dialog, - const DialogSettings& settings, -@@ -370,6 +388,16 @@ - #else - callback.Run(true, base::FilePath(path)); - #endif -+======= -+void SaveDialogCompletion(int chosen, NSSavePanel* dialog, -+ const DialogSettings& settings, -+ const SaveDialogCallback& callback) { -+ if (chosen == NSFileHandlingPanelCancelButton) { -+ callback.Run(false, base::FilePath()); -+ } else { -+ std::string path = base::SysNSStringToUTF8([[dialog URL] path]); -+ callback.Run(true, base::FilePath(path)); -+>>>>>>> .their - } - } - -@@ -391,8 +419,13 @@ - NSWindow* window = settings.parent_window->GetNativeWindow(); - [dialog beginSheetModalForWindow:window - completionHandler:^(NSInteger chosen) { -+<<<<<<< .our - SaveDialogCompletion(chosen, dialog, settings, callback); - }]; -+======= -+ SaveDialogCompletion(chosen, dialog, settings, callback); -+ }]; -+>>>>>>> .their - } - } - -changed in both - base 100644 8f495f3bf7afef98c62456bda19607adab35c930 atom/browser/ui/message_box_mac.mm - our 100644 ee2f59dc8c84ba0bf5fe049a133f403d550a9473 atom/browser/ui/message_box_mac.mm - their 100644 17c66043a27f76077f20ac4ff61522fac0bb2b51 atom/browser/ui/message_box_mac.mm -changed in both - base 100644 e0cd68608a33e999032a7ff2ce4c0e6971c5e8f2 atom/browser/ui/win/atom_desktop_native_widget_aura.cc - our 100644 21300409add439f7513536eaf255601da0778299 atom/browser/ui/win/atom_desktop_native_widget_aura.cc - their 100644 c38760f7c39ea60a6504c700a0262539619999eb atom/browser/ui/win/atom_desktop_native_widget_aura.cc -@@ -12,7 +12,11 @@ - views::internal::NativeWidgetDelegate* delegate) - : views::DesktopNativeWidgetAura(delegate) { - // This is to enable the override of OnWindowActivated -+<<<<<<< .our - wm::SetActivationChangeObserver(GetNativeWindow(), this); -+======= -+ aura::client::SetActivationChangeObserver(GetNativeWindow(), this); -+>>>>>>> .their - } - - void AtomDesktopNativeWidgetAura::Activate() { -@@ -24,6 +28,7 @@ - } - - void AtomDesktopNativeWidgetAura::OnWindowActivated( -+<<<<<<< .our - wm::ActivationChangeObserver::ActivationReason reason, - aura::Window* gained_active, - aura::Window* lost_active) { -@@ -32,6 +37,16 @@ - if (lost_active != nullptr) { - auto* tooltip_controller = static_cast<views::corewm::TooltipController*>( - wm::GetTooltipClient(lost_active->GetRootWindow())); -+======= -+ aura::client::ActivationChangeObserver::ActivationReason reason, -+ aura::Window* gained_active, -+ aura::Window* lost_active) { -+ views::DesktopNativeWidgetAura::OnWindowActivated( -+ reason, gained_active, lost_active); -+ if (lost_active != nullptr) { -+ auto* tooltip_controller = static_cast<views::corewm::TooltipController*>( -+ aura::client::GetTooltipClient(lost_active->GetRootWindow())); -+>>>>>>> .their - - // This will cause the tooltip to be hidden when a window is deactivated, - // as it should be. -changed in both - base 100644 b5a6c0933d5b6527e3f4ee2607acf888197b61ca atom/browser/ui/win/atom_desktop_native_widget_aura.h - our 100644 81c6f2b394a8c1501d97fb017b1a58e4ca240d18 atom/browser/ui/win/atom_desktop_native_widget_aura.h - their 100644 79ce3dd5cd4cc77fd2016e7ed4c93044a4873236 atom/browser/ui/win/atom_desktop_native_widget_aura.h -@@ -19,9 +19,16 @@ - void Activate() override; - - private: -+<<<<<<< .our - void OnWindowActivated(wm::ActivationChangeObserver::ActivationReason reason, - aura::Window* gained_active, - aura::Window* lost_active) override; -+======= -+ void OnWindowActivated( -+ aura::client::ActivationChangeObserver::ActivationReason reason, -+ aura::Window* gained_active, -+ aura::Window* lost_active) override; -+>>>>>>> .their - DISALLOW_COPY_AND_ASSIGN(AtomDesktopNativeWidgetAura); - }; - -changed in both - base 100644 cc621625818feaeddf4fb76cd9103c822795e652 atom/browser/web_contents_preferences.cc - our 100644 c21c93383155091a7481cdd4e741cefad90a4a55 atom/browser/web_contents_preferences.cc - their 100644 2a07ba7f22d06c3e0c1b072c2e291e0b9a8f3eb2 atom/browser/web_contents_preferences.cc -@@ -97,6 +97,7 @@ - instances_.push_back(this); - - // Set WebPreferences defaults onto the JS object -+<<<<<<< .our - SetDefaultBoolIfUndefined(options::kPlugins, false); - SetDefaultBoolIfUndefined(options::kExperimentalFeatures, false); - bool node = SetDefaultBoolIfUndefined(options::kNodeIntegration, true); -@@ -104,12 +105,23 @@ - SetDefaultBoolIfUndefined(options::kWebviewTag, node); - SetDefaultBoolIfUndefined(options::kSandbox, false); - SetDefaultBoolIfUndefined(options::kNativeWindowOpen, false); -+======= -+ SetDefaultBoolIfUndefined("plugins", false); -+ SetDefaultBoolIfUndefined(options::kExperimentalFeatures, false); -+ SetDefaultBoolIfUndefined(options::kExperimentalCanvasFeatures, false); -+ bool node = SetDefaultBoolIfUndefined(options::kNodeIntegration, true); -+ SetDefaultBoolIfUndefined(options::kNodeIntegrationInWorker, false); -+ SetDefaultBoolIfUndefined(options::kWebviewTag, node); -+ SetDefaultBoolIfUndefined("sandbox", false); -+ SetDefaultBoolIfUndefined("nativeWindowOpen", false); -+>>>>>>> .their - SetDefaultBoolIfUndefined(options::kContextIsolation, false); - SetDefaultBoolIfUndefined("javascript", true); - SetDefaultBoolIfUndefined("images", true); - SetDefaultBoolIfUndefined("textAreasAreResizable", true); - SetDefaultBoolIfUndefined("webgl", true); - bool webSecurity = true; -+<<<<<<< .our - SetDefaultBoolIfUndefined(options::kWebSecurity, webSecurity); - // If webSecurity was explicity set to false, let's inherit that into - // insecureContent -@@ -125,6 +137,21 @@ - SetDefaultBoolIfUndefined(options::kOffscreen, false); - - last_preference_ = preference_.Clone(); -+======= -+ SetDefaultBoolIfUndefined("webSecurity", webSecurity); -+ // If webSecurity was explicity set to false, let's inherit that into -+ // insecureContent -+ if (web_preferences.Get("webSecurity", &webSecurity) && !webSecurity) { -+ SetDefaultBoolIfUndefined("allowRunningInsecureContent", true); -+ } else { -+ SetDefaultBoolIfUndefined("allowRunningInsecureContent", false); -+ } -+ #if defined(OS_MACOSX) -+ SetDefaultBoolIfUndefined(options::kScrollBounce, false); -+ #endif -+ SetDefaultBoolIfUndefined("offscreen", false); -+ last_web_preferences_.MergeDictionary(&web_preferences_); -+>>>>>>> .their - } - - WebContentsPreferences::~WebContentsPreferences() { -@@ -154,6 +181,16 @@ - return default_value; - } - -+bool WebContentsPreferences::SetDefaultBoolIfUndefined(const std::string key, -+ bool val) { -+ bool existing; -+ if (!web_preferences_.GetBoolean(key, &existing)) { -+ web_preferences_.SetBoolean(key, val); -+ return val; -+ } -+ return existing; -+} -+ - void WebContentsPreferences::Merge(const base::DictionaryValue& extend) { - if (preference_.is_dict()) - static_cast<base::DictionaryValue*>(&preference_)->MergeDictionary(&extend); -@@ -212,8 +249,18 @@ - return FromWebContents(web_contents); - } - -+<<<<<<< .our - void WebContentsPreferences::AppendCommandLineSwitches( - base::CommandLine* command_line) { -+======= -+ // We are appending args to a webContents so let's save the current state -+ // of our preferences object so that during the lifetime of the WebContents -+ // we can fetch the options used to initally configure the WebContents -+ self->last_web_preferences_.Clear(); -+ self->last_web_preferences_.MergeDictionary(&web_preferences); -+ -+ bool b; -+>>>>>>> .their - // Check if plugins are enabled. - if (IsEnabled(options::kPlugins)) - command_line->AppendSwitch(switches::kEnablePlugins); -changed in both - base 100644 366aa1d9520847d6b81e673cc5a2156d53cc5ba5 atom/browser/web_contents_preferences.h - our 100644 d835347afcd259f473f95271a2c19e42afcc6f2b atom/browser/web_contents_preferences.h - their 100644 be277487d1d669b5e85676ff1a7ca4da365c0572 atom/browser/web_contents_preferences.h -@@ -59,8 +59,15 @@ - bool GetPreloadPath(base::FilePath::StringType* path) const; - - // Returns the web preferences. -+<<<<<<< .our - base::Value* preference() { return &preference_; } - base::Value* last_preference() { return &last_preference_; } -+======= -+ base::DictionaryValue* web_preferences() { return &web_preferences_; } -+ base::DictionaryValue* last_web_preferences() { -+ return &last_web_preferences_; -+ } -+>>>>>>> .their - - private: - friend class content::WebContentsUserData<WebContentsPreferences>; -@@ -75,6 +82,14 @@ - static std::vector<WebContentsPreferences*> instances_; - - content::WebContents* web_contents_; -+<<<<<<< .our -+======= -+ base::DictionaryValue web_preferences_; -+ base::DictionaryValue last_web_preferences_; -+ -+ // Set preference value to given bool if user did not provide value -+ bool SetDefaultBoolIfUndefined(const std::string key, bool val); -+>>>>>>> .their - - base::Value preference_ = base::Value(base::Value::Type::DICTIONARY); - base::Value last_preference_ = base::Value(base::Value::Type::DICTIONARY); -changed in both - base 100644 a20d962c0a82ff7e79bf6552334c2788c235cc3a atom/browser/web_dialog_helper.cc - our 100644 74c8573d13f15bcaa189abdc40fa0cd8e48f89be atom/browser/web_dialog_helper.cc - their 100644 19e5c11a6186ce9e99f61a98e1e965508020648c atom/browser/web_dialog_helper.cc -changed in both - base 100644 08880ffe4a3591d9010f55ef18ce288e69101fe1 atom/common/atom_command_line.cc - our 100644 287e43f75fef778948ef9acdac8b9a7edfe07d0a atom/common/atom_command_line.cc - their 100644 54420b533a6b2600a87c95645b73bc01fbf0122f atom/common/atom_command_line.cc -changed in both - base 100644 a279283cf09dd0275c41669362a9659c01b790dd atom/common/atom_version.h - our 100644 65e7d19911559a40b1b258319df5fe0fa180354f atom/common/atom_version.h - their 100644 1fb5ba2490e9da47a5eedfe7e2ea9a68da84621d atom/common/atom_version.h -@@ -5,10 +5,17 @@ - #ifndef ATOM_COMMON_ATOM_VERSION_H_ - #define ATOM_COMMON_ATOM_VERSION_H_ - -+<<<<<<< .our - #define ATOM_MAJOR_VERSION 4 - #define ATOM_MINOR_VERSION 0 - #define ATOM_PATCH_VERSION 0 - #define ATOM_PRE_RELEASE_VERSION -nightly.20180821 -+======= -+#define ATOM_MAJOR_VERSION 1 -+#define ATOM_MINOR_VERSION 8 -+#define ATOM_PATCH_VERSION 8 -+// #define ATOM_PRE_RELEASE_VERSION -+>>>>>>> .their - - #ifndef ATOM_STRINGIFY - #define ATOM_STRINGIFY(n) ATOM_STRINGIFY_HELPER(n) -@@ -16,6 +23,7 @@ - #endif - - #ifndef ATOM_PRE_RELEASE_VERSION -+<<<<<<< .our - #define ATOM_VERSION_STRING \ - ATOM_STRINGIFY(ATOM_MAJOR_VERSION) \ - "." ATOM_STRINGIFY(ATOM_MINOR_VERSION) "." ATOM_STRINGIFY(ATOM_PATCH_VERSION) -@@ -24,6 +32,16 @@ - ATOM_STRINGIFY(ATOM_MAJOR_VERSION) \ - "." ATOM_STRINGIFY(ATOM_MINOR_VERSION) "." ATOM_STRINGIFY( \ - ATOM_PATCH_VERSION) ATOM_STRINGIFY(ATOM_PRE_RELEASE_VERSION) -+======= -+ #define ATOM_VERSION_STRING ATOM_STRINGIFY(ATOM_MAJOR_VERSION) "." \ -+ ATOM_STRINGIFY(ATOM_MINOR_VERSION) "." \ -+ ATOM_STRINGIFY(ATOM_PATCH_VERSION) -+#else -+ #define ATOM_VERSION_STRING ATOM_STRINGIFY(ATOM_MAJOR_VERSION) "." \ -+ ATOM_STRINGIFY(ATOM_MINOR_VERSION) "." \ -+ ATOM_STRINGIFY(ATOM_PATCH_VERSION) \ -+ ATOM_STRINGIFY(ATOM_PRE_RELEASE_VERSION) -+>>>>>>> .their - #endif - - #define ATOM_VERSION "v" ATOM_VERSION_STRING -changed in both - base 100644 a7908ef30c6bafc4aca1da9a870f7ae12703fe04 atom/common/crash_reporter/crash_reporter_win.cc - our 100644 c574da71c9de9bd8c7b7cad57d3a0f84708fb97c atom/common/crash_reporter/crash_reporter_win.cc - their 100644 49f90b7e6665727b697a243414544bae304fde6e atom/common/crash_reporter/crash_reporter_win.cc -changed in both - base 100644 03e96ae8a4f3cb7e656143fb46dff58eb924fa12 atom/common/node_bindings.cc - our 100644 e6aded2e661af919c2d89c2f9bd46b4921d4aec4 atom/common/node_bindings.cc - their 100644 84792c58207dd85de2d2b60bd789417346c31b50 atom/common/node_bindings.cc -@@ -228,8 +228,12 @@ - } - - node::Environment* NodeBindings::CreateEnvironment( -+<<<<<<< .our - v8::Handle<v8::Context> context, - node::MultiIsolatePlatform* platform) { -+======= -+ v8::Handle<v8::Context> context) { -+>>>>>>> .their - #if defined(OS_WIN) - auto& atom_args = AtomCommandLine::argv(); - std::vector<std::string> args(atom_args.size()); -@@ -255,8 +259,13 @@ - base::FilePath resources_path = GetResourcesPath(browser_env_ == BROWSER); - base::FilePath script_path = - resources_path.Append(FILE_PATH_LITERAL("electron.asar")) -+<<<<<<< .our - .Append(process_type) - .Append(FILE_PATH_LITERAL("init.js")); -+======= -+ .Append(process_type) -+ .Append(FILE_PATH_LITERAL("init.js")); -+>>>>>>> .their - args.insert(args.begin() + 1, script_path.AsUTF8Unsafe()); - - std::unique_ptr<const char* []> c_argv = StringVectorToArgArray(args); -changed in both - base 100644 a265b942f31ff76d7e21da03e7eafb6d164fd610 atom/renderer/api/atom_api_web_frame.cc - our 100644 f0f7ef249d73876f7107d3d3865e8fc71ee33945 atom/renderer/api/atom_api_web_frame.cc - their 100644 b0b5e4fd5f42b9755a8ad9e1063baed70b9ed358 atom/renderer/api/atom_api_web_frame.cc -@@ -13,7 +13,10 @@ - #include "atom/renderer/api/atom_api_spell_check_client.h" - #include "base/memory/memory_pressure_listener.h" - #include "content/public/renderer/render_frame.h" -+<<<<<<< .our - #include "content/public/renderer/render_frame_observer.h" -+======= -+>>>>>>> .their - #include "content/public/renderer/render_frame_visitor.h" - #include "content/public/renderer/render_view.h" - #include "native_mate/dictionary.h" -@@ -119,7 +122,11 @@ - main_frame_ = nullptr; - } - bool Visit(content::RenderFrame* render_frame) override { -+<<<<<<< .our - auto* view = render_frame->GetRenderView(); -+======= -+ auto view = render_frame->GetRenderView(); -+>>>>>>> .their - if (view->GetMainRenderFrame() == main_frame_ || - (render_frame->IsMainFrame() && render_frame == main_frame_)) { - render_frame->GetWebFrame()->SetTextCheckClient(spell_check_client_); -@@ -222,15 +229,30 @@ - return; - } - -+<<<<<<< .our - auto client = std::make_unique<SpellCheckClient>( - language, auto_spell_correct_turned_on, args->isolate(), provider); -+======= -+ std::unique_ptr<SpellCheckClient> client(new SpellCheckClient( -+ language, auto_spell_correct_turned_on, args->isolate(), provider)); -+>>>>>>> .their - // Set spellchecker for all live frames in the same process or - // in the sandbox mode for all live sub frames to this WebFrame. - FrameSpellChecker spell_checker( - client.get(), content::RenderFrame::FromWebFrame(web_frame_)); - content::RenderFrame::ForEach(&spell_checker); - spell_check_client_.swap(client); -+<<<<<<< .our - web_frame_->SetSpellCheckPanelHostClient(spell_check_client_.get()); -+======= -+ web_frame_->View()->SetSpellCheckClient(spell_check_client_.get()); -+} -+ -+void WebFrame::RegisterURLSchemeAsSecure(const std::string& scheme) { -+ // TODO(pfrazee): Remove 2.0 -+ blink::SchemeRegistry::RegisterURLSchemeAsSecure( -+ WTF::String::FromUTF8(scheme.data(), scheme.length())); -+>>>>>>> .their - } - - void WebFrame::RegisterURLSchemeAsBypassingCSP(const std::string& scheme) { -changed in both - base 100644 069ff42e7bf6e01f69e76738925e35560c981b49 atom/renderer/atom_sandboxed_renderer_client.cc - our 100644 6e29fe45a69f44856d7fca449ec1be4eaf6970a2 atom/renderer/atom_sandboxed_renderer_client.cc - their 100644 f8acc3b1b942496ea974cf51e5a06275e1a0c0fa atom/renderer/atom_sandboxed_renderer_client.cc -@@ -33,11 +33,14 @@ - const std::string kIpcKey = "ipcNative"; - const std::string kModuleCacheKey = "native-module-cache"; - -+<<<<<<< .our - bool IsDevTools(content::RenderFrame* render_frame) { - return render_frame->GetWebFrame()->GetDocument().Url().ProtocolIs( - "chrome-devtools"); - } - -+======= -+>>>>>>> .their - v8::Local<v8::Object> GetModuleCache(v8::Isolate* isolate) { - mate::Dictionary global(isolate, isolate->GetCurrentContext()->Global()); - v8::Local<v8::Value> cache; -@@ -176,6 +179,7 @@ - } - - void AtomSandboxedRendererClient::DidCreateScriptContext( -+<<<<<<< .our - v8::Handle<v8::Context> context, - content::RenderFrame* render_frame) { - RendererClientBase::DidCreateScriptContext(context, render_frame); -@@ -184,6 +188,12 @@ - // For devtools we still want to run the preload_bundle script - if (!render_frame->IsMainFrame() && !IsDevTools(render_frame)) - return; -+======= -+ v8::Handle<v8::Context> context, content::RenderFrame* render_frame) { -+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); -+ std::string preload_script = command_line->GetSwitchValueASCII( -+ switches::kPreloadScript); -+>>>>>>> .their - - auto* isolate = context->GetIsolate(); - v8::HandleScope handle_scope(isolate); -changed in both - base 100644 04fc46b740297570b1ef7fc6f97b90dc8ebb6cc2 brightray/brightray.gypi - our 100644 8a945dc0219293d90e30162e4691a4d871071f4f brightray/brightray.gypi - their 100644 4473ced3efbd1668f207511aa7c3510682fd2e74 brightray/brightray.gypi -@@ -249,7 +249,11 @@ - # perform FPO regardless, so we must explicitly disable. - # We still want the false setting above to avoid having - # "/Oy /Oy-" and warnings about overriding. -+<<<<<<< .our - 'AdditionalOptions': ['/Oy-', '/guard:cf'], -+======= -+ 'AdditionalOptions': ['/Oy-', '/d2guard4'], -+>>>>>>> .their - }, - 'VCLibrarianTool': { - 'LinkTimeCodeGeneration': 'true', # /LTCG -@@ -293,6 +297,7 @@ - }], # OS=="linux" - ['OS=="linux" and target_arch in ["ia32", "x64", "arm64"]', { - 'cflags': [ -+<<<<<<< .our - '-flto=thin', - ], - 'ldflags': [ -@@ -301,6 +306,16 @@ - '-Wl,--lto-O0', # this could be removed in future; see https://codereview.chromium.org/2939923004 - '-Wl,-mllvm,-function-sections', - '-Wl,-mllvm,-data-sections', -+======= -+ '-flto', -+ ], -+ 'ldflags': [ -+ '-flto', -+ '-fuse-ld=gold', -+ '-Wl,-plugin-opt,O1', -+ '-Wl,-plugin-opt,-function-sections', -+ '-Wl,--icf=all', -+>>>>>>> .their - ], - }], - ], -changed in both - base 100644 8dea03f1fc6444d6bf56c4ac3ea2fdec206b42da brightray/browser/win/win32_desktop_notifications/desktop_notification_controller.cc - our 100644 71395a49d82f7be8a3ffd66e4795af968973a274 brightray/browser/win/win32_desktop_notifications/desktop_notification_controller.cc - their 100644 358074c602bebb7e440c1c5cd01708617f5b29e9 brightray/browser/win/win32_desktop_notifications/desktop_notification_controller.cc -@@ -176,6 +176,7 @@ - } - - void DesktopNotificationController::AnimateAll() { -+<<<<<<< .our - // NOTE: This function refreshes position and size of all toasts according - // to all current conditions. Animation time is only one of the variables - // influencing them. Screen resolution is another. -@@ -204,6 +205,35 @@ - - if (hdwp) - EndDeferWindowPos(hdwp); -+======= -+ // NOTE: This function refreshes position and size of all toasts according -+ // to all current conditions. Animation time is only one of the variables -+ // influencing them. Screen resolution is another. -+ -+ bool keep_animating = false; -+ -+ if (!instances_.empty()) { -+ RECT work_area; -+ if (SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0)) { -+ ScreenMetrics metrics; -+ POINT origin = { work_area.right, -+ work_area.bottom - metrics.Y(toast_margin_) }; -+ -+ auto hdwp = -+ BeginDeferWindowPos(static_cast<int>(instances_.size())); -+ -+ for (auto&& inst : instances_) { -+ if (!inst.hwnd) continue; -+ -+ auto notification = Toast::Get(inst.hwnd); -+ hdwp = notification->Animate(hdwp, origin); -+ if (!hdwp) break; -+ keep_animating |= notification->IsAnimationActive(); -+ } -+ -+ if (hdwp) EndDeferWindowPos(hdwp); -+ } -+>>>>>>> .their - } - } - -@@ -259,8 +289,29 @@ - else - toast->SetVerticalPosition(target_pos); - -+<<<<<<< .our - target_pos += toast->GetHeight() + margin; - } -+======= -+ // Set new toast positions -+ if (!instances_.empty()) { -+ ScreenMetrics metrics; -+ auto margin = metrics.Y(toast_margin_); -+ -+ int target_pos = 0; -+ for (auto&& inst : instances_) { -+ if (inst.hwnd) { -+ auto toast = Toast::Get(inst.hwnd); -+ -+ if (toast->IsHighlighted()) -+ target_pos = toast->GetVerticalPosition(); -+ else -+ toast->SetVerticalPosition(target_pos); -+ -+ target_pos += toast->GetHeight() + margin; -+ } -+ } -+>>>>>>> .their - } - } - -@@ -310,6 +361,7 @@ - } - - void DesktopNotificationController::CreateToast(NotificationLink&& data) { -+<<<<<<< .our - auto* hinstance = RegisterWndClasses(); - auto* hwnd = Toast::Create(hinstance, data); - if (hwnd) { -@@ -322,6 +374,35 @@ - auto* toast = Toast::Get(item.hwnd); - toast_pos = toast->GetVerticalPosition() + toast->GetHeight() + - scr.Y(toast_margin_); -+======= -+ auto hinstance = RegisterWndClasses(); -+ auto hwnd = Toast::Create(hinstance, data); -+ if (hwnd) { -+ int toast_pos = 0; -+ if (!instances_.empty()) { -+ auto& item = instances_.back(); -+ _ASSERT(item.hwnd); -+ -+ ScreenMetrics scr; -+ auto toast = Toast::Get(item.hwnd); -+ toast_pos = toast->GetVerticalPosition() + -+ toast->GetHeight() + -+ scr.Y(toast_margin_); -+ } -+ -+ instances_.push_back({ hwnd, move(data) }); -+ -+ if (!hwnd_controller_) { -+ // NOTE: We cannot use a message-only window because we need to -+ // receive system notifications -+ hwnd_controller_ = CreateWindow(class_name_, nullptr, 0, -+ 0, 0, 0, 0, -+ NULL, NULL, hinstance, this); -+ } -+ -+ auto toast = Toast::Get(hwnd); -+ toast->PopUp(toast_pos); -+>>>>>>> .their - } - - instances_.push_back({hwnd, move(data)}); -changed in both - base 100644 643a61f5331e0765de31e8cfeab58416e4c23e42 brightray/browser/win/win32_desktop_notifications/desktop_notification_controller.h - our 100644 d6d8fd35a2958b39dc0f6a76b4ee110b2951c832 brightray/browser/win/win32_desktop_notifications/desktop_notification_controller.h - their 100644 1e76e1e1ad2ed268dae7ac5327d7dc56ea48a05a brightray/browser/win/win32_desktop_notifications/desktop_notification_controller.h -@@ -33,6 +33,7 @@ - HFONT GetBodyFont(); - - private: -+<<<<<<< .our - enum TimerID { TimerID_Animate = 1 }; - - static constexpr int toast_margin_ = 20; -@@ -74,6 +75,50 @@ - void CreateToast(NotificationLink&& data); - HWND GetToast(const NotificationData* data) const; - void DestroyToast(ToastInstance& inst); -+======= -+ enum TimerID { -+ TimerID_Animate = 1 -+ }; -+ -+ static constexpr int toast_margin_ = 20; -+ -+ // Wrapper around `NotificationData` which makes sure that -+ // the `controller` member is cleared when the controller object -+ // stops tracking the notification -+ struct NotificationLink : std::shared_ptr<NotificationData> { -+ explicit NotificationLink(DesktopNotificationController* controller); -+ ~NotificationLink(); -+ -+ NotificationLink(NotificationLink&&) = default; -+ NotificationLink(const NotificationLink&) = delete; -+ NotificationLink& operator=(NotificationLink&&) = default; -+ }; -+ -+ struct ToastInstance { -+ HWND hwnd; -+ NotificationLink data; -+ }; -+ -+ class Toast; -+ -+ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, -+ WPARAM wparam, LPARAM lparam); -+ static DesktopNotificationController* Get(HWND hwnd) { -+ return reinterpret_cast<DesktopNotificationController*>( -+ GetWindowLongPtr(hwnd, 0)); -+ } -+ -+ DesktopNotificationController( -+ const DesktopNotificationController&) = delete; -+ -+ void InitializeFonts(); -+ void ClearAssets(); -+ void AnimateAll(); -+ void CheckQueue(); -+ void CreateToast(NotificationLink&& data); -+ HWND GetToast(const NotificationData* data) const; -+ void DestroyToast(ToastInstance& inst); -+>>>>>>> .their - - private: - static const TCHAR class_name_[]; -changed in both - base 100644 31797a87ec72a2448dc7fbca979bcb6924682d0b common.gypi - our 100644 676d1e904127066e4a3d313106f15406fcbed8b6 common.gypi - their 100644 d71415add7a1b124816b99b1f0ee5a6aa9c1f696 common.gypi -@@ -155,7 +155,10 @@ - 'BUILDING_V8_SHARED', - 'BUILDING_V8_PLATFORM_SHARED', - 'BUILDING_V8_BASE_SHARED', -+<<<<<<< .our - 'NODE_WITHOUT_NODE_OPTIONS', -+======= -+>>>>>>> .their - ], - 'conditions': [ - ['OS=="mac" and libchromiumcontent_component==0', { -changed in both - base 100644 6ed06d4be4a82ee91e44bea9a733cce6b05da0ab docs/api/browser-view.md - our 100644 ee1780942db5565c9c9a9e3a4139345c413e1eb9 docs/api/browser-view.md - their 100644 d2e368725fc4d6d407020c0cc426ca88d69fe407 docs/api/browser-view.md -changed in both - base 100644 2cddafa25e762d12efb14d67684b587414f76d5d docs/api/browser-window.md - our 100644 dff61dd336f047cf2f6f06228b2df2b98ff2304d docs/api/browser-window.md - their 100644 9389f38af2214eda6bc0140614bc189933f46c55 docs/api/browser-window.md -changed in both - base 100644 52147bcc292d77f10bb58f8d4c58e6403b1055e2 docs/api/tray.md - our 100644 c60f7ba4c9e9b6ad3fc1b2f717983b71bd286842 docs/api/tray.md - their 100644 6b1b3e41c2cf0195cb5de29323f2fef1d86abe74 docs/api/tray.md -changed in both - base 100644 9b56820d04944a1ca1747e9474d73617239ba81a docs/api/web-contents.md - our 100644 8990fe2e97ab62eafdd3f7a4eb8ee782415124c5 docs/api/web-contents.md - their 100644 087c73784096f093cc5b242d7a3b34501c1b2bf5 docs/api/web-contents.md -@@ -1385,6 +1385,26 @@ - - Shows pop-up dictionary that searches the selected word on the page. - -+<<<<<<< .our -+======= -+#### `contents.setSize(options)` -+ -+Set the size of the page. This is only supported for `<webview>` guest contents. -+ -+* `options` Object -+ * `enableAutoSize` Boolean (optional) - true to make the webview container automatically -+ resize within the bounds specified by the attributes normal, min and max. -+ * `normal` [Size](structures/size.md) (optional) - Normal size of the page. This can be used in -+ combination with the [`disableguestresize`](webview-tag.md#disableguestresize) -+ attribute to manually resize the webview guest contents. -+ * `min` [Size](structures/size.md) (optional) - Minimum size of the page. This can be used in -+ combination with the [`disableguestresize`](webview-tag.md#disableguestresize) -+ attribute to manually resize the webview guest contents. -+ * `max` [Size](structures/size.md) (optional) - Maximium size of the page. This can be used in -+ combination with the [`disableguestresize`](webview-tag.md#disableguestresize) -+ attribute to manually resize the webview guest contents. -+ -+>>>>>>> .their - #### `contents.isOffscreen()` - - Returns `Boolean` - Indicates whether *offscreen rendering* is enabled. -changed in both - base 100644 abe8e4d916264e4de586486c20f961f687ee271c docs/api/web-frame.md - our 100644 989060ef3e50c5d93db1a914997f1d190edf3cf5 docs/api/web-frame.md - their 100644 dee3e150db50c002b7cef8e3424e3843e349fc83 docs/api/web-frame.md -changed in both - base 100644 7474cec466c793aada767b2100f5a9f38cc15f87 docs/tutorial/supported-platforms.md - our 100644 6c84b1438b8fb1f328b38b701c86a8ec9a7483de docs/tutorial/supported-platforms.md - their 100644 9f7b44274c3f3375950c348fe9789bb9e2d3dadf docs/tutorial/supported-platforms.md -@@ -1 +1,47 @@ -+<<<<<<< .our - Moved to [support.md](support.md) -+======= -+# Supported Platforms -+ -+Following platforms are supported by Electron: -+ -+### macOS -+ -+Only 64bit binaries are provided for macOS, and the minimum macOS version -+supported is macOS 10.9. -+ -+### Windows -+ -+Windows 7 and later are supported, older operating systems are not supported -+(and do not work). -+ -+Both `ia32` (`x86`) and `x64` (`amd64`) binaries are provided for Windows. -+Please note, the `ARM` version of Windows is not supported for now. -+ -+### Linux -+ -+The prebuilt binaries of Electron are built for Debian Jessie, but whether the -+prebuilt binary can run on a distribution depends on whether the distribution -+includes the libraries that Electron is linked to on the building platform, so -+only Debian Jessie is guaranteed to work, but following platforms are also -+verified to be able to run the prebuilt binaries of Electron: -+ -+* Ubuntu 12.04 and later -+* Fedora 21 -+* Debian 8 and later -+ -+Electorn provides prebuilt binaries for following CPU architectures: -+ -+* `ia32` (`i686`) -+* `x64` (`amd64`) -+* `armv7l` -+* `arm64` -+* `mips64el` -+ -+The `arm` binary is built against ARM v7 with hard-float ABI and NEON, and it is -+not guaranteed to run on all ARM platforms. -+ -+The `mips64el` binary is built with toolchains provided by Loongson, and it is -+not guaranteed to run on all MIPS64 platforms. And currently all certificate -+related APIs are not working on `mips64el` builds. -+>>>>>>> .their -changed in both - base 100644 e3bf588e79cadae8673419e9854ad5063aa9beac electron.gyp - our 100644 944ddab2a3fd879044e31677e4bac2843fffbdee electron.gyp - their 100644 b5f923dd3cc421473140a513757fe5b469dffc89 electron.gyp -@@ -4,7 +4,11 @@ - 'product_name%': 'Electron', - 'company_name%': 'GitHub, Inc', - 'company_abbr%': 'github', -+<<<<<<< .our - 'version%': '4.0.0-nightly.20180821', -+======= -+ 'version%': '1.8.8', -+>>>>>>> .their - 'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c', - }, - 'includes': [ -@@ -255,6 +259,11 @@ - ], - }, - ], -+ 'link_settings': { -+ 'ldflags': [ -+ '-Wl,-z,noexecstack', -+ ], -+ }, - }], # OS=="linux" - ], - }, # target <(project_name) -changed in both - base 100644 f071924231c089bc6308bd334450770795ff4858 filenames.gypi - our 100644 f57860558f06b7e5d8a50f48cfc7e53044df0bc6 filenames.gypi - their 100644 ad7256736ef4a64683d4a6dd57e020c96e3543d1 filenames.gypi -@@ -114,6 +114,11 @@ - 'atom/app/atom_main_delegate_mac.mm', - 'atom/app/command_line_args.cc', - 'atom/app/command_line_args.h', -+<<<<<<< .our -+======= -+ 'atom/app/node_main.cc', -+ 'atom/app/node_main.h', -+>>>>>>> .their - 'atom/app/uv_task_runner.cc', - 'atom/app/uv_task_runner.h', - 'atom/browser/api/atom_api_app.cc', -changed in both - base 100644 33c324d4fa8cca5ba6e914deb3f1404333e178c0 lib/browser/api/menu.js - our 100644 506e3525c10ce142cafe3fc1bf4de1c255e48503 lib/browser/api/menu.js - their 100644 b7556b1f41b9db0424303add30acdba9fa969721 lib/browser/api/menu.js -@@ -44,15 +44,52 @@ - this.commandsMap = {} - this.groupsMap = {} - this.items = [] -+<<<<<<< .our - this.delegate = delegate - } - - Menu.prototype.popup = function (options = {}) { - if (options == null || typeof options !== 'object') { - throw new TypeError('Options must be an object') -+======= -+ this.delegate = { -+ isCommandIdChecked: id => this.commandsMap[id] ? this.commandsMap[id].checked : undefined, -+ isCommandIdEnabled: id => this.commandsMap[id] ? this.commandsMap[id].enabled : undefined, -+ isCommandIdVisible: id => this.commandsMap[id] ? this.commandsMap[id].visible : undefined, -+ getAcceleratorForCommandId: (id, useDefaultAccelerator) => { -+ const command = this.commandsMap[id] -+ if (!command) return -+ if (command.accelerator != null) return command.accelerator -+ if (useDefaultAccelerator) return command.getDefaultRoleAccelerator() -+ }, -+ getIconForCommandId: id => this.commandsMap[id] ? this.commandsMap[id].icon : undefined, -+ executeCommand: (event, id) => { -+ const command = this.commandsMap[id] -+ if (!command) return -+ command.click(event, BrowserWindow.getFocusedWindow(), webContents.getFocusedWebContents()) -+ }, -+ menuWillShow: () => { -+ // Ensure radio groups have at least one menu item seleted -+ for (const id in this.groupsMap) { -+ const found = this.groupsMap[id].find(item => item.checked) || null -+ if (!found) v8Util.setHiddenValue(this.groupsMap[id][0], 'checked', true) -+ } -+ } -+ } -+} -+ -+Menu.prototype.popup = function (window, x, y, positioningItem) { -+ let asyncPopup, opts -+ let [newX, newY, newPosition, newWindow] = [x, y, positioningItem, window] -+ -+ // menu.popup(x, y, positioningItem) -+ if (window != null && !(window instanceof BrowserWindow)) { -+ [newPosition, newY, newX, newWindow] = [y, x, window, null] -+>>>>>>> .their - } - let {window, x, y, positioningItem, callback} = options - -+<<<<<<< .our - // no callback passed - if (!callback || typeof callback !== 'function') callback = () => {} - -@@ -75,6 +112,46 @@ - - this.popupAt(window, x, y, positioningItem, callback) - return { browserWindow: window, x, y, position: positioningItem } -+======= -+ // menu.popup({}) -+ if (window != null && window.constructor === Object) { -+ opts = window -+ // menu.popup(window, {}) -+ } else if (x && typeof x === 'object') { -+ opts = x -+ } -+ -+ if (opts) { -+ newX = opts.x -+ newY = opts.y -+ newPosition = opts.positioningItem -+ asyncPopup = opts.async -+ } -+ -+ // set defaults -+ if (typeof newX !== 'number') newX = -1 -+ if (typeof newY !== 'number') newY = -1 -+ if (typeof newPosition !== 'number') newPosition = -1 -+ if (typeof asyncPopup !== 'boolean') asyncPopup = false -+ if (!newWindow || (newWindow && newWindow.constructor !== BrowserWindow)) { -+ newWindow = BrowserWindow.getFocusedWindow() -+ -+ // No window focused? -+ if (!newWindow) { -+ const browserWindows = BrowserWindow.getAllWindows() -+ -+ if (browserWindows && browserWindows.length > 0) { -+ newWindow = browserWindows[0] -+ } else { -+ throw new Error(`Cannot open Menu without a BrowserWindow present`) -+ } -+ } -+ } -+ -+ this.popupAt(newWindow, newX, newY, newPosition, asyncPopup) -+ -+ return { browserWindow: newWindow, x: newX, y: newY, position: newPosition, async: asyncPopup } -+>>>>>>> .their - } - - Menu.prototype.closePopup = function (window) { -@@ -156,7 +233,11 @@ - - Menu.buildFromTemplate = function (template) { - if (!Array.isArray(template)) { -+<<<<<<< .our - throw new TypeError('Invalid template for Menu: Menu template must be an array') -+======= -+ throw new TypeError('Invalid template for Menu') -+>>>>>>> .their - } - const menu = new Menu() - if (!areValidTemplateItems(template)) { -changed in both - base 100644 65e9694954a4dd5ff47080d77886c34b94fcec4e lib/browser/api/touch-bar.js - our 100644 72c50f6ff19d2a72d191a83ce33a3667f26b0756 lib/browser/api/touch-bar.js - their 100644 8294582129905e8384f74b3bdc4aa84b4dc32281 lib/browser/api/touch-bar.js -changed in both - base 100644 0338b776f8938c1548ea9786385fe75db9db3403 lib/browser/guest-view-manager.js - our 100644 1e4029e39a981c85fb6ff18c5ccd52f81b3c56f2 lib/browser/guest-view-manager.js - their 100644 dd8e0ff1a9239e5c7a92f90a58da866c076011ca lib/browser/guest-view-manager.js -changed in both - base 100644 bd9473dda879723625af24c0f98de2855234a2c7 lib/browser/guest-window-manager.js - our 100644 7253c1942b0956ae6b9b0c80a23470fc26669b8a lib/browser/guest-window-manager.js - their 100644 6ff9e5f530f0ba4b3c0011ca6d345d7baa9c3a8f lib/browser/guest-window-manager.js -@@ -52,7 +52,11 @@ - // if parent's visibility is available, that overrides 'show' flag (#12125) - const win = BrowserWindow.fromWebContents(embedder.webContents) - if (win != null) { -+<<<<<<< .our - parentOptions = {...embedder.browserWindowOptions, show: win.isVisible()} -+======= -+ parentOptions = Object.assign({}, embedder.browserWindowOptions, {show: win.isVisible()}) -+>>>>>>> .their - } - - // Inherit the original options if it is a BrowserWindow. -@@ -65,7 +69,11 @@ - // Inherit certain option values from parent window - const webPreferences = embedder.getLastWebPreferences() - for (const [name, value] of inheritedWebPreferences) { -+<<<<<<< .our - if (webPreferences[name] === value) { -+======= -+ if (embedder.getLastWebPreferences()[name] === value) { -+>>>>>>> .their - options.webPreferences[name] = value - } - } -changed in both - base 100644 0d1a251c4da9d0cc83a3916f99bdd13900653ce2 lib/renderer/init.js - our 100644 2470a5e8be80e770b0c03f6a439a71e72ae12a1b lib/renderer/init.js - their 100644 bb349cbd0a2945a14198e56c7579329a4b0721a0 lib/renderer/init.js -changed in both - base 100644 119391e79462bfa8bb1494039bcb3522d97acead lib/sandboxed_renderer/init.js - our 100644 30a3fa55216f6bf7588c3accc07b150a31163b7c lib/sandboxed_renderer/init.js - their 100644 a1acbb2bdc26b33db4041e31cbb251b0399ac197 lib/sandboxed_renderer/init.js -@@ -35,12 +35,15 @@ - ['url', require('url')] - ]) - -+<<<<<<< .our - const { - preloadSrc, preloadError, process: processProps - } = electron.ipcRenderer.sendSync('ELECTRON_BROWSER_SANDBOX_LOAD') - - require('../renderer/web-frame-init')() - -+======= -+>>>>>>> .their - // Pass different process object to the preload script(which should not have - // access to things like `process.atomBinding`). - const preloadProcess = new events.EventEmitter() -@@ -78,6 +81,7 @@ - require('../renderer/inspector') - } - -+<<<<<<< .our - if (binding.guestInstanceId) { - process.guestInstanceId = parseInt(binding.guestInstanceId) - } -@@ -88,6 +92,8 @@ - require('../renderer/web-view/web-view-attributes') - } - -+======= -+>>>>>>> .their - // Wrap the script into a function executed in global scope. It won't have - // access to the current scope, so we'll expose a few objects as arguments: - // -@@ -107,6 +113,7 @@ - // and any `require('electron')` calls in `preload.js` will work as expected - // since browserify won't try to include `electron` in the bundle, falling back - // to the `preloadRequire` function above. -+<<<<<<< .our - if (preloadSrc) { - const preloadWrapperSrc = `(function(require, process, Buffer, global, setImmediate, clearImmediate) { - ${preloadSrc} -@@ -118,4 +125,18 @@ - preloadFn(preloadRequire, preloadProcess, Buffer, global, setImmediate, clearImmediate) - } else if (preloadError) { - console.error(preloadError.stack) -+======= -+if (preloadPath) { -+ const preloadSrc = fs.readFileSync(preloadPath).toString() -+ const preloadWrapperSrc = `(function(require, process, Buffer, global, setImmediate) { -+ ${preloadSrc} -+ })` -+ -+ // eval in window scope: -+ // http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.2 -+ const geval = eval -+ const preloadFn = geval(preloadWrapperSrc) -+ const {setImmediate} = require('timers') -+ preloadFn(preloadRequire, preloadProcess, Buffer, global, setImmediate) -+>>>>>>> .their - } -added in both - our 100644 b1d8824658ea05c277e82d1ac6c6febab9c55030 package-lock.json - their 100644 3ce50996b6fb78ed2ed6924a639f01139f53866a package-lock.json -@@ -1,13 +1,23 @@ - { - "name": "electron", -+<<<<<<< .our - "version": "4.0.0-nightly.20180819", -+======= -+ "version": "1.8.5", -+>>>>>>> .their - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/node": { -+<<<<<<< .our - "version": "7.0.69", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.69.tgz", - "integrity": "sha512-S5NC8HV6HnRipg8nC0j30TPl7ktXjRTKqgyINLNe8K/64UJUI8Lq0sRopXC0hProsV2F5ibj8IqPkl1xpGggrw==", -+======= -+ "version": "7.0.59", -+ "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.59.tgz", -+ "integrity": "sha512-FRRJ2hkgzySTgLnwQhXQCGkLRu1ImISVu/YKYWXCIbF6261nqXwDPQ+6xPzZw+c2Il2Zx2JfM/t0tCaw8wzbmA==", -+>>>>>>> .their - "dev": true - }, - "JSONStream": { -@@ -30,6 +40,7 @@ - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", -+<<<<<<< .our - "integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg=", - "dev": true - }, -@@ -43,6 +54,11 @@ - "negotiator": "0.6.1" - } - }, -+======= -+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", -+ "dev": true -+ }, -+>>>>>>> .their - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", -@@ -109,12 +125,15 @@ - "integrity": "sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=", - "dev": true - }, -+<<<<<<< .our - "address": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/address/-/address-1.0.3.tgz", - "integrity": "sha512-z55ocwKBRLryBs394Sm3ushTtBeg6VAeuku7utSoSnsJKvKcnXFIyC6vh27n3rXyxSgkJBBCAvyOn7gSUcTYjg==", - "dev": true - }, -+======= -+>>>>>>> .their - "agent-base": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", -@@ -192,7 +211,11 @@ - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", -+<<<<<<< .our - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", -+======= -+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", -+>>>>>>> .their - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", -@@ -231,13 +254,18 @@ - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", -+<<<<<<< .our - "integrity": "sha1-VT3Lj5HjyImEXf26NMd3IbkLnXo=", -+======= -+ "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", -+>>>>>>> .their - "dev": true, - "requires": { - "micromatch": "2.3.11", - "normalize-path": "2.1.1" - } - }, -+<<<<<<< .our - "arch": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.1.tgz", -@@ -250,6 +278,8 @@ - "integrity": "sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w==", - "dev": true - }, -+======= -+>>>>>>> .their - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", -@@ -259,6 +289,7 @@ - "sprintf-js": "1.0.3" - } - }, -+<<<<<<< .our - "args": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/args/-/args-4.0.0.tgz", -@@ -314,6 +345,8 @@ - } - } - }, -+======= -+>>>>>>> .their - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", -@@ -326,7 +359,11 @@ - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", -+<<<<<<< .our - "integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=", -+======= -+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", -+>>>>>>> .their - "dev": true - }, - "array-filter": { -@@ -348,9 +385,15 @@ - "dev": true - }, - "array-iterate": { -+<<<<<<< .our - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-1.1.2.tgz", - "integrity": "sha512-1hWSHTIlG/8wtYD+PPX5AOBtKWngpDFjrsrHgZpe+JdgNGz0udYu6ZIkAa/xuenIUEqFv7DvE2Yr60jxweJSrQ==", -+======= -+ "version": "1.1.1", -+ "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-1.1.1.tgz", -+ "integrity": "sha1-hlv3+K851rCYLGCQKRSsdrwBCPY=", -+>>>>>>> .their - "dev": true - }, - "array-map": { -@@ -431,7 +474,11 @@ - "requires": { - "bn.js": "4.11.8", - "inherits": "2.0.3", -+<<<<<<< .our - "minimalistic-assert": "1.0.1" -+======= -+ "minimalistic-assert": "1.0.0" -+>>>>>>> .their - } - }, - "assert": { -@@ -483,9 +530,15 @@ - "dev": true - }, - "aws4": { -+<<<<<<< .our - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", - "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", -+======= -+ "version": "1.6.0", -+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", -+ "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", -+>>>>>>> .their - "dev": true - }, - "babel-code-frame": { -@@ -500,9 +553,15 @@ - } - }, - "bail": { -+<<<<<<< .our - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.3.tgz", - "integrity": "sha512-1X8CnjFVQ+a+KW36uBNMTU5s8+v5FzeqrP7hTG5aTb4aPreSbZJlhwPon9VKMuEVgV++JM+SQrALY3kr7eswdg==", -+======= -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.2.tgz", -+ "integrity": "sha1-99bBcxYwqfnw1NNe0fli4gdKF2Q=", -+>>>>>>> .their - "dev": true - }, - "balanced-match": { -@@ -512,6 +571,7 @@ - "dev": true - }, - "base64-js": { -+<<<<<<< .our - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", -@@ -534,6 +594,13 @@ - } - } - }, -+======= -+ "version": "1.2.3", -+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.3.tgz", -+ "integrity": "sha512-MsAhsUW1GxCdgYSO6tAfZrNapmUKk7mWx/k5mFY/A1gBtkaCaNapTg+FExCw1r9yeaZhqx/xPg43xgTFH6KL5w==", -+ "dev": true -+ }, -+>>>>>>> .their - "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", -@@ -567,7 +634,11 @@ - "dev": true, - "requires": { - "readable-stream": "2.3.6", -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - }, - "dependencies": { - "isarray": { -@@ -586,7 +657,11 @@ - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", -+======= -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } -@@ -597,11 +672,16 @@ - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } - }, -+<<<<<<< .our - "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", -@@ -612,6 +692,12 @@ - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha1-LN4J617jQfSEdGuwMJsyU7GxRC8=", -+======= -+ "bn.js": { -+ "version": "4.11.8", -+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", -+ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", -+>>>>>>> .their - "dev": true - }, - "boolbase": { -@@ -637,7 +723,11 @@ - "requires": { - "ansi-align": "2.0.0", - "camelcase": "4.1.0", -+<<<<<<< .our - "chalk": "2.4.1", -+======= -+ "chalk": "2.3.2", -+>>>>>>> .their - "cli-boxes": "1.0.0", - "string-width": "2.1.1", - "term-size": "1.2.0", -@@ -666,14 +756,24 @@ - "dev": true - }, - "chalk": { -+<<<<<<< .our - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", -+======= -+ "version": "2.3.2", -+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", -+ "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", -+<<<<<<< .our - "supports-color": "5.4.0" -+======= -+ "supports-color": "5.3.0" -+>>>>>>> .their - } - }, - "has-flag": { -@@ -691,7 +791,11 @@ - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", -+<<<<<<< .our - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", -+======= -+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", -+>>>>>>> .their - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", -@@ -708,9 +812,15 @@ - } - }, - "supports-color": { -+<<<<<<< .our - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", -+======= -+ "version": "5.3.0", -+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", -+ "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", -+>>>>>>> .their - "dev": true, - "requires": { - "has-flag": "3.0.0" -@@ -754,7 +864,11 @@ - "JSONStream": "1.3.2", - "combine-source-map": "0.8.0", - "defined": "1.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", -+======= -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "through2": "2.0.3", - "umd": "3.0.3" - } -@@ -803,7 +917,11 @@ - "htmlescape": "1.1.1", - "https-browserify": "0.0.1", - "inherits": "2.0.3", -+<<<<<<< .our - "insert-module-globals": "7.0.6", -+======= -+ "insert-module-globals": "7.0.5", -+>>>>>>> .their - "labeled-stream-splicer": "2.0.1", - "module-deps": "4.1.1", - "os-browserify": "0.1.2", -@@ -814,11 +932,19 @@ - "querystring-es3": "0.2.1", - "read-only-stream": "2.0.0", - "readable-stream": "2.3.6", -+<<<<<<< .our - "resolve": "1.7.1", - "shasum": "1.0.2", - "shell-quote": "1.6.1", - "stream-browserify": "2.0.1", - "stream-http": "2.8.2", -+======= -+ "resolve": "1.6.0", -+ "shasum": "1.0.2", -+ "shell-quote": "1.6.1", -+ "stream-browserify": "2.0.1", -+ "stream-http": "2.8.1", -+>>>>>>> .their - "string_decoder": "0.10.31", - "subarg": "1.0.0", - "syntax-error": "1.4.0", -@@ -834,7 +960,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -861,7 +991,11 @@ - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", -+======= -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - }, -@@ -872,7 +1006,11 @@ - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -887,6 +1025,7 @@ - "requires": { - "buffer-xor": "1.0.3", - "cipher-base": "1.0.4", -+<<<<<<< .our - "create-hash": "1.2.0", - "evp_bytestokey": "1.0.3", - "inherits": "2.0.3", -@@ -901,13 +1040,35 @@ - "requires": { - "browserify-aes": "1.2.0", - "browserify-des": "1.0.1", -+======= -+ "create-hash": "1.1.3", -+ "evp_bytestokey": "1.0.3", -+ "inherits": "2.0.3", -+ "safe-buffer": "5.1.1" -+ } -+ }, -+ "browserify-cipher": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", -+ "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", -+ "dev": true, -+ "requires": { -+ "browserify-aes": "1.2.0", -+ "browserify-des": "1.0.0", -+>>>>>>> .their - "evp_bytestokey": "1.0.3" - } - }, - "browserify-des": { -+<<<<<<< .our - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.1.tgz", - "integrity": "sha512-zy0Cobe3hhgpiOM32Tj7KQ3Vl91m0njwsjzZQK1L+JDf11dzP9qIvjreVinsvXrgfjhStXwUWAEpB9D7Gwmayw==", -+======= -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", -+ "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", -+>>>>>>> .their - "dev": true, - "requires": { - "cipher-base": "1.0.4", -@@ -933,11 +1094,19 @@ - "requires": { - "bn.js": "4.11.8", - "browserify-rsa": "4.0.1", -+<<<<<<< .our - "create-hash": "1.2.0", - "create-hmac": "1.1.7", - "elliptic": "6.4.0", - "inherits": "2.0.3", - "parse-asn1": "5.1.1" -+======= -+ "create-hash": "1.1.3", -+ "create-hmac": "1.1.6", -+ "elliptic": "6.4.0", -+ "inherits": "2.0.3", -+ "parse-asn1": "5.1.0" -+>>>>>>> .their - } - }, - "browserify-zlib": { -@@ -955,7 +1124,11 @@ - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "dev": true, - "requires": { -+<<<<<<< .our - "base64-js": "1.3.0", -+======= -+ "base64-js": "1.2.3", -+>>>>>>> .their - "ieee754": "1.1.11", - "isarray": "1.0.0" - }, -@@ -968,6 +1141,7 @@ - } - } - }, -+<<<<<<< .our - "buffer-alloc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.1.0.tgz", -@@ -990,6 +1164,8 @@ - "integrity": "sha512-YgBMBzdRLEfgxJIGu2wrvI2E03tMCFU1p7d1KhB4BOoMN0VxmTFjSyN5JtKt9z8Z9JajMHruI6SE25W96wNv7Q==", - "dev": true - }, -+======= -+>>>>>>> .their - "buffer-from": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz", -@@ -1020,12 +1196,15 @@ - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, -+<<<<<<< .our - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, -+======= -+>>>>>>> .their - "cached-path-relative": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.1.tgz", -@@ -1086,9 +1265,15 @@ - "dev": true - }, - "ccount": { -+<<<<<<< .our - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.3.tgz", - "integrity": "sha512-Jt9tIBkRc9POUof7QA/VwWd+58fKkEEfI+/t1/eOlxKM7ZhrczNzMFefge7Ai+39y1pR/pP6cI19guHy3FSLmw==", -+======= -+ "version": "1.0.2", -+ "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.2.tgz", -+ "integrity": "sha1-U7ai+BW7d7nChx97mnLDol8djok=", -+>>>>>>> .their - "dev": true - }, - "center-align": { -@@ -1133,6 +1318,7 @@ - } - }, - "character-entities": { -+<<<<<<< .our - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.2.tgz", - "integrity": "sha512-sMoHX6/nBiy3KKfC78dnEalnpn0Az0oSNvqUWYTtYrhRI5iUIYsROU48G+E+kMFQzqXaJ8kHJZ85n7y6/PHgwQ==", -@@ -1154,12 +1340,39 @@ - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.2.tgz", - "integrity": "sha512-7I/xceXfKyUJmSAn/jw8ve/9DyOP7XxufNYLI9Px7CmsKgEUaZLUTax6nZxGQtaoiZCjpu6cHPj20xC/vqRReQ==", -+======= -+ "version": "1.2.1", -+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.1.tgz", -+ "integrity": "sha1-92hxvl72bdt/j440eOzDdMJ9bco=", -+ "dev": true -+ }, -+ "character-entities-html4": { -+ "version": "1.1.1", -+ "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.1.tgz", -+ "integrity": "sha1-NZoqSg9+KdPcKsmb2+Ie45Q46lA=", -+ "dev": true -+ }, -+ "character-entities-legacy": { -+ "version": "1.1.1", -+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.1.tgz", -+ "integrity": "sha1-9Ad53xoQGHK7UQo9KV4fzPFHIC8=", -+ "dev": true -+ }, -+ "character-reference-invalid": { -+ "version": "1.1.1", -+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.1.tgz", -+ "integrity": "sha1-lCg191Dk7GGjCOYMLvjMEBEgLvw=", -+>>>>>>> .their - "dev": true - }, - "check-for-leaks": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/check-for-leaks/-/check-for-leaks-1.2.0.tgz", -+<<<<<<< .our - "integrity": "sha1-6jtQFk6XV3kzLGKBMZX/jGr4Jsw=", -+======= -+ "integrity": "sha512-bJ2Bzo6RtsYqamMnsjtVzowGvBNVrR5IPK8Bd+lx5W1TNgOKMsF+AyNHVkqFqO7cpDZNfny5SaqH6gEovpV5Gw==", -+>>>>>>> .their - "dev": true, - "requires": { - "anymatch": "1.3.2", -@@ -1209,7 +1422,11 @@ - "requires": { - "anymatch": "1.3.2", - "async-each": "1.0.1", -+<<<<<<< .our - "fsevents": "1.2.4", -+======= -+ "fsevents": "1.1.3", -+>>>>>>> .their - "glob-parent": "2.0.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", -@@ -1239,16 +1456,25 @@ - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", -+<<<<<<< .our - "integrity": "sha1-h2Dk7MJy9MNjUy+SbYdKriwTl94=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.2" -+======= -+ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", -+ "dev": true, -+ "requires": { -+ "inherits": "2.0.3", -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", -+<<<<<<< .our - "integrity": "sha1-gVyZ6oT2gJUp0vRXkb34JxE1LWY=", - "dev": true - }, -@@ -1279,6 +1505,11 @@ - } - } - }, -+======= -+ "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", -+ "dev": true -+ }, -+>>>>>>> .their - "clean-deep": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/clean-deep/-/clean-deep-2.0.2.tgz", -@@ -1317,6 +1548,7 @@ - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, -+<<<<<<< .our - "clipboardy": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-1.2.3.tgz", -@@ -1344,6 +1576,8 @@ - } - } - }, -+======= -+>>>>>>> .their - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", -@@ -1378,9 +1612,15 @@ - "dev": true - }, - "collapse-white-space": { -+<<<<<<< .our - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.4.tgz", - "integrity": "sha512-YfQ1tAUZm561vpYD+5eyWN8+UsceQbSrqqlc/6zDY2gtAE+uZLSdkkovhnGpmCThsvKBFakq4EdY/FF93E8XIw==", -+======= -+ "version": "1.0.3", -+ "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.3.tgz", -+ "integrity": "sha1-S5BvZw5aljqHt2sOFolkM0G2Ajw=", -+>>>>>>> .their - "dev": true - }, - "color-convert": { -@@ -1399,9 +1639,15 @@ - "dev": true - }, - "colors": { -+<<<<<<< .our - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", - "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", -+======= -+ "version": "1.2.1", -+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.1.tgz", -+ "integrity": "sha512-s8+wktIuDSLffCywiwSxQOMqtPxML11a/dtHE17tMn4B1MSWw/C22EKf7M2KGUBcDaVFEGT+S8N02geDXeuNKg==", -+>>>>>>> .their - "dev": true - }, - "combine-source-map": { -@@ -1441,6 +1687,7 @@ - "dot-prop": "3.0.0" - } - }, -+<<<<<<< .our - "compressible": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.14.tgz", -@@ -1473,6 +1720,8 @@ - "vary": "1.1.2" - } - }, -+======= -+>>>>>>> .their - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", -@@ -1526,7 +1775,11 @@ - "requires": { - "dot-prop": "4.2.0", - "graceful-fs": "4.1.11", -+<<<<<<< .our - "make-dir": "1.3.0", -+======= -+ "make-dir": "1.2.0", -+>>>>>>> .their - "unique-string": "1.0.0", - "write-file-atomic": "2.3.0", - "xdg-basedir": "3.0.0" -@@ -1535,7 +1788,11 @@ - "dot-prop": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", -+<<<<<<< .our - "integrity": "sha1-HxngwuGqDjJ5fEl5nyg3rGr2nFc=", -+======= -+ "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "is-obj": "1.0.1" -@@ -1564,6 +1821,7 @@ - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, -+<<<<<<< .our - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", -@@ -1574,13 +1832,24 @@ - "version": "1.1.24", - "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-1.1.24.tgz", - "integrity": "sha512-2WcSUst4Y3Z4hHvoMTWXMJr/DmgVdLiMOVY1Kak2LfFz+GIz2KDp5naqbFesYbfXPmaZ5p491dO0FWZIJoJw1Q==", -+======= -+ "conventional-changelog": { -+ "version": "1.1.23", -+ "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-1.1.23.tgz", -+ "integrity": "sha512-yCPXU/OXJmxgbvTQfIKXKwKa4KQTvlO0a4T/371Raz3bdxcHIGhQtHtdrNee4Z8nGLNfe54njHDblVG2JNFyjg==", -+>>>>>>> .their - "dev": true, - "requires": { - "conventional-changelog-angular": "1.6.6", - "conventional-changelog-atom": "0.2.8", - "conventional-changelog-codemirror": "0.3.8", -+<<<<<<< .our - "conventional-changelog-core": "2.0.11", - "conventional-changelog-ember": "0.3.12", -+======= -+ "conventional-changelog-core": "2.0.10", -+ "conventional-changelog-ember": "0.3.11", -+>>>>>>> .their - "conventional-changelog-eslint": "1.0.9", - "conventional-changelog-express": "0.3.6", - "conventional-changelog-jquery": "0.1.0", -@@ -1609,6 +1878,7 @@ - } - }, - "conventional-changelog-cli": { -+<<<<<<< .our - "version": "1.3.22", - "resolved": "https://registry.npmjs.org/conventional-changelog-cli/-/conventional-changelog-cli-1.3.22.tgz", - "integrity": "sha512-pnjdIJbxjkZ5VdAX/H1wndr1G10CY8MuZgnXuJhIHglOXfIrXygb7KZC836GW9uo1u8PjEIvIw/bKX0lOmOzZg==", -@@ -1618,6 +1888,17 @@ - "conventional-changelog": "1.1.24", - "lodash": "4.17.10", - "meow": "4.0.1", -+======= -+ "version": "1.3.21", -+ "resolved": "https://registry.npmjs.org/conventional-changelog-cli/-/conventional-changelog-cli-1.3.21.tgz", -+ "integrity": "sha512-K9VBljxzuATZCLTVnI83PN7WdeRJRPPB5FumuLk4ES3E+m2YJvX07DRbdJlINk6C2DeAjj4ioS5JvsvJaaCRbA==", -+ "dev": true, -+ "requires": { -+ "add-stream": "1.0.0", -+ "conventional-changelog": "1.1.23", -+ "lodash": "4.17.5", -+ "meow": "4.0.0", -+>>>>>>> .their - "tempfile": "1.1.1" - } - }, -@@ -1631,9 +1912,15 @@ - } - }, - "conventional-changelog-core": { -+<<<<<<< .our - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-2.0.11.tgz", - "integrity": "sha512-HvTE6RlqeEZ/NFPtQeFLsIDOLrGP3bXYr7lFLMhCVsbduF1MXIe8OODkwMFyo1i9ku9NWBwVnVn0jDmIFXjDRg==", -+======= -+ "version": "2.0.10", -+ "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-2.0.10.tgz", -+ "integrity": "sha512-FP0NHXIbpvU+f5jk/qZdnodhFmlzKW8ENRHQIWT69oe7ffur9nFRVJZlnXnFBOzwHM9WIRbC15ZWh9HZN6t9Uw==", -+>>>>>>> .their - "dev": true, - "requires": { - "conventional-changelog-writer": "3.0.9", -@@ -1643,7 +1930,11 @@ - "git-raw-commits": "1.3.6", - "git-remote-origin-url": "2.0.0", - "git-semver-tags": "1.3.6", -+<<<<<<< .our - "lodash": "4.17.10", -+======= -+ "lodash": "4.17.5", -+>>>>>>> .their - "normalize-package-data": "2.4.0", - "q": "1.5.1", - "read-pkg": "1.1.0", -@@ -1652,9 +1943,15 @@ - } - }, - "conventional-changelog-ember": { -+<<<<<<< .our - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-0.3.12.tgz", - "integrity": "sha512-mmJzA7uzbrOqeF89dMMi6z17O07ORTXlTMArnLG9ZTX4oLaKNolUlxFUFlFm9JUoVWajVpaHQWjxH1EOQ+ARoQ==", -+======= -+ "version": "0.3.11", -+ "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-0.3.11.tgz", -+ "integrity": "sha512-ErjPPiDmTd/WPgj2bSp+CGsLtJiv7FbdPKjZXH2Cd5P7j44Rqf0V9SIAAYFTQNoPqmvcp+sIcr/vH52WzPJUbw==", -+>>>>>>> .their - "dev": true, - "requires": { - "q": "1.5.1" -@@ -1723,8 +2020,13 @@ - "dateformat": "3.0.3", - "handlebars": "4.0.11", - "json-stringify-safe": "5.0.1", -+<<<<<<< .our - "lodash": "4.17.10", - "meow": "4.0.1", -+======= -+ "lodash": "4.17.5", -+ "meow": "4.0.0", -+>>>>>>> .their - "semver": "5.5.0", - "split": "1.0.1", - "through2": "2.0.3" -@@ -1748,8 +2050,13 @@ - "requires": { - "JSONStream": "1.3.2", - "is-text-path": "1.0.1", -+<<<<<<< .our - "lodash": "4.17.10", - "meow": "4.0.1", -+======= -+ "lodash": "4.17.5", -+ "meow": "4.0.0", -+>>>>>>> .their - "split2": "2.2.0", - "through2": "2.0.3", - "trim-off-newlines": "1.0.1" -@@ -1768,9 +2075,15 @@ - "dev": true - }, - "create-ecdh": { -+<<<<<<< .our - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", -+======= -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", -+ "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", -+>>>>>>> .their - "dev": true, - "requires": { - "bn.js": "4.11.8", -@@ -1787,19 +2100,30 @@ - } - }, - "create-hash": { -+<<<<<<< .our - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", -+======= -+ "version": "1.1.3", -+ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", -+ "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", -+>>>>>>> .their - "dev": true, - "requires": { - "cipher-base": "1.0.4", - "inherits": "2.0.3", -+<<<<<<< .our - "md5.js": "1.3.4", - "ripemd160": "2.0.2", -+======= -+ "ripemd160": "2.0.1", -+>>>>>>> .their - "sha.js": "2.4.11" - } - }, - "create-hmac": { -+<<<<<<< .our - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", -@@ -1810,6 +2134,18 @@ - "inherits": "2.0.3", - "ripemd160": "2.0.2", - "safe-buffer": "5.1.2", -+======= -+ "version": "1.1.6", -+ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", -+ "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", -+ "dev": true, -+ "requires": { -+ "cipher-base": "1.0.4", -+ "create-hash": "1.1.3", -+ "inherits": "2.0.3", -+ "ripemd160": "2.0.1", -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "sha.js": "2.4.11" - } - }, -@@ -1819,7 +2155,11 @@ - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { -+<<<<<<< .our - "lru-cache": "4.1.3", -+======= -+ "lru-cache": "4.1.2", -+>>>>>>> .their - "shebang-command": "1.2.0", - "which": "1.3.0" - } -@@ -1836,7 +2176,11 @@ - "boom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", -+<<<<<<< .our - "integrity": "sha1-XdnabuOl8wIHdDYpDLcX0/SlTgI=", -+======= -+ "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", -+>>>>>>> .their - "dev": true, - "requires": { - "hoek": "4.2.1" -@@ -1850,6 +2194,7 @@ - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { -+<<<<<<< .our - "browserify-cipher": "1.0.1", - "browserify-sign": "4.0.4", - "create-ecdh": "4.0.3", -@@ -1859,6 +2204,17 @@ - "inherits": "2.0.3", - "pbkdf2": "3.0.16", - "public-encrypt": "4.0.2", -+======= -+ "browserify-cipher": "1.0.0", -+ "browserify-sign": "4.0.4", -+ "create-ecdh": "4.0.0", -+ "create-hash": "1.1.3", -+ "create-hmac": "1.1.6", -+ "diffie-hellman": "5.0.2", -+ "inherits": "2.0.3", -+ "pbkdf2": "3.0.14", -+ "public-encrypt": "4.0.0", -+>>>>>>> .their - "randombytes": "2.0.6", - "randomfill": "1.0.4" - } -@@ -1960,7 +2316,11 @@ - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", -+<<<<<<< .our - "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", -+======= -+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", -+>>>>>>> .their - "dev": true, - "requires": { - "ms": "2.0.0" -@@ -2018,9 +2378,15 @@ - "dev": true - }, - "deep-extend": { -+<<<<<<< .our - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", - "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", -+======= -+ "version": "0.4.2", -+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", -+ "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", -+>>>>>>> .their - "dev": true - }, - "deep-is": { -@@ -2061,16 +2427,26 @@ - "requires": { - "find-root": "1.1.0", - "glob": "7.1.2", -+<<<<<<< .our - "ignore": "3.3.8", - "pkg-config": "1.1.1", - "run-parallel": "1.1.9", -+======= -+ "ignore": "3.3.7", -+ "pkg-config": "1.1.1", -+ "run-parallel": "1.1.8", -+>>>>>>> .their - "uniq": "1.0.1" - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -2104,12 +2480,15 @@ - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, -+<<<<<<< .our - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", - "dev": true - }, -+======= -+>>>>>>> .their - "deps-sort": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", -@@ -2129,6 +2508,7 @@ - "dev": true, - "requires": { - "inherits": "2.0.3", -+<<<<<<< .our - "minimalistic-assert": "1.0.1" - } - }, -@@ -2146,6 +2526,9 @@ - "requires": { - "address": "1.0.3", - "debug": "2.6.9" -+======= -+ "minimalistic-assert": "1.0.0" -+>>>>>>> .their - } - }, - "detective": { -@@ -2173,9 +2556,15 @@ - "dev": true - }, - "diffie-hellman": { -+<<<<<<< .our - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", -+======= -+ "version": "5.0.2", -+ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", -+ "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", -+>>>>>>> .their - "dev": true, - "requires": { - "bn.js": "4.11.8", -@@ -2184,12 +2573,30 @@ - } - }, - "doctrine": { -+<<<<<<< .our - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "2.0.2" -+======= -+ "version": "1.5.0", -+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", -+ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", -+ "dev": true, -+ "requires": { -+ "esutils": "2.0.2", -+ "isarray": "1.0.0" -+ }, -+ "dependencies": { -+ "isarray": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", -+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", -+ "dev": true -+ } -+>>>>>>> .their - } - }, - "dom-serializer": { -@@ -2223,9 +2630,15 @@ - "dev": true - }, - "domhandler": { -+<<<<<<< .our - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", -+======= -+ "version": "2.4.1", -+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz", -+ "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=", -+>>>>>>> .their - "dev": true, - "requires": { - "domelementtype": "1.3.0" -@@ -2266,9 +2679,15 @@ - } - }, - "dugite": { -+<<<<<<< .our - "version": "1.63.0", - "resolved": "https://registry.npmjs.org/dugite/-/dugite-1.63.0.tgz", - "integrity": "sha512-CFd0sWTB2oouat0kJA4/rEQAeh6ZUvCDL9uFOaSBhLX+2CM/YL+ebKJXd8dYVIe8iVXmK5R9P31NVbRw4Ccoxw==", -+======= -+ "version": "1.61.0", -+ "resolved": "https://registry.npmjs.org/dugite/-/dugite-1.61.0.tgz", -+ "integrity": "sha512-F4d094nICYAIATRN+SZTa6x9XlebJEEyk7os7RLp7qS+IwNkBz8iMIvdrUdNutBVC0POVQ3hrRN9rGxnw7sZrA==", -+>>>>>>> .their - "dev": true, - "requires": { - "checksum": "0.1.1", -@@ -2276,7 +2695,11 @@ - "progress": "2.0.0", - "request": "2.85.0", - "rimraf": "2.6.2", -+<<<<<<< .our - "tar": "4.4.2" -+======= -+ "tar": "4.4.1" -+>>>>>>> .their - } - }, - "duplexer2": { -@@ -2304,7 +2727,11 @@ - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", -+======= -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } -@@ -2315,7 +2742,11 @@ - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -2327,9 +2758,15 @@ - "dev": true - }, - "duplexify": { -+<<<<<<< .our - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz", - "integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==", -+======= -+ "version": "3.5.4", -+ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.4.tgz", -+ "integrity": "sha512-JzYSLYMhoVVBe8+mbHQ4KgpvHpm0DZpJuL8PY93Vyv1fW7jYJ90LoXa1di/CVbJM+TgMs91rbDapE/RNIfnJsA==", -+>>>>>>> .their - "dev": true, - "requires": { - "end-of-stream": "1.4.1", -@@ -2354,7 +2791,11 @@ - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", -+======= -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } -@@ -2365,7 +2806,11 @@ - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -2380,12 +2825,15 @@ - "jsbn": "0.1.1" - } - }, -+<<<<<<< .our - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, -+======= -+>>>>>>> .their - "electabul": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/electabul/-/electabul-0.0.4.tgz", -@@ -2441,7 +2889,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -2467,7 +2919,11 @@ - "path-exists": "3.0.0", - "pify": "2.3.0", - "semver": "5.5.0", -+<<<<<<< .our - "tar-fs": "1.16.2" -+======= -+ "tar-fs": "1.16.0" -+>>>>>>> .their - }, - "dependencies": { - "ora": { -@@ -2523,6 +2979,7 @@ - } - }, - "electron-typescript-definitions": { -+<<<<<<< .our - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/electron-typescript-definitions/-/electron-typescript-definitions-1.3.6.tgz", - "integrity": "sha512-Wz6tPaaZ22lbfWwF9bzVSki7LMW96xilCT1M8eeNYZG6LcpA9x34jlrAZg5HZWTHXR2tfbTQhSmrY+FEVulD/A==", -@@ -2538,6 +2995,23 @@ - "rimraf": "2.6.2", - "tslint": "4.5.1", - "typescript": "2.9.2" -+======= -+ "version": "1.2.11", -+ "resolved": "https://registry.npmjs.org/electron-typescript-definitions/-/electron-typescript-definitions-1.2.11.tgz", -+ "integrity": "sha512-gBVmiGkw2hiut17wnSchYpFxrBmMb+jKFSjxbVFeivCn1OAAFykKtrsg26Sjcrra6AN1YiWyTC7SD9twPAO8dQ==", -+ "dev": true, -+ "requires": { -+ "@types/node": "7.0.59", -+ "colors": "1.2.1", -+ "debug": "2.6.9", -+ "electron-docs": "2.0.1", -+ "electron-docs-linter": "2.3.4", -+ "lodash": "4.17.5", -+ "mkdirp": "0.5.1", -+ "rimraf": "2.6.2", -+ "tslint": "4.5.1", -+ "typescript": "2.8.1" -+>>>>>>> .their - } - }, - "elliptic": { -@@ -2551,6 +3025,7 @@ - "hash.js": "1.1.3", - "hmac-drbg": "1.0.1", - "inherits": "2.0.3", -+<<<<<<< .our - "minimalistic-assert": "1.0.1", - "minimalistic-crypto-utils": "1.0.1" - } -@@ -2561,6 +3036,12 @@ - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, -+======= -+ "minimalistic-assert": "1.0.0", -+ "minimalistic-crypto-utils": "1.0.1" -+ } -+ }, -+>>>>>>> .their - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", -@@ -2686,12 +3167,15 @@ - "es6-symbol": "3.1.1" - } - }, -+<<<<<<< .our - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, -+======= -+>>>>>>> .their - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", -@@ -2744,25 +3228,41 @@ - } - }, - "eslint": { -+<<<<<<< .our - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", - "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", -+======= -+ "version": "3.10.2", -+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.10.2.tgz", -+ "integrity": "sha1-yaEOi/bp1lZRIEd4xQM0Hx6sPOc=", -+>>>>>>> .their - "dev": true, - "requires": { - "babel-code-frame": "6.26.0", - "chalk": "1.1.3", - "concat-stream": "1.5.2", - "debug": "2.6.9", -+<<<<<<< .our - "doctrine": "2.1.0", - "escope": "3.6.0", - "espree": "3.5.4", - "esquery": "1.0.1", -+======= -+ "doctrine": "1.5.0", -+ "escope": "3.6.0", -+ "espree": "3.5.4", -+>>>>>>> .their - "estraverse": "4.2.0", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "glob": "7.1.2", - "globals": "9.18.0", -+<<<<<<< .our - "ignore": "3.3.8", -+======= -+ "ignore": "3.3.7", -+>>>>>>> .their - "imurmurhash": "0.1.4", - "inquirer": "0.12.0", - "is-my-json-valid": "2.17.2", -@@ -2770,7 +3270,11 @@ - "js-yaml": "3.11.0", - "json-stable-stringify": "1.0.1", - "levn": "0.3.0", -+<<<<<<< .our - "lodash": "4.17.10", -+======= -+ "lodash": "4.17.5", -+>>>>>>> .their - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", -@@ -2780,7 +3284,11 @@ - "require-uncached": "1.0.3", - "shelljs": "0.7.8", - "strip-bom": "3.0.0", -+<<<<<<< .our - "strip-json-comments": "2.0.1", -+======= -+ "strip-json-comments": "1.0.4", -+>>>>>>> .their - "table": "3.8.3", - "text-table": "0.2.0", - "user-home": "2.0.0" -@@ -2795,7 +3303,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -2826,10 +3338,20 @@ - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true -+<<<<<<< .our -+======= -+ }, -+ "strip-json-comments": { -+ "version": "1.0.4", -+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", -+ "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", -+ "dev": true -+>>>>>>> .their - } - } - }, - "eslint-config-standard": { -+<<<<<<< .our - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz", - "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=", -@@ -2839,6 +3361,17 @@ - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-4.0.2.tgz", - "integrity": "sha512-F8fRh2WFnTek7dZH9ZaE0PCBwdVGkwVWZmizla/DDNOmg7Tx6B/IlK5+oYpiX29jpu73LszeJj5i1axEZv6VMw==", -+======= -+ "version": "6.2.1", -+ "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-6.2.1.tgz", -+ "integrity": "sha1-06aKr8cZFjnn7kQec0hzkCY1QpI=", -+ "dev": true -+ }, -+ "eslint-config-standard-jsx": { -+ "version": "3.2.0", -+ "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-3.2.0.tgz", -+ "integrity": "sha1-wkDibtkZoRpCqk3oBZRys4Jo1iA=", -+>>>>>>> .their - "dev": true - }, - "eslint-import-resolver-node": { -@@ -2849,7 +3382,11 @@ - "requires": { - "debug": "2.6.9", - "object-assign": "4.1.1", -+<<<<<<< .our - "resolve": "1.7.1" -+======= -+ "resolve": "1.6.0" -+>>>>>>> .their - } - }, - "eslint-module-utils": { -@@ -2878,6 +3415,7 @@ - "lodash.cond": "4.5.2", - "minimatch": "3.0.4", - "pkg-up": "1.0.0" -+<<<<<<< .our - }, - "dependencies": { - "doctrine": { -@@ -2896,11 +3434,14 @@ - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } -+======= -+>>>>>>> .their - } - }, - "eslint-plugin-node": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-4.2.3.tgz", -+<<<<<<< .our - "integrity": "sha1-wEOQq428u2iHF0Aj1vOnJ2nmO5c=", - "dev": true, - "requires": { -@@ -2908,6 +3449,15 @@ - "minimatch": "3.0.4", - "object-assign": "4.1.1", - "resolve": "1.7.1", -+======= -+ "integrity": "sha512-vIUQPuwbVYdz/CYnlTLsJrRy7iXHQjdEe5wz0XhhdTym3IInM/zZLlPf9nZ2mThsH0QcsieCOWs2vOeCy/22LQ==", -+ "dev": true, -+ "requires": { -+ "ignore": "3.3.7", -+ "minimatch": "3.0.4", -+ "object-assign": "4.1.1", -+ "resolve": "1.6.0", -+>>>>>>> .their - "semver": "5.3.0" - }, - "dependencies": { -@@ -2920,6 +3470,7 @@ - } - }, - "eslint-plugin-promise": { -+<<<<<<< .our - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz", - "integrity": "sha1-ePu2/+BHIBYnVp6FpsU3OvKmj8o=", -@@ -2960,6 +3511,27 @@ - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz", - "integrity": "sha1-NNDJFbRe3G8BA5PH7vOCOwhWXPI=", -+======= -+ "version": "3.4.2", -+ "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.4.2.tgz", -+ "integrity": "sha1-G+J5Pq/i0YtbEjuBNsJp+AT+cSI=", -+ "dev": true -+ }, -+ "eslint-plugin-react": { -+ "version": "6.7.1", -+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.7.1.tgz", -+ "integrity": "sha1-Gvlq6lRYVoJRV9l8G1DVqPtkpac=", -+ "dev": true, -+ "requires": { -+ "doctrine": "1.5.0", -+ "jsx-ast-utils": "1.4.1" -+ } -+ }, -+ "eslint-plugin-standard": { -+ "version": "2.0.1", -+ "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-2.0.1.tgz", -+ "integrity": "sha1-NYlpn/nJF/LCX3apFmh/ZBw2n/M=", -+>>>>>>> .their - "dev": true - }, - "espree": { -@@ -3032,12 +3604,15 @@ - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, -+<<<<<<< .our - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, -+======= -+>>>>>>> .their - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", -@@ -3057,11 +3632,19 @@ - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", -+<<<<<<< .our - "integrity": "sha1-f8vbGY3HGVlDLv4ThCaE4FJaywI=", - "dev": true, - "requires": { - "md5.js": "1.3.4", - "safe-buffer": "5.1.2" -+======= -+ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", -+ "dev": true, -+ "requires": { -+ "md5.js": "1.3.4", -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - }, - "execa": { -@@ -3100,7 +3683,11 @@ - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { -+<<<<<<< .our - "fill-range": "2.2.4" -+======= -+ "fill-range": "2.2.3" -+>>>>>>> .their - } - }, - "extend": { -@@ -3143,9 +3730,15 @@ - "dev": true - }, - "fault": { -+<<<<<<< .our - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.2.tgz", - "integrity": "sha512-o2eo/X2syzzERAtN5LcGbiVQ0WwZSlN3qLtadwAz3X8Bu+XWD16dja/KMsjZLiQr+BLGPDnHGkc4yUJf1Xpkpw==", -+======= -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.1.tgz", -+ "integrity": "sha1-3o01Df1IviS13BsChn4IcbkTUJI=", -+>>>>>>> .their - "dev": true, - "requires": { - "format": "0.2.2" -@@ -3177,6 +3770,7 @@ - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, -+<<<<<<< .our - "filesize": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", -@@ -3187,11 +3781,21 @@ - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", -+======= -+ "fill-range": { -+ "version": "2.2.3", -+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", -+ "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", -+>>>>>>> .their - "dev": true, - "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", -+<<<<<<< .our - "randomatic": "3.0.0", -+======= -+ "randomatic": "1.1.7", -+>>>>>>> .their - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" - } -@@ -3199,7 +3803,11 @@ - "find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", -+<<<<<<< .our - "integrity": "sha1-q8/Iunb3CMQql7PWhbfpRQv7nOQ=", -+======= -+ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", -+>>>>>>> .their - "dev": true - }, - "find-up": { -@@ -3308,6 +3916,7 @@ - "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=", - "dev": true - }, -+<<<<<<< .our - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", -@@ -3320,6 +3929,8 @@ - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, -+======= -+>>>>>>> .their - "fs-extra": { - "version": "0.26.7", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", -@@ -3339,7 +3950,11 @@ - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", - "dev": true, - "requires": { -+<<<<<<< .our - "minipass": "2.3.0" -+======= -+ "minipass": "2.2.4" -+>>>>>>> .their - } - }, - "fs.realpath": { -@@ -3349,29 +3964,60 @@ - "dev": true - }, - "fsevents": { -+<<<<<<< .our - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", -+======= -+ "version": "1.1.3", -+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", -+ "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", -+>>>>>>> .their - "dev": true, - "optional": true, - "requires": { - "nan": "2.10.0", -+<<<<<<< .our - "node-pre-gyp": "0.10.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", -+======= -+ "node-pre-gyp": "0.6.39" -+ }, -+ "dependencies": { -+ "abbrev": { -+ "version": "1.1.0", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true - }, -+<<<<<<< .our -+======= -+ "ajv": { -+ "version": "4.11.8", -+ "bundled": true, -+ "dev": true, -+ "optional": true, -+ "requires": { -+ "co": "4.6.0", -+ "json-stable-stringify": "1.0.1" -+ } -+ }, -+>>>>>>> .their - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "aproba": { -+<<<<<<< .our - "version": "1.2.0", -+======= -+ "version": "1.1.1", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true -@@ -3382,6 +4028,7 @@ - "dev": true, - "optional": true, - "requires": { -+<<<<<<< .our - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } -@@ -3402,6 +4049,94 @@ - }, - "chownr": { - "version": "1.0.1", -+======= -+ "delegates": "1.0.0", -+ "readable-stream": "2.2.9" -+ } -+ }, -+ "asn1": { -+ "version": "0.2.3", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ }, -+ "assert-plus": { -+ "version": "0.2.0", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ }, -+ "asynckit": { -+ "version": "0.4.0", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ }, -+ "aws-sign2": { -+ "version": "0.6.0", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ }, -+ "aws4": { -+ "version": "1.6.0", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ }, -+ "balanced-match": { -+ "version": "0.4.2", -+ "bundled": true, -+ "dev": true -+ }, -+ "bcrypt-pbkdf": { -+ "version": "1.0.1", -+ "bundled": true, -+ "dev": true, -+ "optional": true, -+ "requires": { -+ "tweetnacl": "0.14.5" -+ } -+ }, -+ "block-stream": { -+ "version": "0.0.9", -+ "bundled": true, -+ "dev": true, -+ "requires": { -+ "inherits": "2.0.3" -+ } -+ }, -+ "boom": { -+ "version": "2.10.1", -+ "bundled": true, -+ "dev": true, -+ "requires": { -+ "hoek": "2.16.3" -+ } -+ }, -+ "brace-expansion": { -+ "version": "1.1.7", -+ "bundled": true, -+ "dev": true, -+ "requires": { -+ "balanced-match": "0.4.2", -+ "concat-map": "0.0.1" -+ } -+ }, -+ "buffer-shims": { -+ "version": "1.0.0", -+ "bundled": true, -+ "dev": true -+ }, -+ "caseless": { -+ "version": "0.12.0", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ }, -+ "co": { -+ "version": "4.6.0", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true -@@ -3411,6 +4146,17 @@ - "bundled": true, - "dev": true - }, -+<<<<<<< .our -+======= -+ "combined-stream": { -+ "version": "1.0.5", -+ "bundled": true, -+ "dev": true, -+ "requires": { -+ "delayed-stream": "1.0.0" -+ } -+ }, -+>>>>>>> .their - "concat-map": { - "version": "0.0.1", - "bundled": true, -@@ -3424,11 +4170,43 @@ - "core-util-is": { - "version": "1.0.2", - "bundled": true, -+<<<<<<< .our - "dev": true, - "optional": true - }, - "debug": { - "version": "2.6.9", -+======= -+ "dev": true -+ }, -+ "cryptiles": { -+ "version": "2.0.5", -+ "bundled": true, -+ "dev": true, -+ "requires": { -+ "boom": "2.10.1" -+ } -+ }, -+ "dashdash": { -+ "version": "1.14.1", -+ "bundled": true, -+ "dev": true, -+ "optional": true, -+ "requires": { -+ "assert-plus": "1.0.0" -+ }, -+ "dependencies": { -+ "assert-plus": { -+ "version": "1.0.0", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ } -+ } -+ }, -+ "debug": { -+ "version": "2.6.8", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true, -@@ -3437,11 +4215,23 @@ - } - }, - "deep-extend": { -+<<<<<<< .our - "version": "0.5.1", -+======= -+ "version": "0.4.2", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true - }, -+<<<<<<< .our -+======= -+ "delayed-stream": { -+ "version": "1.0.0", -+ "bundled": true, -+ "dev": true -+ }, -+>>>>>>> .their - "delegates": { - "version": "1.0.0", - "bundled": true, -@@ -3449,32 +4239,100 @@ - "optional": true - }, - "detect-libc": { -+<<<<<<< .our - "version": "1.0.3", -+======= -+ "version": "1.0.2", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true - }, -+<<<<<<< .our - "fs-minipass": { - "version": "1.2.5", -+======= -+ "ecc-jsbn": { -+ "version": "0.1.1", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true, - "requires": { -+<<<<<<< .our - "minipass": "^2.2.1" -+======= -+ "jsbn": "0.1.1" - } - }, -- "fs.realpath": { -- "version": "1.0.0", -+ "extend": { -+ "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true - }, -- "gauge": { -- "version": "2.7.4", -+ "extsprintf": { -+ "version": "1.0.2", -+ "bundled": true, -+ "dev": true -+ }, -+ "forever-agent": { -+ "version": "0.6.1", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ }, -+ "form-data": { -+ "version": "2.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { -+ "asynckit": "0.4.0", -+ "combined-stream": "1.0.5", -+ "mime-types": "2.1.15" -+>>>>>>> .their -+ } -+ }, -+ "fs.realpath": { -+ "version": "1.0.0", -+ "bundled": true, -+<<<<<<< .our -+ "dev": true, -+ "optional": true -+======= -+ "dev": true -+ }, -+ "fstream": { -+ "version": "1.0.11", -+ "bundled": true, -+ "dev": true, -+ "requires": { -+ "graceful-fs": "4.1.11", -+ "inherits": "2.0.3", -+ "mkdirp": "0.5.1", -+ "rimraf": "2.6.1" -+ } -+ }, -+ "fstream-ignore": { -+ "version": "1.0.5", -+ "bundled": true, -+ "dev": true, -+ "optional": true, -+ "requires": { -+ "fstream": "1.0.11", -+ "inherits": "2.0.3", -+ "minimatch": "3.0.4" -+ } -+>>>>>>> .their -+ }, -+ "gauge": { -+ "version": "2.7.4", -+ "bundled": true, -+ "dev": true, -+ "optional": true, -+ "requires": { -+<<<<<<< .our - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", -@@ -3483,12 +4341,40 @@ - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" -+======= -+ "aproba": "1.1.1", -+ "console-control-strings": "1.1.0", -+ "has-unicode": "2.0.1", -+ "object-assign": "4.1.1", -+ "signal-exit": "3.0.2", -+ "string-width": "1.0.2", -+ "strip-ansi": "3.0.1", -+ "wide-align": "1.1.2" -+ } -+ }, -+ "getpass": { -+ "version": "0.1.7", -+ "bundled": true, -+ "dev": true, -+ "optional": true, -+ "requires": { -+ "assert-plus": "1.0.0" -+ }, -+ "dependencies": { -+ "assert-plus": { -+ "version": "1.0.0", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ } -+>>>>>>> .their - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, -+<<<<<<< .our - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", -@@ -3497,6 +4383,36 @@ - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" -+======= -+ "requires": { -+ "fs.realpath": "1.0.0", -+ "inflight": "1.0.6", -+ "inherits": "2.0.3", -+ "minimatch": "3.0.4", -+ "once": "1.4.0", -+ "path-is-absolute": "1.0.1" -+ } -+ }, -+ "graceful-fs": { -+ "version": "4.1.11", -+ "bundled": true, -+ "dev": true -+ }, -+ "har-schema": { -+ "version": "1.0.5", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ }, -+ "har-validator": { -+ "version": "4.2.1", -+ "bundled": true, -+ "dev": true, -+ "optional": true, -+ "requires": { -+ "ajv": "4.11.8", -+ "har-schema": "1.0.5" -+>>>>>>> .their - } - }, - "has-unicode": { -@@ -3505,6 +4421,7 @@ - "dev": true, - "optional": true - }, -+<<<<<<< .our - "iconv-lite": { - "version": "0.4.21", - "bundled": true, -@@ -3516,21 +4433,53 @@ - }, - "ignore-walk": { - "version": "3.0.1", -+======= -+ "hawk": { -+ "version": "3.1.3", -+ "bundled": true, -+ "dev": true, -+ "requires": { -+ "boom": "2.10.1", -+ "cryptiles": "2.0.5", -+ "hoek": "2.16.3", -+ "sntp": "1.0.9" -+ } -+ }, -+ "hoek": { -+ "version": "2.16.3", -+ "bundled": true, -+ "dev": true -+ }, -+ "http-signature": { -+ "version": "1.1.1", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true, - "requires": { -+<<<<<<< .our - "minimatch": "^3.0.4" -+======= -+ "assert-plus": "0.2.0", -+ "jsprim": "1.4.0", -+ "sshpk": "1.13.0" -+>>>>>>> .their - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, -+<<<<<<< .our - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" -+======= -+ "requires": { -+ "once": "1.4.0", -+ "wrappy": "1.0.2" -+>>>>>>> .their - } - }, - "inherits": { -@@ -3539,7 +4488,11 @@ - "dev": true - }, - "ini": { -+<<<<<<< .our - "version": "1.3.5", -+======= -+ "version": "1.3.4", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true -@@ -3549,6 +4502,7 @@ - "bundled": true, - "dev": true, - "requires": { -+<<<<<<< .our - "number-is-nan": "^1.0.0" - } - }, -@@ -3582,10 +4536,56 @@ - }, - "minizlib": { - "version": "1.1.0", -+======= -+ "number-is-nan": "1.0.1" -+ } -+ }, -+ "is-typedarray": { -+ "version": "1.0.0", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ }, -+ "isarray": { -+ "version": "1.0.0", -+ "bundled": true, -+ "dev": true -+ }, -+ "isstream": { -+ "version": "0.1.2", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ }, -+ "jodid25519": { -+ "version": "1.0.2", -+ "bundled": true, -+ "dev": true, -+ "optional": true, -+ "requires": { -+ "jsbn": "0.1.1" -+ } -+ }, -+ "jsbn": { -+ "version": "0.1.1", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ }, -+ "json-schema": { -+ "version": "0.2.3", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ }, -+ "json-stable-stringify": { -+ "version": "1.0.1", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true, - "requires": { -+<<<<<<< .our - "minipass": "^2.2.1" - } - }, -@@ -3599,16 +4599,35 @@ - }, - "ms": { - "version": "2.0.0", -+======= -+ "jsonify": "0.0.0" -+ } -+ }, -+ "json-stringify-safe": { -+ "version": "5.0.1", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ }, -+ "jsonify": { -+ "version": "0.0.0", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true - }, -+<<<<<<< .our - "needle": { - "version": "2.2.0", -+======= -+ "jsprim": { -+ "version": "1.4.0", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true, - "requires": { -+<<<<<<< .our - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" -@@ -3644,30 +4663,122 @@ - }, - "npm-bundled": { - "version": "1.0.3", -+======= -+ "assert-plus": "1.0.0", -+ "extsprintf": "1.0.2", -+ "json-schema": "0.2.3", -+ "verror": "1.3.6" -+ }, -+ "dependencies": { -+ "assert-plus": { -+ "version": "1.0.0", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ } -+ } -+ }, -+ "mime-db": { -+ "version": "1.27.0", -+ "bundled": true, -+ "dev": true -+ }, -+ "mime-types": { -+ "version": "2.1.15", -+ "bundled": true, -+ "dev": true, -+ "requires": { -+ "mime-db": "1.27.0" -+ } -+ }, -+ "minimatch": { -+ "version": "3.0.4", -+ "bundled": true, -+ "dev": true, -+ "requires": { -+ "brace-expansion": "1.1.7" -+ } -+ }, -+ "minimist": { -+ "version": "0.0.8", -+ "bundled": true, -+ "dev": true -+ }, -+ "mkdirp": { -+ "version": "0.5.1", -+ "bundled": true, -+ "dev": true, -+ "requires": { -+ "minimist": "0.0.8" -+ } -+ }, -+ "ms": { -+ "version": "2.0.0", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true - }, -+<<<<<<< .our - "npm-packlist": { - "version": "1.1.10", -+======= -+ "node-pre-gyp": { -+ "version": "0.6.39", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true, - "requires": { -+<<<<<<< .our - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", -+======= -+ "detect-libc": "1.0.2", -+ "hawk": "3.1.3", -+ "mkdirp": "0.5.1", -+ "nopt": "4.0.1", -+ "npmlog": "4.1.0", -+ "rc": "1.2.1", -+ "request": "2.81.0", -+ "rimraf": "2.6.1", -+ "semver": "5.3.0", -+ "tar": "2.2.1", -+ "tar-pack": "3.4.0" -+ } -+ }, -+ "nopt": { -+ "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { -+ "abbrev": "1.1.0", -+ "osenv": "0.1.4" -+ } -+ }, -+ "npmlog": { -+ "version": "4.1.0", -+>>>>>>> .their -+ "bundled": true, -+ "dev": true, -+ "optional": true, -+ "requires": { -+<<<<<<< .our - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" -+======= -+ "are-we-there-yet": "1.1.4", -+ "console-control-strings": "1.1.0", -+ "gauge": "2.7.4", -+ "set-blocking": "2.0.0" -+>>>>>>> .their - } - }, - "number-is-nan": { -@@ -3675,6 +4786,15 @@ - "bundled": true, - "dev": true - }, -+<<<<<<< .our -+======= -+ "oauth-sign": { -+ "version": "0.8.2", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ }, -+>>>>>>> .their - "object-assign": { - "version": "4.1.1", - "bundled": true, -@@ -3686,7 +4806,11 @@ - "bundled": true, - "dev": true, - "requires": { -+<<<<<<< .our - "wrappy": "1" -+======= -+ "wrappy": "1.0.2" -+>>>>>>> .their - } - }, - "os-homedir": { -@@ -3702,33 +4826,173 @@ - "optional": true - }, - "osenv": { -+<<<<<<< .our - "version": "0.1.5", -+======= -+ "version": "0.1.4", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true, - "requires": { -+<<<<<<< .our - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" -+======= -+ "os-homedir": "1.0.2", -+ "os-tmpdir": "1.0.2" -+>>>>>>> .their - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, -+<<<<<<< .our -+======= -+ "dev": true -+ }, -+ "performance-now": { -+ "version": "0.2.0", -+ "bundled": true, -+>>>>>>> .their - "dev": true, - "optional": true - }, - "process-nextick-args": { -+<<<<<<< .our - "version": "2.0.0", -+======= -+ "version": "1.0.7", -+ "bundled": true, -+ "dev": true -+ }, -+ "punycode": { -+ "version": "1.4.1", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ }, -+ "qs": { -+ "version": "6.4.0", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { -+<<<<<<< .our - "version": "1.2.7", -+======= -+ "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { -+ "deep-extend": "0.4.2", -+ "ini": "1.3.4", -+ "minimist": "1.2.0", -+ "strip-json-comments": "2.0.1" -+ }, -+ "dependencies": { -+ "minimist": { -+ "version": "1.2.0", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ } -+ } -+ }, -+ "readable-stream": { -+ "version": "2.2.9", -+ "bundled": true, -+ "dev": true, -+ "requires": { -+ "buffer-shims": "1.0.0", -+ "core-util-is": "1.0.2", -+ "inherits": "2.0.3", -+ "isarray": "1.0.0", -+ "process-nextick-args": "1.0.7", -+ "string_decoder": "1.0.1", -+ "util-deprecate": "1.0.2" -+ } -+ }, -+ "request": { -+ "version": "2.81.0", -+ "bundled": true, -+ "dev": true, -+ "optional": true, -+ "requires": { -+ "aws-sign2": "0.6.0", -+ "aws4": "1.6.0", -+ "caseless": "0.12.0", -+ "combined-stream": "1.0.5", -+ "extend": "3.0.1", -+ "forever-agent": "0.6.1", -+ "form-data": "2.1.4", -+ "har-validator": "4.2.1", -+ "hawk": "3.1.3", -+ "http-signature": "1.1.1", -+ "is-typedarray": "1.0.0", -+ "isstream": "0.1.2", -+ "json-stringify-safe": "5.0.1", -+ "mime-types": "2.1.15", -+ "oauth-sign": "0.8.2", -+ "performance-now": "0.2.0", -+ "qs": "6.4.0", -+ "safe-buffer": "5.0.1", -+ "stringstream": "0.0.5", -+ "tough-cookie": "2.3.2", -+ "tunnel-agent": "0.6.0", -+ "uuid": "3.0.1" -+ } -+ }, -+ "rimraf": { -+ "version": "2.6.1", -+ "bundled": true, -+ "dev": true, -+ "requires": { -+ "glob": "7.1.2" -+ } -+ }, -+ "safe-buffer": { -+ "version": "5.0.1", -+ "bundled": true, -+ "dev": true -+ }, -+ "semver": { -+ "version": "5.3.0", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ }, -+ "set-blocking": { -+ "version": "2.0.0", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ }, -+ "signal-exit": { -+ "version": "3.0.2", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+ }, -+ "sntp": { -+ "version": "1.0.9", -+ "bundled": true, -+ "dev": true, -+ "requires": { -+ "hoek": "2.16.3" -+ } -+ }, -+ "sshpk": { -+ "version": "1.13.0", -+>>>>>>> .their -+ "bundled": true, -+ "dev": true, -+ "optional": true, -+ "requires": { -+<<<<<<< .our - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", -@@ -3737,12 +5001,28 @@ - "dependencies": { - "minimist": { - "version": "1.2.0", -+======= -+ "asn1": "0.2.3", -+ "assert-plus": "1.0.0", -+ "bcrypt-pbkdf": "1.0.1", -+ "dashdash": "1.14.1", -+ "ecc-jsbn": "0.1.1", -+ "getpass": "0.1.7", -+ "jodid25519": "1.0.2", -+ "jsbn": "0.1.1", -+ "tweetnacl": "0.14.5" -+ }, -+ "dependencies": { -+ "assert-plus": { -+ "version": "1.0.0", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true - } - } - }, -+<<<<<<< .our - "readable-stream": { - "version": "2.3.6", - "bundled": true, -@@ -3780,10 +5060,33 @@ - }, - "sax": { - "version": "1.2.4", -+======= -+ "string-width": { -+ "version": "1.0.2", -+ "bundled": true, -+ "dev": true, -+ "requires": { -+ "code-point-at": "1.1.0", -+ "is-fullwidth-code-point": "1.0.0", -+ "strip-ansi": "3.0.1" -+ } -+ }, -+ "string_decoder": { -+ "version": "1.0.1", -+ "bundled": true, -+ "dev": true, -+ "requires": { -+ "safe-buffer": "5.0.1" -+ } -+ }, -+ "stringstream": { -+ "version": "0.0.5", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true - }, -+<<<<<<< .our - "semver": { - "version": "5.5.0", - "bundled": true, -@@ -3792,10 +5095,23 @@ - }, - "set-blocking": { - "version": "2.0.0", -+======= -+ "strip-ansi": { -+ "version": "3.0.1", -+ "bundled": true, -+ "dev": true, -+ "requires": { -+ "ansi-regex": "2.1.1" -+ } -+ }, -+ "strip-json-comments": { -+ "version": "2.0.1", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true - }, -+<<<<<<< .our - "signal-exit": { - "version": "3.0.2", - "bundled": true, -@@ -3814,10 +5130,41 @@ - }, - "string_decoder": { - "version": "1.1.1", -+======= -+ "tar": { -+ "version": "2.2.1", -+ "bundled": true, -+ "dev": true, -+ "requires": { -+ "block-stream": "0.0.9", -+ "fstream": "1.0.11", -+ "inherits": "2.0.3" -+ } -+ }, -+ "tar-pack": { -+ "version": "3.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { -+ "debug": "2.6.8", -+ "fstream": "1.0.11", -+ "fstream-ignore": "1.0.5", -+ "once": "1.4.0", -+ "readable-stream": "2.2.9", -+ "rimraf": "2.6.1", -+ "tar": "2.2.1", -+ "uid-number": "0.0.6" -+ } -+ }, -+ "tough-cookie": { -+ "version": "2.3.2", -+>>>>>>> .their -+ "bundled": true, -+ "dev": true, -+ "optional": true, -+ "requires": { -+<<<<<<< .our - "safe-buffer": "~5.1.0" - } - }, -@@ -3831,10 +5178,27 @@ - }, - "strip-json-comments": { - "version": "2.0.1", -+======= -+ "punycode": "1.4.1" -+ } -+ }, -+ "tunnel-agent": { -+ "version": "0.6.0", -+ "bundled": true, -+ "dev": true, -+ "optional": true, -+ "requires": { -+ "safe-buffer": "5.0.1" -+ } -+ }, -+ "tweetnacl": { -+ "version": "0.14.5", -+>>>>>>> .their - "bundled": true, - "dev": true, - "optional": true - }, -+<<<<<<< .our - "tar": { - "version": "4.4.1", - "bundled": true, -@@ -3849,38 +5213,76 @@ - "safe-buffer": "^5.1.1", - "yallist": "^3.0.2" - } -+======= -+ "uid-number": { -+ "version": "0.0.6", -+ "bundled": true, -+ "dev": true, -+ "optional": true -+>>>>>>> .their - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, -+<<<<<<< .our -+ "dev": true, -+ "optional": true -+ }, -+======= -+ "dev": true -+ }, -+ "uuid": { -+ "version": "3.0.1", -+ "bundled": true, - "dev": true, - "optional": true - }, -+ "verror": { -+ "version": "1.3.6", -+ "bundled": true, -+ "dev": true, -+ "optional": true, -+ "requires": { -+ "extsprintf": "1.0.2" -+ } -+ }, -+>>>>>>> .their - "wide-align": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { -+<<<<<<< .our - "string-width": "^1.0.2" -+======= -+ "string-width": "1.0.2" -+>>>>>>> .their - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true -+<<<<<<< .our - }, - "yallist": { - "version": "3.0.2", - "bundled": true, - "dev": true -+======= -+>>>>>>> .their - } - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", -+<<<<<<< .our - "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=", -+======= -+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", -+>>>>>>> .their - "dev": true - }, - "generate-function": { -@@ -4022,7 +5424,11 @@ - "requires": { - "dargs": "4.1.0", - "lodash.template": "4.4.0", -+<<<<<<< .our - "meow": "4.0.1", -+======= -+ "meow": "4.0.0", -+>>>>>>> .their - "split2": "2.2.0", - "through2": "2.0.3" - } -@@ -4043,7 +5449,11 @@ - "integrity": "sha512-2jHlJnln4D/ECk9FxGEBh3k44wgYdWjWDtMmJPaecjoRmxKo3Y1Lh8GMYuOPu04CHw86NTAODchYjC5pnpMQig==", - "dev": true, - "requires": { -+<<<<<<< .our - "meow": "4.0.1", -+======= -+ "meow": "4.0.0", -+>>>>>>> .their - "semver": "5.5.0" - } - }, -@@ -4059,7 +5469,11 @@ - "github": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/github/-/github-9.3.1.tgz", -+<<<<<<< .our - "integrity": "sha1-ajxanMKhzQtdCXpHuu+50Ryu+J4=", -+======= -+ "integrity": "sha512-LvVb6iR8/7bqYgj0VeAtqys0t427jwIBkv/+or/ssypfIk5R1fnz4aeIEv4udPw6VFoH6vL4gi+foBoD5aazXg==", -+>>>>>>> .their - "dev": true, - "requires": { - "follow-redirects": "0.0.7", -@@ -4112,7 +5526,11 @@ - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", -+<<<<<<< .our - "integrity": "sha1-qjiWs+abSH8X4x7SFD1pqOMMLYo=", -+======= -+ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", -+>>>>>>> .their - "dev": true - }, - "globby": { -@@ -4132,7 +5550,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -4158,7 +5580,11 @@ - "is-retry-allowed": "1.1.0", - "is-stream": "1.1.0", - "lowercase-keys": "1.0.1", -+<<<<<<< .our - "safe-buffer": "5.1.2", -+======= -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "timed-out": "4.0.1", - "unzip-response": "2.0.1", - "url-parse-lax": "1.0.0" -@@ -4173,14 +5599,22 @@ - "gunzip-maybe": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/gunzip-maybe/-/gunzip-maybe-1.4.1.tgz", -+<<<<<<< .our - "integrity": "sha1-Occu2J0bSbpwjhh3ZQBIiQKlICc=", -+======= -+ "integrity": "sha512-qtutIKMthNJJgeHQS7kZ9FqDq59/Wn0G2HYCRNjpup7yKfVI6/eqwpmroyZGFoCYaG+sW6psNVb4zoLADHpp2g==", -+>>>>>>> .their - "dev": true, - "requires": { - "browserify-zlib": "0.1.4", - "is-deflate": "1.0.0", - "is-gzip": "1.0.0", - "peek-stream": "1.1.3", -+<<<<<<< .our - "pumpify": "1.5.0", -+======= -+ "pumpify": "1.4.0", -+>>>>>>> .their - "through2": "2.0.3" - } - }, -@@ -4270,6 +5704,7 @@ - "dev": true - }, - "hash-base": { -+<<<<<<< .our - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", -@@ -4277,22 +5712,42 @@ - "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.2" -+======= -+ "version": "2.0.2", -+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", -+ "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", -+ "dev": true, -+ "requires": { -+ "inherits": "2.0.3" -+>>>>>>> .their - } - }, - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", -+<<<<<<< .our - "integrity": "sha1-NA3tvmKQGHFRweodd3o0SJNd+EY=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "minimalistic-assert": "1.0.1" -+======= -+ "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", -+ "dev": true, -+ "requires": { -+ "inherits": "2.0.3", -+ "minimalistic-assert": "1.0.0" -+>>>>>>> .their - } - }, - "hawk": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", -+<<<<<<< .our - "integrity": "sha1-r02RTrBl+bXOTZ0RwcshJu7MMDg=", -+======= -+ "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "boom": "4.3.1", -@@ -4308,7 +5763,11 @@ - "dev": true, - "requires": { - "hash.js": "1.1.3", -+<<<<<<< .our - "minimalistic-assert": "1.0.1", -+======= -+ "minimalistic-assert": "1.0.0", -+>>>>>>> .their - "minimalistic-crypto-utils": "1.0.1" - } - }, -@@ -4318,18 +5777,34 @@ - "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", - "dev": true - }, -+<<<<<<< .our -+======= -+ "home-or-tmp": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", -+ "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", -+ "dev": true, -+ "requires": { -+ "os-homedir": "1.0.2", -+ "os-tmpdir": "1.0.2" -+ } -+ }, -+>>>>>>> .their - "hosted-git-info": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", - "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==", - "dev": true - }, -+<<<<<<< .our - "html-entities": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", - "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", - "dev": true - }, -+======= -+>>>>>>> .their - "htmlescape": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", -@@ -4343,7 +5818,11 @@ - "dev": true, - "requires": { - "domelementtype": "1.3.0", -+<<<<<<< .our - "domhandler": "2.4.2", -+======= -+ "domhandler": "2.4.1", -+>>>>>>> .their - "domutils": "1.5.1", - "entities": "1.1.1", - "inherits": "2.0.3", -@@ -4366,7 +5845,11 @@ - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", -+======= -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } -@@ -4377,11 +5860,16 @@ - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } - }, -+<<<<<<< .our - "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", -@@ -4394,6 +5882,8 @@ - "statuses": "1.5.0" - } - }, -+======= -+>>>>>>> .their - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", -@@ -4425,7 +5915,11 @@ - "husky": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz", -+<<<<<<< .our - "integrity": "sha1-xp7XTi0neXaaF7qDmbVM4LY8EsM=", -+======= -+ "integrity": "sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA==", -+>>>>>>> .their - "dev": true, - "requires": { - "is-ci": "1.1.0", -@@ -4441,12 +5935,15 @@ - } - } - }, -+<<<<<<< .our - "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", - "dev": true - }, -+======= -+>>>>>>> .their - "ieee754": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.11.tgz", -@@ -4454,9 +5951,15 @@ - "dev": true - }, - "ignore": { -+<<<<<<< .our - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz", - "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==", -+======= -+ "version": "3.3.7", -+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", -+ "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", -+>>>>>>> .their - "dev": true - }, - "import-lazy": { -@@ -4526,7 +6029,11 @@ - "cli-cursor": "1.0.2", - "cli-width": "2.2.0", - "figures": "1.7.0", -+<<<<<<< .our - "lodash": "4.17.10", -+======= -+ "lodash": "4.17.5", -+>>>>>>> .their - "readline2": "1.0.1", - "run-async": "0.1.0", - "rx-lite": "3.1.2", -@@ -4536,9 +6043,15 @@ - } - }, - "insert-module-globals": { -+<<<<<<< .our - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.6.tgz", - "integrity": "sha512-R3sidKJr3SsggqQQ5cEwQb3pWG8RNx0UnpyeiOSR6jorRIeAOzH2gkTWnNdMnyRiVbjrG047K7UCtlMkQ1Mo9w==", -+======= -+ "version": "7.0.5", -+ "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.5.tgz", -+ "integrity": "sha512-wgRtrCpMm0ruH2hgLUIx+9YfJsgJQmU1KkPUzTuatW9dbH19yPRqAQhFX1HJU6zbmg2IMmt80BgSE5MWuksw3Q==", -+>>>>>>> .their - "dev": true, - "requires": { - "JSONStream": "1.3.2", -@@ -4546,7 +6059,10 @@ - "concat-stream": "1.6.2", - "is-buffer": "1.1.6", - "lexical-scope": "1.2.0", -+<<<<<<< .our - "path-is-absolute": "1.0.1", -+======= -+>>>>>>> .their - "process": "0.11.10", - "through2": "2.0.3", - "xtend": "4.0.1" -@@ -4580,7 +6096,11 @@ - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", -+======= -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } -@@ -4591,7 +6111,11 @@ - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -4608,12 +6132,15 @@ - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, -+<<<<<<< .our - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, -+======= -+>>>>>>> .their - "irregular-plurals": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.4.0.tgz", -@@ -4621,9 +6148,15 @@ - "dev": true - }, - "is-alphabetical": { -+<<<<<<< .our - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.2.tgz", - "integrity": "sha512-V0xN4BYezDHcBSKb1QHUFMlR4as/XEuCZBzMJUU4n7+Cbt33SmUnSol+pnXFvLxSHNq2CemUXNdaXV6Flg7+xg==", -+======= -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.1.tgz", -+ "integrity": "sha1-x3B5zJHU76x3W+EDS/LSQ/lebwg=", -+>>>>>>> .their - "dev": true - }, - "is-alphanumeric": { -@@ -4633,6 +6166,7 @@ - "dev": true - }, - "is-alphanumerical": { -+<<<<<<< .our - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.2.tgz", - "integrity": "sha512-pyfU/0kHdISIgslFfZN9nfY1Gk3MquQgUm1mJTjdkEPpkAKNWuBTSqFwewOpR7N351VkErCiyV71zX7mlQQqsg==", -@@ -4640,6 +6174,15 @@ - "requires": { - "is-alphabetical": "1.0.2", - "is-decimal": "1.0.2" -+======= -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.1.tgz", -+ "integrity": "sha1-37SqTRCF4zvbYcLe6cgOnGwZ9Ts=", -+ "dev": true, -+ "requires": { -+ "is-alphabetical": "1.0.1", -+ "is-decimal": "1.0.1" -+>>>>>>> .their - } - }, - "is-arrayish": { -@@ -4694,9 +6237,15 @@ - "dev": true - }, - "is-decimal": { -+<<<<<<< .our - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.2.tgz", - "integrity": "sha512-TRzl7mOCchnhchN+f3ICUCzYvL9ul7R+TYOsZ8xia++knyZAJfv/uA1FvQXsAnYIl1T3B2X5E/J7Wb1QXiIBXg==", -+======= -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.1.tgz", -+ "integrity": "sha1-9ftqlJlq2ejjdh+/vQkfH8qMToI=", -+>>>>>>> .their - "dev": true - }, - "is-deflate": { -@@ -4778,9 +6327,15 @@ - "dev": true - }, - "is-hexadecimal": { -+<<<<<<< .our - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.2.tgz", - "integrity": "sha512-but/G3sapV3MNyqiDBLrOi4x8uCIw0RY3o/Vb5GT0sMFHrVV7731wFSVy41T5FO1og7G0gXLJh0MkgPRouko/A==", -+======= -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.1.tgz", -+ "integrity": "sha1-bghLvJIGH7sJcexYts5tQE4k2mk=", -+>>>>>>> .their - "dev": true - }, - "is-hidden": { -@@ -4960,6 +6515,7 @@ - "dev": true - }, - "is-whitespace-character": { -+<<<<<<< .our - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.2.tgz", - "integrity": "sha512-SzM+T5GKUCtLhlHFKt2SDAX2RFzfS6joT91F2/WSi9LxgFdsnhfPK/UIA+JhRR2xuyLdrCys2PiFDrtn1fU5hQ==", -@@ -4975,6 +6531,17 @@ - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", -+======= -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.1.tgz", -+ "integrity": "sha1-muAXbzKCtlRXoZks2whPil+DPjs=", -+ "dev": true -+ }, -+ "is-word-character": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.1.tgz", -+ "integrity": "sha1-WgP6HqkazopusMfNdw64bWXIvvs=", -+>>>>>>> .their - "dev": true - }, - "isarray": { -@@ -5086,7 +6653,11 @@ - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", -+<<<<<<< .our - "integrity": "sha1-RJnt3NERDgshi6zy+n9/WfVcqAQ=", -+======= -+ "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", -+>>>>>>> .their - "dev": true - } - } -@@ -5277,12 +6848,15 @@ - "invert-kv": "1.0.0" - } - }, -+<<<<<<< .our - "leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", - "dev": true - }, -+======= -+>>>>>>> .their - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", -@@ -5311,12 +6885,15 @@ - "uc.micro": "1.0.5" - } - }, -+<<<<<<< .our - "lint": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/lint/-/lint-1.1.2.tgz", - "integrity": "sha1-Ne0GTzIlR8MxNY2JmGhmSWi6Nx8=", - "dev": true - }, -+======= -+>>>>>>> .their - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", -@@ -5331,6 +6908,7 @@ - } - }, - "load-plugin": { -+<<<<<<< .our - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-2.2.2.tgz", - "integrity": "sha512-FYzamtURIJefQykZGtiClYuZkJBUKzmx8Tc74y8JGAulDzbzVm/C+w/MbAljHRr+REL0cRzy3WgnHE+T8gce5g==", -@@ -5338,6 +6916,15 @@ - "requires": { - "npm-prefix": "1.2.0", - "resolve-from": "4.0.0" -+======= -+ "version": "2.2.1", -+ "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-2.2.1.tgz", -+ "integrity": "sha512-raqInsJNdPGpzZyb+FjjJYmXsjIm8fIiOjOmqmUTGPyCXDMeEK3p4x4Xm1ZCNp43UmfDTWvo7pZkB2fKbD5AAA==", -+ "dev": true, -+ "requires": { -+ "npm-prefix": "1.2.0", -+ "resolve-from": "2.0.0" -+>>>>>>> .their - } - }, - "locate-path": { -@@ -5359,9 +6946,15 @@ - } - }, - "lodash": { -+<<<<<<< .our - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", -+======= -+ "version": "4.17.5", -+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", -+ "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", -+>>>>>>> .their - "dev": true - }, - "lodash._reinterpolate": { -@@ -5541,9 +7134,15 @@ - "dev": true - }, - "lru-cache": { -+<<<<<<< .our - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", -+======= -+ "version": "4.1.2", -+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.2.tgz", -+ "integrity": "sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "pseudomap": "1.0.2", -@@ -5559,9 +7158,15 @@ - } - }, - "make-dir": { -+<<<<<<< .our - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", -+======= -+ "version": "1.2.0", -+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz", -+ "integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==", -+>>>>>>> .their - "dev": true, - "requires": { - "pify": "3.0.0" -@@ -5582,9 +7187,15 @@ - "dev": true - }, - "markdown-escapes": { -+<<<<<<< .our - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.2.tgz", - "integrity": "sha512-lbRZ2mE3Q9RtLjxZBZ9+IMl68DKIXaVAhwvwn9pmjnPLS0h/6kyBMgNhqi1xFJ/2yv6cSyv0jbiZavZv93JkkA==", -+======= -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.1.tgz", -+ "integrity": "sha1-GZTfLTr0gR3lmmcUk0wrIpJzRRg=", -+>>>>>>> .their - "dev": true - }, - "markdown-extensions": { -@@ -5616,9 +7227,15 @@ - } - }, - "markdown-table": { -+<<<<<<< .our - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.2.tgz", - "integrity": "sha512-NcWuJFHDA8V3wkDgR/j4+gZx+YQwstPgfQDV8ndUeWWzta3dnDTBxpVzqS9lkmJAuV5YX35lmyojl6HO5JXAgw==", -+======= -+ "version": "1.1.1", -+ "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.1.tgz", -+ "integrity": "sha1-Sz3ToTPRUYuO8NvHCb8qG0gkvIw=", -+>>>>>>> .their - "dev": true - }, - "marky-markdown-lite": { -@@ -5628,7 +7245,11 @@ - "dev": true, - "requires": { - "cheerio": "0.20.0", -+<<<<<<< .our - "conventional-changelog-cli": "1.3.22", -+======= -+ "conventional-changelog-cli": "1.3.21", -+>>>>>>> .their - "is-file": "1.0.0", - "markdown-it": "6.1.1", - "markdown-it-named-headers": "0.0.4" -@@ -5645,7 +7266,11 @@ - "entities": "1.1.1", - "htmlparser2": "3.8.3", - "jsdom": "7.2.2", -+<<<<<<< .our - "lodash": "4.17.10" -+======= -+ "lodash": "4.17.5" -+>>>>>>> .their - } - }, - "domhandler": { -@@ -5683,18 +7308,25 @@ - "matcher-collection": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-1.0.5.tgz", -+<<<<<<< .our - "integrity": "sha1-LuCVQ4Nyy4iE8FgjQTjAXGROwzk=", -+======= -+ "integrity": "sha512-nUCmzKipcJEwYsBVAFh5P+d7JBuhJaW1xs85Hara9xuMLqtCVUrW6DSC0JVIkluxEH2W45nPBM/wjHtBXa/tYA==", -+>>>>>>> .their - "dev": true, - "requires": { - "minimatch": "3.0.4" - } - }, -+<<<<<<< .our - "math-random": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", - "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", - "dev": true - }, -+======= -+>>>>>>> .their - "md5.js": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", -@@ -5703,6 +7335,21 @@ - "requires": { - "hash-base": "3.0.4", - "inherits": "2.0.3" -+<<<<<<< .our -+======= -+ }, -+ "dependencies": { -+ "hash-base": { -+ "version": "3.0.4", -+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", -+ "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", -+ "dev": true, -+ "requires": { -+ "inherits": "2.0.3", -+ "safe-buffer": "5.1.1" -+ } -+ } -+>>>>>>> .their - } - }, - "mdast-comment-marker": { -@@ -5717,8 +7364,13 @@ - "integrity": "sha1-zbX4TitqLTEU3zO9BdnLMuPECDo=", - "dev": true, - "requires": { -+<<<<<<< .our - "unist-util-modify-children": "1.1.2", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-modify-children": "1.1.1", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "mdast-util-heading-style": { -@@ -5740,9 +7392,15 @@ - "dev": true - }, - "meow": { -+<<<<<<< .our - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", - "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", -+======= -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.0.tgz", -+ "integrity": "sha512-Me/kel335m6vMKmEmA6c87Z6DUFW3JqkINRnxkbC+A/PUm0D5Fl2dEBQrPKnqCL9Te/CIa1MUt/0InMJhuC/sw==", -+>>>>>>> .their - "dev": true, - "requires": { - "camelcase-keys": "4.2.0", -@@ -5831,6 +7489,7 @@ - } - } - }, -+<<<<<<< .our - "micro": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/micro/-/micro-9.3.1.tgz", -@@ -5890,6 +7549,8 @@ - "compression": "1.7.3" - } - }, -+======= -+>>>>>>> .their - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", -@@ -5914,7 +7575,11 @@ - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", -+<<<<<<< .our - "integrity": "sha1-8IA1HIZbDcViqEYpZtqlNUPHik0=", -+======= -+ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", -+>>>>>>> .their - "dev": true, - "requires": { - "bn.js": "4.11.8", -@@ -5949,9 +7614,15 @@ - "dev": true - }, - "minimalistic-assert": { -+<<<<<<< .our - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", -+======= -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", -+ "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=", -+>>>>>>> .their - "dev": true - }, - "minimalistic-crypto-utils": { -@@ -5963,7 +7634,11 @@ - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", -+<<<<<<< .our - "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", -+======= -+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", -+>>>>>>> .their - "dev": true, - "requires": { - "brace-expansion": "1.1.11" -@@ -5986,12 +7661,21 @@ - } - }, - "minipass": { -+<<<<<<< .our - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.0.tgz", - "integrity": "sha512-jWC2Eg+Np4bxah7llu1IrUNSJQxtLz/J+pOjTM0nFpJXGAaV18XBWhUn031Q1tAA/TJtA1jgwnOe9S2PQa4Lbg==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2", -+======= -+ "version": "2.2.4", -+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz", -+ "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==", -+ "dev": true, -+ "requires": { -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "yallist": "3.0.2" - } - }, -@@ -6001,7 +7685,11 @@ - "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", - "dev": true, - "requires": { -+<<<<<<< .our - "minipass": "2.3.0" -+======= -+ "minipass": "2.2.4" -+>>>>>>> .their - } - }, - "mkdirp": { -@@ -6060,7 +7748,11 @@ - "inherits": "2.0.3", - "parents": "1.0.1", - "readable-stream": "2.3.6", -+<<<<<<< .our - "resolve": "1.7.1", -+======= -+ "resolve": "1.6.0", -+>>>>>>> .their - "stream-combiner2": "1.1.1", - "subarg": "1.0.0", - "through2": "2.0.3", -@@ -6083,7 +7775,11 @@ - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", -+======= -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } -@@ -6094,17 +7790,24 @@ - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } - }, -+<<<<<<< .our - "mri": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.0.tgz", - "integrity": "sha1-XAo/KcjM/7ux7JQdzsCdcfoy82o=", - "dev": true - }, -+======= -+>>>>>>> .their - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", -@@ -6130,12 +7833,15 @@ - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, -+<<<<<<< .our - "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", - "dev": true - }, -+======= -+>>>>>>> .their - "netrc": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/netrc/-/netrc-0.1.4.tgz", -@@ -6157,6 +7863,7 @@ - "minimatch": "3.0.4" - } - }, -+<<<<<<< .our - "node-fetch": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", -@@ -6169,6 +7876,8 @@ - "integrity": "sha512-rEwE51JWn0yN3Wl5BXeGn5d52OGbSXzWiiXRjAQeuyvcGKyvuSILW2rb3G7Xh+nexzLwhTpek6Ehxd6IjvHePg==", - "dev": true - }, -+======= -+>>>>>>> .their - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", -@@ -6181,7 +7890,11 @@ - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", -+<<<<<<< .our - "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=", -+======= -+ "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", -+>>>>>>> .their - "dev": true, - "requires": { - "hosted-git-info": "2.6.0", -@@ -6205,7 +7918,11 @@ - "integrity": "sha1-5hlFX3B0ulTMZtbQ033Z8b5ry8A=", - "dev": true, - "requires": { -+<<<<<<< .our - "rc": "1.2.7", -+======= -+ "rc": "1.2.6", -+>>>>>>> .their - "shellsubstitute": "1.2.0", - "untildify": "2.1.0" - } -@@ -6304,6 +8021,7 @@ - "is-extendable": "0.1.1" - } - }, -+<<<<<<< .our - "octicons": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/octicons/-/octicons-7.3.0.tgz", -@@ -6328,6 +8046,8 @@ - "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", - "dev": true - }, -+======= -+>>>>>>> .their - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", -@@ -6343,6 +8063,7 @@ - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, -+<<<<<<< .our - "openssl-self-signed-certificate": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/openssl-self-signed-certificate/-/openssl-self-signed-certificate-1.1.6.tgz", -@@ -6358,6 +8079,8 @@ - "is-wsl": "1.1.0" - } - }, -+======= -+>>>>>>> .their - "optimist": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", -@@ -6494,13 +8217,20 @@ - } - }, - "parse-asn1": { -+<<<<<<< .our - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", - "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", -+======= -+ "version": "5.1.0", -+ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", -+ "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", -+>>>>>>> .their - "dev": true, - "requires": { - "asn1.js": "4.10.1", - "browserify-aes": "1.2.0", -+<<<<<<< .our - "create-hash": "1.2.0", - "evp_bytestokey": "1.0.3", - "pbkdf2": "3.0.16" -@@ -6518,6 +8248,25 @@ - "is-alphanumerical": "1.0.2", - "is-decimal": "1.0.2", - "is-hexadecimal": "1.0.2" -+======= -+ "create-hash": "1.1.3", -+ "evp_bytestokey": "1.0.3", -+ "pbkdf2": "3.0.14" -+ } -+ }, -+ "parse-entities": { -+ "version": "1.1.1", -+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.1.1.tgz", -+ "integrity": "sha1-gRLYhHExnyerrk1klksSL+ThuJA=", -+ "dev": true, -+ "requires": { -+ "character-entities": "1.2.1", -+ "character-entities-legacy": "1.1.1", -+ "character-reference-invalid": "1.1.1", -+ "is-alphanumerical": "1.0.1", -+ "is-decimal": "1.0.1", -+ "is-hexadecimal": "1.0.1" -+>>>>>>> .their - } - }, - "parse-github-repo-url": { -@@ -6644,6 +8393,7 @@ - } - }, - "pbkdf2": { -+<<<<<<< .our - "version": "3.0.16", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", - "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", -@@ -6653,6 +8403,17 @@ - "create-hmac": "1.1.7", - "ripemd160": "2.0.2", - "safe-buffer": "5.1.2", -+======= -+ "version": "3.0.14", -+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", -+ "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", -+ "dev": true, -+ "requires": { -+ "create-hash": "1.1.3", -+ "create-hmac": "1.1.6", -+ "ripemd160": "2.0.1", -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "sha.js": "2.4.11" - } - }, -@@ -6663,7 +8424,11 @@ - "dev": true, - "requires": { - "buffer-from": "1.0.0", -+<<<<<<< .our - "duplexify": "3.6.0", -+======= -+ "duplexify": "3.5.4", -+>>>>>>> .their - "through2": "2.0.3" - } - }, -@@ -6953,15 +8718,26 @@ - "dev": true - }, - "public-encrypt": { -+<<<<<<< .our - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", - "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", -+======= -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", -+ "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", -+>>>>>>> .their - "dev": true, - "requires": { - "bn.js": "4.11.8", - "browserify-rsa": "4.0.1", -+<<<<<<< .our - "create-hash": "1.2.0", - "parse-asn1": "5.1.1", -+======= -+ "create-hash": "1.1.3", -+ "parse-asn1": "5.1.0", -+>>>>>>> .their - "randombytes": "2.0.6" - } - }, -@@ -6976,12 +8752,21 @@ - } - }, - "pumpify": { -+<<<<<<< .our - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.0.tgz", - "integrity": "sha512-UWi0klDoq8xtVzlMRgENV9F7iCTZExaJQSQL187UXsxpk9NnrKGqTqqUNYAKGOzucSOxs2+jUnRNI+rLviPhJg==", - "dev": true, - "requires": { - "duplexify": "3.6.0", -+======= -+ "version": "1.4.0", -+ "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.4.0.tgz", -+ "integrity": "sha512-2kmNR9ry+Pf45opRVirpNuIFotsxUGLaYqxIwuR77AYrYRMuFCz9eryHBS52L360O+NcR383CL4QYlMKPq4zYA==", -+ "dev": true, -+ "requires": { -+ "duplexify": "3.5.4", -+>>>>>>> .their - "inherits": "2.0.3", - "pump": "2.0.1" - } -@@ -6999,9 +8784,15 @@ - "dev": true - }, - "qs": { -+<<<<<<< .our - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", -+======= -+ "version": "6.5.1", -+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", -+ "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", -+>>>>>>> .their - "dev": true - }, - "querystring": { -@@ -7023,6 +8814,7 @@ - "dev": true - }, - "randomatic": { -+<<<<<<< .our - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", - "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", -@@ -7040,10 +8832,49 @@ - "dev": true - }, - "kind-of": { -- "version": "6.0.2", -- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", -- "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", -- "dev": true -+ "version": "6.0.2", -+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", -+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", -+ "dev": true -+======= -+ "version": "1.1.7", -+ "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", -+ "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", -+ "dev": true, -+ "requires": { -+ "is-number": "3.0.0", -+ "kind-of": "4.0.0" -+ }, -+ "dependencies": { -+ "is-number": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", -+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", -+ "dev": true, -+ "requires": { -+ "kind-of": "3.2.2" -+ }, -+ "dependencies": { -+ "kind-of": { -+ "version": "3.2.2", -+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", -+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", -+ "dev": true, -+ "requires": { -+ "is-buffer": "1.1.6" -+ } -+ } -+ } -+ }, -+ "kind-of": { -+ "version": "4.0.0", -+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", -+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", -+ "dev": true, -+ "requires": { -+ "is-buffer": "1.1.6" -+ } -+>>>>>>> .their - } - } - }, -@@ -7053,7 +8884,11 @@ - "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", - "dev": true, - "requires": { -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - }, - "randomfill": { -@@ -7063,6 +8898,7 @@ - "dev": true, - "requires": { - "randombytes": "2.0.6", -+<<<<<<< .our - "safe-buffer": "5.1.2" - } - }, -@@ -7091,6 +8927,18 @@ - "dev": true, - "requires": { - "deep-extend": "0.5.1", -+======= -+ "safe-buffer": "5.1.1" -+ } -+ }, -+ "rc": { -+ "version": "1.2.6", -+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.6.tgz", -+ "integrity": "sha1-6xiYnG1PTxYsOZ953dKfODVWgJI=", -+ "dev": true, -+ "requires": { -+ "deep-extend": "0.4.2", -+>>>>>>> .their - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" -@@ -7121,7 +8969,11 @@ - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", -+======= -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } -@@ -7132,7 +8984,11 @@ - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -7198,7 +9054,11 @@ - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", -+======= -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } -@@ -7209,7 +9069,11 @@ - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -7231,7 +9095,11 @@ - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { -+<<<<<<< .our - "resolve": "1.7.1" -+======= -+ "resolve": "1.6.0" -+>>>>>>> .their - } - }, - "redent": { -@@ -7247,7 +9115,11 @@ - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", -+<<<<<<< .our - "integrity": "sha1-db3FiioUls7EihKDW8VMjVYjNt0=", -+======= -+ "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "is-equal-shallow": "0.1.3" -@@ -7259,8 +9131,13 @@ - "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", - "dev": true, - "requires": { -+<<<<<<< .our - "rc": "1.2.7", - "safe-buffer": "5.1.2" -+======= -+ "rc": "1.2.6", -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - }, - "registry-url": { -@@ -7269,7 +9146,11 @@ - "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", - "dev": true, - "requires": { -+<<<<<<< .our - "rc": "1.2.7" -+======= -+ "rc": "1.2.6" -+>>>>>>> .their - } - }, - "remark": { -@@ -7280,7 +9161,11 @@ - "requires": { - "remark-parse": "4.0.0", - "remark-stringify": "4.0.0", -+<<<<<<< .our - "unified": "6.2.0" -+======= -+ "unified": "6.1.6" -+>>>>>>> .their - } - }, - "remark-cli": { -@@ -7312,9 +9197,15 @@ - "mdast-util-to-string": "1.0.4", - "plur": "2.1.2", - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-code-block-style": { -@@ -7324,9 +9215,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-definition-case": { -@@ -7336,9 +9233,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-definition-spacing": { -@@ -7348,9 +9251,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-emphasis-marker": { -@@ -7360,9 +9269,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-fenced-code-flag": { -@@ -7372,9 +9287,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-fenced-code-marker": { -@@ -7384,9 +9305,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-file-extension": { -@@ -7405,9 +9332,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-hard-break-spaces": { -@@ -7417,9 +9350,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-heading-increment": { -@@ -7429,8 +9368,13 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-heading-style": { -@@ -7441,8 +9385,13 @@ - "requires": { - "mdast-util-heading-style": "1.0.3", - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-link-title-style": { -@@ -7452,10 +9401,17 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1", - "vfile-location": "2.0.3" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0", -+ "vfile-location": "2.0.2" -+>>>>>>> .their - } - }, - "remark-lint-list-item-content-indent": { -@@ -7466,9 +9422,15 @@ - "requires": { - "plur": "2.1.2", - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-list-item-indent": { -@@ -7479,9 +9441,15 @@ - "requires": { - "plur": "2.1.2", - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-list-item-spacing": { -@@ -7491,9 +9459,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-maximum-heading-length": { -@@ -7504,8 +9478,13 @@ - "requires": { - "mdast-util-to-string": "1.0.4", - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-maximum-line-length": { -@@ -7515,9 +9494,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-no-auto-link-without-protocol": { -@@ -7528,9 +9513,15 @@ - "requires": { - "mdast-util-to-string": "1.0.4", - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-no-blockquote-without-marker": { -@@ -7540,10 +9531,17 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1", - "vfile-location": "2.0.3" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0", -+ "vfile-location": "2.0.2" -+>>>>>>> .their - } - }, - "remark-lint-no-consecutive-blank-lines": { -@@ -7554,9 +9552,15 @@ - "requires": { - "plur": "2.1.2", - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-no-duplicate-headings": { -@@ -7567,9 +9571,15 @@ - "requires": { - "mdast-util-to-string": "1.0.4", - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-no-emphasis-as-heading": { -@@ -7579,8 +9589,13 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-no-file-name-articles": { -@@ -7636,8 +9651,13 @@ - "requires": { - "mdast-util-to-string": "1.0.4", - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-no-inline-padding": { -@@ -7648,8 +9668,13 @@ - "requires": { - "mdast-util-to-string": "1.0.4", - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-no-literal-urls": { -@@ -7660,9 +9685,15 @@ - "requires": { - "mdast-util-to-string": "1.0.4", - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-no-multiple-toplevel-headings": { -@@ -7672,9 +9703,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-no-shell-dollars": { -@@ -7684,8 +9721,13 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-no-shortcut-reference-image": { -@@ -7695,8 +9737,13 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-no-shortcut-reference-link": { -@@ -7706,8 +9753,13 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-no-table-indentation": { -@@ -7717,9 +9769,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-ordered-list-marker-style": { -@@ -7729,9 +9787,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-ordered-list-marker-value": { -@@ -7741,9 +9805,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-rule-style": { -@@ -7753,9 +9823,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-strong-marker": { -@@ -7765,9 +9841,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-table-cell-padding": { -@@ -7777,9 +9859,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-table-pipe-alignment": { -@@ -7789,9 +9877,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-table-pipes": { -@@ -7801,9 +9895,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-lint-unordered-list-marker-style": { -@@ -7813,9 +9913,15 @@ - "dev": true, - "requires": { - "unified-lint-rule": "1.0.2", -+<<<<<<< .our - "unist-util-generated": "1.1.2", - "unist-util-position": "3.0.1", - "unist-util-visit": "1.3.1" -+======= -+ "unist-util-generated": "1.1.1", -+ "unist-util-position": "3.0.0", -+ "unist-util-visit": "1.3.0" -+>>>>>>> .their - } - }, - "remark-message-control": { -@@ -7825,7 +9931,11 @@ - "dev": true, - "requires": { - "mdast-comment-marker": "1.0.2", -+<<<<<<< .our - "unified-message-control": "1.0.4", -+======= -+ "unified-message-control": "1.0.3", -+>>>>>>> .their - "xtend": "4.0.1" - } - }, -@@ -7835,6 +9945,7 @@ - "integrity": "sha512-XZgICP2gJ1MHU7+vQaRM+VA9HEL3X253uwUM/BGgx3iv6TH2B3bF3B8q00DKcyP9YrJV+/7WOWEWBFF/u8cIsw==", - "dev": true, - "requires": { -+<<<<<<< .our - "collapse-white-space": "1.0.4", - "is-alphabetical": "1.0.2", - "is-decimal": "1.0.2", -@@ -7849,6 +9960,22 @@ - "unherit": "1.1.1", - "unist-util-remove-position": "1.1.2", - "vfile-location": "2.0.3", -+======= -+ "collapse-white-space": "1.0.3", -+ "is-alphabetical": "1.0.1", -+ "is-decimal": "1.0.1", -+ "is-whitespace-character": "1.0.1", -+ "is-word-character": "1.0.1", -+ "markdown-escapes": "1.0.1", -+ "parse-entities": "1.1.1", -+ "repeat-string": "1.6.1", -+ "state-toggle": "1.0.0", -+ "trim": "0.0.1", -+ "trim-trailing-lines": "1.1.0", -+ "unherit": "1.1.0", -+ "unist-util-remove-position": "1.1.1", -+ "vfile-location": "2.0.2", -+>>>>>>> .their - "xtend": "4.0.1" - } - }, -@@ -7911,6 +10038,7 @@ - "integrity": "sha512-xLuyKTnuQer3ke9hkU38SUYLiTmS078QOnoFavztmbt/pAJtNSkNtFgR0U//uCcmG0qnyxao+PDuatQav46F1w==", - "dev": true, - "requires": { -+<<<<<<< .our - "ccount": "1.0.3", - "is-alphanumeric": "1.0.0", - "is-decimal": "1.0.2", -@@ -7924,6 +10052,21 @@ - "state-toggle": "1.0.1", - "stringify-entities": "1.3.2", - "unherit": "1.1.1", -+======= -+ "ccount": "1.0.2", -+ "is-alphanumeric": "1.0.0", -+ "is-decimal": "1.0.1", -+ "is-whitespace-character": "1.0.1", -+ "longest-streak": "2.0.2", -+ "markdown-escapes": "1.0.1", -+ "markdown-table": "1.1.1", -+ "mdast-util-compact": "1.0.1", -+ "parse-entities": "1.1.1", -+ "repeat-string": "1.6.1", -+ "state-toggle": "1.0.0", -+ "stringify-entities": "1.3.1", -+ "unherit": "1.1.0", -+>>>>>>> .their - "xtend": "4.0.1" - } - }, -@@ -7967,7 +10110,11 @@ - "dev": true, - "requires": { - "aws-sign2": "0.7.0", -+<<<<<<< .our - "aws4": "1.7.0", -+======= -+ "aws4": "1.6.0", -+>>>>>>> .their - "caseless": "0.12.0", - "combined-stream": "1.0.6", - "extend": "3.0.1", -@@ -7982,9 +10129,15 @@ - "mime-types": "2.1.18", - "oauth-sign": "0.8.2", - "performance-now": "2.1.0", -+<<<<<<< .our - "qs": "6.5.2", - "safe-buffer": "5.1.2", - "stringstream": "0.0.6", -+======= -+ "qs": "6.5.1", -+ "safe-buffer": "5.1.1", -+ "stringstream": "0.0.5", -+>>>>>>> .their - "tough-cookie": "2.3.4", - "tunnel-agent": "0.6.0", - "uuid": "3.2.1" -@@ -8021,18 +10174,30 @@ - } - }, - "resolve": { -+<<<<<<< .our - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", - "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", -+======= -+ "version": "1.6.0", -+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.6.0.tgz", -+ "integrity": "sha512-mw7JQNu5ExIkcw4LPih0owX/TZXjD/ZUF/ZQ/pDnkw3ZKhDcZZw5klmBlj6gVMwjQ3Pz5Jgu7F3d0jcDVuEWdw==", -+>>>>>>> .their - "dev": true, - "requires": { - "path-parse": "1.0.5" - } - }, - "resolve-from": { -+<<<<<<< .our - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", -+======= -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", -+ "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", -+>>>>>>> .their - "dev": true - }, - "restore-cursor": { -@@ -8064,7 +10229,11 @@ - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", -+<<<<<<< .our - "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=", -+======= -+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", -+>>>>>>> .their - "dev": true, - "requires": { - "glob": "7.1.2" -@@ -8073,7 +10242,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -8087,12 +10260,21 @@ - } - }, - "ripemd160": { -+<<<<<<< .our - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "3.0.4", -+======= -+ "version": "2.0.1", -+ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", -+ "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", -+ "dev": true, -+ "requires": { -+ "hash-base": "2.0.2", -+>>>>>>> .their - "inherits": "2.0.3" - } - }, -@@ -8106,9 +10288,15 @@ - } - }, - "run-parallel": { -+<<<<<<< .our - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", -+======= -+ "version": "1.1.8", -+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.8.tgz", -+ "integrity": "sha512-e5t1NVhr5VWmD9V9U4KjjSGkf5w6CcTPgw11A3CfIvkkQxlAKzX3usPUp1NUQTmpOOjU+f9QRICU3tMbKwn9ZQ==", -+>>>>>>> .their - "dev": true - }, - "rx-lite": { -@@ -8118,15 +10306,25 @@ - "dev": true - }, - "safe-buffer": { -+<<<<<<< .our - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", -+======= -+ "version": "5.1.1", -+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", -+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", -+>>>>>>> .their - "dev": true - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", -+<<<<<<< .our - "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk=", -+======= -+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", -+>>>>>>> .their - "dev": true, - "optional": true - }, -@@ -8145,6 +10343,7 @@ - "semver": "5.5.0" - } - }, -+<<<<<<< .our - "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", -@@ -8294,6 +10493,8 @@ - } - } - }, -+======= -+>>>>>>> .their - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", -@@ -8306,12 +10507,15 @@ - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true - }, -+<<<<<<< .our - "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", - "dev": true - }, -+======= -+>>>>>>> .their - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", -@@ -8319,7 +10523,11 @@ - "dev": true, - "requires": { - "inherits": "2.0.3", -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - }, - "shasum": { -@@ -8373,7 +10581,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -8475,7 +10687,11 @@ - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", -+<<<<<<< .our - "integrity": "sha1-YFvZvjA6pZ+zX5Ip++oN3snqB9k=", -+======= -+ "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", -+>>>>>>> .their - "dev": true, - "requires": { - "through": "2.3.8" -@@ -8484,7 +10700,11 @@ - "split2": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", -+<<<<<<< .our - "integrity": "sha1-GGsldbz4PoW30YRldWI47k7kJJM=", -+======= -+ "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", -+>>>>>>> .their - "dev": true, - "requires": { - "through2": "2.0.3" -@@ -8513,6 +10733,7 @@ - } - }, - "standard": { -+<<<<<<< .our - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/standard/-/standard-10.0.3.tgz", - "integrity": "sha512-JURZ+85ExKLQULckDFijdX5WHzN6RC7fgiZNSV4jFQVo+3tPoQGHyBrGekye/yf0aOfb4210EM5qPNlc2cRh4w==", -@@ -8539,6 +10760,34 @@ - "get-stdin": "5.0.1", - "minimist": "1.2.0", - "pkg-conf": "2.1.0" -+======= -+ "version": "8.6.0", -+ "resolved": "https://registry.npmjs.org/standard/-/standard-8.6.0.tgz", -+ "integrity": "sha1-Y1Eyvnv7VnwpIQBfMPnjUOR1Kq0=", -+ "dev": true, -+ "requires": { -+ "eslint": "3.10.2", -+ "eslint-config-standard": "6.2.1", -+ "eslint-config-standard-jsx": "3.2.0", -+ "eslint-plugin-promise": "3.4.2", -+ "eslint-plugin-react": "6.7.1", -+ "eslint-plugin-standard": "2.0.1", -+ "standard-engine": "5.2.0" -+ } -+ }, -+ "standard-engine": { -+ "version": "5.2.0", -+ "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-5.2.0.tgz", -+ "integrity": "sha1-QAZgrlrM6K/U22D/IhSpGQrXkKM=", -+ "dev": true, -+ "requires": { -+ "deglob": "2.1.0", -+ "find-root": "1.1.0", -+ "get-stdin": "5.0.1", -+ "home-or-tmp": "2.0.0", -+ "minimist": "1.2.0", -+ "pkg-config": "1.1.1" -+>>>>>>> .their - }, - "dependencies": { - "get-stdin": { -@@ -8552,7 +10801,11 @@ - "standard-markdown": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/standard-markdown/-/standard-markdown-4.0.2.tgz", -+<<<<<<< .our - "integrity": "sha1-NaC1bLtX5JzuLXQ9ocmERMNK1Lg=", -+======= -+ "integrity": "sha512-h+WTmoGN0qmse8I1VX8VD6V5JeVLXZOPQltvxQP9FfSpSl6RmKYMLTUQ2j/QhdmsdxQKDqulZF/Bf8oEnttIQA==", -+>>>>>>> .their - "dev": true, - "requires": { - "async": "2.6.0", -@@ -8579,6 +10832,7 @@ - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "dev": true, - "requires": { -+<<<<<<< .our - "lodash": "4.17.10" - } - }, -@@ -8586,11 +10840,24 @@ - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", -+======= -+ "lodash": "4.17.5" -+ } -+ }, -+ "chalk": { -+ "version": "2.3.2", -+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", -+ "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", -+<<<<<<< .our - "supports-color": "5.4.0" -+======= -+ "supports-color": "5.3.0" -+>>>>>>> .their - } - }, - "cli-cursor": { -@@ -8603,15 +10870,165 @@ - } - }, - "cli-spinners": { -+<<<<<<< .our - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.3.1.tgz", - "integrity": "sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg==", -+======= -+ "version": "1.3.0", -+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.3.0.tgz", -+ "integrity": "sha512-ahr3q/EW26uLN3vqBaDQS4g1rUwKMbVSTRlyfyoY06VwwSJmMYRxhT3FTAiTz9Yam6OOb1e0ldwvbsnuThvuzA==", -+ "dev": true -+ }, -+ "doctrine": { -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", -+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", -+ "dev": true, -+ "requires": { -+ "esutils": "2.0.2" -+ } -+ }, -+ "eslint": { -+ "version": "3.19.0", -+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", -+ "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", -+ "dev": true, -+ "requires": { -+ "babel-code-frame": "6.26.0", -+ "chalk": "1.1.3", -+ "concat-stream": "1.5.2", -+ "debug": "2.6.9", -+ "doctrine": "2.1.0", -+ "escope": "3.6.0", -+ "espree": "3.5.4", -+ "esquery": "1.0.1", -+ "estraverse": "4.2.0", -+ "esutils": "2.0.2", -+ "file-entry-cache": "2.0.0", -+ "glob": "7.1.2", -+ "globals": "9.18.0", -+ "ignore": "3.3.7", -+ "imurmurhash": "0.1.4", -+ "inquirer": "0.12.0", -+ "is-my-json-valid": "2.17.2", -+ "is-resolvable": "1.1.0", -+ "js-yaml": "3.11.0", -+ "json-stable-stringify": "1.0.1", -+ "levn": "0.3.0", -+ "lodash": "4.17.5", -+ "mkdirp": "0.5.1", -+ "natural-compare": "1.4.0", -+ "optionator": "0.8.2", -+ "path-is-inside": "1.0.2", -+ "pluralize": "1.2.1", -+ "progress": "1.1.8", -+ "require-uncached": "1.0.3", -+ "shelljs": "0.7.8", -+ "strip-bom": "3.0.0", -+ "strip-json-comments": "2.0.1", -+ "table": "3.8.3", -+ "text-table": "0.2.0", -+ "user-home": "2.0.0" -+ }, -+ "dependencies": { -+ "ansi-styles": { -+ "version": "2.2.1", -+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", -+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", -+ "dev": true -+ }, -+ "chalk": { -+ "version": "1.1.3", -+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", -+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", -+ "dev": true, -+ "requires": { -+ "ansi-styles": "2.2.1", -+ "escape-string-regexp": "1.0.5", -+ "has-ansi": "2.0.0", -+ "strip-ansi": "3.0.1", -+ "supports-color": "2.0.0" -+ } -+ }, -+ "supports-color": { -+ "version": "2.0.0", -+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", -+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", -+ "dev": true -+ } -+ } -+ }, -+ "eslint-config-standard": { -+ "version": "10.2.1", -+ "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz", -+ "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=", -+ "dev": true -+ }, -+ "eslint-config-standard-jsx": { -+ "version": "4.0.2", -+ "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-4.0.2.tgz", -+ "integrity": "sha512-F8fRh2WFnTek7dZH9ZaE0PCBwdVGkwVWZmizla/DDNOmg7Tx6B/IlK5+oYpiX29jpu73LszeJj5i1axEZv6VMw==", -+ "dev": true -+ }, -+ "eslint-plugin-promise": { -+ "version": "3.5.0", -+ "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz", -+ "integrity": "sha1-ePu2/+BHIBYnVp6FpsU3OvKmj8o=", -+ "dev": true -+ }, -+ "eslint-plugin-react": { -+ "version": "6.10.3", -+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz", -+ "integrity": "sha1-xUNb6wZ3ThLH2y9qut3L+QDNP3g=", -+ "dev": true, -+ "requires": { -+ "array.prototype.find": "2.0.4", -+ "doctrine": "1.5.0", -+ "has": "1.0.1", -+ "jsx-ast-utils": "1.4.1", -+ "object.assign": "4.1.0" -+ }, -+ "dependencies": { -+ "doctrine": { -+ "version": "1.5.0", -+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", -+ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", -+ "dev": true, -+ "requires": { -+ "esutils": "2.0.2", -+ "isarray": "1.0.0" -+ } -+ } -+ } -+ }, -+ "eslint-plugin-standard": { -+ "version": "3.0.1", -+ "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz", -+ "integrity": "sha1-NNDJFbRe3G8BA5PH7vOCOwhWXPI=", -+ "dev": true -+ }, -+ "estraverse": { -+ "version": "4.2.0", -+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", -+ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", -+ "dev": true -+ }, -+ "get-stdin": { -+ "version": "5.0.1", -+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", -+ "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=", -+>>>>>>> .their - "dev": true - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -8641,13 +11058,35 @@ - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, -+<<<<<<< .our -+======= -+ "isarray": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", -+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", -+ "dev": true -+ }, -+ "json-stable-stringify": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", -+ "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", -+ "dev": true, -+ "requires": { -+ "jsonify": "0.0.0" -+ } -+ }, -+>>>>>>> .their - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { -+<<<<<<< .our - "chalk": "2.4.1" -+======= -+ "chalk": "2.3.2" -+>>>>>>> .their - } - }, - "onetime": { -@@ -8665,12 +11104,27 @@ - "integrity": "sha512-iMK1DOQxzzh2MBlVsU42G80mnrvUhqsMh74phHtDlrcTZPK0pH6o7l7DRshK+0YsxDyEuaOkziVdvM3T0QTzpw==", - "dev": true, - "requires": { -+<<<<<<< .our - "chalk": "2.4.1", - "cli-cursor": "2.1.0", - "cli-spinners": "1.3.1", - "log-symbols": "2.2.0" - } - }, -+======= -+ "chalk": "2.3.2", -+ "cli-cursor": "2.1.0", -+ "cli-spinners": "1.3.0", -+ "log-symbols": "2.2.0" -+ } -+ }, -+ "progress": { -+ "version": "1.1.8", -+ "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", -+ "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", -+ "dev": true -+ }, -+>>>>>>> .their - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", -@@ -8681,10 +11135,52 @@ - "signal-exit": "3.0.2" - } - }, -+<<<<<<< .our - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", -+======= -+ "standard": { -+ "version": "10.0.3", -+ "resolved": "https://registry.npmjs.org/standard/-/standard-10.0.3.tgz", -+ "integrity": "sha512-JURZ+85ExKLQULckDFijdX5WHzN6RC7fgiZNSV4jFQVo+3tPoQGHyBrGekye/yf0aOfb4210EM5qPNlc2cRh4w==", -+ "dev": true, -+ "requires": { -+ "eslint": "3.19.0", -+ "eslint-config-standard": "10.2.1", -+ "eslint-config-standard-jsx": "4.0.2", -+ "eslint-plugin-import": "2.2.0", -+ "eslint-plugin-node": "4.2.3", -+ "eslint-plugin-promise": "3.5.0", -+ "eslint-plugin-react": "6.10.3", -+ "eslint-plugin-standard": "3.0.1", -+ "standard-engine": "7.0.0" -+ } -+ }, -+ "standard-engine": { -+ "version": "7.0.0", -+ "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-7.0.0.tgz", -+ "integrity": "sha1-67d7nI/CyBZf+jU72Rug3/Qa9pA=", -+ "dev": true, -+ "requires": { -+ "deglob": "2.1.0", -+ "get-stdin": "5.0.1", -+ "minimist": "1.2.0", -+ "pkg-conf": "2.1.0" -+ } -+ }, -+ "strip-bom": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", -+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", -+ "dev": true -+ }, -+ "supports-color": { -+ "version": "5.3.0", -+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", -+ "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", -+>>>>>>> .their - "dev": true, - "requires": { - "has-flag": "3.0.0" -@@ -8693,6 +11189,7 @@ - } - }, - "state-toggle": { -+<<<<<<< .our - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.1.tgz", - "integrity": "sha512-Qe8QntFrrpWTnHwvwj2FZTgv+PKIsp0B9VxLzLLbSpPXWOgRgc5LVj/aTiSfK1RqIeF9jeC1UeOH8Q8y60A7og==", -@@ -8702,6 +11199,11 @@ - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", -+======= -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.0.tgz", -+ "integrity": "sha1-0g+aYWu08MO5i5GSLSW2QKorxCU=", -+>>>>>>> .their - "dev": true - }, - "stream-browserify": { -@@ -8730,7 +11232,11 @@ - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", -+======= -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } -@@ -8741,7 +11247,11 @@ - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -8772,7 +11282,11 @@ - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", -+======= -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } -@@ -8783,7 +11297,11 @@ - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -8795,9 +11313,15 @@ - "dev": true - }, - "stream-http": { -+<<<<<<< .our - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.2.tgz", - "integrity": "sha512-QllfrBhqF1DPcz46WxKTs6Mz1Bpc+8Qm6vbqOpVav5odAXwbyzwnEczoWqtxrsmlO+cJqtPrp/8gWKWjaKLLlA==", -+======= -+ "version": "2.8.1", -+ "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.1.tgz", -+ "integrity": "sha512-cQ0jo17BLca2r0GfRdZKYAGLU6JRoIWxqSOakUMuKOT6MOK7AAlE856L33QuDmAy/eeOrhLee3dZKX0Uadu93A==", -+>>>>>>> .their - "dev": true, - "requires": { - "builtin-status-codes": "3.0.0", -@@ -8823,7 +11347,11 @@ - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", -+======= -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } -@@ -8834,7 +11362,11 @@ - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -8871,7 +11403,11 @@ - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", -+======= -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } -@@ -8882,7 +11418,11 @@ - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -8911,6 +11451,7 @@ - "dev": true - }, - "stringify-entities": { -+<<<<<<< .our - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz", - "integrity": "sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==", -@@ -8926,6 +11467,23 @@ - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", - "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", -+======= -+ "version": "1.3.1", -+ "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.1.tgz", -+ "integrity": "sha1-sVDsLXKsTBtfMktR+2soyc3/BYw=", -+ "dev": true, -+ "requires": { -+ "character-entities-html4": "1.1.1", -+ "character-entities-legacy": "1.1.1", -+ "is-alphanumerical": "1.0.1", -+ "is-hexadecimal": "1.0.1" -+ } -+ }, -+ "stringstream": { -+ "version": "0.0.5", -+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", -+ "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", -+>>>>>>> .their - "dev": true - }, - "strip-ansi": { -@@ -9016,7 +11574,11 @@ - "ajv": "4.11.8", - "ajv-keywords": "1.5.1", - "chalk": "1.1.3", -+<<<<<<< .our - "lodash": "4.17.10", -+======= -+ "lodash": "4.17.5", -+>>>>>>> .their - "slice-ansi": "0.0.4", - "string-width": "2.1.1" - }, -@@ -9055,7 +11617,11 @@ - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", -+<<<<<<< .our - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", -+======= -+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", -+>>>>>>> .their - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", -@@ -9074,30 +11640,53 @@ - } - }, - "tar": { -+<<<<<<< .our - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.2.tgz", - "integrity": "sha512-BfkE9CciGGgDsATqkikUHrQrraBCO+ke/1f6SFAEMnxyyfN9lxC+nW1NFWMpqH865DhHIy9vQi682gk1X7friw==", -+======= -+ "version": "4.4.1", -+ "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.1.tgz", -+ "integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==", -+>>>>>>> .their - "dev": true, - "requires": { - "chownr": "1.0.1", - "fs-minipass": "1.2.5", -+<<<<<<< .our - "minipass": "2.3.0", - "minizlib": "1.1.0", - "mkdirp": "0.5.1", - "safe-buffer": "5.1.2", -+======= -+ "minipass": "2.2.4", -+ "minizlib": "1.1.0", -+ "mkdirp": "0.5.1", -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "yallist": "3.0.2" - } - }, - "tar-fs": { -+<<<<<<< .our - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.2.tgz", - "integrity": "sha512-LdknWjPEiZC1nOBwhv0JBzfJBGPJar08dZg2rwZe0ZTLQoRGEzgrl7vF3qUEkCHpI/wN9e7RyCuDhMsJUCLPPQ==", -+======= -+ "version": "1.16.0", -+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.0.tgz", -+ "integrity": "sha512-I9rb6v7mjWLtOfCau9eH5L7sLJyU2BnxtEZRQ5Mt+eRKmf1F0ohXmT/Jc3fr52kDvjJ/HV5MH3soQfPL5bQ0Yg==", -+>>>>>>> .their - "dev": true, - "requires": { - "chownr": "1.0.1", - "mkdirp": "0.5.1", - "pump": "1.0.3", -+<<<<<<< .our - "tar-stream": "1.6.0" -+======= -+ "tar-stream": "1.5.5" -+>>>>>>> .their - }, - "dependencies": { - "pump": { -@@ -9113,6 +11702,7 @@ - } - }, - "tar-stream": { -+<<<<<<< .our - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.0.tgz", - "integrity": "sha512-lh2iAPG/BHNmN6WB9Ybdynk9rEJ5GD/dy4zscHmVlwa1dq2tpE+BH78i5vjYwYVWEaOXGBjzxr89aVACF17Cpw==", -@@ -9124,6 +11714,16 @@ - "fs-constants": "1.0.0", - "readable-stream": "2.3.6", - "to-buffer": "1.1.1", -+======= -+ "version": "1.5.5", -+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz", -+ "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==", -+ "dev": true, -+ "requires": { -+ "bl": "1.2.2", -+ "end-of-stream": "1.4.1", -+ "readable-stream": "2.3.6", -+>>>>>>> .their - "xtend": "4.0.1" - }, - "dependencies": { -@@ -9143,7 +11743,11 @@ - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", -+======= -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } -@@ -9154,7 +11758,11 @@ - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -9207,7 +11815,11 @@ - "text-extensions": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.7.0.tgz", -+<<<<<<< .our - "integrity": "sha1-+qq6JiXtdG1WiiPk0KrNm/CKizk=", -+======= -+ "integrity": "sha512-AKXZeDq230UaSzaO5s3qQUZOaC7iKbzq0jOFL614R7d9R593HLqAOL0cYoqLdkNrjBSOdmoQI06yigq1TSBXAg==", -+>>>>>>> .their - "dev": true - }, - "text-table": { -@@ -9254,7 +11866,11 @@ - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", -+<<<<<<< .our - "safe-buffer": "5.1.2", -+======= -+ "safe-buffer": "5.1.1", -+>>>>>>> .their - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } -@@ -9265,7 +11881,11 @@ - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - } - } -@@ -9300,12 +11920,15 @@ - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, -+<<<<<<< .our - "to-buffer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", - "dev": true - }, -+======= -+>>>>>>> .their - "to-vfile": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/to-vfile/-/to-vfile-2.2.0.tgz", -@@ -9378,6 +12001,7 @@ - "dev": true - }, - "trim-trailing-lines": { -+<<<<<<< .our - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.1.tgz", - "integrity": "sha512-bWLv9BbWbbd7mlqqs2oQYnLD/U/ZqeJeJwbO0FG2zA1aTq+HTvxfHNKFa/HGCVyJpDiioUYaBhfiT6rgk+l4mg==", -@@ -9387,6 +12011,17 @@ - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.2.tgz", - "integrity": "sha512-FHkoUZvG6Egrv9XZAyYGKEyb1JMsFphgPjoczkZC2y6W93U1jswcVURB8MUvtsahEPEVACyxD47JAL63vF4JsQ==", -+======= -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.0.tgz", -+ "integrity": "sha1-eu+7eAjfnWafbaLkOMrIxGradoQ=", -+ "dev": true -+ }, -+ "trough": { -+ "version": "1.0.1", -+ "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.1.tgz", -+ "integrity": "sha1-qf2LA5Swro//guBjOgo2zK1bX4Y=", -+>>>>>>> .their - "dev": true - }, - "tslint": { -@@ -9396,20 +12031,34 @@ - "dev": true, - "requires": { - "babel-code-frame": "6.26.0", -+<<<<<<< .our - "colors": "1.2.5", -+======= -+ "colors": "1.2.1", -+>>>>>>> .their - "diff": "3.5.0", - "findup-sync": "0.3.0", - "glob": "7.1.2", - "optimist": "0.6.1", -+<<<<<<< .our - "resolve": "1.7.1", - "tsutils": "1.9.1", - "update-notifier": "2.5.0" -+======= -+ "resolve": "1.6.0", -+ "tsutils": "1.9.1", -+ "update-notifier": "2.4.0" -+>>>>>>> .their - }, - "dependencies": { - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -9456,7 +12105,11 @@ - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { -+<<<<<<< .our - "safe-buffer": "5.1.2" -+======= -+ "safe-buffer": "5.1.1" -+>>>>>>> .their - } - }, - "tweetnacl": { -@@ -9482,9 +12135,15 @@ - "dev": true - }, - "typescript": { -+<<<<<<< .our - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", - "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", -+======= -+ "version": "2.8.1", -+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.8.1.tgz", -+ "integrity": "sha512-Ao/f6d/4EPLq0YwzsQz8iXflezpTkQzqAyenTiw4kCUGr1uPiFLC3+fZ+gMZz6eeI/qdRUqvC+HxIJzUAzEFdg==", -+>>>>>>> .their - "dev": true - }, - "uc.micro": { -@@ -9534,9 +12193,15 @@ - "dev": true - }, - "unherit": { -+<<<<<<< .our - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.1.tgz", - "integrity": "sha512-+XZuV691Cn4zHsK0vkKYwBEwB74T3IZIcxrgn2E4rKwTfFyI1zCh7X7grwh9Re08fdPlarIdyWgI8aVB3F5A5g==", -+======= -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.0.tgz", -+ "integrity": "sha1-a5qu379z3xdWrZ4xbdmBiFhAzX0=", -+>>>>>>> .their - "dev": true, - "requires": { - "inherits": "2.0.3", -@@ -9544,6 +12209,7 @@ - } - }, - "unified": { -+<<<<<<< .our - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-6.2.0.tgz", - "integrity": "sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==", -@@ -9554,6 +12220,19 @@ - "is-plain-obj": "1.1.0", - "trough": "1.0.2", - "vfile": "2.3.0", -+======= -+ "version": "6.1.6", -+ "resolved": "https://registry.npmjs.org/unified/-/unified-6.1.6.tgz", -+ "integrity": "sha512-pW2f82bCIo2ifuIGYcV12fL96kMMYgw7JKVEgh7ODlrM9rj6vXSY3BV+H6lCcv1ksxynFf582hwWLnA1qRFy4w==", -+ "dev": true, -+ "requires": { -+ "bail": "1.0.2", -+ "extend": "3.0.1", -+ "is-plain-obj": "1.1.0", -+ "trough": "1.0.1", -+ "vfile": "2.3.0", -+ "x-is-function": "1.0.4", -+>>>>>>> .their - "x-is-string": "0.1.0" - } - }, -@@ -9564,7 +12243,11 @@ - "dev": true, - "requires": { - "camelcase": "4.1.0", -+<<<<<<< .our - "chalk": "2.4.1", -+======= -+ "chalk": "2.3.2", -+>>>>>>> .their - "chokidar": "1.7.0", - "minimist": "1.2.0", - "text-table": "0.2.0", -@@ -9587,14 +12270,24 @@ - "dev": true - }, - "chalk": { -+<<<<<<< .our - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", -+======= -+ "version": "2.3.2", -+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", -+ "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", -+<<<<<<< .our - "supports-color": "5.4.0" -+======= -+ "supports-color": "5.3.0" -+>>>>>>> .their - } - }, - "has-flag": { -@@ -9604,9 +12297,15 @@ - "dev": true - }, - "supports-color": { -+<<<<<<< .our - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", -+======= -+ "version": "5.3.0", -+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", -+ "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", -+>>>>>>> .their - "dev": true, - "requires": { - "has-flag": "3.0.0" -@@ -9622,20 +12321,36 @@ - "requires": { - "concat-stream": "1.5.2", - "debug": "2.6.9", -+<<<<<<< .our - "fault": "1.0.2", - "fn-name": "2.0.1", - "glob": "7.1.2", - "ignore": "3.3.8", -+======= -+ "fault": "1.0.1", -+ "fn-name": "2.0.1", -+ "glob": "7.1.2", -+ "ignore": "3.3.7", -+>>>>>>> .their - "is-empty": "1.2.0", - "is-hidden": "1.1.1", - "is-object": "1.0.1", - "js-yaml": "3.11.0", -+<<<<<<< .our - "load-plugin": "2.2.2", - "parse-json": "2.2.0", - "to-vfile": "2.2.0", - "trough": "1.0.2", - "vfile-reporter": "4.0.0", - "vfile-statistics": "1.1.1", -+======= -+ "load-plugin": "2.2.1", -+ "parse-json": "2.2.0", -+ "to-vfile": "2.2.0", -+ "trough": "1.0.1", -+ "vfile-reporter": "4.0.0", -+ "vfile-statistics": "1.1.0", -+>>>>>>> .their - "x-is-function": "1.0.4", - "x-is-string": "0.1.0", - "xtend": "4.0.1" -@@ -9667,6 +12382,7 @@ - } - }, - "unified-message-control": { -+<<<<<<< .our - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unified-message-control/-/unified-message-control-1.0.4.tgz", - "integrity": "sha512-e1dEtN4Z/TvLn/qHm+xeZpzqhJTtfZusFErk336kkZVpqrJYiV9ptxq+SbRPFMlN0OkjDYHmVJ929KYjsMTo3g==", -@@ -9675,6 +12391,16 @@ - "trim": "0.0.1", - "unist-util-visit": "1.3.1", - "vfile-location": "2.0.3" -+======= -+ "version": "1.0.3", -+ "resolved": "https://registry.npmjs.org/unified-message-control/-/unified-message-control-1.0.3.tgz", -+ "integrity": "sha512-zXx8LVgecdkzIMHj5c+aV3GQqJ8uxIhKi2yCccW5mhNQ5Ettb8GMA5VKvurk9Xg382/+EmUlTWW/NhBBgwmG+A==", -+ "dev": true, -+ "requires": { -+ "trim": "0.0.1", -+ "unist-util-visit": "1.3.0", -+ "vfile-location": "2.0.2" -+>>>>>>> .their - } - }, - "uniq": { -@@ -9693,6 +12419,7 @@ - } - }, - "unist-util-generated": { -+<<<<<<< .our - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.2.tgz", - "integrity": "sha512-1HcwiEO62dr0XWGT+abVK4f0aAm8Ik8N08c5nAYVmuSxfvpA9rCcNyX/le8xXj1pJK5nBrGlZefeWB6bN8Pstw==", -@@ -9755,6 +12482,58 @@ - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, -+======= -+ "version": "1.1.1", -+ "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.1.tgz", -+ "integrity": "sha1-mfFseJWayFTe58YVwpGSTIv03n8=", -+ "dev": true -+ }, -+ "unist-util-is": { -+ "version": "2.1.1", -+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.1.tgz", -+ "integrity": "sha1-DDEmKeP5YMZukx6BLT2A53AQlHs=", -+ "dev": true -+ }, -+ "unist-util-modify-children": { -+ "version": "1.1.1", -+ "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-1.1.1.tgz", -+ "integrity": "sha1-ZtfmpEnm9nIguXarPLi166w55R0=", -+ "dev": true, -+ "requires": { -+ "array-iterate": "1.1.1" -+ } -+ }, -+ "unist-util-position": { -+ "version": "3.0.0", -+ "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.0.0.tgz", -+ "integrity": "sha1-5uHgPu64HF4a/lU+jUrfvXwNj4I=", -+ "dev": true -+ }, -+ "unist-util-remove-position": { -+ "version": "1.1.1", -+ "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.1.tgz", -+ "integrity": "sha1-WoXBVV/BugwQG4ZwfRXlD6TIcbs=", -+ "dev": true, -+ "requires": { -+ "unist-util-visit": "1.3.0" -+ } -+ }, -+ "unist-util-stringify-position": { -+ "version": "1.1.1", -+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.1.tgz", -+ "integrity": "sha1-PMvcU2ee7W7PN3fdf14yKcG2qjw=", -+ "dev": true -+ }, -+ "unist-util-visit": { -+ "version": "1.3.0", -+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.3.0.tgz", -+ "integrity": "sha512-9ntYcxPFtl44gnwXrQKZ5bMqXMY0ZHzUpqMFiU4zcc8mmf/jzYm8GhYgezuUlX4cJIM1zIDYaO6fG/fI+L6iiQ==", -+ "dev": true, -+ "requires": { -+ "unist-util-is": "2.1.1" -+ } -+ }, -+>>>>>>> .their - "untildify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-2.1.0.tgz", -@@ -9770,6 +12549,7 @@ - "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", - "dev": true - }, -+<<<<<<< .our - "update-check": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.1.tgz", -@@ -9788,6 +12568,16 @@ - "requires": { - "boxen": "1.3.0", - "chalk": "2.4.1", -+======= -+ "update-notifier": { -+ "version": "2.4.0", -+ "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.4.0.tgz", -+ "integrity": "sha1-+bTHAPv9TsEsgRWHJYd31WPYyGY=", -+ "dev": true, -+ "requires": { -+ "boxen": "1.3.0", -+ "chalk": "2.3.2", -+>>>>>>> .their - "configstore": "3.1.2", - "import-lazy": "2.1.0", - "is-ci": "1.1.0", -@@ -9808,14 +12598,24 @@ - } - }, - "chalk": { -+<<<<<<< .our - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", -+======= -+ "version": "2.3.2", -+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", -+ "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", -+<<<<<<< .our - "supports-color": "5.4.0" -+======= -+ "supports-color": "5.3.0" -+>>>>>>> .their - } - }, - "has-flag": { -@@ -9825,9 +12625,15 @@ - "dev": true - }, - "supports-color": { -+<<<<<<< .our - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", -+======= -+ "version": "5.3.0", -+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", -+ "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", -+>>>>>>> .their - "dev": true, - "requires": { - "has-flag": "3.0.0" -@@ -9910,12 +12716,15 @@ - "spdx-expression-parse": "3.0.0" - } - }, -+<<<<<<< .our - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, -+======= -+>>>>>>> .their - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", -@@ -9935,6 +12744,7 @@ - "requires": { - "is-buffer": "1.1.6", - "replace-ext": "1.0.0", -+<<<<<<< .our - "unist-util-stringify-position": "1.1.2", - "vfile-message": "1.0.1" - } -@@ -9952,6 +12762,25 @@ - "dev": true, - "requires": { - "unist-util-stringify-position": "1.1.2" -+======= -+ "unist-util-stringify-position": "1.1.1", -+ "vfile-message": "1.0.0" -+ } -+ }, -+ "vfile-location": { -+ "version": "2.0.2", -+ "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.2.tgz", -+ "integrity": "sha1-02dcWch3SY5JK0dW/2Xkrxp1IlU=", -+ "dev": true -+ }, -+ "vfile-message": { -+ "version": "1.0.0", -+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.0.0.tgz", -+ "integrity": "sha512-HPREhzTOB/sNDc9/Mxf8w0FmHnThg5CRSJdR9VRFkD2riqYWs+fuXlj5z8mIpv2LrD7uU41+oPWFOL4Mjlf+dw==", -+ "dev": true, -+ "requires": { -+ "unist-util-stringify-position": "1.1.1" -+>>>>>>> .their - } - }, - "vfile-reporter": { -@@ -9963,8 +12792,13 @@ - "repeat-string": "1.6.1", - "string-width": "1.0.2", - "supports-color": "4.5.0", -+<<<<<<< .our - "unist-util-stringify-position": "1.1.2", - "vfile-statistics": "1.1.1" -+======= -+ "unist-util-stringify-position": "1.1.1", -+ "vfile-statistics": "1.1.0" -+>>>>>>> .their - }, - "dependencies": { - "has-flag": { -@@ -9985,9 +12819,15 @@ - } - }, - "vfile-statistics": { -+<<<<<<< .our - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-1.1.1.tgz", - "integrity": "sha512-dxUM6IYvGChHuwMT3dseyU5BHprNRXzAV0OHx1A769lVGsTiT50kU7BbpRFV+IE6oWmU+PwHdsTKfXhnDIRIgQ==", -+======= -+ "version": "1.1.0", -+ "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-1.1.0.tgz", -+ "integrity": "sha1-AhBMYP3u0dEbH3OtZTMLdjSz2JU=", -+>>>>>>> .their - "dev": true - }, - "vm-browserify": { -@@ -10002,7 +12842,11 @@ - "walk-sync": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-0.3.2.tgz", -+<<<<<<< .our - "integrity": "sha1-SCcoCvxC0OA1NnxKTjHurA0Tb3U=", -+======= -+ "integrity": "sha512-FMB5VqpLqOCcqrzA9okZFc0wq0Qbmdm396qJxvQZhDpyu0W95G9JCmp74tx7iyYnyOcBtUuKJsgIKAqjozvmmQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "ensure-posix-path": "1.0.2", -@@ -10029,7 +12873,11 @@ - "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", -+<<<<<<< .our - "integrity": "sha1-/wS9/AEO5UfXgL7DjhrBwnd9JTo=", -+======= -+ "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", -+>>>>>>> .their - "dev": true, - "requires": { - "isexe": "2.0.0" -@@ -10142,7 +12990,11 @@ - "write-file-atomic": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", -+<<<<<<< .our - "integrity": "sha1-H/YVdcLipOjlENb6TiQ8zhg5mas=", -+======= -+ "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", -+>>>>>>> .their - "dev": true, - "requires": { - "graceful-fs": "4.1.11", -changed in both - base 100644 14c3ba9421dbc3f8367641960d1aaafda16c7416 package.json - our 100644 c081cd89450cd50efba1ec280ff1349a96ea3ce0 package.json - their 100644 baee69b3712f6ce4345afddf0b60e573acd80e6d package.json -@@ -1,6 +1,10 @@ - { - "name": "electron", -+<<<<<<< .our - "version": "4.0.0-nightly.20180821", -+======= -+ "version": "1.8.8", -+>>>>>>> .their - "repository": "https://github.com/electron/electron", - "description": "Build cross platform desktop apps with JavaScript, HTML, and CSS", - "devDependencies": { -@@ -13,7 +17,11 @@ - "dugite": "^1.45.0", - "electabul": "~0.0.4", - "electron-docs-linter": "^2.3.4", -+<<<<<<< .our - "electron-typescript-definitions": "^1.3.6", -+======= -+ "electron-typescript-definitions": "~1.2.11", -+>>>>>>> .their - "github": "^9.2.0", - "html-entities": "^1.2.1", - "husky": "^0.14.3", -changed in both - base 100755 4465b85c135ddb55a673c5180e15f05f09dac57e script/bootstrap.py - our 100755 e4aaf89e216b0164f15882a3040e8cac70bf1fd9 script/bootstrap.py - their 100755 1ee84561d1100be2a75927c922da9c153c0fd0ca script/bootstrap.py -@@ -230,12 +230,21 @@ - def download_native_mksnapshot(arch): - if not os.path.exists(os.path.join(VENDOR_DIR, - 'native_mksnapshot')): -+<<<<<<< .our - tar_name = 'native-mksnapshot.tar.bz2' - url = '{0}/linux/{1}/{2}/{3}'.format(BASE_URL, arch, - get_libchromiumcontent_commit(), tar_name) - download(tar_name, url, os.path.join(SOURCE_ROOT, tar_name)) - subprocess.call(['tar', '-jxf', tar_name, '-C', VENDOR_DIR]) - os.remove(tar_name) -+======= -+ zip_name = 'native-mksnapshot.zip' -+ url = '{0}/linux/{1}/{2}/{3}'.format(BASE_URL, arch, -+ get_libchromiumcontent_commit(), zip_name) -+ download(zip_name, url, os.path.join(SOURCE_ROOT, zip_name)) -+ subprocess.call(['unzip', zip_name, '-d', VENDOR_DIR]) -+ os.remove(zip_name) -+>>>>>>> .their - - def create_chrome_version_h(): - version_file = os.path.join(VENDOR_DIR, 'libchromiumcontent', 'VERSION') -changed in both - base 100755 c97cd8336f7d7980911d0bdea93137e7bc95ba24 script/build.py - our 100755 fb2b95d3bb71a25ce1ca58acf596afdc0f2cc5bd script/build.py - their 100755 2a2231394207c28fcd2b86d3d9f9b079b08d637e script/build.py -@@ -40,6 +40,12 @@ - if is_verbose_mode(): - ninja.append('-v') - -+<<<<<<< .our -+======= -+ args = parse_args() -+ if args.ninja_path: -+ ninja = args.ninja_path -+>>>>>>> .their - if args.libcc: - if ('D' not in args.configuration - or not os.path.exists(GCLIENT_DONE) -@@ -93,12 +99,15 @@ - parser.add_argument('--ninja-path', - help='Path of ninja command to use.', - required=False) -+<<<<<<< .our - parser.add_argument('--compdb', - help=( - 'Generate JSON compilation database. This will not ' - 'trigger actual build. ' - ), - action='store_true', default=False) -+======= -+>>>>>>> .their - return parser.parse_args() - - -changed in both - base 100644 e6870246b5698116bc6c123c821b1069a8362e77 script/ci-release-build.js - our 100644 be9f9597387f5f8b7bfddc61c202f32ce4c6d478 script/ci-release-build.js - their 100644 60c3682ac708e0177352aee7284744b82255c05b script/ci-release-build.js -@@ -3,12 +3,15 @@ - const assert = require('assert') - const request = require('request') - const buildAppVeyorURL = 'https://windows-ci.electronjs.org/api/builds' -+<<<<<<< .our - const vstsURL = 'https://github.visualstudio.com/electron/_apis/build' - - const appVeyorJobs = { - 'electron-x64': 'electron', - 'electron-ia32': 'electron-39ng6' - } -+======= -+>>>>>>> .their - - const circleCIJobs = [ - 'electron-linux-arm', -@@ -18,11 +21,14 @@ - 'electron-linux-x64' - ] - -+<<<<<<< .our - const vstsJobs = [ - 'electron-release-mas-x64', - 'electron-release-osx-x64' - ] - -+======= -+>>>>>>> .their - async function makeRequest (requestOptions, parseResponse) { - return new Promise((resolve, reject) => { - request(requestOptions, (err, res, body) => { -@@ -139,6 +145,7 @@ - } - } - -+<<<<<<< .our - async function buildVSTS (targetBranch, options) { - if (options.job) { - assert(vstsJobs.includes(options.job), `Unknown VSTS CI job name: ${options.job}. Valid values are: ${vstsJobs}.`) -@@ -202,6 +209,8 @@ - console.log(`VSTS release build request for ${build.name} successful. Check ${vstsResponse._links.web.href} for status.`) - } - -+======= -+>>>>>>> .their - function runRelease (targetBranch, options) { - if (options.ci) { - switch (options.ci) { -@@ -213,6 +222,7 @@ - buildAppVeyor(targetBranch, options) - break - } -+<<<<<<< .our - case 'VSTS': { - buildVSTS(targetBranch, options) - break -@@ -226,12 +236,19 @@ - buildCircleCI(targetBranch, options) - buildAppVeyor(targetBranch, options) - buildVSTS(targetBranch, options) -+======= -+ } -+ } else { -+ buildCircleCI(targetBranch, options.ghRelease, options.job) -+ buildAppVeyor(targetBranch, options.ghRelease) -+>>>>>>> .their - } - } - - module.exports = runRelease - - if (require.main === module) { -+<<<<<<< .our - const args = require('minimist')(process.argv.slice(2), { - boolean: ['ghRelease', 'automaticRelease'] - }) -@@ -239,6 +256,13 @@ - if (args._.length < 1) { - console.log(`Trigger CI to build release builds of electron. - Usage: ci-release-build.js [--job=CI_JOB_NAME] [--ci=CircleCI|AppVeyor|VSTS] [--ghRelease] [--automaticRelease] TARGET_BRANCH -+======= -+ const args = require('minimist')(process.argv.slice(2), { boolean: 'ghRelease' }) -+ const targetBranch = args._[0] -+ if (args._.length < 1) { -+ console.log(`Trigger CI to build release builds of electron. -+ Usage: ci-release-build.js [--job=CI_JOB_NAME] [--ci=CircleCI|AppVeyor] [--ghRelease] TARGET_BRANCH -+>>>>>>> .their - `) - process.exit(0) - } -changed in both - base 100755 9eef2bffef97c473849d226f90580db061d7087c script/create-dist.py - our 100755 4a6c0c7ce8f275175e48c4c380ff33627f7a5961 script/create-dist.py - their 100755 f20ebf83adfd79ef2c1f0fb71e577eb3b8b44c5c script/create-dist.py -@@ -147,7 +147,11 @@ - - # Copy file and keep the executable bit. - shutil.copyfile(src, dest) -+<<<<<<< .our - add_exec_bit(dest) -+======= -+ os.chmod(dest, os.stat(dest).st_mode | stat.S_IEXEC) -+>>>>>>> .their - - def copy_vcruntime_binaries(): - arch = get_target_arch() -@@ -231,7 +235,7 @@ - elif get_target_arch() == 'arm64': - strip = 'aarch64-linux-gnu-strip' - elif get_target_arch() == 'mips64el': -- strip = 'mips64el-redhat-linux-strip' -+ strip = 'mips64el-loongson-linux-strip' - else: - strip = 'strip' - execute([strip, binary_path], env=build_env()) -@@ -302,7 +306,11 @@ - dest = os.path.join(DIST_DIR, binary) - # Copy file and keep the executable bit. - shutil.copyfile(src, dest) -+<<<<<<< .our - add_exec_bit(dest) -+======= -+ os.chmod(dest, os.stat(dest).st_mode | stat.S_IEXEC) -+>>>>>>> .their - - dist_name = get_zip_name(binary, version) - zip_file = os.path.join(SOURCE_ROOT, 'dist', dist_name) -merged - result 100644 052f0830e8bfc18ad4a0785af5a96c7267e4a1fa script/lib/config.py - our 100644 9ad0fbc680e5ecdeb8c13d0f0d6678bbba7d9031 script/lib/config.py -@@ -8,8 +8,8 @@ - # URL to the mips64el sysroot image. - MIPS64EL_SYSROOT_URL = 'https://github.com/electron/debian-sysroot-image-creator/releases/download/v0.5.0/debian_jessie_mips64-sysroot.tar.bz2' - # URL to the mips64el toolchain. --MIPS64EL_GCC = 'gcc-4.8.3-d197-n64-loongson' --MIPS64EL_GCC_URL = 'http://ftp.loongnix.org/toolchain/gcc/release/' + MIPS64EL_GCC + '.tar.gz' -+MIPS64EL_GCC = 'cross-gcc-4.9.3-n64-loongson-rc5.4' -+MIPS64EL_GCC_URL = 'https://github.com/electron/debian-sysroot-image-creator/releases/download/v0.5.0/' + MIPS64EL_GCC + '.tar.gz' - - BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ - 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' -@@ -93,11 +93,11 @@ - VENDOR_DIR = os.path.join(SOURCE_ROOT, 'vendor') - gcc_dir = os.path.join(VENDOR_DIR, MIPS64EL_GCC) - ldlib_dirs = [ -- gcc_dir + '/usr/x86_64-unknown-linux-gnu/mips64el-redhat-linux/lib', -+ gcc_dir + '/usr/x86_64-unknown-linux-gnu/mips64el-loongson-linux/lib', - gcc_dir + '/usr/lib64', -- gcc_dir + '/usr/mips64el-redhat-linux/lib64', -- gcc_dir + '/usr/mips64el-redhat-linux/sysroot/lib64', -- gcc_dir + '/usr/mips64el-redhat-linux/sysroot/usr/lib64', -+ gcc_dir + '/usr/mips64el-loongson-linux/lib64', -+ gcc_dir + '/usr/mips64el-loongson-linux/sysroot/lib64', -+ gcc_dir + '/usr/mips64el-loongson-linux/sysroot/usr/lib64', - ] - env['LD_LIBRARY_PATH'] = os.pathsep.join(ldlib_dirs) - env['PATH'] = os.pathsep.join([gcc_dir + '/usr/bin', env['PATH']]) -changed in both - base 100755 ccc9057693fe3524bf7ffc8cd619579fbe8635e3 script/prepare-release.js - our 100755 72a28b719bf1ff7770692caef86c76746c4d8edf script/prepare-release.js - their 100755 cb5ea44688210d23b03a13dc8e68d2b7b635dd98 script/prepare-release.js -@@ -34,6 +34,13 @@ - if (!dryRun) { - console.log(`Bumping for new "${versionType}" version.`) - } -+<<<<<<< .our -+======= -+} -+ -+function getNewVersion (dryRun) { -+ console.log(`Bumping for new "${versionType}" version.`) -+>>>>>>> .their - let bumpScript = path.join(__dirname, 'bump-version.py') - let scriptArgs = [bumpScript, '--bump', versionType] - if (args.stable) { -@@ -164,6 +171,7 @@ - githubOpts.draft = true - githubOpts.name = `electron ${newVersion}` - if (isBeta) { -+<<<<<<< .our - if (newVersion.indexOf('nightly') > 0) { - githubOpts.body = `Note: This is a nightly release. Please file new issues ` + - `for any bugs you find in it.\n \n This release is published to npm ` + -@@ -175,6 +183,12 @@ - `under the beta tag and can be installed via npm install electron@beta, ` + - `or npm i electron@${newVersion.substr(1)}.\n \n ${releaseNotes}` - } -+======= -+ githubOpts.body = `Note: This is a beta release. Please file new issues ` + -+ `for any bugs you find in it.\n \n This release is published to npm ` + -+ `under the beta tag and can be installed via npm install electron@beta, ` + -+ `or npm i electron@${newVersion.substr(1)}.\n \n ${releaseNotes}` -+>>>>>>> .their - githubOpts.name = `${githubOpts.name}` - githubOpts.prerelease = true - } else { -@@ -250,11 +264,36 @@ - }) - } - -+<<<<<<< .our - // function to determine if there have been commits to master since the last release - async function changesToRelease () { - let lastCommitWasRelease = new RegExp(`^Bump v[0-9.]*(-beta[0-9.]*)?(-nightly[0-9.]*)?$`, 'g') - let lastCommit = await GitProcess.exec(['log', '-n', '1', `--pretty=format:'%s'`], gitDir) - return !lastCommitWasRelease.test(lastCommit.stdout) -+======= -+async function verifyNewVersion () { -+ let newVersion = await getNewVersion(true) -+ let response = await promptForVersion(newVersion) -+ if (response.match(/^y/i)) { -+ console.log(`${pass} Starting release of ${newVersion}`) -+ } else { -+ console.log(`${fail} Aborting release of ${newVersion}`) -+ process.exit() -+ } -+} -+ -+async function promptForVersion (version) { -+ return new Promise((resolve, reject) => { -+ const rl = readline.createInterface({ -+ input: process.stdin, -+ output: process.stdout -+ }) -+ rl.question(`Do you want to create the release ${version.green} (y/N)? `, (answer) => { -+ rl.close() -+ resolve(answer) -+ }) -+ }) -+>>>>>>> .their - } - - async function prepareRelease (isBeta, notesOnly) { -@@ -262,6 +301,7 @@ - let newVersion = await getNewVersion(true) - console.log(newVersion) - } else { -+<<<<<<< .our - const currentBranch = (args.branch) ? args.branch : await getCurrentBranch(gitDir) - if (notesOnly) { - let releaseNotes = await getReleaseNotes(currentBranch) -@@ -278,6 +318,13 @@ - process.exit(1) - } - } -+======= -+ await verifyNewVersion() -+ await createReleaseBranch() -+ await createRelease(currentBranch, isBeta) -+ await pushRelease() -+ await runReleaseBuilds() -+>>>>>>> .their - } - } - -changed in both - base 100644 aaf93f33cd9a49f4ce4981efd8a8480e6658579f script/publish-to-npm.js - our 100644 27290c513bb28d9bd394575d833f1e6786e3b479 script/publish-to-npm.js - their 100644 eb0702ff5ef265b545824ba21ffb4c5d760d5476 script/publish-to-npm.js -changed in both - base 100755 1baa56a7c8862da9f24f7814dc12359c0c75b072 script/release.js - our 100755 84e00ad4f309201f151c3f8fcbaf9ee536c9b6cb script/release.js - their 100755 9863ef912cd5a940428e9ac22e1993494b2b1828 script/release.js -@@ -446,6 +446,7 @@ - `shasums defined in ${validationArgs.shaSumFile}.`) - } - -+<<<<<<< .our - async function tagLibCC () { - const tag = `electron-${pkg.version}` - const libccDir = path.join(path.resolve(__dirname, '..'), 'vendor', 'libchromiumcontent') -@@ -459,6 +460,23 @@ - console.log(`${fail} Error pushing libchromiumcontent tag ${tag}: ` + - `${pushDetails.stderr}`) - } -+======= -+async function cleanupReleaseBranch () { -+ console.log(`Cleaning up release branch.`) -+ let errorMessage = `Could not delete local release branch.` -+ let successMessage = `Successfully deleted local release branch.` -+ await callGit(['branch', '-D', 'release'], errorMessage, successMessage) -+ errorMessage = `Could not delete remote release branch.` -+ successMessage = `Successfully deleted remote release branch.` -+ return callGit(['push', 'origin', ':release'], errorMessage, successMessage) -+} -+ -+async function callGit (args, errorMessage, successMessage) { -+ let gitResult = await GitProcess.exec(args, gitDir) -+ if (gitResult.exitCode === 0) { -+ console.log(`${pass} ${successMessage}`) -+ return true -+>>>>>>> .their - } else { - console.log(`${fail} Error tagging libchromiumcontent with ${tag}: ` + - `${tagDetails.stderr}`) -changed in both - base 100755 cea171d8597c9917839e322cb6c8e4d0c308ac30 script/update-clang.sh - our 100755 0c7ab60533381e33152b8735aaccf41d5f0d6676 script/update-clang.sh - their 100755 4a0924576a0fe26d980c71bfa7ff4917d3fb66db script/update-clang.sh -@@ -46,37 +46,54 @@ - - # Check if there's a prebuilt binary and if so just fetch that. That's faster, - # and goma relies on having matching binary hashes on client and server too. --CDS_FILE="clang-${PACKAGE_VERSION}.tgz" -+echo Trying to download prebuilt clang -+rm -rf "${LLVM_BUILD_DIR}" -+mkdir -p "${LLVM_BUILD_DIR}" -+ -+CDS_FILES=("clang-${PACKAGE_VERSION}.tgz") - CDS_OUT_DIR=$(mktemp -d -t clang_download.XXXXXX) --CDS_OUTPUT="${CDS_OUT_DIR}/${CDS_FILE}" - if [ "${OS}" = "Linux" ]; then - ARCH="$(uname -m)" - if [ "${ARCH}" = "aarch64" ]; then -+<<<<<<< .our - CDS_FULL_URL="${S3_URL}/arm64/${CDS_FILE}" - else - CDS_FULL_URL="${CDS_URL}/Linux_x64/${CDS_FILE}" -+======= -+ CDS_URL="${S3_URL}" -+ CDS_SUBDIR="arm64" -+ else -+ CDS_FILES+=("llvmgold-${PACKAGE_VERSION}.tgz") -+ CDS_SUBDIR="Linux_x64" -+>>>>>>> .their - fi - elif [ "${OS}" = "Darwin" ]; then -- CDS_FULL_URL="${CDS_URL}/Mac/${CDS_FILE}" --fi --echo Trying to download prebuilt clang --if which curl > /dev/null; then -- curl -L --fail "${CDS_FULL_URL}" -o "${CDS_OUTPUT}" || \ -- rm -rf "${CDS_OUT_DIR}" --elif which wget > /dev/null; then -- wget "${CDS_FULL_URL}" -O "${CDS_OUTPUT}" || rm -rf "${CDS_OUT_DIR}" --else -- echo "Neither curl nor wget found. Please install one of these." -- exit 1 --fi --if [ -f "${CDS_OUTPUT}" ]; then -- rm -rf "${LLVM_BUILD_DIR}" -- mkdir -p "${LLVM_BUILD_DIR}" -- tar -xzf "${CDS_OUTPUT}" -C "${LLVM_BUILD_DIR}" -- echo clang "${PACKAGE_VERSION}" unpacked -- echo "${PACKAGE_VERSION}" > "${STAMP_FILE}" -- rm -rf "${CDS_OUT_DIR}" -- exit 0 --else -- echo Did not find prebuilt clang "${PACKAGE_VERSION}", building -+ CDS_SUBDIR="Mac" - fi -+for CDS_FILE in "${CDS_FILES[@]}" -+do -+ CDS_OUTPUT="${CDS_OUT_DIR}/${CDS_FILE}" -+ CDS_FULL_URL="${CDS_URL}/${CDS_SUBDIR}/${CDS_FILE}" -+ -+ if which curl > /dev/null; then -+ curl -L --fail "${CDS_FULL_URL}" -o "${CDS_OUTPUT}" || \ -+ rm -rf "${CDS_OUT_DIR}" -+ elif which wget > /dev/null; then -+ wget "${CDS_FULL_URL}" -O "${CDS_OUTPUT}" || rm -rf "${CDS_OUT_DIR}" -+ else -+ echo "Neither curl nor wget found. Please install one of these." -+ exit 1 -+ fi -+ -+ if [ -f "${CDS_OUTPUT}" ]; then -+ tar -xzf "${CDS_OUTPUT}" -C "${LLVM_BUILD_DIR}" -+ else -+ echo Did not find prebuilt clang "${PACKAGE_VERSION}" -+ exit 1 -+ fi -+done -+ -+echo clang "${PACKAGE_VERSION}" unpacked -+echo "${PACKAGE_VERSION}" > "${STAMP_FILE}" -+rm -rf "${CDS_OUT_DIR}" -+exit 0 -changed in both - base 100755 2be84be82d78c16a55dae4070d81c6ec79ab2691 script/upload.py - our 100755 2d9eaa201265971ca01acaea6e84a440e5db0532 script/upload.py - their 100755 ee7a027af02274326ba06d84df031bb0d241ec47 script/upload.py -@@ -76,9 +76,23 @@ - upload_electron(release, os.path.join(DIST_DIR, ffmpeg), args) - - chromedriver = get_zip_name('chromedriver', ELECTRON_VERSION) -+<<<<<<< .our - upload_electron(release, os.path.join(DIST_DIR, chromedriver), args) - mksnapshot = get_zip_name('mksnapshot', ELECTRON_VERSION) - upload_electron(release, os.path.join(DIST_DIR, mksnapshot), args) -+======= -+ upload_electron(github, release, os.path.join(DIST_DIR, chromedriver), -+ args.upload_to_s3) -+ mksnapshot = get_zip_name('mksnapshot', ELECTRON_VERSION) -+ upload_electron(github, release, os.path.join(DIST_DIR, mksnapshot), -+ args.upload_to_s3) -+ -+ if get_target_arch().startswith('arm'): -+ # Upload the x64 binary for arm/arm64 mksnapshot -+ mksnapshot = get_zip_name('mksnapshot', ELECTRON_VERSION, 'x64') -+ upload_electron(github, release, os.path.join(DIST_DIR, mksnapshot), -+ args.upload_to_s3) -+>>>>>>> .their - - if get_target_arch().startswith('arm'): - # Upload the x64 binary for arm/arm64 mksnapshot -@@ -149,8 +163,56 @@ - return dist_time > int(head_time) - - -+<<<<<<< .our - def upload_electron(release, file_path, args): - filename = os.path.basename(file_path) -+======= -+def get_text_with_editor(name): -+ editor = os.environ.get('EDITOR', 'nano') -+ initial_message = '\n# Please enter the body of your release note for %s.' \ -+ % name -+ -+ t = tempfile.NamedTemporaryFile(suffix='.tmp', delete=False) -+ t.write(initial_message) -+ t.close() -+ subprocess.call([editor, t.name]) -+ -+ text = '' -+ for line in open(t.name, 'r'): -+ if len(line) == 0 or line[0] != '#': -+ text += line -+ -+ os.unlink(t.name) -+ return text -+ -+def create_or_get_release_draft(github, releases, tag, tag_exists): -+ # Search for existing draft. -+ for release in releases: -+ if release['draft'] and release['tag_name'] == tag: -+ return release -+ -+ if tag_exists: -+ tag = 'do-not-publish-me' -+ return create_release_draft(github, tag) -+ -+ -+def create_release_draft(github, tag): -+ name = '{0} {1} beta'.format(PROJECT_NAME, tag) -+ if os.environ.has_key('CI'): -+ body = '(placeholder)' -+ else: -+ body = get_text_with_editor(name) -+ if body == '': -+ sys.stderr.write('Quit due to empty release note.\n') -+ sys.exit(0) -+ -+ data = dict(tag_name=tag, name=name, body=body, draft=True, prerelease=True) -+ r = github.repos(ELECTRON_REPO).releases.post(data=data) -+ return r -+ -+ -+def upload_electron(github, release, file_path, upload_to_s3): -+>>>>>>> .their - - # if upload_to_s3 is set, skip github upload. - if args.upload_to_s3: -changed in both - base 100644 3df3a87e66429193d65c27545e92a034dce92eeb spec/api-app-spec.js - our 100644 d224eda2989332c18d655cef05a8bacc2eb6d4b8 spec/api-app-spec.js - their 100644 5816902d7cd68c74d4161ef3a87402125a44c0a5 spec/api-app-spec.js -@@ -720,6 +720,54 @@ - }) - }) - -+ describe('app launch through uri', () => { -+ before(function () { -+ if (process.platform !== 'win32') { -+ this.skip() -+ } -+ }) -+ -+ it('does not launch for blacklisted argument', function (done) { -+ const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app') -+ // App should exit with non 123 code. -+ const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'electron-test://?', '--no-sandbox', '--gpu-launcher=cmd.exe /c start calc']) -+ first.once('exit', (code) => { -+ assert.notEqual(code, 123) -+ done() -+ }) -+ }) -+ -+ it('launches successfully for multiple uris in cmd args', function (done) { -+ const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app') -+ // App should exit with code 123. -+ const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'http://electronjs.org', 'electron-test://testdata']) -+ first.once('exit', (code) => { -+ assert.equal(code, 123) -+ done() -+ }) -+ }) -+ -+ it('does not launch for encoded space', function (done) { -+ const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app') -+ // App should exit with non 123 code. -+ const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'electron-test://?', '--no-sandbox', '--gpu-launcher%20"cmd.exe /c start calc']) -+ first.once('exit', (code) => { -+ assert.notEqual(code, 123) -+ done() -+ }) -+ }) -+ -+ it('launches successfully for argnames similar to blacklisted ones', function (done) { -+ const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app') -+ // inspect is blacklisted, but inspector should work, and app launch should succeed -+ const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'electron-test://?', '--inspector']) -+ first.once('exit', (code) => { -+ assert.equal(code, 123) -+ done() -+ }) -+ }) -+ }) -+ - describe('getFileIcon() API', () => { - const iconPath = path.join(__dirname, 'fixtures/assets/icon.ico') - const sizes = { -changed in both - base 100644 ab96021ebf4c4360fa581b5a695249456a9afeda spec/api-browser-view-spec.js - our 100644 968912a4abf3d759a1363e2420d2c21b7923dbd6 spec/api-browser-view-spec.js - their 100644 df239a8914527a2d62f652b878c97a7791f63a9d spec/api-browser-view-spec.js -@@ -44,9 +44,15 @@ - describe('BrowserView.isDestroyed()', () => { - it('returns correct value', () => { - view = new BrowserView() -+<<<<<<< .our - expect(view.isDestroyed()).to.be.false() - view.destroy() - expect(view.isDestroyed()).to.be.true() -+======= -+ assert.ok(!view.isDestroyed()) -+ view.destroy() -+ assert.ok(view.isDestroyed()) -+>>>>>>> .their - }) - }) - -changed in both - base 100644 2adc82df05d0d9c0524324edfe33f83824f47cb4 spec/api-browser-window-spec.js - our 100644 f4cba12ec19d224bc46fca898db42a99baf4972e spec/api-browser-window-spec.js - their 100644 2a52bbc1043c17624ffe60cca6a09b43bf3089aa spec/api-browser-window-spec.js -@@ -453,6 +453,29 @@ - // Values can be 0,2,3,4, or 6. We want 6, which is RGB + Alpha - expect(imgBuffer[25]).to.equal(6) - }) -+ -+ it('preserves transparency', (done) => { -+ w.close() -+ const width = 400 -+ const height = 400 -+ w = new BrowserWindow({ -+ show: false, -+ width: width, -+ height: height, -+ transparent: true -+ }) -+ w.loadURL('data:text/html,<html><body background-color: rgba(255,255,255,0)></body></html>') -+ w.once('ready-to-show', () => { -+ w.show() -+ w.capturePage((image) => { -+ let imgBuffer = image.toPNG() -+ // Check 25th byte in the PNG -+ // Values can be 0,2,3,4, or 6. We want 6, which is RGB + Alpha -+ assert.equal(imgBuffer[25], 6) -+ done() -+ }) -+ }) -+ }) - }) - - describe('BrowserWindow.setSize(width, height)', () => { -changed in both - base 100644 2a74fc7297af92e99ff99ec38d6a57e1246b6f38 spec/api-menu-spec.js - our 100644 ed2749700c6c8bf299f507d52606c1ae3f597e5c spec/api-menu-spec.js - their 100644 4afac1b4f7f2f46aa9fd573c40a6aa74ecb0cc88 spec/api-menu-spec.js -@@ -648,10 +648,28 @@ - return closeWindow(w).then(() => { w = null }) - }) - -+<<<<<<< .our - it('throws an error if options is not an object', () => { - expect(() => { - menu.popup('this is a string, not an object') - }).to.throw(/Options must be an object/) -+======= -+ it('returns immediately', () => { -+ const { browserWindow, x, y, async } = menu.popup(w, {x: 100, y: 101, async: true}) -+ -+ assert.equal(browserWindow, w) -+ assert.equal(x, 100) -+ assert.equal(y, 101) -+ assert.equal(async, true) -+ }) -+ -+ it('works without a given BrowserWindow and options', () => { -+ const { browserWindow, x, y } = menu.popup({x: 100, y: 101, async: true}) -+ -+ assert.equal(browserWindow.constructor.name, 'BrowserWindow') -+ assert.equal(x, 100) -+ assert.equal(y, 101) -+>>>>>>> .their - }) - - it('allows for options to be optional', () => { -changed in both - base 100644 54235a334a5403dd580424d3129569c60e4c41de spec/api-session-spec.js - our 100644 b9093d1d6335ece5ca713a668a67bf3b40f4fabe spec/api-session-spec.js - their 100644 5e9743f83d9ab56419080674f82f8847495eb2e5 spec/api-session-spec.js -@@ -298,8 +298,12 @@ - filename, port, savePath, isCustom) => { - assert.equal(state, 'completed') - assert.equal(filename, 'mock.pdf') -+<<<<<<< .our - assert.ok(path.isAbsolute(savePath)) - assert.ok(isPathEqual(savePath, path.join(__dirname, 'fixtures', 'mock.pdf'))) -+======= -+ assert.equal(savePath, path.join(__dirname, 'fixtures', 'mock.pdf')) -+>>>>>>> .their - if (isCustom) { - assert.equal(url, `${protocolName}://item`) - } else { -changed in both - base 100644 1420fed7c6a7b64ad1fb04da0751725bddb87b5c spec/chromium-spec.js - our 100644 d90269769d269e4054d25cba4b6c4ac8a1929aa6 spec/chromium-spec.js - their 100644 ffcc187e8434e1baaf5b667184a7a376200987fe spec/chromium-spec.js -@@ -319,8 +319,12 @@ - b = window.open(windowUrl, '', 'nodeIntegration=no,show=no') - }) - -+<<<<<<< .our - // TODO(codebytere): re-enable this test - xit('disables node integration when it is disabled on the parent window for chrome devtools URLs', (done) => { -+======= -+ it('disables node integration when it is disabled on the parent window for chrome devtools URLs', (done) => { -+>>>>>>> .their - let b - app.once('web-contents-created', (event, contents) => { - contents.once('did-finish-load', () => { -changed in both - base 100644 cfe840ca0a44c5766509b2865034d98e375da1a1 spec/modules-spec.js - our 100644 b996b8f4839bff2160bffb69e55263b16a4178d7 spec/modules-spec.js - their 100644 28f2602acff67b2da9accd0574d64d386e0795a7 spec/modules-spec.js -changed in both - base 100644 57cb31e2b52888c7d2135d0169d514e26106d356 spec/node-spec.js - our 100644 9bb03494a56ffacec075c40bebde39a3b57ac734 spec/node-spec.js - their 100644 572c9548c1d2a3657473a64e74679c777ca5a2ba spec/node-spec.js -changed in both - base 100644 4a4dfd109df33c9f5f607d6ea593276973e0bb3f spec/static/main.js - our 100644 5659c44c8de4456a25e0026e29199b827c89cb08 spec/static/main.js - their 100644 f91dc4e5216774d73a5d7648ee873770ac694210 spec/static/main.js -changed in both - base 100644 6580f18a1ad9e53ab3f2ae88cb7ea023bcf9579c toolchain.gypi - our 100644 697add78e42191741cee1b015cdcf4f801c570e7 toolchain.gypi - their 100644 82408a5ac62ac1c84ae33c3b440b8fc243674fee toolchain.gypi -@@ -9,7 +9,7 @@ - 'cc_wrapper%': '', - - # Path to mips64el toolchain. -- 'make_mips64_dir%': 'vendor/gcc-4.8.3-d197-n64-loongson/usr', -+ 'make_mips64_dir%': 'vendor/cross-gcc-4.9.3-n64-loongson-rc5.4/usr', - - 'variables': { - # The minimum macOS SDK version to use. -@@ -116,8 +116,10 @@ - # Setup building with clang. - ['clang==1', { - 'make_global_settings': [ -+ ['AR', '<(make_clang_dir)/bin/llvm-ar'], - ['CC', '<(make_clang_dir)/bin/clang'], - ['CXX', '<(make_clang_dir)/bin/clang++'], -+ ['AR.host', '<(make_clang_dir)/bin/llvm-ar'], - ['CC.host', '$(CC)'], - ['CXX.host', '$(CXX)'], - ], -@@ -192,8 +194,8 @@ - - ['target_arch=="mips64el"', { - 'make_global_settings': [ -- ['CC', '<(make_mips64_dir)/bin/mips64el-redhat-linux-gcc'], -- ['CXX', '<(make_mips64_dir)/bin/mips64el-redhat-linux-g++'], -+ ['CC', '<(make_mips64_dir)/bin/mips64el-loongson-linux-gcc'], -+ ['CXX', '<(make_mips64_dir)/bin/mips64el-loongson-linux-g++'], - ['CC.host', '$(CC)'], - ['CXX.host', '$(CXX)'], - ], -changed in both - base 160000 eb1db5393cd8bf2f931c5ef3ab7c55948bd57d60 vendor/libchromiumcontent - our 160000 c85470a1c379b1c4bedb372c146521bc4be9b75d vendor/libchromiumcontent - their 160000 07396ffd8e07470ae2e939d26bc8d7b6b4c3d9d3 vendor/libchromiumcontent -changed in both - base 160000 dc8fe9d390b1deb32ae2601357a90679cbcc757e vendor/node - our 160000 ece0a06ac8147efb5b5af431c21f312f1884616e vendor/node - their 160000 2586ef1eb5f5f53da2c1852efb47c20dc8888534 vendor/node -added in both - our 100644 84bd69c2b2868ac23bc30061aa208ad38fbb9506 vsts.yml - their 100644 aaee2e6522650cd470f09e43b74b4d0a126c2128 vsts.yml -@@ -59,7 +59,11 @@ - - bash: | - echo 'Verifying ffmpeg on build' - if [ "$ELECTRON_RELEASE" == "1" ]; then -+<<<<<<< .our - script/verify-ffmpeg.py -c R -+======= -+ script/verify-ffmpeg.py -R -+>>>>>>> .their - else - script/verify-ffmpeg.py - fi -@@ -69,6 +73,7 @@ - - task: PublishTestResults@2 - displayName: Publish Test Results - inputs: -+<<<<<<< .our - testResultsFiles: '**/test-*.xml' - condition: and(always(), eq(variables['MOCHA_FILE'], 'test-results.xml')) - -@@ -93,5 +98,18 @@ - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/out' - ArtifactName: out -+======= -+ testResultsFiles: 'test-results.xml' -+ searchFolder: junit -+ condition: and(always(), ne(variables['ELECTRON_RELEASE'], '1')) -+ -+- task: kasunkodagoda.slack-notification.slack-notification-task.SlackNotification@3 -+ displayName: Post Slack Notification -+ inputs: -+ SlackApiToken: '$(slack_token)' -+ Channel: '#bot-nightly-releases' -+ Message: '$(Build.DefinitionName)-$(Build.BuildNumber) finished with a $(Agent.JobStatus) status.' -+ condition: and(always(), eq(variables['Build.Reason'], 'Schedule')) -+>>>>>>> .their - - - task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3 diff --git a/app/test/fixtures/merge-parser/electron/merge-2-0-x-into-master.txt b/app/test/fixtures/merge-parser/electron/merge-2-0-x-into-master.txt deleted file mode 100644 index 99d23d16233..00000000000 --- a/app/test/fixtures/merge-parser/electron/merge-2-0-x-into-master.txt +++ /dev/null @@ -1,6917 +0,0 @@ -changed in both - base 100644 d4f98eab95b73b59018f170b09b9132d4d03477b .circleci/config.yml - our 100644 6d44d618aabcce04c60344f2274dec5b0c2a1f68 .circleci/config.yml - their 100644 8d065e3f257178d4706dcbd1340326be42b2e2e2 .circleci/config.yml -@@ -19,6 +19,7 @@ - fi - when: on_success - -+<<<<<<< .our - build-steps: &build-steps - steps: - - checkout -@@ -92,6 +93,13 @@ - fi - - run: - name: Test -+======= -+version: 2 -+jobs: -+ electron-linux-arm: -+ docker: -+ - image: electronbuilds/electron:0.0.7 -+>>>>>>> .their - environment: - MOCHA_FILE: junit/test-results.xml - MOCHA_REPORTER: mocha-junit-reporter -@@ -110,6 +118,7 @@ - echo 'Skipping tests on GitHub release' - fi - fi -+<<<<<<< .our - else - echo 'Skipping tests due to configuration' - fi -@@ -117,6 +126,76 @@ - name: Verify FFmpeg - command: | - if [ "$RUN_TESTS" == "true" ]; then -+======= -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Optionally finish release -+ shell: /bin/sh -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then -+ echo 'Trying to finish release' -+ node script/release.js --validateRelease --automaticRelease -+ releaseExitCode=$? -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release is ready to go; releasing' -+ node script/release.js--automaticRelease -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release successful, now publishing to npm' -+ echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc -+ npm run publish-to-npm -+ echo 'Release has been published to npm' -+ fi -+ else -+ echo 'Release is not complete, skipping publish for now' -+ fi -+ else -+ echo 'Skipping finishing release because build is not for release' -+ fi -+ - run: -+ name: Zip out directory -+ command: | -+>>>>>>> .their - if [ "$ELECTRON_RELEASE" != "1" ]; then - echo 'Verifying ffmpeg on debug build' - script/verify-ffmpeg.py -@@ -391,11 +470,105 @@ - resource_class: 2xlarge - - electron-linux-arm64: -+<<<<<<< .our - environment: - TARGET_ARCH: arm64 - <<: *build-defaults - resource_class: 2xlarge - -+======= -+ docker: -+ - image: electronbuilds/electron:0.0.7 -+ environment: -+ TARGET_ARCH: arm64 -+ resource_class: 2xlarge -+ steps: -+ - checkout -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Optionally finish release -+ shell: /bin/sh -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then -+ echo 'Trying to finish release' -+ node script/release.js --validateRelease --automaticRelease -+ releaseExitCode=$? -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release is ready to go; releasing' -+ node script/release.js--automaticRelease -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release successful, now publishing to npm' -+ echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc -+ npm run publish-to-npm -+ echo 'Release has been published to npm' -+ fi -+ else -+ echo 'Release is not complete, skipping publish for now' -+ fi -+ else -+ echo 'Skipping finishing release because build is not for release' -+ fi -+ - run: -+ name: Zip out directory -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ zip -r electron.zip out/D -+ fi -+ - persist_to_workspace: -+ root: /home/builduser -+ paths: -+ - project/out -+ - store_artifacts: -+ path: electron.zip -+>>>>>>> .their - electron-linux-arm64-test: - machine: true - steps: -@@ -430,6 +603,7 @@ - resource_class: 2xlarge - - electron-linux-ia32: -+<<<<<<< .our - environment: - TARGET_ARCH: ia32 - DISPLAY: ':99.0' -@@ -469,10 +643,317 @@ - NIGHTLY_BUILD: true - <<: *build-defaults - resource_class: xlarge -+======= -+ docker: -+ - image: electronbuilds/electron:0.0.7 -+ environment: -+ TARGET_ARCH: ia32 -+ DISPLAY: ':99.0' -+ resource_class: xlarge -+ steps: -+ - checkout -+ - run: -+ name: Setup for headless testing -+ command: sh -e /etc/init.d/xvfb start -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Optionally finish release -+ shell: /bin/sh -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then -+ echo 'Trying to finish release' -+ node script/release.js --validateRelease --automaticRelease -+ releaseExitCode=$? -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release is ready to go; releasing' -+ node script/release.js--automaticRelease -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release successful, now publishing to npm' -+ echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc -+ npm run publish-to-npm -+ echo 'Release has been published to npm' -+ fi -+ else -+ echo 'Release is not complete, skipping publish for now' -+ fi -+ else -+ echo 'Skipping finishing release because build is not for release' -+ fi -+ - run: -+ name: Test -+ environment: -+ MOCHA_FILE: junit/test-results.xml -+ MOCHA_REPORTER: mocha-junit-reporter -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Testing Electron debug build' -+ out/D/electron --version -+ mkdir junit -+ script/test.py --ci --rebuild_native_modules -+ else -+ echo 'Skipping testing on release build' -+ fi -+ - run: -+ name: Verify FFmpeg -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Verifying ffmpeg on debug build' -+ script/verify-ffmpeg.py -+ else -+ echo 'Skipping verify ffmpeg on release build' -+ fi -+ electron-linux-mips64el: -+ docker: -+ - image: electronbuilds/electron:0.0.7 -+ environment: -+ TARGET_ARCH: mips64el -+ resource_class: xlarge -+ steps: -+ - checkout -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Optionally finish release -+ shell: /bin/sh -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then -+ echo 'Trying to finish release' -+ node script/release.js --validateRelease --automaticRelease -+ releaseExitCode=$? -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release is ready to go; releasing' -+ node script/release.js--automaticRelease -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release successful, now publishing to npm' -+ echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc -+ npm run publish-to-npm -+ echo 'Release has been published to npm' -+ fi -+ else -+ echo 'Release is not complete, skipping publish for now' -+ fi -+ else -+ echo 'Skipping finishing release because build is not for release' -+ fi -+ -+ electron-linux-x64: -+ docker: -+ - image: electronbuilds/electron:0.0.7 -+ environment: -+ TARGET_ARCH: x64 -+ DISPLAY: ':99.0' -+ resource_class: xlarge -+ steps: -+ - checkout -+ - run: -+ name: Setup for headless testing -+ command: sh -e /etc/init.d/xvfb start -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Optionally finish release -+ shell: /bin/sh -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then -+ echo 'Trying to finish release' -+ node script/release.js --validateRelease --automaticRelease -+ releaseExitCode=$? -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release is ready to go; releasing' -+ node script/release.js--automaticRelease -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release successful, now publishing to npm' -+ echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc -+ npm run publish-to-npm -+ echo 'Release has been published to npm' -+ fi -+ else -+ echo 'Release is not complete, skipping publish for now' -+ fi -+ else -+ echo 'Skipping finishing release because build is not for release' -+ fi -+ - run: -+ name: Test -+ environment: -+ MOCHA_FILE: junit/test-results.xml -+ MOCHA_REPORTER: mocha-junit-reporter -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Testing Electron debug build' -+ mkdir junit -+ script/test.py --ci --rebuild_native_modules -+ else -+ echo 'Skipping testing on release build' -+ fi -+ - run: -+ name: Verify FFmpeg -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Verifying ffmpeg on debug build' -+ script/verify-ffmpeg.py -+ else -+ echo 'Skipping verify ffmpeg on release build' -+ fi -+ - run: -+ name: Generate Typescript Definitions -+ command: npm run create-typescript-definitions -+ - store_test_results: -+ path: junit -+ - store_artifacts: -+ path: junit -+ - store_artifacts: -+ path: out/electron.d.ts -+ - store_artifacts: -+ path: out/electron-api.json -+>>>>>>> .their - - electron-osx-x64: - environment: - TARGET_ARCH: x64 -+<<<<<<< .our - RUN_TESTS: true - INSTALL_MACOS_NODE: true - macos: -@@ -488,11 +969,107 @@ - macos: - xcode: "8.3.3" - <<: *build-steps -+======= -+ macos: -+ xcode: "9.0" -+ steps: -+ - checkout -+ - run: -+ name: Reclaim disk space -+ command: | -+ df -h -+ sudo rm -rf /Library/Developer/CoreSimulator -+ df -h -+ sysctl -n hw.ncpu -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Test -+ environment: -+ MOCHA_FILE: junit/test-results.xml -+ MOCHA_REPORTER: mocha-junit-reporter -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Testing Electron debug build' -+ mkdir junit -+ script/test.py --ci --rebuild_native_modules -+ else -+ echo 'Skipping testing on release build' -+ fi -+ - run: -+ name: Verify FFmpeg -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Verifying ffmpeg on debug build' -+ script/verify-ffmpeg.py -+ else -+ echo 'Skipping verify ffmpeg on release build' -+ fi -+ - run: -+ name: Generate Typescript Definitions -+ command: npm run create-typescript-definitions -+ - store_test_results: -+ path: junit -+ - store_artifacts: -+ path: junit -+ - store_artifacts: -+ path: out/electron.d.ts -+ - store_artifacts: -+ path: out/electron-api.json -+>>>>>>> .their - - electron-mas-x64: - environment: - TARGET_ARCH: x64 - MAS_BUILD: 1 -+<<<<<<< .our - RUN_TESTS: true - INSTALL_MACOS_NODE: true - macos: -@@ -668,6 +1245,101 @@ - GN_EXTRA_ARGS: 'is_mas_build = true' - <<: *gn-mac-build-machine - <<: *gn-mac-build-steps -+======= -+ macos: -+ xcode: "9.0" -+ steps: -+ - checkout -+ - run: -+ name: Reclaim disk space -+ command: | -+ df -h -+ sudo rm -rf /Library/Developer/CoreSimulator -+ df -h -+ sysctl -n hw.ncpu -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Test -+ environment: -+ MOCHA_FILE: junit/test-results.xml -+ MOCHA_REPORTER: mocha-junit-reporter -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Testing Electron debug build' -+ mkdir junit -+ script/test.py --ci --rebuild_native_modules -+ else -+ echo 'Skipping testing on release build' -+ fi -+ - run: -+ name: Verify FFmpeg -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Verifying ffmpeg on debug build' -+ script/verify-ffmpeg.py -+ else -+ echo 'Skipping verify ffmpeg on release build' -+ fi -+ - run: -+ name: Generate Typescript Definitions -+ command: npm run create-typescript-definitions -+ - store_test_results: -+ path: junit -+ - store_artifacts: -+ path: junit -+ - store_artifacts: -+ path: out/electron.d.ts -+ - store_artifacts: -+ path: out/electron-api.json -+>>>>>>> .their - - workflows: - version: 2 -@@ -695,6 +1367,7 @@ - build-mas-x64: - jobs: - - electron-mas-x64 -+<<<<<<< .our - build-gn-linux: - jobs: - - electron-gn-linux-x64-debug-fyi -@@ -745,3 +1418,5 @@ - - electron-gn-linux-arm64-release-fyi - - electron-gn-mas-release-fyi - - electron-gn-osx-release-fyi -+======= -+>>>>>>> .their -changed in both - base 100644 8632e8e30869d32176552cd218560f5016a24300 .gitignore - our 100644 f393b1cdcef87b41bb3ed47ebae59757fed3a780 .gitignore - their 100644 f82d92052e4f7ac936637ac2c163633e02588f12 .gitignore -changed in both - base 100644 5d04da05397c4c74ce00d6d6c8969ce370adb32d CONTRIBUTING.md - our 100644 414f83db905db904728facf3b40e70e7b7973193 CONTRIBUTING.md - their 100644 0955f68c4f2b1097e770398cf51d3af811f53050 CONTRIBUTING.md -changed in both - base 100644 4cfea0e70f9af56ba746347b4cae410970f3d900 Dockerfile - our 100644 74e5eeedea9bea87cd7a98ac2cb63f4376275a2a Dockerfile - their 100644 2d74e16915d2e89e1e1e7f3ffd259cc448e1b864 Dockerfile -@@ -7,8 +7,13 @@ - RUN chmod a+rwx /home - - # Install node.js -+<<<<<<< .our - RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - - RUN apt-get install -y nodejs -+======= -+RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - -+RUN apt-get update && apt-get install -y nodejs -+>>>>>>> .their - - # Install wget used by crash reporter - RUN apt-get install -y wget -changed in both - base 100644 271947c56e39b91fc23bf10579f61cab50b0f4dc Dockerfile.circleci - our 100644 d369c8c640161fc3ba65935297aec7dd27eb1e9f Dockerfile.circleci - their 100644 0cdb1e88c24f01a5acdfd8ef348126819f593454 Dockerfile.circleci -@@ -3,8 +3,13 @@ - USER root - - # Install node.js -+<<<<<<< .our - RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - - RUN apt-get install -y nodejs -+======= -+RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - -+RUN apt-get update && apt-get install -y nodejs -+>>>>>>> .their - - # Install wget used by crash reporter - RUN apt-get install -y wget -added in remote - their 100644 c6d558f7f3518ea2924fa9075ed38ab48d70d204 Jenkinsfile.arm64 -@@ -0,0 +1,36 @@ -+pipeline { -+ agent { -+ docker { -+ image 'electronbuilds/arm64v8:0.0.2' -+ args '--privileged' -+ } -+ } -+ environment { -+ TARGET_ARCH='arm64' -+ DISPLAY=':99.0' -+ MOCHA_TIMEOUT='60000' -+ } -+ stages { -+ stage('Bootstrap') { -+ steps { -+ sh 'script/bootstrap.py -v --dev --target_arch=$TARGET_ARCH' -+ } -+ } -+ stage('Build') { -+ steps { -+ sh 'script/build.py -c D --ninja-path /usr/local/ninja/ninja' -+ } -+ } -+ stage('Test') { -+ steps { -+ sh '/etc/init.d/xvfb start' -+ sh 'script/test.py --ci' -+ } -+ } -+ } -+ post { -+ always { -+ cleanWs() -+ } -+ } -+} -changed in both - base 100644 160dae7908236105f8534f9448f4111da1bcb014 README.md - our 100644 ec09364417b767ac59b2d970fee5e2ab2db2173b README.md - their 100644 a7b4fa6ed40a6449245cfdbdace8bb38945284d2 README.md -added in both - our 100644 67a2b2124619d866f67d849f57f3548ba28be26a appveyor.yml - their 100644 2c4eaacb01d60137be83cf673bfa95d5d4b398e3 appveyor.yml -@@ -1,3 +1,4 @@ -+<<<<<<< .our - version: 1.0.{build} - branches: - except: -@@ -71,3 +72,72 @@ - & python script\upload.py - } - } -+======= -+build_cloud: electron-16 -+image: electron-16-vs2015 -+build_script: -+- ps: >- -+ if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) { -+ Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild -+ } else { -+ Add-Path "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64" -+ $env:path = "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64;$env:path" -+ if($env:APPVEYOR_SCHEDULED_BUILD -eq 'True') { -+ $env:RUN_RELEASE_BUILD = "1" -+ } -+ $Message = (git log --format=%B -n 1 HEAD) | Out-String -+ if ((Test-Path Env:\RUN_RELEASE_BUILD)) { -+ $env:ELECTRON_RELEASE = '1' -+ Write-Output "release build triggered from api" -+ } -+ if ((Test-Path Env:\ELECTRON_RELEASE)) { -+ Write-Output "Running release build" -+ python script\bootstrap.py --target_arch=$env:TARGET_ARCH -+ python script\build.py -c R -+ python script\create-dist.py -+ } else { -+ Write-Output "Running debug build" -+ python script\bootstrap.py --target_arch=$env:TARGET_ARCH --dev -+ python script\build.py -c D -+ } -+ if ($? -ne 'True') { -+ throw "Build failed with exit code $?" -+ } else { -+ "Build succeeded." -+ } -+ Push-AppveyorArtifact out -+ } -+test_script: -+- ps: >- -+ if (Test-Path Env:\ELECTRON_RELEASE) { -+ Write-Output "Skipping tests for release build" -+ } else { -+ Write-Output "Running tests for debug build" -+ python script\test.py --ci --rebuild_native_modules -+ if ($LASTEXITCODE -ne '0') { -+ throw "Tests failed with exit code $LASTEXITCODE" -+ } else { -+ Write-Output "Tests succeeded." -+ } -+ python script\verify-ffmpeg.py -+ if ($LASTEXITCODE -ne '0') { -+ throw "Verify ffmpeg failed with exit code $LASTEXITCODE" -+ } else { -+ "Verify ffmpeg succeeded." -+ } -+ } -+artifacts: -+- path: test-results.xml -+ name: test-results.xml -+deploy_script: -+- ps: >- -+ if (Test-Path Env:\ELECTRON_RELEASE) { -+ if (Test-Path Env:\RUN_RELEASE_BUILD) { -+ Write-Output "Uploading Electron release distribution to s3" -+ & python script\upload.py --upload_to_s3 -+ } else { -+ Write-Output "Uploading Electron release distribution to github releases" -+ & python script\upload.py -+ } -+ } -+>>>>>>> .their -changed in both - base 100644 9472d1cb9fd76beca4047bb24db024b9c6378aae atom/app/command_line_args.cc - our 100644 23e870cf4a32aecfc246a81edad46971b4456a55 atom/app/command_line_args.cc - their 100644 be171457726a09cde9eb7a090ba1e2a67f4cb9cb atom/app/command_line_args.cc -@@ -31,6 +31,1376 @@ - return false; - } - -+<<<<<<< .our -+======= -+/* -+ * The blacklist of command line switches, must be sorted. -+ * Update the list by pasting the following command into bash -+ * in libchromiumcontent/src/: -+ -+ (find ./ \( -name "*switches.cc" -o -name "*switch_list.h" \) | \ -+ xargs grep -P --no-filename '"\S+"[);]$' | \ -+ perl -pe 's|^.*?"(\S+)"[);]$| "$1",|'; \ -+ echo ' "inspect",'; \ -+ echo ' "inspect-brk",') | \ -+ LANG="C" sort | \ -+ uniq > blacklist-switches.txt -+ -+ */ -+const char* kBlacklist[] = { -+ "/prefetch:1", -+ "/prefetch:2", -+ "/prefetch:3", -+ "/prefetch:4", -+ "/prefetch:5", -+ "/prefetch:6", -+ "/prefetch:8", -+ "0", -+ "?", -+ "BlacklistOnly", -+ "ChromeOSMemoryPressureHandling", -+ "Disabled", -+ "OnlineCheckOnly", -+ "SafeSites", -+ "accept-resource-provider", -+ "account-consistency", -+ "adaboost", -+ "aec-refined-adaptive-filter", -+ "agc-startup-min-volume", -+ "aggressive", -+ "aggressive-cache-discard", -+ "aggressive-tab-discard", -+ "all-toolchains", -+ "allarticles", -+ "allow-cross-origin-auth-prompt", -+ "allow-external-pages", -+ "allow-failed-policy-fetch-for-test", -+ "allow-file-access-from-files", -+ "allow-hidden-media-playback", -+ "allow-http-background-page", -+ "allow-http-screen-capture", -+ "allow-insecure-localhost", -+ "allow-legacy-extension-manifests", -+ "allow-loopback-in-peer-connection", -+ "allow-nacl-crxfs-api", -+ "allow-nacl-file-handle-api", -+ "allow-nacl-socket-api", -+ "allow-no-sandbox-job", -+ "allow-outdated-plugins", -+ "allow-ra-in-dev-mode", -+ "allow-running-insecure-content", -+ "allow-sandbox-debugging", -+ "allow-silent-push", -+ "alsa-check-close-timeout", -+ "alsa-enable-upsampling", -+ "alsa-fixed-output-sample-rate", -+ "alsa-input-device", -+ "alsa-mute-device-name", -+ "alsa-mute-element-name", -+ "alsa-output-avail-min", -+ "alsa-output-buffer-size", -+ "alsa-output-device", -+ "alsa-output-period-size", -+ "alsa-output-start-threshold", -+ "alsa-volume-device-name", -+ "alsa-volume-element-name", -+ "also-emit-success-logs", -+ "alternative", -+ "always-authorize-plugins", -+ "always-on", -+ "always-use-complex-text", -+ "alwaystrue", -+ "android-fonts-path", -+ "android-stderr-port", -+ "android-stdin-port", -+ "android-stdout-port", -+ "angle", -+ "app", -+ "app-auto-launched", -+ "app-id", -+ "app-mode-auth-code", -+ "app-mode-oauth-token", -+ "app-mode-oem-manifest", -+ "app-shell-allow-roaming", -+ "app-shell-host-window-size", -+ "app-shell-preferred-network", -+ "app-shell-refresh-token", -+ "app-shell-user", -+ "apple", -+ "apps-gallery-download-url", -+ "apps-gallery-update-url", -+ "apps-gallery-url", -+ "apps-keep-chrome-alive-in-tests", -+ "arc-availability", -+ "arc-available", -+ "arc-start-mode", -+ "arc-transition-migration-required", -+ "args", -+ "artifacts-dir", -+ "ash-animate-from-boot-splash-screen", -+ "ash-constrain-pointer-to-root", -+ "ash-copy-host-background-at-boot", -+ "ash-debug-shortcuts", -+ "ash-dev-shortcuts", -+ "ash-disable-smooth-screen-rotation", -+ "ash-disable-touch-exploration-mode", -+ "ash-enable-magnifier-key-scroller", -+ "ash-enable-mirrored-screen", -+ "ash-enable-night-light", -+ "ash-enable-palette-on-all-displays", -+ "ash-enable-scale-settings-tray", -+ "ash-enable-software-mirroring", -+ "ash-enable-unified-desktop", -+ "ash-estimated-presentation-delay", -+ "ash-hide-notifications-for-factory", -+ "ash-host-window-bounds", -+ "ash-shelf-color", -+ "ash-shelf-color-scheme", -+ "ash-touch-hud", -+ "ash-webui-init", -+ "attestation-server", -+ "audio-buffer-size", -+ "audio-output-channels", -+ "aura-legacy-power-button", -+ "auth-ext-path", -+ "auth-server-whitelist", -+ "auth-spnego-account-type", -+ "auto", -+ "auto-open-devtools-for-tabs", -+ "auto-select-desktop-capture-source", -+ "autoplay-policy", -+ "blink-settings", -+ "bootstrap", -+ "browser-subprocess-path", -+ "browser-test", -+ "bwsi", -+ "bypass-app-banner-engagement-checks", -+ "canvas-msaa-sample-count", -+ "cast-initial-screen-height", -+ "cast-initial-screen-width", -+ "cc-layer-tree-test-long-timeout", -+ "cc-layer-tree-test-no-timeout", -+ "cc-rebaseline-pixeltests", -+ "cellular-first", -+ "cellular-only", -+ "check-for-update-interval", -+ "check-layout-test-sys-deps", -+ "child-wallpaper-large", -+ "child-wallpaper-small", -+ "chrome-home-swipe-logic", -+ "cipher-suite-blacklist", -+ "clamshell", -+ "class", -+ "clear-token-service", -+ "cloud-print-file", -+ "cloud-print-file-type", -+ "cloud-print-job-title", -+ "cloud-print-print-ticket", -+ "cloud-print-setup-proxy", -+ "cloud-print-url", -+ "cloud-print-xmpp-endpoint", -+ "color", -+ "compensate-for-unstable-pinch-zoom", -+ "compile-shader-always-succeeds", -+ "component-updater", -+ "connectivity-check-url", -+ "conservative", -+ "content-image-texture-target", -+ "content-shell-host-window-size", -+ "controller", -+ "crash-dumps-dir", -+ "crash-on-failure", -+ "crash-on-hang-threads", -+ "crash-server-url", -+ "crash-test", -+ "crashpad-handler", -+ "create-browser-on-startup-for-tests", -+ "create-default-gl-context", -+ "cros-gaia-api-v1", -+ "cros-region", -+ "cros-regions-mode", -+ "crosh-command", -+ "cryptauth-http-host", -+ "custom-devtools-frontend", -+ "custom-launcher-page", -+ "custom_summary", -+ "d3d11", -+ "d3d9", -+ "daemon", -+ "dark_muted", -+ "dark_vibrant", -+ "data-path", -+ "data-reduction-proxy-config-url", -+ "data-reduction-proxy-experiment", -+ "data-reduction-proxy-http-proxies", -+ "data-reduction-proxy-lo-fi", -+ "data-reduction-proxy-pingback-url", -+ "data-reduction-proxy-secure-proxy-check-url", -+ "data-reduction-proxy-server-experiments-disabled", -+ "dbus-stub", -+ "debug-devtools", -+ "debug-enable-frame-toggle", -+ "debug-packed-apps", -+ "debug-print", -+ "default", -+ "default-background-color", -+ "default-tile-height", -+ "default-tile-width", -+ "default-wallpaper-is-oem", -+ "default-wallpaper-large", -+ "default-wallpaper-small", -+ "delay-reload-stop-button-change", -+ "demo", -+ "derelict-detection-timeout", -+ "derelict-idle-timeout", -+ "desktop", -+ "desktop-window-1080p", -+ "deterministic-fetch", -+ "device-management-url", -+ "device-scale-factor", -+ "devtools-flags", -+ "diagnostics", -+ "diagnostics-format", -+ "diagnostics-recovery", -+ "dice", -+ "disable", -+ "disable-2d-canvas-clip-aa", -+ "disable-2d-canvas-image-chromium", -+ "disable-3d-apis", -+ "disable-accelerated-2d-canvas", -+ "disable-accelerated-jpeg-decoding", -+ "disable-accelerated-mjpeg-decode", -+ "disable-accelerated-video-decode", -+ "disable-app-info-dialog-mac", -+ "disable-app-list-dismiss-on-blur", -+ "disable-app-window-cycling", -+ "disable-appcontainer", -+ "disable-arc-data-wipe", -+ "disable-arc-opt-in-verification", -+ "disable-audio-support-for-desktop-share", -+ "disable-avfoundation-overlays", -+ "disable-background-networking", -+ "disable-background-timer-throttling", -+ "disable-backgrounding-occluded-windows", -+ "disable-backing-store-limit", -+ "disable-blink-features", -+ "disable-bookmark-reordering", -+ "disable-boot-animation", -+ "disable-breakpad", -+ "disable-browser-task-scheduler", -+ "disable-bundled-ppapi-flash", -+ "disable-canvas-aa", -+ "disable-captive-portal-bypass-proxy", -+ "disable-cast-streaming-hw-encoding", -+ "disable-checker-imaging", -+ "disable-clear-browsing-data-counters", -+ "disable-client-side-phishing-detection", -+ "disable-cloud-import", -+ "disable-component-cloud-policy", -+ "disable-component-extensions-with-background-pages", -+ "disable-component-update", -+ "disable-composited-antialiasing", -+ "disable-contextual-search", -+ "disable-d3d11", -+ "disable-databases", -+ "disable-datasaver-prompt", -+ "disable-default-apps", -+ "disable-demo-mode", -+ "disable-device-disabling", -+ "disable-device-discovery-notifications", -+ "disable-dinosaur-easter-egg", -+ "disable-direct-composition", -+ "disable-direct-composition-layers", -+ "disable-directwrite-for-ui", -+ "disable-display-color-calibration", -+ "disable-display-list-2d-canvas", -+ "disable-distance-field-text", -+ "disable-domain-blocking-for-3d-apis", -+ "disable-domain-reliability", -+ "disable-drive-search-in-app-launcher", -+ "disable-dwm-composition", -+ "disable-encryption-migration", -+ "disable-eol-notification", -+ "disable-es3-apis", -+ "disable-es3-gl-context", -+ "disable-extensions", -+ "disable-extensions-except", -+ "disable-extensions-file-access-check", -+ "disable-extensions-http-throttling", -+ "disable-fast-web-scroll-view-insets", -+ "disable-features", -+ "disable-field-trial-config", -+ "disable-file-manager-touch-mode", -+ "disable-file-system", -+ "disable-flash-3d", -+ "disable-flash-stage3d", -+ "disable-fullscreen-low-power-mode", -+ "disable-fullscreen-tab-detaching", -+ "disable-gaia-services", -+ "disable-gesture-editing", -+ "disable-gesture-requirement-for-presentation", -+ "disable-gesture-typing", -+ "disable-gl-drawing-for-tests", -+ "disable-gl-error-limit", -+ "disable-gl-extensions", -+ "disable-glsl-translator", -+ "disable-gpu", -+ "disable-gpu-compositing", -+ "disable-gpu-driver-bug-workarounds", -+ "disable-gpu-early-init", -+ "disable-gpu-memory-buffer-compositor-resources", -+ "disable-gpu-memory-buffer-video-frames", -+ "disable-gpu-process-crash-limit", -+ "disable-gpu-program-cache", -+ "disable-gpu-rasterization", -+ "disable-gpu-sandbox", -+ "disable-gpu-shader-disk-cache", -+ "disable-gpu-vsync", -+ "disable-gpu-watchdog", -+ "disable-hang-monitor", -+ "disable-hid-detection-on-oobe", -+ "disable-histogram-customizer", -+ "disable-hosted-app-shim-creation", -+ "disable-hosted-apps-in-windows", -+ "disable-http2", -+ "disable-in-process-stack-traces", -+ "disable-infobars", -+ "disable-input-ime-api", -+ "disable-input-view", -+ "disable-ios-password-generation", -+ "disable-ios-password-suggestions", -+ "disable-ios-physical-web", -+ "disable-javascript-harmony-shipping", -+ "disable-kill-after-bad-ipc", -+ "disable-lcd-text", -+ "disable-legacy-window", -+ "disable-local-storage", -+ "disable-lock-screen-apps", -+ "disable-logging", -+ "disable-logging-redirect", -+ "disable-login-animations", -+ "disable-login-screen-apps", -+ "disable-low-end-device-mode", -+ "disable-low-latency-dxva", -+ "disable-low-res-tiling", -+ "disable-lru-snapshot-cache", -+ "disable-mac-overlays", -+ "disable-mac-views-native-app-windows", -+ "disable-machine-cert-request", -+ "disable-main-frame-before-activation", -+ "disable-md-error-screen", -+ "disable-md-oobe", -+ "disable-media-session-api", -+ "disable-media-suspend", -+ "disable-merge-key-char-events", -+ "disable-mojo-local-storage", -+ "disable-mojo-renderer", -+ "disable-mtp-write-support", -+ "disable-multi-display-layout", -+ "disable-namespace-sandbox", -+ "disable-native-gpu-memory-buffers", -+ "disable-network-portal-notification", -+ "disable-new-channel-switcher-ui", -+ "disable-new-korean-ime", -+ "disable-new-virtual-keyboard-behavior", -+ "disable-new-zip-unpacker", -+ "disable-notifications", -+ "disable-ntp-most-likely-favicons-from-server", -+ "disable-ntp-popular-sites", -+ "disable-nv12-dxgi-video", -+ "disable-offer-store-unmasked-wallet-cards", -+ "disable-offer-upload-credit-cards", -+ "disable-office-editing-component-extension", -+ "disable-offline-auto-reload", -+ "disable-offline-auto-reload-visible-only", -+ "disable-origin-trial-controlled-blink-features", -+ "disable-overscroll-edge-effect", -+ "disable-panel-fitting", -+ "disable-partial-raster", -+ "disable-password-generation", -+ "disable-pepper-3d", -+ "disable-pepper-3d-image-chromium", -+ "disable-permission-action-reporting", -+ "disable-permissions-api", -+ "disable-physical-keyboard-autocorrect", -+ "disable-pinch", -+ "disable-pnacl-crash-throttling", -+ "disable-popup-blocking", -+ "disable-prefer-compositing-to-lcd-text", -+ "disable-presentation-api", -+ "disable-print-preview", -+ "disable-prompt-on-repost", -+ "disable-proximity-auth-bluetooth-low-energy-discovery", -+ "disable-pull-to-refresh-effect", -+ "disable-push-api-background-mode", -+ "disable-quic", -+ "disable-reading-from-canvas", -+ "disable-remote-core-animation", -+ "disable-remote-fonts", -+ "disable-remote-playback-api", -+ "disable-renderer-accessibility", -+ "disable-renderer-backgrounding", -+ "disable-renderer-priority-management", -+ "disable-request-mobile-site", -+ "disable-resize-lock", -+ "disable-rgba-4444-textures", -+ "disable-rollback-option", -+ "disable-rtc-smoothness-algorithm", -+ "disable-screen-orientation-lock", -+ "disable-search-geolocation-disclosure", -+ "disable-seccomp-filter-sandbox", -+ "disable-settings-window", -+ "disable-setuid-sandbox", -+ "disable-shader-name-hashing", -+ "disable-shared-workers", -+ "disable-signin-promo", -+ "disable-signin-scoped-device-id", -+ "disable-single-click-autofill", -+ "disable-skia-runtime-opts", -+ "disable-slim-navigation-manager", -+ "disable-slimming-paint-invalidation", -+ "disable-smooth-scrolling", -+ "disable-software-rasterizer", -+ "disable-speech-api", -+ "disable-suggestions-ui", -+ "disable-sync", -+ "disable-sync-app-list", -+ "disable-sync-types", -+ "disable-system-timezone-automatic-detection", -+ "disable-tab-for-desktop-share", -+ "disable-tab-strip-autoscroll-new-tabs", -+ "disable-third-party-keyboard-workaround", -+ "disable-threaded-animation", -+ "disable-threaded-compositing", -+ "disable-threaded-scrolling", -+ "disable-touch-adjustment", -+ "disable-touch-drag-drop", -+ "disable-translate-new-ux", -+ "disable-usb-keyboard-detect", -+ "disable-v8-idle-tasks", -+ "disable-vaapi-accelerated-video-encode", -+ "disable-virtual-keyboard-overscroll", -+ "disable-voice-input", -+ "disable-volume-adjust-sound", -+ "disable-wake-on-wifi", -+ "disable-web-notification-custom-layouts", -+ "disable-web-security", -+ "disable-webgl", -+ "disable-webgl-image-chromium", -+ "disable-webrtc-encryption", -+ "disable-webrtc-hw-decoding", -+ "disable-webrtc-hw-encoding", -+ "disable-win32k-lockdown", -+ "disable-xss-auditor", -+ "disable-zero-browsers-open-for-tests", -+ "disable-zero-copy", -+ "disable-zero-copy-dxgi-video", -+ "disabled", -+ "disabled-new-style-notification", -+ "disallow-non-exact-resource-reuse", -+ "disk-cache-dir", -+ "disk-cache-size", -+ "display", -+ "dmg-device", -+ "dns-log-details", -+ "document-user-activation-required", -+ "dom-automation", -+ "dotfile", -+ "draft", -+ "draw-view-bounds-rects", -+ "duck-flash", -+ "dump-blink-runtime-call-stats", -+ "dump-browser-histograms", -+ "dump-dom", -+ "eafe-path", -+ "eafe-url", -+ "easy-unlock-app-path", -+ "edge-touch-filtering", -+ "egl", -+ "elevate", -+ "embedded-extension-options", -+ "emphasize-titles-in-omnibox-dropdown", -+ "emulate-shader-precision", -+ "enable-accelerated-2d-canvas", -+ "enable-accelerated-vpx-decode", -+ "enable-accessibility-tab-switcher", -+ "enable-adaptive-selection-handle-orientation", -+ "enable-aggressive-domstorage-flushing", -+ "enable-android-wallpapers-app", -+ "enable-app-info-dialog-mac", -+ "enable-app-list", -+ "enable-app-window-cycling", -+ "enable-appcontainer", -+ "enable-arc", -+ "enable-arc-oobe-optin", -+ "enable-audio-debug-recordings-from-extension", -+ "enable-audio-focus", -+ "enable-automation", -+ "enable-benchmarking", -+ "enable-ble-advertising-in-apps", -+ "enable-blink-features", -+ "enable-bookmark-reordering", -+ "enable-bookmark-undo", -+ "enable-browser-side-navigation", -+ "enable-browser-task-scheduler", -+ "enable-checker-imaging", -+ "enable-chromevox-arc-support", -+ "enable-clear-browsing-data-counters", -+ "enable-cloud-print-proxy", -+ "enable-cloud-print-xps", -+ "enable-consumer-kiosk", -+ "enable-contextual-search", -+ "enable-crash-reporter", -+ "enable-crash-reporter-for-testing", -+ "enable-crx-hash-check", -+ "enable-data-reduction-proxy-bypass-warning", -+ "enable-data-reduction-proxy-force-pingback", -+ "enable-data-reduction-proxy-lite-page", -+ "enable-data-reduction-proxy-savings-promo", -+ "enable-datasaver-prompt", -+ "enable-device-discovery-notifications", -+ "enable-devtools-experiments", -+ "enable-direct-composition-layers", -+ "enable-display-list-2d-canvas", -+ "enable-distance-field-text", -+ "enable-distillability-service", -+ "enable-dom-distiller", -+ "enable-domain-reliability", -+ "enable-drive-search-in-app-launcher", -+ "enable-drm-atomic", -+ "enable-embedded-extension-options", -+ "enable-encryption-migration", -+ "enable-encryption-selection", -+ "enable-es3-apis", -+ "enable-exclusive-audio", -+ "enable-experimental-accessibility-features", -+ "enable-experimental-canvas-features", -+ "enable-experimental-extension-apis", -+ "enable-experimental-fullscreen-exit-ui", -+ "enable-experimental-input-view-features", -+ "enable-experimental-web-platform-features", -+ "enable-extension-activity-log-testing", -+ "enable-extension-activity-logging", -+ "enable-extension-assets-sharing", -+ "enable-fast-unload", -+ "enable-fast-web-scroll-view-insets", -+ "enable-features", -+ "enable-file-manager-touch-mode", -+ "enable-first-run-ui-transitions", -+ "enable-floating-virtual-keyboard", -+ "enable-font-antialiasing", -+ "enable-fullscreen-tab-detaching", -+ "enable-fullscreen-toolbar-reveal", -+ "enable-google-branded-context-menu", -+ "enable-gpu-async-worker-context", -+ "enable-gpu-benchmarking", -+ "enable-gpu-client-logging", -+ "enable-gpu-client-tracing", -+ "enable-gpu-command-logging", -+ "enable-gpu-debugging", -+ "enable-gpu-driver-debug-logging", -+ "enable-gpu-memory-buffer-compositor-resources", -+ "enable-gpu-memory-buffer-video-frames", -+ "enable-gpu-rasterization", -+ "enable-gpu-service-logging", -+ "enable-gpu-service-tracing", -+ "enable-hardware-overlays", -+ "enable-harfbuzz-rendertext", -+ "enable-hdr", -+ "enable-heap-profiling", -+ "enable-hosted-app-quit-notification", -+ "enable-hosted-apps-in-windows", -+ "enable-hotword-hardware", -+ "enable-hung-renderer-infobar", -+ "enable-inband-text-tracks", -+ "enable-input-ime-api", -+ "enable-internal-media-session", -+ "enable-ios-handoff-to-other-devices", -+ "enable-ios-password-generation", -+ "enable-ios-physical-web", -+ "enable-layer-lists", -+ "enable-lcd-text", -+ "enable-leak-detection", -+ "enable-local-file-accesses", -+ "enable-local-sync-backend", -+ "enable-logging", -+ "enable-longpress-drag-selection", -+ "enable-low-end-device-mode", -+ "enable-low-res-tiling", -+ "enable-lru-snapshot-cache", -+ "enable-mac-views-native-app-windows", -+ "enable-main-frame-before-activation", -+ "enable-md-feedback", -+ "enable-md-policy-page", -+ "enable-media-suspend", -+ "enable-merge-key-char-events", -+ "enable-message-center-always-scroll-up-upon-notification-removal", -+ "enable-nacl", -+ "enable-nacl-debug", -+ "enable-nacl-nonsfi-mode", -+ "enable-native-gpu-memory-buffers", -+ "enable-natural-scroll-default", -+ "enable-navigation-tracing", -+ "enable-net-benchmarking", -+ "enable-network-information-downlink-max", -+ "enable-network-portal-notification", -+ "enable-new-app-menu-icon", -+ "enable-ntp-most-likely-favicons-from-server", -+ "enable-ntp-popular-sites", -+ "enable-ntp-search-engine-country-detection", -+ "enable-offer-store-unmasked-wallet-cards", -+ "enable-offer-upload-credit-cards", -+ "enable-offline-auto-reload", -+ "enable-offline-auto-reload-visible-only", -+ "enable-osk-overscroll", -+ "enable-override-bookmarks-ui", -+ "enable-partial-raster", -+ "enable-password-generation", -+ "enable-pepper-testing", -+ "enable-permission-action-reporting", -+ "enable-physical-keyboard-autocorrect", -+ "enable-picture-in-picture", -+ "enable-pinch", -+ "enable-pixel-output-in-tests", -+ "enable-plugin-placeholder-testing", -+ "enable-potentially-annoying-security-features", -+ "enable-power-overlay", -+ "enable-precise-memory-info", -+ "enable-prefer-compositing-to-lcd-text", -+ "enable-print-browser", -+ "enable-print-preview-register-promos", -+ "enable-profile-shortcut-manager", -+ "enable-profiling", -+ "enable-push-api-background-mode", -+ "enable-quic", -+ "enable-reader-mode-toolbar-icon", -+ "enable-refresh-token-annotation-request", -+ "enable-request-tablet-site", -+ "enable-rgba-4444-textures", -+ "enable-sandbox", -+ "enable-sandbox-logging", -+ "enable-screenshot-testing-with-mode", -+ "enable-scripts-require-action", -+ "enable-scroll-prediction", -+ "enable-service-manager-tracing", -+ "enable-settings-window", -+ "enable-sgi-video-sync", -+ "enable-signin-promo", -+ "enable-single-click-autofill", -+ "enable-site-settings", -+ "enable-skia-benchmarking", -+ "enable-slim-navigation-manager", -+ "enable-slimming-paint-invalidation", -+ "enable-slimming-paint-v2", -+ "enable-smooth-scrolling", -+ "enable-spatial-navigation", -+ "enable-spdy-proxy-auth", -+ "enable-speech-dispatcher", -+ "enable-spelling-feedback-field-trial", -+ "enable-spotlight-actions", -+ "enable-stats-collection-bindings", -+ "enable-stats-table", -+ "enable-strict-mixed-content-checking", -+ "enable-strict-powerful-feature-restrictions", -+ "enable-suggestions-ui", -+ "enable-suggestions-with-substring-match", -+ "enable-supervised-user-managed-bookmarks-folder", -+ "enable-surface-synchronization", -+ "enable-swap-buffers-with-bounds", -+ "enable-sync-app-list", -+ "enable-sync-articles", -+ "enable-tab-audio-muting", -+ "enable-tablet-splitview", -+ "enable-tcp-fastopen", -+ "enable-third-party-keyboard-workaround", -+ "enable-threaded-compositing", -+ "enable-threaded-texture-mailboxes", -+ "enable-tile-compression", -+ "enable-touch-calibration-setting", -+ "enable-touch-drag-drop", -+ "enable-touchpad-three-finger-click", -+ "enable-touchview", -+ "enable-trace-app-source", -+ "enable-tracing", -+ "enable-tracing-output", -+ "enable-translate-new-ux", -+ "enable-ui-devtools", -+ "enable-use-zoom-for-dsf", -+ "enable-user-controlled-alternate-protocol-ports", -+ "enable-user-metrics", -+ "enable-usermedia-screen-capturing", -+ "enable-video-player-chromecast-support", -+ "enable-viewport", -+ "enable-virtual-keyboard", -+ "enable-voice-interaction", -+ "enable-vtune-support", -+ "enable-vulkan", -+ "enable-wayland-server", -+ "enable-web-notification-custom-layouts", -+ "enable-webfonts-intervention-trigger", -+ "enable-webfonts-intervention-v2", -+ "enable-webgl-draft-extensions", -+ "enable-webgl-image-chromium", -+ "enable-webrtc-event-logging-from-extension", -+ "enable-webrtc-srtp-aes-gcm", -+ "enable-webrtc-stun-origin", -+ "enable-webview-finch", -+ "enable-webvr", -+ "enable-wifi-credential-sync", -+ "enable-win7-webrtc-hw-h264-decoding", -+ "enable-zero-copy", -+ "enable-zip-archiver-on-file-manager", -+ "enabled", -+ "enabled-2g", -+ "enabled-3g", -+ "enabled-new-style-notification", -+ "enabled-slow2g", -+ "encode-binary", -+ "enforce", -+ "enforce-gl-minimums", -+ "enforce-webrtc-ip-permission-check", -+ "enforce_strict", -+ "enterprise-disable-arc", -+ "enterprise-enable-forced-re-enrollment", -+ "enterprise-enable-license-type-selection", -+ "enterprise-enable-zero-touch-enrollment", -+ "enterprise-enrollment-initial-modulus", -+ "enterprise-enrollment-modulus-limit", -+ "error-console", -+ "experiment", -+ "explicitly-allowed-ports", -+ "expose-internals-for-testing", -+ "extension-content-verification", -+ "extension-process", -+ "extensions-install-verification", -+ "extensions-multi-account", -+ "extensions-not-webstore", -+ "extensions-on-chrome-urls", -+ "extensions-update-frequency", -+ "extra-search-query-params", -+ "fail-on-unused-args", -+ "fake-variations-channel", -+ "false", -+ "fast", -+ "fast-start", -+ "feedback-server", -+ "field-trial-handle", -+ "first-exec-after-boot", -+ "flag-switches-begin", -+ "flag-switches-end", -+ "font-cache-shared-handle", -+ "force-android-app-mode", -+ "force-app-mode", -+ "force-clamshell-power-button", -+ "force-color-profile", -+ "force-desktop-ios-promotion", -+ "force-dev-mode-highlighting", -+ "force-device-scale-factor", -+ "force-display-list-2d-canvas", -+ "force-effective-connection-type", -+ "force-enable-metrics-reporting", -+ "force-enable-stylus-tools", -+ "force-fieldtrial-params", -+ "force-fieldtrials", -+ "force-first-run", -+ "force-first-run-ui", -+ "force-gpu-mem-available-mb", -+ "force-gpu-rasterization", -+ "force-happiness-tracking-system", -+ "force-load-easy-unlock-app-in-tests", -+ "force-local-ntp", -+ "force-login-manager-in-tests", -+ "force-mediafoundation", -+ "force-overlay-fullscreen-video", -+ "force-password-reauth", -+ "force-pnacl-subzero", -+ "force-renderer-accessibility", -+ "force-show-update-menu-badge", -+ "force-show-update-menu-item", -+ "force-system-compositor-mode", -+ "force-tablet-mode", -+ "force-text-direction", -+ "force-ui-direction", -+ "force-variation-ids", -+ "force-video-overlays", -+ "force-wave-audio", -+ "force-webrtc-ip-handling-policy", -+ "full-memory-crash-report", -+ "gaia-url", -+ "gcm-checkin-url", -+ "gcm-mcs-endpoint", -+ "gcm-registration-url", -+ "generate-accessibility-test-expectations", -+ "gl", -+ "gl-composited-overlay-candidate-quad-border", -+ "gl-shader-interm-output", -+ "gles", -+ "golden-screenshots-dir", -+ "google-apis-url", -+ "google-base-url", -+ "google-doodle-url", -+ "google-url", -+ "gpu-active-device-id", -+ "gpu-active-vendor-id", -+ "gpu-device-id", -+ "gpu-driver-bug-workarounds", -+ "gpu-driver-date", -+ "gpu-driver-vendor", -+ "gpu-driver-version", -+ "gpu-launcher", -+ "gpu-no-complete-info-collection", -+ "gpu-no-context-lost", -+ "gpu-process", -+ "gpu-program-cache-size-kb", -+ "gpu-rasterization-msaa-sample-count", -+ "gpu-sandbox-allow-sysv-shm", -+ "gpu-sandbox-failures-fatal", -+ "gpu-sandbox-start-early", -+ "gpu-secondary-device-ids", -+ "gpu-secondary-vendor-ids", -+ "gpu-startup-dialog", -+ "gpu-testing-device-id", -+ "gpu-testing-driver-date", -+ "gpu-testing-gl-renderer", -+ "gpu-testing-gl-vendor", -+ "gpu-testing-gl-version", -+ "gpu-testing-os-version", -+ "gpu-testing-secondary-device-ids", -+ "gpu-testing-secondary-vendor-ids", -+ "gpu-testing-vendor-id", -+ "gpu-vendor-id", -+ "guest-wallpaper-large", -+ "guest-wallpaper-small", -+ "h", -+ "has-chromeos-diamond-key", -+ "has-chromeos-keyboard", -+ "has-internal-stylus", -+ "headless", -+ "help", -+ "hide", -+ "hide-icons", -+ "hide-scrollbars", -+ "history-entry-requires-user-gesture", -+ "homedir", -+ "homepage", -+ "host", -+ "host-pairing-oobe", -+ "host-resolver-rules", -+ "host-rules", -+ "icu-data-dir", -+ "ignore-autocomplete-off-autofill", -+ "ignore-autoplay-restrictions", -+ "ignore-certificate-errors", -+ "ignore-certificate-errors-spki-list", -+ "ignore-gpu-blacklist", -+ "ignore-urlfetcher-cert-requests", -+ "ignore-user-profile-mapping-for-tests", -+ "in-process-gpu", -+ "incognito", -+ "input", -+ "inspect", -+ "inspect-brk", -+ "install-chrome-app", -+ "install-supervised-user-whitelists", -+ "instant-process", -+ "invalidation-use-gcm-channel", -+ "ipc-connection-timeout", -+ "ipc-dump-directory", -+ "ipc-fuzzer-testcase", -+ "is-running-in-mash", -+ "isolate-origins", -+ "isolate-sites-for-testing", -+ "javascript-harmony", -+ "js-flags", -+ "keep-alive-for-test", -+ "kiosk", -+ "kiosk-printing", -+ "lang", -+ "last-launched-app", -+ "layer", -+ "light_muted", -+ "light_vibrant", -+ "limit-fps", -+ "load-and-launch-app", -+ "load-apps", -+ "load-extension", -+ "load-media-router-component-extension", -+ "local-heuristics-only-for-password-generation", -+ "local-ntp-reload", -+ "local-sync-backend-dir", -+ "log-gpu-control-list-decisions", -+ "log-level", -+ "log-net-log", -+ "login-manager", -+ "login-profile", -+ "login-user", -+ "lso-url", -+ "ltr", -+ "main-frame-resizes-are-orientation-changes", -+ "make-chrome-default", -+ "make-default-browser", -+ "managed-user-id", -+ "managed-user-sync-token", -+ "mark-non-secure-as", -+ "markdown", -+ "market-url-for-testing", -+ "mash", -+ "material", -+ "material-design-ink-drop-animation-speed", -+ "material-hybrid", -+ "max-gum-fps", -+ "max-output-volume-dba1m", -+ "max-untiled-layer-height", -+ "max-untiled-layer-width", -+ "media-cache-size", -+ "mem-pressure-system-reserved-kb", -+ "memlog", -+ "memlog-pipe", -+ "memory-pressure-off", -+ "memory-pressure-thresholds", -+ "memory-pressure-thresholds-mb", -+ "message-center-changes-while-open", -+ "metrics-client-id", -+ "metrics-recording-only", -+ "mhtml-generator-option", -+ "mirror", -+ "mock", -+ "mojo-local-storage", -+ "mojo-pipe-token", -+ "monitoring-destination-id", -+ "mse-audio-buffer-size-limit", -+ "mse-video-buffer-size-limit", -+ "mus", -+ "mus-config", -+ "mute-audio", -+ "nacl-broker", -+ "nacl-dangerous-no-sandbox-nonsfi", -+ "nacl-debug-mask", -+ "nacl-gdb", -+ "nacl-gdb-script", -+ "nacl-loader", -+ "nacl-loader-nonsfi", -+ "native", -+ "native-crx-bindings", -+ "need-arc-migration-policy-check", -+ "net-log-capture-mode", -+ "netifs-to-ignore", -+ "network-country-iso", -+ "network-settings-config", -+ "new-window", -+ "no-default-browser-check", -+ "no-experiments", -+ "no-first-run", -+ "no-managed-user-acknowledgment-check", -+ "no-network-profile-warning", -+ "no-pings", -+ "no-proxy-server", -+ "no-referrers", -+ "no-sandbox", -+ "no-service-autorun", -+ "no-session-id", -+ "no-startup-window", -+ "no-user-gesture-required", -+ "no-wifi", -+ "no-zygote", -+ "nocolor", -+ "noerrdialogs", -+ "non-material", -+ "non-secure", -+ "non-secure-after-editing", -+ "non-secure-while-incognito", -+ "non-secure-while-incognito-or-editing", -+ "none", -+ "normal_muted", -+ "normal_vibrant", -+ "note-taking-app-ids", -+ "ntp-snippets-add-incomplete", -+ "ntp-switch-to-existing-tab", -+ "null", -+ "num-raster-threads", -+ "oauth2-client-id", -+ "oauth2-client-secret", -+ "off", -+ "on", -+ "oobe-bootstrapping-master", -+ "oobe-force-show-screen", -+ "oobe-guest-session", -+ "oobe-skip-postlogin", -+ "oobe-timer-interval", -+ "open-ash", -+ "opengraph", -+ "origin-to-force-quic-on", -+ "origin-trial-disabled-features", -+ "origin-trial-disabled-tokens", -+ "origin-trial-public-key", -+ "original-process-start-time", -+ "osmesa", -+ "output", -+ "override", -+ "override-metrics-upload-url", -+ "override-plugin-power-saver-for-testing", -+ "override-use-software-gl-for-tests", -+ "overscroll-history-navigation", -+ "overscroll-start-threshold", -+ "ozone-dump-file", -+ "ozone-platform", -+ "pack-extension", -+ "pack-extension-key", -+ "parent-profile", -+ "parent-window", -+ "passive-listeners-default", -+ "password-store", -+ "permission-request-api-scope", -+ "permission-request-api-url", -+ "ppapi", -+ "ppapi-antialiased-text-enabled", -+ "ppapi-broker", -+ "ppapi-flash-args", -+ "ppapi-flash-path", -+ "ppapi-flash-version", -+ "ppapi-in-process", -+ "ppapi-plugin-launcher", -+ "ppapi-startup-dialog", -+ "ppapi-subpixel-rendering-setting", -+ "prerender-from-omnibox", -+ "previous-app", -+ "primary", -+ "print-to-pdf", -+ "privet-ipv6-only", -+ "process-per-site", -+ "process-per-tab", -+ "product-version", -+ "profile-directory", -+ "profiler-timing", -+ "profiling", -+ "profiling-at-start", -+ "profiling-file", -+ "profiling-flush", -+ "progress-bar-animation", -+ "progress-bar-completion", -+ "prompt-for-external-extensions", -+ "proxy-auto-detect", -+ "proxy-bypass-list", -+ "proxy-pac-url", -+ "proxy-server", -+ "q", -+ "quic-connection-options", -+ "quic-max-packet-length", -+ "quic-version", -+ "rdp_desktop_session", -+ "reader-mode-feedback", -+ "reader-mode-heuristics", -+ "rebaseline-pixel-tests", -+ "record-type", -+ "reduce-security-for-testing", -+ "reduced-referrer-granularity", -+ "register-font-files", -+ "register-pepper-plugins", -+ "relauncher", -+ "remote-debugging-address", -+ "remote-debugging-port", -+ "remote-debugging-socket-fd", -+ "remote-debugging-socket-name", -+ "remote-debugging-targets", -+ "renderer", -+ "renderer-client-id", -+ "renderer-cmd-prefix", -+ "renderer-process-limit", -+ "renderer-startup-dialog", -+ "renderer-wait-for-java-debugger", -+ "renderpass", -+ "repl", -+ "report-vp9-as-an-unsupported-mime-type", -+ "require-audio-hardware-for-testing", -+ "reset-app-list-install-state", -+ "reset-variation-state", -+ "restore-last-session", -+ "root", -+ "root-layer-scrolls", -+ "rtl", -+ "run-layout-test", -+ "runtime-deps-list-file", -+ "safebrowsing-disable-auto-update", -+ "safebrowsing-disable-download-protection", -+ "safebrowsing-disable-extension-blacklist", -+ "safebrowsing-manual-download-blacklist", -+ "sandbox-ipc", -+ "save-page-as-mhtml", -+ "screen-config", -+ "screenshot", -+ "script-executable", -+ "scripts-require-action", -+ "scroll-end-effect", -+ "search-provider-logo-url", -+ "secondary", -+ "secondary-display-layout", -+ "secondary-ui-md", -+ "service", -+ "service-manager", -+ "service-name", -+ "service-pipe-token", -+ "service-request-channel-token", -+ "service-runner", -+ "shared-files", -+ "shill-stub", -+ "show-app-list", -+ "show-autofill-signatures", -+ "show-autofill-type-predictions", -+ "show-cert-link", -+ "show-component-extension-options", -+ "show-composited-layer-borders", -+ "show-fps-counter", -+ "show-icons", -+ "show-layer-animation-bounds", -+ "show-login-dev-overlay", -+ "show-mac-overlay-borders", -+ "show-md-login", -+ "show-non-md-login", -+ "show-overdraw-feedback", -+ "show-paint-rects", -+ "show-property-changed-rects", -+ "show-saved-copy", -+ "show-screenspace-rects", -+ "show-surface-damage-rects", -+ "silent-debugger-extension-api", -+ "silent-launch", -+ "simulate-critical-update", -+ "simulate-elevated-recovery", -+ "simulate-outdated", -+ "simulate-outdated-no-au", -+ "simulate-upgrade", -+ "single-process", -+ "site-per-process", -+ "skip-gpu-data-loading", -+ "skip-nostore-all", -+ "skip-nostore-main", -+ "skip-reencoding-on-skp-capture", -+ "slow", -+ "slow-connections-only", -+ "slow-down-raster-scale-factor", -+ "sms-test-messages", -+ "spdy-proxy-auth-fallback", -+ "spdy-proxy-auth-origin", -+ "spdy-proxy-auth-value", -+ "spelling-service-feedback-interval-seconds", -+ "spelling-service-feedback-url", -+ "spurious-power-button-accel-count", -+ "spurious-power-button-keyboard-accel", -+ "spurious-power-button-lid-angle-change", -+ "spurious-power-button-screen-accel", -+ "spurious-power-button-window", -+ "ssl-key-log-file", -+ "ssl-version-max", -+ "ssl-version-min", -+ "stable-release-mode", -+ "start-fullscreen", -+ "start-maximized", -+ "start-stack-profiler", -+ "started", -+ "stub", -+ "stub-cros-settings", -+ "supports-dual-gpus", -+ "surface", -+ "swiftshader", -+ "swiftshader-webgl", -+ "sync-allow-insecure-xmpp-connection", -+ "sync-deferred-startup-timeout-seconds", -+ "sync-disable-deferred-startup", -+ "sync-enable-get-update-avoidance", -+ "sync-notification-host-port", -+ "sync-on-draw-hardware", -+ "sync-short-initial-retry-override", -+ "sync-short-nudge-delay-for-test", -+ "sync-url", -+ "system-developer-mode", -+ "system-log-upload-frequency", -+ "tab-management-experiment-type-disabled", -+ "tab-management-experiment-type-elderberry", -+ "task-profiler", -+ "team-drives", -+ "test-auto-update-ui", -+ "test-child-process", -+ "test-cros-gaia-id-migration", -+ "test-do-not-initialize-icu", -+ "test-encryption-migration-ui", -+ "test-gl-lib", -+ "test-launcher-batch-limit", -+ "test-launcher-bot-mode", -+ "test-launcher-debug-launcher", -+ "test-launcher-filter-file", -+ "test-launcher-force-run-broken-tests", -+ "test-launcher-jobs", -+ "test-launcher-list-tests", -+ "test-launcher-output", -+ "test-launcher-print-test-stdio", -+ "test-launcher-print-writable-path", -+ "test-launcher-retry-limit", -+ "test-launcher-shard-index", -+ "test-launcher-summary-output", -+ "test-launcher-test-part-results-limit", -+ "test-launcher-timeout", -+ "test-launcher-total-shards", -+ "test-launcher-trace", -+ "test-name", -+ "test-tiny-timeout", -+ "test-type", -+ "testing-fixed-http-port", -+ "testing-fixed-https-port", -+ "tether-stub", -+ "threads", -+ "time", -+ "timeout", -+ "tls1", -+ "tls1.1", -+ "tls1.2", -+ "tls1.3", -+ "tls13-variant", -+ "top-chrome-md", -+ "top-controls-hide-threshold", -+ "top-controls-show-threshold", -+ "touch-calibration", -+ "touch-devices", -+ "touch-events", -+ "touch-noise-filtering", -+ "touch-selection-strategy", -+ "touch_view", -+ "trace-config-file", -+ "trace-export-events-to-etw", -+ "trace-shutdown", -+ "trace-shutdown-file", -+ "trace-startup", -+ "trace-startup-duration", -+ "trace-startup-file", -+ "trace-to-console", -+ "trace-to-file", -+ "trace-to-file-name", -+ "trace-upload-url", -+ "tracelog", -+ "translate-ranker-model-url", -+ "translate-script-url", -+ "translate-security-origin", -+ "true", -+ "trusted-download-sources", -+ "try-chrome-again", -+ "try-supported-channel-layouts", -+ "type", -+ "ui-disable-partial-swap", -+ "ui-enable-layer-lists", -+ "ui-enable-rgba-4444-textures", -+ "ui-enable-zero-copy", -+ "ui-prioritize-in-gpu-process", -+ "ui-show-composited-layer-borders", -+ "ui-show-fps-counter", -+ "ui-show-layer-animation-bounds", -+ "ui-show-paint-rects", -+ "ui-show-property-changed-rects", -+ "ui-show-screenspace-rects", -+ "ui-show-surface-damage-rects", -+ "ui-slow-animations", -+ "ui-test-action-max-timeout", -+ "ui-test-action-timeout", -+ "uninstall", -+ "unlimited-storage", -+ "unsafe-pac-url", -+ "unsafely-allow-protected-media-identifier-for-domain", -+ "unsafely-treat-insecure-origin-as-secure", -+ "use-angle", -+ "use-cras", -+ "use-double-buffering", -+ "use-fake-device-for-media-stream", -+ "use-fake-jpeg-decode-accelerator", -+ "use-fake-ui-for-media-stream", -+ "use-file-for-fake-audio-capture", -+ "use-file-for-fake-video-capture", -+ "use-first-display-as-internal", -+ "use-gl", -+ "use-gpu-in-tests", -+ "use-ime-service", -+ "use-mobile-user-agent", -+ "use-mock-keychain", -+ "use-passthrough-cmd-decoder", -+ "use-simple-cache-backend", -+ "use-system-default-printer", -+ "use-test-config", -+ "user-agent", -+ "user-always-affiliated", -+ "user-data-dir", -+ "user-gesture-required", -+ "user-gesture-required-for-cross-origin", -+ "utility", -+ "utility-allowed-dir", -+ "utility-cmd-prefix", -+ "utility-run-elevated", -+ "v", -+ "v2-sandbox", -+ "v2-sandbox-enabled", -+ "v8-cache-options", -+ "v8-cache-strategies-for-cache-storage", -+ "validate-crx", -+ "validate-input-event-stream", -+ "variations-override-country", -+ "variations-server-url", -+ "version", -+ "video-image-texture-target", -+ "video-threads", -+ "video-underflow-threshold-ms", -+ "virtual-time-budget", -+ "vmodule", -+ "voice-interaction-supported-locales", -+ "wait-for-debugger", -+ "wait-for-debugger-children", -+ "wake-on-wifi-packet", -+ "wallet-service-use-sandbox", -+ "watcher", -+ "waveout-buffers", -+ "webapk-server-url", -+ "webrtc-max-cpu-consumption-percentage", -+ "webrtc-stun-probe-trial", -+ "webview-enable-safebrowsing-support", -+ "webview-sandboxed-renderer", -+ "whitelisted-extension-id", -+ "win-jumplist-action", -+ "window-position", -+ "window-size", -+ "window-workspace", -+ "windows10-custom-titlebar", -+ "winhttp-proxy-resolver", -+ "wm-window-animations-disabled", -+ "yield-between-content-script-runs", -+ "zygote", -+ "zygote-cmd-prefix", -+}; -+ -+bool IsBlacklistedArg(const base::CommandLine::CharType* arg) { -+#if defined(OS_WIN) -+ const auto converted = base::WideToUTF8(arg); -+ const char* a = converted.c_str(); -+#else -+ const char* a = arg; -+#endif -+ -+ static const char* prefixes[] = {"--", "-", "/"}; -+ -+ int prefix_length = 0; -+ for (auto& prefix : prefixes) { -+ if (base::StartsWith(a, prefix, base::CompareCase::SENSITIVE)) { -+ prefix_length = strlen(prefix); -+ break; -+ } -+ } -+ -+ if (prefix_length > 0) { -+ a += prefix_length; -+ std::string switch_name = -+ base::ToLowerASCII(base::StringPiece(a, strcspn(a, "="))); -+ return std::binary_search(std::begin(kBlacklist), std::end(kBlacklist), -+ switch_name); -+ } -+ -+ return false; -+} -+ -+>>>>>>> .their - } // namespace - - namespace atom { -changed in both - base 100644 4bd88a5a43c03ceba308ec06fdf0cbadeddcaae3 atom/browser/api/atom_api_browser_view.cc - our 100644 bd83208694c61c4d7c43ce4be26939c2682b2a13 atom/browser/api/atom_api_browser_view.cc - their 100644 41f0e99cdd79bf1ad2c4c8c0db5aaa97ac5e1297 atom/browser/api/atom_api_browser_view.cc -changed in both - base 100644 cb5b9af26d8f21040a45ad7d1f0c4a23e7c8c445 atom/browser/api/atom_api_menu_mac.mm - our 100644 2b63b8a6cefe6265d96399dc6b70ab3ffdc352c3 atom/browser/api/atom_api_menu_mac.mm - their 100644 a2919e65d1b4ded98cb50884ead6763ed288e7c7 atom/browser/api/atom_api_menu_mac.mm -@@ -135,9 +135,15 @@ - // static - void Menu::SetApplicationMenu(Menu* base_menu) { - MenuMac* menu = static_cast<MenuMac*>(base_menu); -+<<<<<<< .our - base::scoped_nsobject<AtomMenuController> menu_controller([ - [AtomMenuController alloc] initWithModel:menu->model_.get() - useDefaultAccelerator:YES]); -+======= -+ base::scoped_nsobject<AtomMenuController> menu_controller( -+ [[AtomMenuController alloc] initWithModel:menu->model_.get() -+ useDefaultAccelerator:YES]); -+>>>>>>> .their - - NSRunLoop* currentRunLoop = [NSRunLoop currentRunLoop]; - [currentRunLoop cancelPerformSelector:@selector(setMainMenu:) -changed in both - base 100644 ced1cb31d8df7689f7652111720ba20fb029b1fe atom/browser/api/atom_api_menu_views.cc - our 100644 3da7dc2842fa4561e037aa67f290d0cc6ca71014 atom/browser/api/atom_api_menu_views.cc - their 100644 fa178e57d82413544b92172ae0ed4401ea5f178b atom/browser/api/atom_api_menu_views.cc -@@ -49,8 +49,16 @@ - menu_runners_[window_id] = - std::make_unique<MenuRunner>(model(), flags, close_callback); - menu_runners_[window_id]->RunMenuAt( -+<<<<<<< .our - native_window->widget(), NULL, gfx::Rect(location, gfx::Size()), - views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE); -+======= -+ native_window->widget(), -+ NULL, -+ gfx::Rect(location, gfx::Size()), -+ views::MENU_ANCHOR_TOPLEFT, -+ ui::MENU_SOURCE_MOUSE); -+>>>>>>> .their - } - - void MenuViews::ClosePopupAt(int32_t window_id) { -removed in local - base 100644 0d22fad5b8b5e3ed7711d55aa763f930014a75d7 atom/browser/api/atom_api_screen_mac.mm - their 100644 056b775fdfc221cb0501ba5b7afd8de01f2d4d63 atom/browser/api/atom_api_screen_mac.mm -changed in both - base 100644 6e5c4b9cbe77c1a4004bbc2bf7b0f0089ffb9004 atom/browser/api/atom_api_session.cc - our 100644 658f913bb60b66ae1bf3aae97d7d9158e56f7ee0 atom/browser/api/atom_api_session.cc - their 100644 d36812daa35dc795b667c190952b980f25d9e618 atom/browser/api/atom_api_session.cc -@@ -29,7 +29,6 @@ - #include "base/guid.h" - #include "base/strings/string_number_conversions.h" - #include "base/strings/string_util.h" --#include "base/threading/thread_task_runner_handle.h" - #include "brightray/browser/media/media_device_id_salt.h" - #include "chrome/browser/browser_process.h" - #include "chrome/common/pref_names.h" -@@ -46,8 +45,12 @@ - #include "net/dns/host_cache.h" - #include "net/http/http_auth_handler_factory.h" - #include "net/http/http_auth_preferences.h" -+<<<<<<< .our - #include "net/proxy_resolution/proxy_config_service_fixed.h" - #include "net/proxy_resolution/proxy_service.h" -+======= -+#include "net/proxy/proxy_config_service_fixed.h" -+>>>>>>> .their - #include "net/url_request/static_http_user_agent_settings.h" - #include "net/url_request/url_request_context.h" - #include "net/url_request/url_request_context_getter.h" -@@ -236,6 +239,7 @@ - // Referenced session objects. - std::map<uint32_t, v8::Global<v8::Object>> g_sessions; - -+<<<<<<< .our - class ResolveProxyHelper { - public: - ResolveProxyHelper(AtomBrowserContext* browser_context, -@@ -286,6 +290,8 @@ - DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper); - }; - -+======= -+>>>>>>> .their - // Runs the callback in UI thread. - void RunCallbackInUI(const base::Callback<void()>& callback) { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); -@@ -451,6 +457,7 @@ - AtomNetworkDelegate* network_delegate = - static_cast<AtomNetworkDelegate*>(context->network_delegate()); - network_delegate->SetDevToolsNetworkEmulationClientId(client_id); -+<<<<<<< .our - } - - void DestroyGlobalHandle(v8::Isolate* isolate, -@@ -468,6 +475,8 @@ - object->SetAlignedPointerInInternalField(0, nullptr); - } - } -+======= -+>>>>>>> .their - } - - } // namespace -@@ -513,8 +522,10 @@ - } - } - --void Session::ResolveProxy(const GURL& url, ResolveProxyCallback callback) { -- new ResolveProxyHelper(browser_context(), url, callback); -+void Session::ResolveProxy( -+ const GURL& url, -+ const ResolveProxyHelper::ResolveProxyCallback& callback) { -+ browser_context_->GetResolveProxyHelper()->ResolveProxy(url, callback); - } - - template <Session::CacheAction action> -changed in both - base 100644 d56c2400d4df9d197a03335c4e2b7e735065f301 atom/browser/api/atom_api_session.h - our 100644 6c8247c5c4a90e643712dd47d000d37d181a147b atom/browser/api/atom_api_session.h - their 100644 547f0e627b0ecf23e808b85cbd5173892479673f atom/browser/api/atom_api_session.h -@@ -10,6 +10,7 @@ - - #include "atom/browser/api/trackable_object.h" - #include "atom/browser/atom_blob_reader.h" -+#include "atom/browser/net/resolve_proxy_helper.h" - #include "base/values.h" - #include "content/public/browser/download_manager.h" - #include "native_mate/handle.h" -@@ -39,8 +40,6 @@ - class Session : public mate::TrackableObject<Session>, - public content::DownloadManager::Observer { - public: -- using ResolveProxyCallback = base::Callback<void(std::string)>; -- - enum class CacheAction { - CLEAR, - STATS, -@@ -63,8 +62,14 @@ - v8::Local<v8::FunctionTemplate> prototype); - - // Methods. -+<<<<<<< .our - void ResolveProxy(const GURL& url, ResolveProxyCallback callback); - template <CacheAction action> -+======= -+ void ResolveProxy(const GURL& url, -+ const ResolveProxyHelper::ResolveProxyCallback& callback); -+ template<CacheAction action> -+>>>>>>> .their - void DoCacheAction(const net::CompletionCallback& callback); - void ClearStorageData(mate::Arguments* args); - void FlushStorageData(); -changed in both - base 100644 83adf62eee8301c49799b5397f2dcf6bfdbbd295 atom/browser/api/atom_api_web_contents.cc - our 100644 20a1ac2e672f08ffea528b6e094ba530ff8083d1 atom/browser/api/atom_api_web_contents.cc - their 100644 9a19b727a82229565ec37e6a436bdbec4e670925 atom/browser/api/atom_api_web_contents.cc -@@ -124,6 +124,30 @@ - struct Converter<PrintSettings> { - static bool FromV8(v8::Isolate* isolate, - v8::Local<v8::Value> val, -+<<<<<<< .our -+======= -+ atom::SetSizeParams* out) { -+ mate::Dictionary params; -+ if (!ConvertFromV8(isolate, val, ¶ms)) -+ return false; -+ bool autosize; -+ if (params.Get("enableAutoSize", &autosize)) -+ out->enable_auto_size.reset(new bool(autosize)); -+ gfx::Size size; -+ if (params.Get("min", &size)) -+ out->min_size.reset(new gfx::Size(size)); -+ if (params.Get("max", &size)) -+ out->max_size.reset(new gfx::Size(size)); -+ if (params.Get("normal", &size)) -+ out->normal_size.reset(new gfx::Size(size)); -+ return true; -+ } -+}; -+ -+template<> -+struct Converter<PrintSettings> { -+ static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val, -+>>>>>>> .their - PrintSettings* out) { - mate::Dictionary dict; - if (!ConvertFromV8(isolate, val, &dict)) -@@ -280,7 +304,12 @@ - - // Called when CapturePage is done. - void OnCapturePageDone(const base::Callback<void(const gfx::Image&)>& callback, -+<<<<<<< .our - const SkBitmap& bitmap) { -+======= -+ const SkBitmap& bitmap, -+ content::ReadbackResponse response) { -+>>>>>>> .their - // Hack to enable transparency in captured image - // TODO(nitsakh) Remove hack once fixed in chromium - const_cast<SkBitmap&>(bitmap).setAlphaType(kPremul_SkAlphaType); -@@ -1015,6 +1044,18 @@ - content::RenderFrameHost* frame_host) { - bool handled = true; - FrameDispatchHelper helper = {this, frame_host}; -+<<<<<<< .our -+======= -+ auto relay = NativeWindowRelay::FromWebContents(web_contents()); -+ if (relay) { -+ IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(NativeWindow, message, frame_host) -+ IPC_MESSAGE_FORWARD(AtomAutofillFrameHostMsg_HidePopup, -+ relay->window.get(), NativeWindow::HideAutofillPopup) -+ IPC_MESSAGE_UNHANDLED(handled = false) -+ IPC_END_MESSAGE_MAP() -+ } -+ -+>>>>>>> .their - IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(WebContents, message, frame_host) - IPC_MESSAGE_HANDLER(AtomFrameHostMsg_Message, OnRendererMessage) - IPC_MESSAGE_FORWARD_DELAY_REPLY(AtomFrameHostMsg_Message_Sync, &helper, -@@ -1024,10 +1065,14 @@ - FrameDispatchHelper::OnSetTemporaryZoomLevel) - IPC_MESSAGE_FORWARD_DELAY_REPLY(AtomFrameHostMsg_GetZoomLevel, &helper, - FrameDispatchHelper::OnGetZoomLevel) -+<<<<<<< .our - #if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX) - IPC_MESSAGE_HANDLER(AtomAutofillFrameHostMsg_ShowPopup, ShowAutofillPopup) - IPC_MESSAGE_HANDLER(AtomAutofillFrameHostMsg_HidePopup, HideAutofillPopup) - #endif -+======= -+ IPC_MESSAGE_HANDLER(AtomAutofillFrameHostMsg_ShowPopup, ShowAutofillPopup) -+>>>>>>> .their - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - -@@ -1075,6 +1120,20 @@ - details.is_same_document, details.did_replace_entry); - } - -+<<<<<<< .our -+======= -+int64_t WebContents::GetIDForContents(content::WebContents* web_contents) { -+ int64_t process_id = web_contents->GetRenderProcessHost()->GetID(); -+ int64_t routing_id = web_contents->GetMainFrame()->GetRoutingID(); -+ int64_t rv = (process_id << 32) + routing_id; -+ return rv; -+} -+ -+int64_t WebContents::GetID() const { -+ return WebContents::GetIDForContents(web_contents()); -+} -+ -+>>>>>>> .their - int WebContents::GetProcessID() const { - return web_contents()->GetMainFrame()->GetProcess()->GetID(); - } -@@ -1552,7 +1611,11 @@ - bool WebContents::SendIPCMessage(bool all_frames, - const base::string16& channel, - const base::ListValue& args) { -+<<<<<<< .our - auto* frame_host = web_contents()->GetMainFrame(); -+======= -+ auto frame_host = web_contents()->GetMainFrame(); -+>>>>>>> .their - if (frame_host) { - return frame_host->Send(new AtomFrameMsg_Message( - frame_host->GetRoutingID(), all_frames, channel, args)); -@@ -1853,6 +1916,7 @@ - rfh->Send(reply_msg); - } - -+<<<<<<< .our - v8::Local<v8::Value> WebContents::GetPreloadPath(v8::Isolate* isolate) const { - if (auto* web_preferences = WebContentsPreferences::From(web_contents())) { - base::FilePath::StringType preload; -@@ -1880,6 +1944,25 @@ - } - - v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() const { -+======= -+v8::Local<v8::Value> WebContents::GetWebPreferences(v8::Isolate* isolate) { -+ WebContentsPreferences* web_preferences = -+ WebContentsPreferences::FromWebContents(web_contents()); -+ if (!web_preferences) -+ return v8::Null(isolate); -+ return mate::ConvertToV8(isolate, *web_preferences->web_preferences()); -+} -+ -+v8::Local<v8::Value> WebContents::GetLastWebPreferences(v8::Isolate* isolate) { -+ WebContentsPreferences* web_preferences = -+ WebContentsPreferences::FromWebContents(web_contents()); -+ if (!web_preferences) -+ return v8::Null(isolate); -+ return mate::ConvertToV8(isolate, *web_preferences->last_web_preferences()); -+} -+ -+v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() { -+>>>>>>> .their - if (owner_window()) - return BrowserWindow::From(isolate(), owner_window()); - else -@@ -2013,7 +2096,10 @@ - .SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription) - .SetMethod("startDrag", &WebContents::StartDrag) - .SetMethod("isGuest", &WebContents::IsGuest) -+<<<<<<< .our - .SetMethod("attachToIframe", &WebContents::AttachToIframe) -+======= -+>>>>>>> .their - .SetMethod("isOffscreen", &WebContents::IsOffScreen) - .SetMethod("startPainting", &WebContents::StartPainting) - .SetMethod("stopPainting", &WebContents::StopPainting) -changed in both - base 100644 16f23210557ca816cdeadd50b9332447eca8815f atom/browser/api/atom_api_web_contents.h - our 100644 7939f8268aa8c3371623e0c15f3b6001d7f1efa4 atom/browser/api/atom_api_web_contents.h - their 100644 027332a3706d5ac43a4a769234d361304bdc0350 atom/browser/api/atom_api_web_contents.h -@@ -97,6 +97,8 @@ - static void BuildPrototype(v8::Isolate* isolate, - v8::Local<v8::FunctionTemplate> prototype); - -+ static int64_t GetIDForContents(content::WebContents* web_contents); -+ - // Notifies to destroy any guest web contents before destroying self. - void DestroyWebContents(bool async); - -@@ -234,8 +236,13 @@ - v8::Local<v8::Value> GetPreloadPath(v8::Isolate* isolate) const; - - // Returns the web preferences of current WebContents. -+<<<<<<< .our - v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate) const; - v8::Local<v8::Value> GetLastWebPreferences(v8::Isolate* isolate) const; -+======= -+ v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate); -+ v8::Local<v8::Value> GetLastWebPreferences(v8::Isolate* isolate); -+>>>>>>> .their - - // Returns the owner window. - v8::Local<v8::Value> GetOwnerBrowserWindow() const; -changed in both - base 100644 3f53f4d3d7204f59037ba80556a2c9896e23aae4 atom/browser/api/atom_api_web_request.cc - our 100644 c088196f833160ac964e67030fa083302dd090b0 atom/browser/api/atom_api_web_request.cc - their 100644 ac84ac196b69a121a54dc64b87b7c2c1d6df21b5 atom/browser/api/atom_api_web_request.cc -@@ -40,7 +40,11 @@ - - namespace { - -+<<<<<<< .our - template <typename Method, typename Event, typename Listener> -+======= -+template<typename Method, typename Event, typename Listener> -+>>>>>>> .their - void CallNetworkDelegateMethod( - brightray::URLRequestContextGetter* url_request_context_getter, - Method method, -@@ -95,14 +99,24 @@ - } - - brightray::URLRequestContextGetter* url_request_context_getter = -+<<<<<<< .our - browser_context_->GetRequestContext(); -+======= -+ browser_context_->url_request_context_getter(); -+>>>>>>> .their - if (!url_request_context_getter) - return; - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, -+<<<<<<< .our - base::BindOnce(&CallNetworkDelegateMethod<Method, Event, Listener>, - base::RetainedRef(url_request_context_getter), method, - type, std::move(patterns), std::move(listener))); -+======= -+ base::Bind(&CallNetworkDelegateMethod<Method, Event, Listener>, -+ base::RetainedRef(url_request_context_getter), -+ method, type, std::move(patterns), std::move(listener))); -+>>>>>>> .their - } - - // static -removed in local - base 100644 993f9680ccb475f8870a2e3b4da2d20472531d91 atom/browser/api/atom_api_window.cc - their 100644 d177afb300f65ba14daa8c07042d4d768b00fd54 atom/browser/api/atom_api_window.cc -removed in local - base 100644 f86c387a34afb15920738413c6819176081b5ee7 atom/browser/api/atom_api_window.h - their 100644 e07f34e23f060906942b5fce81081965ea792204 atom/browser/api/atom_api_window.h -changed in both - base 100644 8810fed4b9aef78842fb65db93ed2efebabb6928 atom/browser/api/event.cc - our 100644 7b617034eca5a229fc9323bfd6d531ebded752d6 atom/browser/api/event.cc - their 100644 1ee0d57e36068c9b6427c278e9a7a5a66b7f8f79 atom/browser/api/event.cc -@@ -6,7 +6,10 @@ - - #include "atom/common/api/api_messages.h" - #include "atom/common/native_mate_converters/string16_converter.h" -+<<<<<<< .our - #include "atom/common/native_mate_converters/value_converter.h" -+======= -+>>>>>>> .their - #include "content/public/browser/render_frame_host.h" - #include "content/public/browser/web_contents.h" - #include "native_mate/object_template_builder.h" -@@ -27,6 +30,7 @@ - message_ = message; - - Observe(content::WebContents::FromRenderFrameHost(sender)); -+<<<<<<< .our - } - - void Event::RenderFrameDeleted(content::RenderFrameHost* rfh) { -@@ -42,6 +46,23 @@ - sender_ = new_rfh; - } - -+======= -+} -+ -+void Event::RenderFrameDeleted(content::RenderFrameHost* rfh) { -+ if (sender_ != rfh) -+ return; -+ sender_ = nullptr; -+ message_ = nullptr; -+} -+ -+void Event::RenderFrameHostChanged(content::RenderFrameHost* old_rfh, -+ content::RenderFrameHost* new_rfh) { -+ if (sender_ && sender_ == old_rfh) -+ sender_ = new_rfh; -+} -+ -+>>>>>>> .their - void Event::FrameDeleted(content::RenderFrameHost* rfh) { - if (sender_ != rfh) - return; -@@ -57,7 +78,11 @@ - if (message_ == nullptr || sender_ == nullptr) - return false; - -+<<<<<<< .our - AtomFrameHostMsg_Message_Sync::WriteReplyParams(message_, result); -+======= -+ AtomFrameHostMsg_Message_Sync::WriteReplyParams(message_, json); -+>>>>>>> .their - bool success = sender_->Send(message_); - message_ = nullptr; - sender_ = nullptr; -changed in both - base 100644 d73bd2f64b55b5eb0827f819805578559b947f46 atom/browser/api/event.h - our 100644 fbec8f27574691005d203adbafb50709f5c2d010 atom/browser/api/event.h - their 100644 05ad7daff8ac524294c1cacb66f876efc9716dd4 atom/browser/api/event.h -@@ -44,8 +44,13 @@ - - private: - // Replyer for the synchronous messages. -+<<<<<<< .our - content::RenderFrameHost* sender_ = nullptr; - IPC::Message* message_ = nullptr; -+======= -+ content::RenderFrameHost* sender_; -+ IPC::Message* message_; -+>>>>>>> .their - - DISALLOW_COPY_AND_ASSIGN(Event); - }; -changed in both - base 100644 3dbcd0601ef8a63cd6712b566cdc7f388c85e3ee atom/browser/api/event_emitter.cc - our 100644 c6e810b51225c8f89eaf53ac3e46381b52ba63b5 atom/browser/api/event_emitter.cc - their 100644 91769cbb94794a978732773612a3fec245acd750 atom/browser/api/event_emitter.cc -changed in both - base 100644 8d9d2960df35a33a09dfc79c4c35d424738df43f atom/browser/api/event_emitter.h - our 100644 5e4ca3b4ffcb184583ef386100eabda7a9e00da0 atom/browser/api/event_emitter.h - their 100644 8145113084a9c0c34ea808e3712879f5f70737c9 atom/browser/api/event_emitter.h -changed in both - base 100644 c83a99c2b38708ca296b4c9215e26cb58eb9a7d2 atom/browser/atom_browser_client.cc - our 100644 57c4ee582405e6d501ec23940ccb10689ecd64a1 atom/browser/atom_browser_client.cc - their 100644 5c442b32d70e1e1a51b79bfd2d093479ab518060 atom/browser/atom_browser_client.cc -@@ -343,6 +343,11 @@ - web_preferences->AppendCommandLineSwitches(command_line); - SessionPreferences::AppendExtraCommandLineSwitches( - web_contents->GetBrowserContext(), command_line); -+ -+ auto context_id = atom::api::WebContents::GetIDForContents( -+ web_contents); -+ command_line->AppendSwitchASCII(switches::kContextId, -+ base::IntToString(context_id)); - } - } - -@@ -497,7 +502,6 @@ - - brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts( - const content::MainFunctionParams&) { -- v8::V8::Initialize(); // Init V8 before creating main parts. - return new AtomBrowserMainParts; - } - -changed in both - base 100644 07b351b551b609e8b7201753b8969ad9dc6f6a52 atom/browser/atom_browser_context.cc - our 100644 e036cbc8103f19a034ce386940462f8a23ea6807 atom/browser/atom_browser_context.cc - their 100644 f297fbef0a6e75cdb5ca00c86090eb27e44031a7 atom/browser/atom_browser_context.cc -@@ -9,8 +9,18 @@ - #include "atom/browser/atom_download_manager_delegate.h" - #include "atom/browser/atom_permission_manager.h" - #include "atom/browser/browser.h" -+<<<<<<< .our - #include "atom/browser/request_context_delegate.h" - #include "atom/browser/special_storage_policy.h" -+======= -+#include "atom/browser/net/about_protocol_handler.h" -+#include "atom/browser/net/asar/asar_protocol_handler.h" -+#include "atom/browser/net/atom_cert_verifier.h" -+#include "atom/browser/net/atom_network_delegate.h" -+#include "atom/browser/net/atom_url_request_job_factory.h" -+#include "atom/browser/net/http_protocol_handler.h" -+#include "atom/browser/net/resolve_proxy_helper.h" -+>>>>>>> .their - #include "atom/browser/web_view_manager.h" - #include "atom/common/atom_version.h" - #include "atom/common/chrome_version.h" -@@ -133,6 +143,14 @@ - return blob_reader_.get(); - } - -+ResolveProxyHelper* AtomBrowserContext::GetResolveProxyHelper() { -+ if (!resolve_proxy_helper_.get()) { -+ resolve_proxy_helper_ = -+ base::MakeRefCounted<ResolveProxyHelper>(url_request_context_getter()); -+ } -+ return resolve_proxy_helper_.get(); -+} -+ - // static - scoped_refptr<AtomBrowserContext> AtomBrowserContext::From( - const std::string& partition, -changed in both - base 100644 359d3d6b71a5ea1d606b59d7f9b158a15baf1942 atom/browser/atom_browser_context.h - our 100644 9e6a841ceb8d11069a1a094bf7dbbd3a788918b3 atom/browser/atom_browser_context.h - their 100644 77469254db0a598a714d5c9ac3abefbe41ed89af atom/browser/atom_browser_context.h -@@ -20,8 +20,12 @@ - class AtomBlobReader; - class AtomDownloadManagerDelegate; - class AtomPermissionManager; -+<<<<<<< .our - class RequestContextDelegate; - class SpecialStoragePolicy; -+======= -+class ResolveProxyHelper; -+>>>>>>> .their - class WebViewManager; - - class AtomBrowserContext : public brightray::BrowserContext { -@@ -49,8 +53,16 @@ - void OnMainRequestContextCreated( - brightray::URLRequestContextGetter* getter) override; - -+<<<<<<< .our - RequestContextDelegate* GetRequestContextDelegate() const { - return request_context_delegate_.get(); -+======= -+ ResolveProxyHelper* GetResolveProxyHelper(); -+ -+ AtomBlobReader* GetBlobReader(); -+ AtomCookieDelegate* cookie_delegate() const { -+ return cookie_delegate_.get(); -+>>>>>>> .their - } - - protected: -@@ -60,8 +72,12 @@ - ~AtomBrowserContext() override; - - private: -+<<<<<<< .our - brightray::URLRequestContextGetter* url_request_context_getter_; - -+======= -+ scoped_refptr<ResolveProxyHelper> resolve_proxy_helper_; -+>>>>>>> .their - std::unique_ptr<AtomDownloadManagerDelegate> download_manager_delegate_; - std::unique_ptr<WebViewManager> guest_manager_; - std::unique_ptr<AtomPermissionManager> permission_manager_; -changed in both - base 100644 86d50d3c78bda4f4c61dedf43904f9243633d946 atom/browser/atom_browser_main_parts.cc - our 100644 5229b19ca9af7845a3f2f13b7e0913f633b68b1d atom/browser/atom_browser_main_parts.cc - their 100644 4ecd61b3ab14ceeebab78f95f44b0f1153ccb350 atom/browser/atom_browser_main_parts.cc -changed in both - base 100644 f16ee50158508565cc1e043d3257ad687cc69215 atom/browser/browser.cc - our 100644 ce35de64d60c6767ac52596c1b32e7bde5ceefa0 atom/browser/browser.cc - their 100644 3ba915f91eb3403df9630697e77cce9ed7fa3307 atom/browser/browser.cc -changed in both - base 100644 0970b26b776b34f68e5f22776e74c19ddcc039ad atom/browser/browser.h - our 100644 aed7d25c37da59c0dd5e09940a064c329353a0b2 atom/browser/browser.h - their 100644 a8c1a8c5e7c4409e3a78279da46fb2ba6112f409 atom/browser/browser.h -@@ -277,7 +277,11 @@ - bool is_ready_ = false; - - // The browser is being shutdown. -+<<<<<<< .our - bool is_shutdown_ = false; -+======= -+ bool is_shutdown_; -+>>>>>>> .their - - int badge_count_ = 0; - -changed in both - base 100644 0faeee36f9390b36bc5963b2f90d2063e3603109 atom/browser/browser_mac.mm - our 100644 27e347eccebf006336d5d110c81717ecc45af9c3 atom/browser/browser_mac.mm - their 100644 e47b8cb9d3c7fcf24279cd6e973a1b00a85ea25a atom/browser/browser_mac.mm -changed in both - base 100644 7c154b60b00e25c42847ceefb98723b50ea03dd0 atom/browser/native_browser_view.h - our 100644 56937e4c8c69e3605d2b6cc71a0877b74ff4e83d atom/browser/native_browser_view.h - their 100644 cab6980fa2cf035c1a5ca6b4aee822a0ee604fd4 atom/browser/native_browser_view.h -changed in both - base 100644 17b0a1ee9006dd70888165a9209076fd7065f3cc atom/browser/native_browser_view_mac.mm - our 100644 0416e26e89f1e0f37366ef1798b4359da0729225 atom/browser/native_browser_view_mac.mm - their 100644 86df632638ef7772270569824515b251470d0c08 atom/browser/native_browser_view_mac.mm -changed in both - base 100644 78e788b3019c23bce13fdc8d94385d4a3937cf22 atom/browser/native_browser_view_views.cc - our 100644 6414005a1e40d80ae86102b12edee0255cab9adb atom/browser/native_browser_view_views.cc - their 100644 def64d12e3520fa15a2b6779147a819a6eaec2f8 atom/browser/native_browser_view_views.cc -changed in both - base 100644 5dcda13447cde098fccaf8782fefb97d861d47f4 atom/browser/native_browser_view_views.h - our 100644 8f8e860292baddad1156c50ae7cfaa0fd6e87d99 atom/browser/native_browser_view_views.h - their 100644 abf47178302ad7527c1640a3f41492f871f137e5 atom/browser/native_browser_view_views.h -changed in both - base 100644 34778fb6434707e6ae3c70ab55e48e87eb556448 atom/browser/native_window.cc - our 100644 4ff2bcfcabfd34d8563f9ed213c03655a99dd9c6 atom/browser/native_window.cc - their 100644 26ac44607ebceadcde1d4c038890d914c888a0d5 atom/browser/native_window.cc -@@ -21,6 +21,11 @@ - #include "ui/display/win/screen_win.h" - #endif - -+#if defined(OS_WIN) -+#include "ui/base/win/shell.h" -+#include "ui/display/win/screen_win.h" -+#endif -+ - DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::NativeWindowRelay); - - namespace atom { -@@ -45,9 +50,29 @@ - - } // namespace - -+<<<<<<< .our - NativeWindow::NativeWindow(const mate::Dictionary& options, - NativeWindow* parent) - : widget_(new views::Widget), parent_(parent), weak_factory_(this) { -+======= -+NativeWindow::NativeWindow( -+ brightray::InspectableWebContents* inspectable_web_contents, -+ const mate::Dictionary& options, -+ NativeWindow* parent) -+ : content::WebContentsObserver(inspectable_web_contents->GetWebContents()), -+ has_frame_(true), -+ transparent_(false), -+ enable_larger_than_screen_(false), -+ is_closed_(false), -+ sheet_offset_x_(0.0), -+ sheet_offset_y_(0.0), -+ aspect_ratio_(0.0), -+ parent_(parent), -+ is_modal_(false), -+ is_osr_dummy_(false), -+ inspectable_web_contents_(inspectable_web_contents), -+ weak_factory_(this) { -+>>>>>>> .their - options.Get(options::kFrame, &has_frame_); - options.Get(options::kTransparent, &transparent_); - options.Get(options::kEnableLargerThanScreen, &enable_larger_than_screen_); -changed in both - base 100644 d1cfa7cc352971772689ecd60a110b48ef1a7eaa atom/browser/native_window.h - our 100644 35b67e2dd230692c415a32aae5f0a5e99ab74ac0 atom/browser/native_window.h - their 100644 61922aea78e3b61db614354e6a578fcda925096b atom/browser/native_window.h -@@ -220,6 +220,17 @@ - virtual void HandleKeyboardEvent( - content::WebContents*, - const content::NativeWebKeyboardEvent& event) {} -+<<<<<<< .our -+======= -+ virtual void ShowAutofillPopup(content::RenderFrameHost* frame_host, -+ content::WebContents* web_contents, -+ const gfx::RectF& bounds, -+ const std::vector<base::string16>& values, -+ const std::vector<base::string16>& labels) {} -+ virtual void HideAutofillPopup(content::RenderFrameHost* frame_host) {} -+>>>>>>> .their -+ -+ virtual void UpdateDraggableRegionViews() {} - - // Public API used by platform-dependent delegates and observers to send UI - // related notifications. -@@ -340,8 +351,13 @@ - class NativeWindowRelay - : public content::WebContentsUserData<NativeWindowRelay> { - public: -+<<<<<<< .our - explicit NativeWindowRelay(base::WeakPtr<NativeWindow> window); - ~NativeWindowRelay() override; -+======= -+ explicit NativeWindowRelay(base::WeakPtr<NativeWindow> window) -+ : key(UserDataKey()), window(window) {} -+>>>>>>> .their - - static void* UserDataKey() { - return content::WebContentsUserData<NativeWindowRelay>::UserDataKey(); -changed in both - base 100644 60d8fc23f59a842c100412b1c236b87d0815a7a0 atom/browser/native_window_mac.h - our 100644 44a78198f44cdba9875e3fb27c8e2c87eaa6f33b atom/browser/native_window_mac.h - their 100644 9e8c3aef87dd8d2d4a3260587b7013d260649b55 atom/browser/native_window_mac.h -@@ -118,8 +118,11 @@ - void MoveTabToNewWindow() override; - void ToggleTabBar() override; - bool AddTabbedWindow(NativeWindow* window) override; -+<<<<<<< .our - - bool SetWindowButtonVisibility(bool visible) override; -+======= -+>>>>>>> .their - - void SetVibrancy(const std::string& type) override; - void SetTouchBar( -@@ -130,8 +133,19 @@ - gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) const override; - gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) const override; - -+<<<<<<< .our - // Use a custom content view instead of Chromium's BridgedContentView. - void OverrideNSWindowContentView(); -+======= -+ // content::WebContentsObserver: -+ void RenderViewHostChanged(content::RenderViewHost* old_host, -+ content::RenderViewHost* new_host) override; -+ -+ // Refresh the DraggableRegion views. -+ void UpdateDraggableRegionViews() override { -+ UpdateDraggableRegionViews(draggable_regions_); -+ } -+>>>>>>> .their - - // Set the attribute of NSWindow while work around a bug of zoom button. - void SetStyleMask(bool on, NSUInteger flag); -changed in both - base 100644 ad1713e401240dbc1c2054551d0caeb41aea2884 atom/browser/native_window_mac.mm - our 100644 004263ec127709067e903ffbf31003b8844226b4 atom/browser/native_window_mac.mm - their 100644 0397c62d8df94b3ce66482c0d9c4b3b87ac97a45 atom/browser/native_window_mac.mm -@@ -28,9 +28,12 @@ - #include "skia/ext/skia_utils_mac.h" - #include "ui/gfx/skia_util.h" - #include "ui/gl/gpu_switching_manager.h" -+<<<<<<< .our - #include "ui/views/background.h" - #include "ui/views/cocoa/bridged_native_widget.h" - #include "ui/views/widget/widget.h" -+======= -+>>>>>>> .their - - // This view always takes the size of its superview. It is intended to be used - // as a NSWindow's contentView. It is needed because NSWindow's implementation -@@ -1144,10 +1147,17 @@ - } - - bool NativeWindowMac::AddTabbedWindow(NativeWindow* window) { -+<<<<<<< .our - if (window_ == window->GetNativeWindow()) { - return false; - } else { - if (@available(macOS 10.12, *)) -+======= -+ if (window_.get() == window->GetNativeWindow()) { -+ return false; -+ } else { -+ if ([window_ respondsToSelector:@selector(addTabbedWindow:ordered:)]) -+>>>>>>> .their - [window_ addTabbedWindow:window->GetNativeWindow() ordered:NSWindowAbove]; - } - return true; -@@ -1185,15 +1195,22 @@ - return; - } - -+<<<<<<< .our - background_color_before_vibrancy_.reset([[window_ backgroundColor] retain]); - transparency_before_vibrancy_ = [window_ titlebarAppearsTransparent]; - ui::GpuSwitchingManager::SetTransparent(true); -+======= -+ [vibrant_view removeFromSuperview]; -+ [window_ setVibrantView:nil]; -+ ui::GpuSwitchingManager::SetTransparent(transparent()); -+>>>>>>> .their - - if (title_bar_style_ != NORMAL) { - [window_ setTitlebarAppearsTransparent:YES]; - [window_ setBackgroundColor:[NSColor clearColor]]; - } - -+<<<<<<< .our - NSVisualEffectView* effect_view = (NSVisualEffectView*)vibrant_view; - if (effect_view == nil) { - effect_view = [[[NSVisualEffectView alloc] -@@ -1208,6 +1225,31 @@ - positioned:NSWindowBelow - relativeTo:nil]; - } -+======= -+ SetRenderWidgetHostOpaque(false); -+ background_color_before_vibrancy_.reset([window_ backgroundColor]); -+ transparency_before_vibrancy_ = [window_ titlebarAppearsTransparent]; -+ ui::GpuSwitchingManager::SetTransparent(true); -+ -+ if (title_bar_style_ != NORMAL) { -+ [window_ setTitlebarAppearsTransparent:YES]; -+ [window_ setBackgroundColor:[NSColor clearColor]]; -+ } -+ -+ NSVisualEffectView* effect_view = (NSVisualEffectView*)vibrant_view; -+ if (effect_view == nil) { -+ effect_view = [[[NSVisualEffectView alloc] -+ initWithFrame: [[window_ contentView] bounds]] autorelease]; -+ [window_ setVibrantView:(NSView*)effect_view]; -+ -+ [effect_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; -+ [effect_view setBlendingMode:NSVisualEffectBlendingModeBehindWindow]; -+ [effect_view setState:NSVisualEffectStateActive]; -+ [[window_ contentView] addSubview:effect_view -+ positioned:NSWindowBelow -+ relativeTo:nil]; -+ } -+>>>>>>> .their - - NSVisualEffectMaterial vibrancyType = NSVisualEffectMaterialLight; - -@@ -1387,6 +1429,7 @@ - [parent->GetNativeWindow() addChildWindow:window_ ordered:NSWindowAbove]; - } - -+<<<<<<< .our - void NativeWindowMac::ShowWindowButton(NSWindowButton button) { - auto view = [window_ standardWindowButton:button]; - [view.superview addSubview:view positioned:NSWindowAbove relativeTo:nil]; -@@ -1395,6 +1438,35 @@ - void NativeWindowMac::SetForwardMouseMessages(bool forward) { - [window_ setAcceptsMouseMovedEvents:forward]; - } -+======= -+ // Remove all ControlRegionViews that are added last time. -+ // Note that [webView subviews] returns the view's mutable internal array and -+ // it should be copied to avoid mutating the original array while enumerating -+ // it. -+ base::scoped_nsobject<NSArray> subviews([[webView subviews] copy]); -+ for (NSView* subview in subviews.get()) -+ if ([subview isKindOfClass:[ControlRegionView class]]) -+ [subview removeFromSuperview]; -+ -+ // Draggable regions is implemented by having the whole web view draggable -+ // (mouseDownCanMoveWindow) and overlaying regions that are not draggable. -+ std::vector<gfx::Rect> drag_exclude_rects = -+ CalculateNonDraggableRegions(regions, webViewWidth, webViewHeight); -+ -+ if (browser_view_) { -+ browser_view_->UpdateDraggableRegions(drag_exclude_rects); -+ } -+ -+ // Create and add a ControlRegionView for each region that needs to be -+ // excluded from the dragging. -+ for (const auto& rect : drag_exclude_rects) { -+ base::scoped_nsobject<NSView> controlRegion( -+ [[ControlRegionView alloc] initWithFrame:NSZeroRect]); -+ [controlRegion setFrame:NSMakeRect(rect.x(), webViewHeight - rect.bottom(), -+ rect.width(), rect.height())]; -+ [webView addSubview:controlRegion]; -+ } -+>>>>>>> .their - - void NativeWindowMac::OverrideNSWindowContentView() { - // When using `views::Widget` to hold WebContents, Chromium would use -changed in both - base 100644 008109970ec8d3c55a2028a173c3b941908d78a7 atom/browser/native_window_views.cc - our 100644 0dba39942f92d54ba34db7709b73012055680d94 atom/browser/native_window_views.cc - their 100644 f3e6fc09c5850cbc3d6989a2a94607b1f9a5d514 atom/browser/native_window_views.cc -@@ -1115,7 +1115,11 @@ - if (!active && IsMenuBarAutoHide() && IsMenuBarVisible()) - SetMenuBarVisibility(false); - -+<<<<<<< .our - root_view_->ResetAltState(); -+======= -+ menu_bar_alt_pressed_ = false; -+>>>>>>> .their - } - - void NativeWindowViews::OnWidgetBoundsChanged(views::Widget* changed_widget, -@@ -1237,9 +1241,138 @@ - void NativeWindowViews::HandleKeyboardEvent( - content::WebContents*, - const content::NativeWebKeyboardEvent& event) { -+<<<<<<< .our - keyboard_event_handler_->HandleKeyboardEvent(event, - root_view_->GetFocusManager()); - root_view_->HandleKeyEvent(event); -+======= -+ keyboard_event_handler_->HandleKeyboardEvent(event, GetFocusManager()); -+ -+ if (!menu_bar_) -+ return; -+ -+ // Show accelerator when "Alt" is pressed. -+ if (menu_bar_visible_ && IsAltKey(event)) -+ menu_bar_->SetAcceleratorVisibility( -+ event.GetType() == blink::WebInputEvent::kRawKeyDown); -+ -+ // Show the submenu when "Alt+Key" is pressed. -+ if (event.GetType() == blink::WebInputEvent::kRawKeyDown && -+ !IsAltKey(event) && IsAltModifier(event)) { -+ if (!menu_bar_visible_ && -+ (menu_bar_->HasAccelerator(event.windows_key_code))) -+ SetMenuBarVisibility(true); -+ menu_bar_->ActivateAccelerator(event.windows_key_code); -+ return; -+ } -+ -+ if (!menu_bar_autohide_) -+ return; -+ -+ // Toggle the menu bar only when a single Alt is released. -+ if (event.GetType() == blink::WebInputEvent::kRawKeyDown && IsAltKey(event)) { -+ // When a single Alt is pressed: -+ menu_bar_alt_pressed_ = true; -+ } else if (event.GetType() == blink::WebInputEvent::kKeyUp && -+ IsAltKey(event) && menu_bar_alt_pressed_) { -+ // When a single Alt is released right after a Alt is pressed: -+ menu_bar_alt_pressed_ = false; -+ SetMenuBarVisibility(!menu_bar_visible_); -+ } else { -+ // When any other keys except single Alt have been pressed/released: -+ menu_bar_alt_pressed_ = false; -+ } -+} -+ -+void NativeWindowViews::ShowAutofillPopup( -+ content::RenderFrameHost* frame_host, -+ content::WebContents* web_contents, -+ const gfx::RectF& bounds, -+ const std::vector<base::string16>& values, -+ const std::vector<base::string16>& labels) { -+ bool is_offsceen = false; -+ bool is_embedder_offscreen = false; -+ -+ auto* web_contents_preferences = -+ WebContentsPreferences::FromWebContents(web_contents); -+ if (web_contents_preferences) { -+ const auto* web_preferences = web_contents_preferences->web_preferences(); -+ -+ web_preferences->GetBoolean("offscreen", &is_offsceen); -+ int guest_instance_id = 0; -+ web_preferences->GetInteger(options::kGuestInstanceID, &guest_instance_id); -+ -+ if (guest_instance_id) { -+ auto manager = WebViewManager::GetWebViewManager(web_contents); -+ if (manager) { -+ auto embedder = manager->GetEmbedder(guest_instance_id); -+ if (embedder) { -+ is_embedder_offscreen = WebContentsPreferences::IsPreferenceEnabled( -+ "offscreen", embedder); -+ } -+ } -+ } -+ } -+ -+ autofill_popup_->CreateView( -+ frame_host, -+ is_offsceen || is_embedder_offscreen, -+ widget(), -+ bounds); -+ autofill_popup_->SetItems(values, labels); -+ autofill_popup_->UpdatePopupBounds(menu_bar_visible_ ? 0 : kMenuBarHeight); -+} -+ -+void NativeWindowViews::HideAutofillPopup( -+ content::RenderFrameHost* frame_host) { -+ autofill_popup_->Hide(); -+} -+ -+void NativeWindowViews::Layout() { -+ const auto size = GetContentsBounds().size(); -+ const auto menu_bar_bounds = -+ menu_bar_visible_ ? gfx::Rect(0, 0, size.width(), kMenuBarHeight) -+ : gfx::Rect(); -+ if (menu_bar_) { -+ menu_bar_->SetBoundsRect(menu_bar_bounds); -+ } -+ -+ if (web_view_) { -+ web_view_->SetBoundsRect( -+ gfx::Rect(0, menu_bar_bounds.height(), size.width(), -+ size.height() - menu_bar_bounds.height())); -+ } -+ -+ if (autofill_popup_.get()) -+ autofill_popup_->UpdatePopupBounds(menu_bar_visible_ ? 0 : kMenuBarHeight); -+} -+ -+gfx::Size NativeWindowViews::GetMinimumSize() const { -+ return NativeWindow::GetMinimumSize(); -+} -+ -+gfx::Size NativeWindowViews::GetMaximumSize() const { -+ return NativeWindow::GetMaximumSize(); -+} -+ -+bool NativeWindowViews::AcceleratorPressed(const ui::Accelerator& accelerator) { -+ return accelerator_util::TriggerAcceleratorTableCommand( -+ &accelerator_table_, accelerator); -+} -+ -+void NativeWindowViews::RegisterAccelerators(AtomMenuModel* menu_model) { -+ // Clear previous accelerators. -+ views::FocusManager* focus_manager = GetFocusManager(); -+ accelerator_table_.clear(); -+ focus_manager->UnregisterAccelerators(this); -+ -+ // Register accelerators with focus manager. -+ accelerator_util::GenerateAcceleratorTable(&accelerator_table_, menu_model); -+ for (const auto& iter : accelerator_table_) { -+ focus_manager->RegisterAccelerator( -+ iter.first, ui::AcceleratorManager::kNormalPriority, this); -+ } -+>>>>>>> .their - } - - ui::WindowShowState NativeWindowViews::GetRestoredState() { -changed in both - base 100644 a39e84ce5b8d7b757233dab4bed646e08cb8c76a atom/browser/net/asar/url_request_asar_job.cc - our 100644 85eb2e1dd142b6d64aafb5350ae47603db989e8f atom/browser/net/asar/url_request_asar_job.cc - their 100644 a6fe5e26540c9533f16dcf56fc955d0025de3b4a atom/browser/net/asar/url_request_asar_job.cc -changed in both - base 100644 9b0f3a98dc53b922c0d070244f8f7457f332d850 atom/browser/net/atom_network_delegate.cc - our 100644 e71ea74317b69f31a5aac8e723902748972fed8f atom/browser/net/atom_network_delegate.cc - their 100644 239a64016febb8f9d81206d7f2a7d100ccd1f293 atom/browser/net/atom_network_delegate.cc -@@ -250,6 +250,7 @@ - - AtomNetworkDelegate::~AtomNetworkDelegate() {} - -+<<<<<<< .our - void AtomNetworkDelegate::SetSimpleListenerInIO(SimpleEvent type, - URLPatterns patterns, - SimpleListener callback) { -@@ -266,6 +267,26 @@ - response_listeners_.erase(type); - else - response_listeners_[type] = {std::move(patterns), std::move(callback)}; -+======= -+void AtomNetworkDelegate::SetSimpleListenerInIO( -+ SimpleEvent type, -+ URLPatterns patterns, -+ SimpleListener callback) { -+ if (callback.is_null()) -+ simple_listeners_.erase(type); -+ else -+ simple_listeners_[type] = { std::move(patterns), std::move(callback) }; -+} -+ -+void AtomNetworkDelegate::SetResponseListenerInIO( -+ ResponseEvent type, -+ URLPatterns patterns, -+ ResponseListener callback) { -+ if (callback.is_null()) -+ response_listeners_.erase(type); -+ else -+ response_listeners_[type] = { std::move(patterns), std::move(callback) }; -+>>>>>>> .their - } - - void AtomNetworkDelegate::SetDevToolsNetworkEmulationClientId( -changed in both - base 100644 e00c26ff2cbc134b987b4361896971e48056951d atom/browser/net/atom_network_delegate.h - our 100644 39a7a8ddfcda17fd7d022331132b54485d07a279 atom/browser/net/atom_network_delegate.h - their 100644 ad37a926d4732d94526f74b2f927e35504d2efe3 atom/browser/net/atom_network_delegate.h -added in remote - their 100644 fde8718f89c5d4d4a6dd0a9b08353832c07902c5 atom/browser/net/resolve_proxy_helper.cc -@@ -0,0 +1,85 @@ -+// Copyright (c) 2018 GitHub, Inc. -+// Use of this source code is governed by the MIT license that can be -+// found in the LICENSE file. -+ -+#include "atom/browser/net/resolve_proxy_helper.h" -+ -+#include "base/threading/thread_task_runner_handle.h" -+#include "net/url_request/url_request_context.h" -+#include "net/url_request/url_request_context_getter.h" -+ -+namespace atom { -+ -+ResolveProxyHelper::ResolveProxyHelper(net::URLRequestContextGetter* getter) -+ : context_getter_(getter), -+ original_thread_(base::ThreadTaskRunnerHandle::Get()) {} -+ -+ResolveProxyHelper::~ResolveProxyHelper() { -+ // Clear all pending requests if the ProxyService is still alive. -+ pending_requests_.clear(); -+} -+ -+void ResolveProxyHelper::ResolveProxy(const GURL& url, -+ const ResolveProxyCallback& callback) { -+ // Enqueue the pending request. -+ pending_requests_.push_back(PendingRequest(url, callback)); -+ -+ // If nothing is in progress, start. -+ if (pending_requests_.size() == 1) -+ StartPendingRequest(); -+} -+ -+void ResolveProxyHelper::SendProxyResult(const std::string& proxy) { -+ CHECK(!pending_requests_.empty()); -+ -+ const auto& completed_request = pending_requests_.front(); -+ if (!completed_request.callback.is_null()) -+ completed_request.callback.Run(proxy); -+ -+ // Clear the current (completed) request. -+ pending_requests_.pop_front(); -+ -+ // Start the next request. -+ if (!pending_requests_.empty()) -+ StartPendingRequest(); -+} -+ -+void ResolveProxyHelper::StartPendingRequest() { -+ auto& request = pending_requests_.front(); -+ context_getter_->GetNetworkTaskRunner()->PostTask( -+ FROM_HERE, -+ base::BindOnce(&ResolveProxyHelper::StartPendingRequestInIO, -+ base::Unretained(this), request.url, request.pac_req)); -+} -+ -+void ResolveProxyHelper::OnResolveProxyCompleted(int result) { -+ std::string proxy; -+ if (result == net::OK) -+ proxy = proxy_info_.ToPacString(); -+ -+ original_thread_->PostTask( -+ FROM_HERE, base::BindOnce(&ResolveProxyHelper::SendProxyResult, -+ base::Unretained(this), proxy)); -+} -+ -+void ResolveProxyHelper::StartPendingRequestInIO( -+ const GURL& url, -+ net::ProxyService::PacRequest* pac_req) { -+ // Verify the request wasn't started yet. -+ DCHECK(nullptr == pac_req); -+ -+ auto proxy_service = context_getter_->GetURLRequestContext()->proxy_service(); -+ -+ // Start the request. -+ int result = proxy_service->ResolveProxy( -+ url, std::string(), &proxy_info_, -+ base::Bind(&ResolveProxyHelper::OnResolveProxyCompleted, -+ base::Unretained(this)), -+ &pac_req, nullptr, net::NetLogWithSource()); -+ -+ // Completed synchronously. -+ if (result != net::ERR_IO_PENDING) -+ OnResolveProxyCompleted(result); -+} -+ -+} // namespace atom -added in remote - their 100644 cc85d4ff62ce753ff4ba1fc5979760b5e5d768a6 atom/browser/net/resolve_proxy_helper.h -@@ -0,0 +1,59 @@ -+// Copyright (c) 2018 GitHub, Inc. -+// Use of this source code is governed by the MIT license that can be -+// found in the LICENSE file. -+ -+#ifndef ATOM_BROWSER_NET_RESOLVE_PROXY_HELPER_H_ -+#define ATOM_BROWSER_NET_RESOLVE_PROXY_HELPER_H_ -+ -+#include <deque> -+#include <string> -+ -+#include "base/memory/ref_counted.h" -+#include "net/proxy/proxy_service.h" -+#include "url/gurl.h" -+ -+namespace net { -+class URLRequestContextGetter; -+} -+ -+namespace atom { -+ -+class ResolveProxyHelper -+ : public base::RefCountedThreadSafe<ResolveProxyHelper> { -+ public: -+ using ResolveProxyCallback = base::Callback<void(std::string)>; -+ explicit ResolveProxyHelper(net::URLRequestContextGetter* getter); -+ -+ void ResolveProxy(const GURL& url, const ResolveProxyCallback& callback); -+ -+ private: -+ friend class base::RefCountedThreadSafe<ResolveProxyHelper>; -+ struct PendingRequest { -+ public: -+ PendingRequest(const GURL& url, const ResolveProxyCallback& callback) -+ : url(url), callback(callback), pac_req(nullptr) {} -+ -+ GURL url; -+ ResolveProxyCallback callback; -+ net::ProxyService::PacRequest* pac_req; -+ }; -+ -+ ~ResolveProxyHelper(); -+ -+ void StartPendingRequest(); -+ void StartPendingRequestInIO(const GURL& request, -+ net::ProxyService::PacRequest* pac_req); -+ void SendProxyResult(const std::string& proxy); -+ void OnResolveProxyCompleted(int result); -+ -+ net::ProxyInfo proxy_info_; -+ std::deque<PendingRequest> pending_requests_; -+ scoped_refptr<net::URLRequestContextGetter> context_getter_; -+ scoped_refptr<base::SingleThreadTaskRunner> original_thread_; -+ -+ DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper); -+}; -+ -+} // namespace atom -+ -+#endif // ATOM_BROWSER_NET_RESOLVE_PROXY_HELPER_H_ -changed in both - base 100644 3313eba36bb903426778fac6cd18258a95fec677 atom/browser/resources/mac/Info.plist - our 100644 9094f0f7335edf833d51f688851e6a105de60433 atom/browser/resources/mac/Info.plist - their 100644 35e7c7c7db7078814e62dec008da8ed1e8130940 atom/browser/resources/mac/Info.plist -@@ -17,9 +17,15 @@ - <key>CFBundleIconFile</key> - <string>electron.icns</string> - <key>CFBundleVersion</key> -+<<<<<<< .our - <string>4.0.0</string> - <key>CFBundleShortVersionString</key> - <string>4.0.0</string> -+======= -+ <string>2.0.8</string> -+ <key>CFBundleShortVersionString</key> -+ <string>2.0.8</string> -+>>>>>>> .their - <key>LSApplicationCategoryType</key> - <string>public.app-category.developer-tools</string> - <key>LSMinimumSystemVersion</key> -changed in both - base 100644 c349f99d712ff69960d35b18587ddb6c417f7cd5 atom/browser/resources/win/atom.rc - our 100644 c0bd831e8bddf10180f75cd40694831e2e98622d atom/browser/resources/win/atom.rc - their 100644 0a45ab66c64dd400f7928e5eaed7c24a0eea60de atom/browser/resources/win/atom.rc -@@ -56,8 +56,13 @@ - // - - VS_VERSION_INFO VERSIONINFO -+<<<<<<< .our - FILEVERSION 4,0,0,20180821 - PRODUCTVERSION 4,0,0,20180821 -+======= -+ FILEVERSION 2,0,8,0 -+ PRODUCTVERSION 2,0,8,0 -+>>>>>>> .their - FILEFLAGSMASK 0x3fL - #ifdef _DEBUG - FILEFLAGS 0x1L -@@ -74,12 +79,20 @@ - BEGIN - VALUE "CompanyName", "GitHub, Inc." - VALUE "FileDescription", "Electron" -+<<<<<<< .our - VALUE "FileVersion", "4.0.0" -+======= -+ VALUE "FileVersion", "2.0.8" -+>>>>>>> .their - VALUE "InternalName", "electron.exe" - VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." - VALUE "OriginalFilename", "electron.exe" - VALUE "ProductName", "Electron" -+<<<<<<< .our - VALUE "ProductVersion", "4.0.0" -+======= -+ VALUE "ProductVersion", "2.0.8" -+>>>>>>> .their - VALUE "SquirrelAwareVersion", "1" - END - END -changed in both - base 100644 8bdf4e0c2be32fc7d704bc989d7ccec5dd5db672 atom/browser/ui/cocoa/atom_menu_controller.mm - our 100644 cecf30ce1c88e007957a65427648941765a6067e atom/browser/ui/cocoa/atom_menu_controller.mm - their 100644 ea141b495e710222f12913f35625cf435b947e18 atom/browser/ui/cocoa/atom_menu_controller.mm -@@ -334,8 +334,13 @@ - if (isMenuOpen_) { - isMenuOpen_ = NO; - model_->MenuWillClose(); -+<<<<<<< .our - // Post async task so that itemSelected runs before the close callback - // deletes the controller from the map which deallocates it -+======= -+ // Post async task so that itemSelected runs before the close callback -+ // deletes the controller from the map which deallocates it -+>>>>>>> .their - if (!closeCallback.is_null()) { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, closeCallback); - } -changed in both - base 100644 b26d472db131f7be9d5bfbbd1cebfc992743d312 atom/browser/ui/file_dialog_mac.mm - our 100644 18b18a8b240cda5512ae49e0afde5c749bdf75c0 atom/browser/ui/file_dialog_mac.mm - their 100644 89ecaf46ec7f32ca4f3a3a89de13efcbdad5619f atom/browser/ui/file_dialog_mac.mm -@@ -27,9 +27,12 @@ - - @implementation PopUpButtonHandler - -+<<<<<<< .our - @synthesize savePanel; - @synthesize fileTypesList; - -+======= -+>>>>>>> .their - - (instancetype)initWithPanel:(NSSavePanel*)panel - andTypesList:(NSArray*)typesList { - self = [super init]; -@@ -55,6 +58,7 @@ - } - - @end -+<<<<<<< .our - - // Manages the PopUpButtonHandler. - @interface AtomAccessoryView : NSView -@@ -65,6 +69,17 @@ - - (void)dealloc { - auto* popupButton = - static_cast<NSPopUpButton*>([[self subviews] objectAtIndex:1]); -+======= -+ -+// Manages the PopUpButtonHandler. -+@interface AtomAccessoryView : NSView -+@end -+ -+@implementation AtomAccessoryView -+ -+- (void)dealloc { -+ auto* popupButton = static_cast<NSPopUpButton*>([[self subviews] objectAtIndex: 1]); -+>>>>>>> .their - [[popupButton target] release]; - [super dealloc]; - } -@@ -76,8 +91,11 @@ - DialogSettings::DialogSettings() = default; - DialogSettings::~DialogSettings() = default; - -+<<<<<<< .our - namespace { - -+======= -+>>>>>>> .their - void SetAllowedFileTypes(NSSavePanel* dialog, const Filters& filters) { - NSMutableArray* file_types_list = [NSMutableArray array]; - NSMutableArray* filter_names = [NSMutableArray array]; -@@ -85,9 +103,18 @@ - // Create array to keep file types and their name. - for (const Filter& filter : filters) { - NSMutableSet* file_type_set = [NSMutableSet set]; -+<<<<<<< .our - [filter_names addObject:@(filter.first.c_str())]; - for (const std::string& ext : filter.second) { - [file_type_set addObject:@(ext.c_str())]; -+======= -+ base::ScopedCFTypeRef<CFStringRef> name_cf( -+ base::SysUTF8ToCFStringRef(filter.first)); -+ [filter_names addObject:base::mac::CFToNSCast(name_cf.get())]; -+ for (const std::string& ext : filter.second) { -+ base::ScopedCFTypeRef<CFStringRef> ext_cf(base::SysUTF8ToCFStringRef(ext)); -+ [file_type_set addObject:base::mac::CFToNSCast(ext_cf.get())]; -+>>>>>>> .their - } - [file_types_list addObject:[file_type_set allObjects]]; - } -@@ -119,12 +146,19 @@ - [label setBezeled:NO]; - [label setDrawsBackground:NO]; - -+<<<<<<< .our - NSPopUpButton* popupButton = - [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) - pullsDown:NO]; - PopUpButtonHandler* popUpButtonHandler = - [[PopUpButtonHandler alloc] initWithPanel:dialog - andTypesList:file_types_list]; -+======= -+ NSPopUpButton* popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) -+ pullsDown:NO]; -+ PopUpButtonHandler* popUpButtonHandler = [[PopUpButtonHandler alloc] initWithPanel:dialog -+ andTypesList:file_types_list]; -+>>>>>>> .their - [popupButton addItemsWithTitles:filter_names]; - [popupButton setTarget:popUpButtonHandler]; - [popupButton setAction:@selector(selectFormat:)]; -changed in both - base 100644 17c66043a27f76077f20ac4ff61522fac0bb2b51 atom/browser/ui/message_box_mac.mm - our 100644 ee2f59dc8c84ba0bf5fe049a133f403d550a9473 atom/browser/ui/message_box_mac.mm - their 100644 a98ce79bf97165b5693cb05f6ebaa4e9617a89da atom/browser/ui/message_box_mac.mm -changed in both - base 100644 a358f676a8c41d15bb9c3157cce4a62ef8356855 atom/browser/ui/tray_icon_cocoa.mm - our 100644 2c434d7a9e312adfb3802628a3d092a95d4ac49f atom/browser/ui/tray_icon_cocoa.mm - their 100644 aedce38f656eaab389502df98bb20b28e3e3619a atom/browser/ui/tray_icon_cocoa.mm -@@ -240,13 +240,22 @@ - } - - // check title_ being nil -+<<<<<<< .our - NSString* title = @""; -+======= -+ NSString *title = @""; -+>>>>>>> .their - if (title_) - title = title_; - - attributedTitle_.reset([[NSMutableAttributedString alloc] -+<<<<<<< .our - initWithString:title - attributes:attributes]); -+======= -+ initWithString:title -+ attributes:attributes]); -+>>>>>>> .their - - // NSFontAttributeName:[NSFont menuBarFontOfSize:0], - // NSForegroundColorAttributeName:[self colorWithHighlight: highlight] -changed in both - base 100644 e1836ad68985f6068a5ea4be76d6f58682056d04 atom/browser/ui/tray_icon_gtk.cc - our 100644 4c780285c80a157afca74b0927175ba3b045def9 atom/browser/ui/tray_icon_gtk.cc - their 100644 eb7be1ed3b4345cf825075785c1c1708a7b69d30 atom/browser/ui/tray_icon_gtk.cc -@@ -36,9 +36,16 @@ - if (libgtkui::AppIndicatorIcon::CouldOpen()) { - ++indicators_count; - icon_.reset(new libgtkui::AppIndicatorIcon( -+<<<<<<< .our - base::StringPrintf("%s%d", Browser::Get()->GetName().c_str(), - indicators_count), - image.AsImageSkia(), toolTip)); -+======= -+ base::StringPrintf( -+ "%s%d", Browser::Get()->GetName().c_str(), indicators_count), -+ image.AsImageSkia(), -+ toolTip)); -+>>>>>>> .their - } else { - icon_.reset(new libgtkui::Gtk2StatusIcon(image.AsImageSkia(), toolTip)); - } -changed in both - base 100644 5182e1a0f7f141e8ddfa95fd8cca8771f2cabd9f atom/browser/ui/views/frameless_view.cc - our 100644 8959ee13612979d2819621acc14ebf641fb7f116 atom/browser/ui/views/frameless_view.cc - their 100644 b78e897b8f51747fbeb86cdf1e507ecf5be0bf9b atom/browser/ui/views/frameless_view.cc -changed in both - base 100644 f2ab22f70a6fa08ff1315d197ff3ff3cb700733f atom/browser/ui/views/global_menu_bar_x11.cc - our 100644 656bd8f991f87c06a240cdc09a3bfcd500d1c1c8 atom/browser/ui/views/global_menu_bar_x11.cc - their 100644 eaeefbd1fb411fca13d6de5dbbc17806d271affd atom/browser/ui/views/global_menu_bar_x11.cc -changed in both - base 100644 bf9801a1457740da391c75621214b8d91cb7467d atom/browser/ui/views/menu_bar.cc - our 100644 e838d3cc217b5ffdb77226beff0d7217539f23f9 atom/browser/ui/views/menu_bar.cc - their 100644 d963c121bbd29bf3f67b488666297c86b4fee225 atom/browser/ui/views/menu_bar.cc -@@ -18,11 +18,17 @@ - - namespace { - -+<<<<<<< .our -+======= -+const char kViewClassName[] = "ElectronMenuBar"; -+ -+>>>>>>> .their - // Default color of the menu bar. - const SkColor kDefaultColor = SkColorSetARGB(255, 233, 233, 233); - - } // namespace - -+<<<<<<< .our - const char MenuBar::kViewClassName[] = "ElectronMenuBar"; - - MenuBar::MenuBar(views::View* window) -@@ -32,12 +38,35 @@ - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); - window_->GetFocusManager()->AddFocusChangeListener(this); -+======= -+MenuBar::MenuBar(NativeWindow* window) -+ : background_color_(kDefaultColor), menu_model_(NULL), window_(window) { -+ RefreshColorCache(); -+ UpdateViewColors(); -+ SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal)); -+>>>>>>> .their - } - - MenuBar::~MenuBar() { - window_->GetFocusManager()->RemoveFocusChangeListener(this); - } - -+<<<<<<< .our -+======= -+void MenuBar::AddedToWidget() { -+ auto fm = GetFocusManager(); -+ fm->AddFocusChangeListener(this); -+ // Note that we don't own fm -- this manages the _connection_ -+ focus_manager_.reset(fm, [this](views::FocusManager* fm) { -+ fm->RemoveFocusChangeListener(this); -+ }); -+} -+ -+void MenuBar::RemovedFromWidget() { -+ focus_manager_.reset(); -+} -+ -+>>>>>>> .their - void MenuBar::SetMenu(AtomMenuModel* model) { - menu_model_ = model; - RebuildChildren(); -@@ -61,7 +90,11 @@ - } - - void MenuBar::ActivateAccelerator(base::char16 key) { -+<<<<<<< .our - auto* child = FindAccelChild(key); -+======= -+ auto child = FindAccelChild(key); -+>>>>>>> .their - if (child) - static_cast<SubmenuButton*>(child)->Activate(nullptr); - } -@@ -151,7 +184,11 @@ - void MenuBar::RebuildChildren() { - RemoveAllChildViews(true); - for (int i = 0, n = GetItemCount(); i < n; ++i) { -+<<<<<<< .our - auto* button = -+======= -+ auto button = -+>>>>>>> .their - new SubmenuButton(menu_model_->GetLabelAt(i), this, background_color_); - button->set_tag(i); - AddChildView(button); -@@ -169,7 +206,11 @@ - #if defined(USE_X11) - const auto& textColor = has_focus_ ? enabled_color_ : disabled_color_; - for (auto* child : GetChildrenInZOrder()) { -+<<<<<<< .our - auto* button = static_cast<SubmenuButton*>(child); -+======= -+ auto button = static_cast<SubmenuButton*>(child); -+>>>>>>> .their - button->SetTextColor(views::Button::STATE_NORMAL, textColor); - button->SetTextColor(views::Button::STATE_DISABLED, disabled_color_); - button->SetTextColor(views::Button::STATE_PRESSED, enabled_color_); -@@ -178,7 +219,11 @@ - } - #elif defined(OS_WIN) - for (auto* child : GetChildrenInZOrder()) { -+<<<<<<< .our - auto* button = static_cast<SubmenuButton*>(child); -+======= -+ auto button = static_cast<SubmenuButton*>(child); -+>>>>>>> .their - button->SetUnderlineColor(color_utils::GetSysSkColor(COLOR_MENUTEXT)); - } - #endif -changed in both - base 100644 761e31b98ea75f44bcd016da3b34b7615f3b409f atom/browser/ui/views/menu_bar.h - our 100644 2b10ba3e3bf2ccfc0453fdb59ad022ef7da8ed5b atom/browser/ui/views/menu_bar.h - their 100644 13cfa32f3988881e3aa87cae6cae65656fa68d70 atom/browser/ui/views/menu_bar.h -@@ -5,6 +5,12 @@ - #ifndef ATOM_BROWSER_UI_VIEWS_MENU_BAR_H_ - #define ATOM_BROWSER_UI_VIEWS_MENU_BAR_H_ - -+<<<<<<< .our -+======= -+#include <memory> -+ -+#include "atom/browser/native_window.h" -+>>>>>>> .their - #include "atom/browser/ui/atom_menu_model.h" - #include "ui/views/controls/button/menu_button_listener.h" - #include "ui/views/focus/focus_manager.h" -@@ -49,7 +55,9 @@ - - protected: - // views::View: -+ void AddedToWidget() override; - const char* GetClassName() const override; -+ void RemovedFromWidget() override; - - // views::MenuButtonListener: - void OnMenuButtonClicked(views::MenuButton* source, -@@ -79,6 +87,11 @@ - - bool has_focus_ = true; - -+ View* FindAccelChild(base::char16 key); -+ -+ std::shared_ptr<views::FocusManager> focus_manager_; -+ bool has_focus_ = true; -+ - DISALLOW_COPY_AND_ASSIGN(MenuBar); - }; - -changed in both - base 100644 3c3cff3c65410f2e61bdade6e457a096ffba3a54 atom/browser/ui/views/submenu_button.cc - our 100644 1124d3d01471876fefa2757570ba3cff796a991c atom/browser/ui/views/submenu_button.cc - their 100644 baee28f2cd6931611e048ec46c83e602b95b4b59 atom/browser/ui/views/submenu_button.cc -@@ -82,8 +82,12 @@ - - bool SubmenuButton::GetUnderlinePosition(const base::string16& text, - base::char16* accelerator, -+<<<<<<< .our - int* start, - int* end) const { -+======= -+ int* start, int* end) const { -+>>>>>>> .their - int pos, span; - base::string16 trimmed = gfx::RemoveAcceleratorChar(text, '&', &pos, &span); - if (pos > -1 && span != 0) { -@@ -96,9 +100,14 @@ - return false; - } - -+<<<<<<< .our - void SubmenuButton::GetCharacterPosition(const base::string16& text, - int index, - int* pos) const { -+======= -+void SubmenuButton::GetCharacterPosition( -+ const base::string16& text, int index, int* pos) const { -+>>>>>>> .their - int height = 0; - gfx::Canvas::SizeStringInt(text.substr(0, index), gfx::FontList(), pos, - &height, 0, 0); -changed in both - base 100644 5c05481cbbfb85b5d77511cb91cc19cc8ef0e626 atom/browser/ui/views/submenu_button.h - our 100644 d8b7785da131271e88533879d090badfd6e49dd5 atom/browser/ui/views/submenu_button.h - their 100644 0f7eddf4c914790675f0c9bfab696b2a96b91f74 atom/browser/ui/views/submenu_button.h -@@ -33,11 +33,17 @@ - private: - bool GetUnderlinePosition(const base::string16& text, - base::char16* accelerator, -+<<<<<<< .our - int* start, - int* end) const; - void GetCharacterPosition(const base::string16& text, - int index, - int* pos) const; -+======= -+ int* start, int* end) const; -+ void GetCharacterPosition( -+ const base::string16& text, int index, int* pos) const; -+>>>>>>> .their - - base::char16 accelerator_ = 0; - -changed in both - base 100644 84a6d9aa3e50ced33616fb4b78e124f39461cd0e atom/browser/ui/win/atom_desktop_window_tree_host_win.cc - our 100644 97857d6515aa5617cf8c1972690a1dcdfd645ac1 atom/browser/ui/win/atom_desktop_window_tree_host_win.cc - their 100644 3da0241a27a9d272c09db30db068939c1bc66d19 atom/browser/ui/win/atom_desktop_window_tree_host_win.cc -changed in both - base 100644 47e4cb6aed2a962bfdd2a92edaca74b452d15c4d atom/browser/ui/win/atom_desktop_window_tree_host_win.h - our 100644 30af3cc162b4429cb3335c6864b801eac1d5f963 atom/browser/ui/win/atom_desktop_window_tree_host_win.h - their 100644 b0164f2ab6ca9580d11ae1aaff68d9caae314d54 atom/browser/ui/win/atom_desktop_window_tree_host_win.h -@@ -25,10 +25,15 @@ - ~AtomDesktopWindowTreeHostWin() override; - - protected: -+<<<<<<< .our - bool PreHandleMSG(UINT message, - WPARAM w_param, - LPARAM l_param, - LRESULT* result) override; -+======= -+ bool PreHandleMSG( -+ UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) override; -+>>>>>>> .their - bool HasNativeFrame() const override; - - private: -changed in both - base 100644 2cbf07be86a812f07105846dc8caf8226a8595df atom/browser/web_contents_preferences.cc - our 100644 c21c93383155091a7481cdd4e741cefad90a4a55 atom/browser/web_contents_preferences.cc - their 100644 98b39fee234cb15ac0da99fd5639c7b8265d71b0 atom/browser/web_contents_preferences.cc -@@ -97,6 +97,7 @@ - instances_.push_back(this); - - // Set WebPreferences defaults onto the JS object -+<<<<<<< .our - SetDefaultBoolIfUndefined(options::kPlugins, false); - SetDefaultBoolIfUndefined(options::kExperimentalFeatures, false); - bool node = SetDefaultBoolIfUndefined(options::kNodeIntegration, true); -@@ -104,12 +105,23 @@ - SetDefaultBoolIfUndefined(options::kWebviewTag, node); - SetDefaultBoolIfUndefined(options::kSandbox, false); - SetDefaultBoolIfUndefined(options::kNativeWindowOpen, false); -+======= -+ SetDefaultBoolIfUndefined("plugins", false); -+ SetDefaultBoolIfUndefined(options::kExperimentalFeatures, false); -+ SetDefaultBoolIfUndefined(options::kExperimentalCanvasFeatures, false); -+ bool node = SetDefaultBoolIfUndefined(options::kNodeIntegration, true); -+ SetDefaultBoolIfUndefined(options::kNodeIntegrationInWorker, false); -+ SetDefaultBoolIfUndefined(options::kWebviewTag, node); -+ SetDefaultBoolIfUndefined("sandbox", false); -+ SetDefaultBoolIfUndefined("nativeWindowOpen", false); -+>>>>>>> .their - SetDefaultBoolIfUndefined(options::kContextIsolation, false); - SetDefaultBoolIfUndefined("javascript", true); - SetDefaultBoolIfUndefined("images", true); - SetDefaultBoolIfUndefined("textAreasAreResizable", true); - SetDefaultBoolIfUndefined("webgl", true); - bool webSecurity = true; -+<<<<<<< .our - SetDefaultBoolIfUndefined(options::kWebSecurity, webSecurity); - // If webSecurity was explicity set to false, let's inherit that into - // insecureContent -@@ -125,6 +137,21 @@ - SetDefaultBoolIfUndefined(options::kOffscreen, false); - - last_preference_ = preference_.Clone(); -+======= -+ SetDefaultBoolIfUndefined("webSecurity", webSecurity); -+ // If webSecurity was explicity set to false, let's inherit that into -+ // insecureContent -+ if (web_preferences.Get("webSecurity", &webSecurity) && !webSecurity) { -+ SetDefaultBoolIfUndefined("allowRunningInsecureContent", true); -+ } else { -+ SetDefaultBoolIfUndefined("allowRunningInsecureContent", false); -+ } -+ #if defined(OS_MACOSX) -+ SetDefaultBoolIfUndefined(options::kScrollBounce, false); -+ #endif -+ SetDefaultBoolIfUndefined("offscreen", false); -+ last_web_preferences_.MergeDictionary(&web_preferences_); -+>>>>>>> .their - } - - WebContentsPreferences::~WebContentsPreferences() { -@@ -154,6 +181,16 @@ - return default_value; - } - -+bool WebContentsPreferences::SetDefaultBoolIfUndefined(const std::string key, -+ bool val) { -+ bool existing; -+ if (!web_preferences_.GetBoolean(key, &existing)) { -+ web_preferences_.SetBoolean(key, val); -+ return val; -+ } -+ return existing; -+} -+ - void WebContentsPreferences::Merge(const base::DictionaryValue& extend) { - if (preference_.is_dict()) - static_cast<base::DictionaryValue*>(&preference_)->MergeDictionary(&extend); -@@ -212,8 +249,18 @@ - return FromWebContents(web_contents); - } - -+<<<<<<< .our - void WebContentsPreferences::AppendCommandLineSwitches( - base::CommandLine* command_line) { -+======= -+ // We are appending args to a webContents so let's save the current state -+ // of our preferences object so that during the lifetime of the WebContents -+ // we can fetch the options used to initally configure the WebContents -+ self->last_web_preferences_.Clear(); -+ self->last_web_preferences_.MergeDictionary(&web_preferences); -+ -+ bool b; -+>>>>>>> .their - // Check if plugins are enabled. - if (IsEnabled(options::kPlugins)) - command_line->AppendSwitch(switches::kEnablePlugins); -changed in both - base 100644 94dd8dc598bef5cc35383d69d20ade8d644a7ef5 atom/browser/web_contents_preferences.h - our 100644 d835347afcd259f473f95271a2c19e42afcc6f2b atom/browser/web_contents_preferences.h - their 100644 28ee9a85485e26b33b8a7852a4a212b4c11b71a0 atom/browser/web_contents_preferences.h -@@ -59,25 +59,45 @@ - bool GetPreloadPath(base::FilePath::StringType* path) const; - - // Returns the web preferences. -+<<<<<<< .our - base::Value* preference() { return &preference_; } - base::Value* last_preference() { return &last_preference_; } -+======= -+ base::DictionaryValue* web_preferences() { return &web_preferences_; } -+ base::DictionaryValue* last_web_preferences() { -+ return &last_web_preferences_; -+ } -+>>>>>>> .their - - private: - friend class content::WebContentsUserData<WebContentsPreferences>; - friend class AtomBrowserClient; - -+<<<<<<< .our - // Get WebContents according to process ID. - static content::WebContents* GetWebContentsFromProcessID(int process_id); - - // Set preference value to given bool if user did not provide value - bool SetDefaultBoolIfUndefined(const base::StringPiece& key, bool val); -+======= -+ // Set preference value to given bool if user did not provide value -+ bool SetDefaultBoolIfUndefined(const std::string key, bool val); -+ -+ // Get preferences value as integer possibly coercing it from a string -+ bool GetInteger(const std::string& attributeName, int* intValue); -+>>>>>>> .their - - static std::vector<WebContentsPreferences*> instances_; - - content::WebContents* web_contents_; -+<<<<<<< .our - - base::Value preference_ = base::Value(base::Value::Type::DICTIONARY); - base::Value last_preference_ = base::Value(base::Value::Type::DICTIONARY); -+======= -+ base::DictionaryValue web_preferences_; -+ base::DictionaryValue last_web_preferences_; -+>>>>>>> .their - - DISALLOW_COPY_AND_ASSIGN(WebContentsPreferences); - }; -changed in both - base 100644 1dd479883d872dc6d76ef069782aad6dc4f731da atom/browser/web_dialog_helper.cc - our 100644 74c8573d13f15bcaa189abdc40fa0cd8e48f89be atom/browser/web_dialog_helper.cc - their 100644 c76b48a74b3629b9b8588983cb4563aada6d28b9 atom/browser/web_dialog_helper.cc -changed in both - base 100644 ad8c1d49bbc049b89eb4c69224b42fb51906c726 atom/common/api/api_messages.h - our 100644 6131a7a473c68e31790fcd8697c8f380c65ad275 atom/common/api/api_messages.h - their 100644 46e6142260d67b6408060ccaf328ee1f74335fe4 atom/common/api/api_messages.h -@@ -59,6 +59,7 @@ - - // Sent by renderer to set the temporary zoom level. - IPC_SYNC_MESSAGE_ROUTED1_1(AtomFrameHostMsg_SetTemporaryZoomLevel, -+<<<<<<< .our - double /* zoom level */, - double /* result */) - -@@ -69,3 +70,10 @@ - IPC_MESSAGE_ROUTED2(AtomFrameHostMsg_PDFSaveURLAs, - GURL /* url */, - content::Referrer /* referrer */) -+======= -+ double /* zoom level */, -+ double /* result */) -+ -+// Sent by renderer to get the zoom level. -+IPC_SYNC_MESSAGE_ROUTED0_1(AtomFrameHostMsg_GetZoomLevel, double /* result */) -+>>>>>>> .their -changed in both - base 100644 a01ca8f84d917f6402a2e8d0aa153c6f7be9a3c5 atom/common/api/atom_api_v8_util.cc - our 100644 3d80db0c0a4cdbb4c7a78fa7e4266fc6fc87193f atom/common/api/atom_api_v8_util.cc - their 100644 b579d6f7d66c9d28006029ac78a6837007dbb217 atom/common/api/atom_api_v8_util.cc -changed in both - base 100644 d1a185d51f394b1828d66cbcf2a1d1cc278de23d atom/common/api/remote_callback_freer.cc - our 100644 eba828591353dae53d1b7cdaa60fee52166d7473 atom/common/api/remote_callback_freer.cc - their 100644 099e2160cc0d28322a60e4a9891a22b29ab841f9 atom/common/api/remote_callback_freer.cc -@@ -29,7 +29,12 @@ - : ObjectLifeMonitor(isolate, target), - content::WebContentsObserver(web_contents), - context_id_(context_id), -+<<<<<<< .our - object_id_(object_id) {} -+======= -+ object_id_(object_id) { -+} -+>>>>>>> .their - - RemoteCallbackFreer::~RemoteCallbackFreer() {} - -@@ -39,7 +44,11 @@ - base::ListValue args; - args.AppendString(context_id_); - args.AppendInteger(object_id_); -+<<<<<<< .our - auto* frame_host = web_contents()->GetMainFrame(); -+======= -+ auto frame_host = web_contents()->GetMainFrame(); -+>>>>>>> .their - if (frame_host) { - frame_host->Send(new AtomFrameMsg_Message(frame_host->GetRoutingID(), false, - channel, args)); -changed in both - base 100644 315127822d1709802abf317c4d8cf49ec7e2bfaa atom/common/api/remote_object_freer.cc - our 100644 8afe8b9a32bc4ba4d5cdfc66ecf7036b8553cb48 atom/common/api/remote_object_freer.cc - their 100644 6e9778994ff21fb3c6be3dd27dbf7cbe2c4c94d6 atom/common/api/remote_object_freer.cc -changed in both - base 100644 5fa39680ca814675d344665b3b2a6ce5d94e625f atom/common/atom_version.h - our 100644 65e7d19911559a40b1b258319df5fe0fa180354f atom/common/atom_version.h - their 100644 93e2a1dba6b95b4582d269b273cc728325a32e8b atom/common/atom_version.h -@@ -5,10 +5,17 @@ - #ifndef ATOM_COMMON_ATOM_VERSION_H_ - #define ATOM_COMMON_ATOM_VERSION_H_ - -+<<<<<<< .our - #define ATOM_MAJOR_VERSION 4 - #define ATOM_MINOR_VERSION 0 - #define ATOM_PATCH_VERSION 0 - #define ATOM_PRE_RELEASE_VERSION -nightly.20180821 -+======= -+#define ATOM_MAJOR_VERSION 2 -+#define ATOM_MINOR_VERSION 0 -+#define ATOM_PATCH_VERSION 8 -+// #define ATOM_PRE_RELEASE_VERSION -+>>>>>>> .their - - #ifndef ATOM_STRINGIFY - #define ATOM_STRINGIFY(n) ATOM_STRINGIFY_HELPER(n) -changed in both - base 100644 a7908ef30c6bafc4aca1da9a870f7ae12703fe04 atom/common/crash_reporter/crash_reporter_win.cc - our 100644 c574da71c9de9bd8c7b7cad57d3a0f84708fb97c atom/common/crash_reporter/crash_reporter_win.cc - their 100644 49f90b7e6665727b697a243414544bae304fde6e atom/common/crash_reporter/crash_reporter_win.cc -changed in both - base 100644 cff228ba49068a8a683257e9ac50778437a56c45 atom/common/linux/application_info.cc - our 100644 3354c73b8b60f77cf054f975ea713d96b7e7683e atom/common/linux/application_info.cc - their 100644 05bd7f6fc15015a4f570e36801aea622a8f0cb3a atom/common/linux/application_info.cc -@@ -19,7 +19,11 @@ - namespace { - - GDesktopAppInfo* get_desktop_app_info() { -+<<<<<<< .our - GDesktopAppInfo* ret = nullptr; -+======= -+ GDesktopAppInfo * ret = nullptr; -+>>>>>>> .their - - std::string desktop_id; - if (brightray::platform_util::GetDesktopName(&desktop_id)) -changed in both - base 100644 eed6e7bc092f84bd1bde673c27f5fe5363c7783c atom/common/options_switches.cc - our 100644 8b1836f80c583e4db68971ff1b00ca4f86356b45 atom/common/options_switches.cc - their 100644 c1cd185443c0fdbadeb7ba2e174d2048ab2d45d7 atom/common/options_switches.cc -@@ -188,6 +188,9 @@ - // The application path - const char kAppPath[] = "app-path"; - -+// The context ID for this process -+const char kContextId[] = "context-id"; -+ - // The command line switch versions of the options. - const char kBackgroundColor[] = "background-color"; - const char kPreloadScript[] = "preload"; -changed in both - base 100644 525301971c8a05c45e12aada7d0534b84307aebf atom/common/options_switches.h - our 100644 5f6d7e9d38120668ed06922ced2f8d6a6e27a52b atom/common/options_switches.h - their 100644 9d65bc376925906063c24a9a254b2c31c7e22c34 atom/common/options_switches.h -@@ -92,6 +92,7 @@ - extern const char kSecureSchemes[]; - extern const char kAppUserModelId[]; - extern const char kAppPath[]; -+extern const char kContextId[]; - - extern const char kBackgroundColor[]; - extern const char kPreloadScript[]; -changed in both - base 100644 7bee1411ba1c2fbac516ff8b65bcbd89f6132819 atom/renderer/api/atom_api_renderer_ipc.cc - our 100644 3e48a4f7d0c11f40e6360b0acc2c83c38e671319 atom/renderer/api/atom_api_renderer_ipc.cc - their 100644 ad6a12b90d525e9c6a49fac7a5d122b8c2c295f9 atom/renderer/api/atom_api_renderer_ipc.cc -@@ -12,8 +12,13 @@ - #include "native_mate/dictionary.h" - #include "third_party/WebKit/public/web/WebLocalFrame.h" - -+<<<<<<< .our - using blink::WebLocalFrame; - using content::RenderFrame; -+======= -+using content::RenderFrame; -+using blink::WebLocalFrame; -+>>>>>>> .their - - namespace atom { - -@@ -48,10 +53,17 @@ - - RenderFrame* render_frame = GetCurrentRenderFrame(); - if (render_frame == nullptr) -+<<<<<<< .our - return result; - - IPC::SyncMessage* message = new AtomFrameHostMsg_Message_Sync( - render_frame->GetRoutingID(), channel, arguments, &result); -+======= -+ return json; -+ -+ IPC::SyncMessage* message = new AtomFrameHostMsg_Message_Sync( -+ render_frame->GetRoutingID(), channel, arguments, &json); -+>>>>>>> .their - bool success = render_frame->Send(message); - - if (!success) -changed in both - base 100644 d0164f44a0a523b26a919e02b5b7add25a0e7224 atom/renderer/api/atom_api_web_frame.cc - our 100644 f0f7ef249d73876f7107d3d3865e8fc71ee33945 atom/renderer/api/atom_api_web_frame.cc - their 100644 c36d1a06491994f126333c98796f6ff64cfc6506 atom/renderer/api/atom_api_web_frame.cc -changed in both - base 100644 1971a26c1c5d4f5c5f5f029e6334f157a16b5394 atom/renderer/atom_render_frame_observer.cc - our 100644 ea2355fd968339600ae8093524f1c3dcfd2f4ff3 atom/renderer/atom_render_frame_observer.cc - their 100644 4ddf9186b723091ef91d69cfaedc4fbdd1ac09fa atom/renderer/atom_render_frame_observer.cc -@@ -7,6 +7,8 @@ - #include <string> - #include <vector> - -+#include "atom/common/native_mate_converters/string16_converter.h" -+ - #include "atom/common/api/api_messages.h" - #include "atom/common/api/event_emitter_caller.h" - #include "atom/common/native_mate_converters/value_converter.h" -@@ -72,7 +74,12 @@ - RendererClientBase* renderer_client) - : content::RenderFrameObserver(frame), - render_frame_(frame), -+<<<<<<< .our - renderer_client_(renderer_client) { -+======= -+ renderer_client_(renderer_client), -+ document_created_(false) { -+>>>>>>> .their - // Initialise resource for directory listing. - net::NetModule::SetResourceProvider(NetResourceProvider); - } -@@ -195,8 +202,13 @@ - } - - void AtomRenderFrameObserver::EmitIPCEvent(blink::WebLocalFrame* frame, -+<<<<<<< .our - const base::string16& channel, - const base::ListValue& args) { -+======= -+ const base::string16& channel, -+ const base::ListValue& args) { -+>>>>>>> .their - if (!frame) - return; - -changed in both - base 100644 248d5a68096dedea0f6ffb3c9df38ff3373e7c18 atom/renderer/atom_render_frame_observer.h - our 100644 e774741c019956a3bff00db2f6d2b133bf1be6de atom/renderer/atom_render_frame_observer.h - their 100644 d4f3d0c7d5c454bb65a190f59b26501137dd04e0 atom/renderer/atom_render_frame_observer.h -@@ -56,7 +56,11 @@ - - content::RenderFrame* render_frame_; - RendererClientBase* renderer_client_; -+<<<<<<< .our - bool document_created_ = false; -+======= -+ bool document_created_; -+>>>>>>> .their - - DISALLOW_COPY_AND_ASSIGN(AtomRenderFrameObserver); - }; -changed in both - base 100644 4d3e7cba7a65330a45a5f2aebba90c257b206e35 atom/renderer/atom_render_view_observer.h - our 100644 097616e12369662473c12645a93e27cffcb55e3b atom/renderer/atom_render_view_observer.h - their 100644 ca9fb01288e3bd4788c7718f0feb8b37307383e6 atom/renderer/atom_render_view_observer.h -@@ -14,7 +14,11 @@ - explicit AtomRenderViewObserver(content::RenderView* render_view); - - protected: -+<<<<<<< .our - ~AtomRenderViewObserver() override; -+======= -+ virtual ~AtomRenderViewObserver(); -+>>>>>>> .their - - private: - // content::RenderViewObserver implementation. -changed in both - base 100644 82ba9d024350009ae86bc5406513c8086073990a atom/renderer/atom_renderer_client.cc - our 100644 204f17c2cf0d2d4ec4a71bdbecfcd1cbdc5fc8be atom/renderer/atom_renderer_client.cc - their 100644 9241410d7516bcfecc945e2659e02c178ddad2a7 atom/renderer/atom_renderer_client.cc -@@ -77,8 +77,12 @@ - } - - void AtomRendererClient::DidCreateScriptContext( -+<<<<<<< .our - v8::Handle<v8::Context> context, - content::RenderFrame* render_frame) { -+======= -+ v8::Handle<v8::Context> context, content::RenderFrame* render_frame) { -+>>>>>>> .their - RendererClientBase::DidCreateScriptContext(context, render_frame); - - // Only allow node integration for the main frame, unless it is a devtools -changed in both - base 100644 07d20bda8b00b1acdb823546f5e606154278cd4e atom/renderer/atom_sandboxed_renderer_client.cc - our 100644 6e29fe45a69f44856d7fca449ec1be4eaf6970a2 atom/renderer/atom_sandboxed_renderer_client.cc - their 100644 f3642244f7847fc3f16144a40d2560478c276fa9 atom/renderer/atom_sandboxed_renderer_client.cc -@@ -12,11 +12,16 @@ - #include "atom/common/options_switches.h" - #include "atom/renderer/api/atom_api_renderer_ipc.h" - #include "atom/renderer/atom_render_frame_observer.h" -+<<<<<<< .our - #include "base/base_paths.h" - #include "base/command_line.h" - #include "base/files/file_path.h" - #include "base/path_service.h" - #include "base/process/process_handle.h" -+======= -+#include "base/command_line.h" -+#include "base/files/file_path.h" -+>>>>>>> .their - #include "chrome/renderer/printing/print_web_view_helper.h" - #include "content/public/renderer/render_frame.h" - #include "native_mate/dictionary.h" -@@ -34,8 +39,13 @@ - const std::string kModuleCacheKey = "native-module-cache"; - - bool IsDevTools(content::RenderFrame* render_frame) { -+<<<<<<< .our - return render_frame->GetWebFrame()->GetDocument().Url().ProtocolIs( - "chrome-devtools"); -+======= -+ return render_frame->GetWebFrame()->GetDocument().Url() -+ .ProtocolIs("chrome-devtools"); -+>>>>>>> .their - } - - v8::Local<v8::Object> GetModuleCache(v8::Isolate* isolate) { -@@ -102,12 +112,19 @@ - AtomSandboxedRenderFrameObserver(content::RenderFrame* render_frame, - AtomSandboxedRendererClient* renderer_client) - : AtomRenderFrameObserver(render_frame, renderer_client), -+<<<<<<< .our - renderer_client_(renderer_client) {} -+======= -+ v8_converter_(new atom::V8ValueConverter), -+ renderer_client_(renderer_client) { -+ v8_converter_->SetDisableNode(true); -+ } -+>>>>>>> .their - - protected: - void EmitIPCEvent(blink::WebLocalFrame* frame, - const base::string16& channel, -- const base::ListValue& args) override { -+ const base::ListValue& args) { - if (!frame) - return; - -@@ -176,6 +193,7 @@ - } - - void AtomSandboxedRendererClient::DidCreateScriptContext( -+<<<<<<< .our - v8::Handle<v8::Context> context, - content::RenderFrame* render_frame) { - RendererClientBase::DidCreateScriptContext(context, render_frame); -@@ -184,6 +202,19 @@ - // For devtools we still want to run the preload_bundle script - if (!render_frame->IsMainFrame() && !IsDevTools(render_frame)) - return; -+======= -+ v8::Handle<v8::Context> context, content::RenderFrame* render_frame) { -+ RendererClientBase::DidCreateScriptContext(context, render_frame); -+ -+ // Only allow preload for the main frame or -+ // For devtools we still want to run the preload_bundle script -+ if (!render_frame->IsMainFrame() && !IsDevTools(render_frame)) -+ return; -+ -+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); -+ base::FilePath preload_script_path = command_line->GetSwitchValuePath( -+ switches::kPreloadScript); -+>>>>>>> .their - - auto* isolate = context->GetIsolate(); - v8::HandleScope handle_scope(isolate); -@@ -203,7 +234,14 @@ - auto binding = v8::Object::New(isolate); - InitializeBindings(binding, context); - AddRenderBindings(isolate, binding); -+<<<<<<< .our - v8::Local<v8::Value> args[] = {binding}; -+======= -+ v8::Local<v8::Value> args[] = { -+ binding, -+ mate::ConvertToV8(isolate, preload_script_path.value()) -+ }; -+>>>>>>> .their - // Execute the function with proper arguments - ignore_result( - func->Call(context, v8::Null(isolate), node::arraysize(args), args)); -changed in both - base 100644 89af0932d10a598f87dd28ec4b32ae3b2e0eadca atom/renderer/renderer_client_base.cc - our 100644 69490420ef5b8f87e7cb8fd97ebd5ec4509fa1ae atom/renderer/renderer_client_base.cc - their 100644 dbb39a363cd31b6de64f52b5854225d35bcc5a54 atom/renderer/renderer_client_base.cc -@@ -16,6 +16,10 @@ - #include "atom/renderer/content_settings_observer.h" - #include "atom/renderer/preferences_manager.h" - #include "base/command_line.h" -+<<<<<<< .our -+======= -+#include "base/memory/ptr_util.h" -+>>>>>>> .their - #include "base/process/process_handle.h" - #include "base/strings/string_split.h" - #include "base/strings/stringprintf.h" -@@ -42,6 +46,7 @@ - #include <shlobj.h> - #endif - -+<<<<<<< .our - #if defined(ENABLE_PDF_VIEWER) - #include "atom/common/atom_constants.h" - #endif // defined(ENABLE_PDF_VIEWER) -@@ -50,6 +55,8 @@ - #include "chrome/renderer/pepper/pepper_helper.h" - #endif // defined(ENABLE_PEPPER_FLASH) - -+======= -+>>>>>>> .their - // This is defined in later versions of Chromium, remove this if you see - // compiler complaining duplicate defines. - #if defined(OS_WIN) || defined(OS_FUCHSIA) -@@ -105,6 +112,19 @@ - context->Global()->SetPrivate(context, private_key, value); - } - -+void RendererClientBase::DidCreateScriptContext( -+ v8::Handle<v8::Context> context, -+ content::RenderFrame* render_frame) { -+ // global.setHidden("contextId", `${processId}-${++nextContextId}`) -+ std::string context_id = base::StringPrintf( -+ "%" CrPRIdPid "-%d", base::GetCurrentProcId(), ++next_context_id_); -+ v8::Isolate* isolate = context->GetIsolate(); -+ v8::Local<v8::String> key = mate::StringToSymbol(isolate, "contextId"); -+ v8::Local<v8::Private> private_key = v8::Private::ForApi(isolate, key); -+ v8::Local<v8::Value> value = mate::ConvertToV8(isolate, context_id); -+ context->Global()->SetPrivate(context, private_key, value); -+} -+ - void RendererClientBase::AddRenderBindings( - v8::Isolate* isolate, - v8::Local<v8::Object> binding_object) { -@@ -161,7 +181,10 @@ - - void RendererClientBase::RenderFrameCreated( - content::RenderFrame* render_frame) { -+<<<<<<< .our - #if defined(TOOLKIT_VIEWS) -+======= -+>>>>>>> .their - new AutofillAgent(render_frame); - #endif - #if defined(ENABLE_PEPPER_FLASH) -changed in both - base 100644 ba302e6a34498cb59cfa8cbf8636044691ee904c atom/renderer/renderer_client_base.h - our 100644 f04be0a0fb555fce88aa006c6c6623cc8730d4ed atom/renderer/renderer_client_base.h - their 100644 70db197294b7d2491d9c1eaf008ac8b36796f418 atom/renderer/renderer_client_base.h -@@ -20,10 +20,17 @@ - RendererClientBase(); - ~RendererClientBase() override; - -+<<<<<<< .our - virtual void DidCreateScriptContext(v8::Handle<v8::Context> context, - content::RenderFrame* render_frame); - virtual void WillReleaseScriptContext(v8::Handle<v8::Context> context, - content::RenderFrame* render_frame) = 0; -+======= -+ virtual void DidCreateScriptContext( -+ v8::Handle<v8::Context> context, content::RenderFrame* render_frame); -+ virtual void WillReleaseScriptContext( -+ v8::Handle<v8::Context> context, content::RenderFrame* render_frame) = 0; -+>>>>>>> .their - virtual void DidClearWindowObject(content::RenderFrame* render_frame); - virtual void SetupMainWorldOverrides(v8::Handle<v8::Context> context) = 0; - -changed in both - base 100644 653aca2b86182a17d5a1a53aeda6d441bfd3652a atom/utility/atom_content_utility_client.cc - our 100644 e2a856d53ae243de988c43b0a3335b9391e54b4e atom/utility/atom_content_utility_client.cc - their 100644 91168f7fc2da98546864d12f03d1e0f75a7ca64f atom/utility/atom_content_utility_client.cc -@@ -4,12 +4,29 @@ - - #include "atom/utility/atom_content_utility_client.h" - -+#include "content/public/common/service_manager_connection.h" -+#include "content/public/common/simple_connection_filter.h" -+#include "content/public/utility/utility_thread.h" -+#include "mojo/public/cpp/bindings/strong_binding.h" -+#include "net/proxy/mojo_proxy_resolver_factory_impl.h" -+#include "services/service_manager/public/cpp/binder_registry.h" -+ - #if defined(OS_WIN) - #include "chrome/utility/printing_handler_win.h" - #endif - - namespace atom { - -+namespace { -+ -+void CreateProxyResolverFactory( -+ net::interfaces::ProxyResolverFactoryRequest request) { -+ mojo::MakeStrongBinding(base::MakeUnique<net::MojoProxyResolverFactoryImpl>(), -+ std::move(request)); -+} -+ -+} // namespace -+ - AtomContentUtilityClient::AtomContentUtilityClient() { - #if defined(OS_WIN) - handlers_.push_back(std::make_unique<printing::PrintingHandlerWin>()); -@@ -18,7 +35,29 @@ - - AtomContentUtilityClient::~AtomContentUtilityClient() {} - -+<<<<<<< .our - bool AtomContentUtilityClient::OnMessageReceived(const IPC::Message& message) { -+======= -+void AtomContentUtilityClient::UtilityThreadStarted() { -+ content::ServiceManagerConnection* connection = -+ content::ChildThread::Get()->GetServiceManagerConnection(); -+ -+ // NOTE: Some utility process instances are not connected to the Service -+ // Manager. Nothing left to do in that case. -+ if (!connection) -+ return; -+ -+ auto registry = base::MakeUnique<service_manager::BinderRegistry>(); -+ registry->AddInterface<net::interfaces::ProxyResolverFactory>( -+ base::Bind(CreateProxyResolverFactory), -+ base::ThreadTaskRunnerHandle::Get()); -+ connection->AddConnectionFilter( -+ base::MakeUnique<content::SimpleConnectionFilter>(std::move(registry))); -+} -+ -+bool AtomContentUtilityClient::OnMessageReceived( -+ const IPC::Message& message) { -+>>>>>>> .their - #if defined(OS_WIN) - for (const auto& handler : handlers_) { - if (handler->OnMessageReceived(message)) -merged - result 100644 75359a2456129dd0caeb03a37eebf7bbfb9a2e21 atom/utility/atom_content_utility_client.h - our 100644 7694970457b745a84ecab24a2f0ec8eaefa8a1ad atom/utility/atom_content_utility_client.h -@@ -20,6 +20,7 @@ - AtomContentUtilityClient(); - ~AtomContentUtilityClient() override; - -+ void UtilityThreadStarted() override; - bool OnMessageReceived(const IPC::Message& message) override; - - private: -changed in both - base 100644 065fe818a64586b6f786cdaa163c40b8a3aacabe brightray/brightray.gyp - our 100644 f233257e88bad8f0ff703034bea02e4715a5b5b9 brightray/brightray.gyp - their 100644 03d48ccef48fccb58bd39f9604e73b872f825d76 brightray/brightray.gyp -@@ -127,6 +127,8 @@ - '<(libchromiumcontent_dir)/libviz_service.a', - # services/device/wake_lock/power_save_blocker/ - '<(libchromiumcontent_dir)/libpower_save_blocker.a', -+ # net/proxy/mojo_* -+ '<(libchromiumcontent_dir)/libnet_proxy_service.a', - # Friends of libpdf.a: - # On Linux we have to use "--whole-archive" to include - # all symbols, otherwise there will be plenty of -@@ -178,6 +180,7 @@ - ], - }, - }], -+<<<<<<< .our - # Due to strange linker behavior, component build of arm needs to - # be linked with libjpeg.a explicitly. - ['target_arch=="arm" and libchromiumcontent_component==1', { -@@ -187,6 +190,8 @@ - ], - }, - }], -+======= -+>>>>>>> .their - ], - }], # OS=="linux" - ['OS=="mac"', { -@@ -221,6 +226,8 @@ - '<(libchromiumcontent_dir)/libviz_service.a', - # services/device/wake_lock/power_save_blocker/ - '<(libchromiumcontent_dir)/libpower_save_blocker.a', -+ # net/proxy/mojo_* -+ '<(libchromiumcontent_dir)/libnet_proxy_service.a', - # Friends of libpdf.a: - '<(libchromiumcontent_dir)/libpdf.a', - '<(libchromiumcontent_dir)/libppapi_cpp_objects.a', -@@ -288,6 +295,20 @@ - ], - }, - }], -+ # In the OSX 10.10 SDK, CoreBluetooth became a top level framework. -+ # Previously, it was nested in IOBluetooth. In order for Chrome to run on -+ # OSes older than OSX 10.10, the top level CoreBluetooth framework must be -+ # weakly linked. -+ ['mac_sdk=="10.10" and libchromiumcontent_component==0', { -+ 'direct_dependent_settings': { -+ 'xcode_settings': { -+ 'OTHER_LDFLAGS': [ -+ '-weak_framework', -+ 'CoreBluetooth', -+ ], -+ }, -+ }, -+ }], - ] - }], # OS=="mac" - ['OS=="win"', { -@@ -359,6 +380,8 @@ - '<(libchromiumcontent_dir)/viz_service.lib', - # services/device/wake_lock/power_save_blocker/ - '<(libchromiumcontent_dir)/power_save_blocker.lib', -+ # net/proxy/mojo_* -+ '<(libchromiumcontent_dir)/net_proxy_service.lib', - # Friends of pdf.lib: - '<(libchromiumcontent_dir)/pdf.lib', - '<(libchromiumcontent_dir)/ppapi_cpp_objects.lib', -changed in both - base 100644 d7a4c672926c03dcf4c1a4df1a9e5fa09b19d272 brightray/browser/browser_context.cc - our 100644 1eff7344e9aef78bb88720c38c0f75fb92e6bc09 brightray/browser/browser_context.cc - their 100644 241398ce96efbe0e4f2203acd86f224c910443e2 brightray/browser/browser_context.cc -@@ -89,6 +89,7 @@ - } - - void BrowserContext::InitPrefs() { -+ base::ThreadRestrictions::ScopedAllowIO allow_io; - auto prefs_path = GetPath().Append(FILE_PATH_LITERAL("Preferences")); - base::ThreadRestrictions::ScopedAllowIO allow_io; - PrefServiceFactory prefs_factory; -changed in both - base 100644 642734aa4db9fd3c8025986bb987d79102b27dd5 brightray/browser/browser_main_parts.cc - our 100644 78d0ef15ef1343e7db123f97182bac7f9a98b3eb brightray/browser/browser_main_parts.cc - their 100644 c79ce69b4b3566b21e5411f2a477b52bcf5ce899 brightray/browser/browser_main_parts.cc -@@ -183,18 +183,29 @@ - auto* cmd_line = base::CommandLine::ForCurrentProcess(); - const auto enable_features = - cmd_line->GetSwitchValueASCII(switches::kEnableFeatures); -+<<<<<<< .our - auto disable_features = - cmd_line->GetSwitchValueASCII(switches::kDisableFeatures); - auto feature_list = std::make_unique<base::FeatureList>(); -+======= -+ const auto disable_features = -+ cmd_line->GetSwitchValueASCII(switches::kDisableFeatures); -+ -+ std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); -+>>>>>>> .their - feature_list->InitializeFromCommandLine(enable_features, disable_features); - base::FeatureList::SetInstance(std::move(feature_list)); - } - -+<<<<<<< .our - bool BrowserMainParts::ShouldContentCreateFeatureList() { - return false; - } - - int BrowserMainParts::PreEarlyInitialization() { -+======= -+void BrowserMainParts::PreEarlyInitialization() { -+>>>>>>> .their - InitializeFeatureList(); - OverrideAppLogsPath(); - #if defined(USE_X11) -changed in both - base 100644 f69682ce51610a754dcaa4f9751c7a22b9a359b2 brightray/browser/browser_main_parts.h - our 100644 cf8e0296585b17f1e7dab1717e0aa80293d902dd brightray/browser/browser_main_parts.h - their 100644 df8234995d6ed3258d94bf0ebf88112629629f07 brightray/browser/browser_main_parts.h -changed in both - base 100644 143a5fdea3eb6ad7709fa8383298029a24c1b407 brightray/browser/linux/libnotify_notification.cc - our 100644 0725ffded989d3c6bce753a210e464deca346ad1 brightray/browser/linux/libnotify_notification.cc - their 100644 7f9fb35e434f7cc85cf4145661e754ff4a0d84fc brightray/browser/linux/libnotify_notification.cc -added in remote - their 100644 def1fc7f25e6fa60aa4a548d4ddbe9c2f5633289 brightray/browser/net/chrome_mojo_proxy_resolver_factory.cc -@@ -0,0 +1,117 @@ -+// Copyright 2015 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "brightray/browser/net/chrome_mojo_proxy_resolver_factory.h" -+ -+#include <utility> -+ -+#include "base/logging.h" -+#include "base/memory/ptr_util.h" -+#include "base/memory/singleton.h" -+#include "base/single_thread_task_runner.h" -+#include "base/strings/utf_string_conversions.h" -+#include "base/threading/thread_task_runner_handle.h" -+#include "content/public/browser/browser_thread.h" -+#include "content/public/browser/utility_process_host.h" -+#include "content/public/browser/utility_process_host_client.h" -+#include "services/service_manager/public/cpp/interface_provider.h" -+ -+namespace { -+const int kUtilityProcessIdleTimeoutSeconds = 5; -+} -+ -+// static -+ChromeMojoProxyResolverFactory* ChromeMojoProxyResolverFactory::GetInstance() { -+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO); -+ return base::Singleton< -+ ChromeMojoProxyResolverFactory, -+ base::LeakySingletonTraits<ChromeMojoProxyResolverFactory>>::get(); -+} -+ -+ChromeMojoProxyResolverFactory::ChromeMojoProxyResolverFactory() { -+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO); -+} -+ -+ChromeMojoProxyResolverFactory::~ChromeMojoProxyResolverFactory() { -+ DCHECK(thread_checker_.CalledOnValidThread()); -+} -+ -+std::unique_ptr<base::ScopedClosureRunner> -+ChromeMojoProxyResolverFactory::CreateResolver( -+ const std::string& pac_script, -+ mojo::InterfaceRequest<net::interfaces::ProxyResolver> req, -+ net::interfaces::ProxyResolverFactoryRequestClientPtr client) { -+ DCHECK(thread_checker_.CalledOnValidThread()); -+ if (!resolver_factory_) -+ CreateFactory(); -+ -+ if (!resolver_factory_) { -+ // If factory creation failed, close |req|'s message pipe, which should -+ // cause a connection error. -+ req = nullptr; -+ return nullptr; -+ } -+ idle_timer_.Stop(); -+ num_proxy_resolvers_++; -+ resolver_factory_->CreateResolver(pac_script, std::move(req), -+ std::move(client)); -+ return base::MakeUnique<base::ScopedClosureRunner>( -+ base::Bind(&ChromeMojoProxyResolverFactory::OnResolverDestroyed, -+ base::Unretained(this))); -+} -+ -+void ChromeMojoProxyResolverFactory::CreateFactory() { -+ DCHECK(thread_checker_.CalledOnValidThread()); -+ DCHECK(!resolver_factory_); -+ DCHECK(!weak_utility_process_host_); -+ -+ DVLOG(1) << "Attempting to create utility process for proxy resolver"; -+ content::UtilityProcessHost* utility_process_host = -+ content::UtilityProcessHost::Create( -+ scoped_refptr<content::UtilityProcessHostClient>(), -+ base::ThreadTaskRunnerHandle::Get()); -+ utility_process_host->SetName(base::ASCIIToUTF16("Electron Proxy Resolver")); -+ bool process_started = utility_process_host->Start(); -+ if (process_started) { -+ BindInterface(utility_process_host, &resolver_factory_); -+ weak_utility_process_host_ = utility_process_host->AsWeakPtr(); -+ } else { -+ LOG(ERROR) << "Unable to connect to utility process"; -+ return; -+ } -+ -+ resolver_factory_.set_connection_error_handler(base::Bind( -+ &ChromeMojoProxyResolverFactory::DestroyFactory, base::Unretained(this))); -+} -+ -+void ChromeMojoProxyResolverFactory::DestroyFactory() { -+ resolver_factory_.reset(); -+ delete weak_utility_process_host_.get(); -+ weak_utility_process_host_.reset(); -+} -+ -+void ChromeMojoProxyResolverFactory::OnResolverDestroyed() { -+ DCHECK(thread_checker_.CalledOnValidThread()); -+ DCHECK_GT(num_proxy_resolvers_, 0u); -+ if (--num_proxy_resolvers_ == 0) { -+ // When all proxy resolvers have been destroyed, the proxy resolver factory -+ // is no longer needed. However, new proxy resolvers may be created -+ // shortly after being destroyed (e.g. due to a network change). -+ // -+ // On desktop, where a utility process is used, if the utility process is -+ // shut down immediately, this would cause unnecessary process churn, so -+ // wait for an idle timeout before shutting down the proxy resolver utility -+ // process. -+ idle_timer_.Start( -+ FROM_HERE, -+ base::TimeDelta::FromSeconds(kUtilityProcessIdleTimeoutSeconds), this, -+ &ChromeMojoProxyResolverFactory::OnIdleTimeout); -+ } -+} -+ -+void ChromeMojoProxyResolverFactory::OnIdleTimeout() { -+ DCHECK(thread_checker_.CalledOnValidThread()); -+ DCHECK_EQ(num_proxy_resolvers_, 0u); -+ DestroyFactory(); -+} -added in remote - their 100644 47e51efebf3285c981ab71ba344d27bcd89c52e6 brightray/browser/net/chrome_mojo_proxy_resolver_factory.h -@@ -0,0 +1,73 @@ -+// Copyright 2015 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef BRIGHTRAY_BROWSER_NET_CHROME_MOJO_PROXY_RESOLVER_FACTORY_H_ -+#define BRIGHTRAY_BROWSER_NET_CHROME_MOJO_PROXY_RESOLVER_FACTORY_H_ -+ -+#include <stddef.h> -+#include <string> -+ -+#include "base/macros.h" -+#include "base/memory/weak_ptr.h" -+#include "base/threading/thread_checker.h" -+#include "base/timer/timer.h" -+#include "net/proxy/mojo_proxy_resolver_factory.h" -+ -+namespace content { -+class UtilityProcessHost; -+} -+ -+namespace base { -+template <typename Type> -+struct DefaultSingletonTraits; -+} // namespace base -+ -+// A factory used to create connections to Mojo proxy resolver services. On -+// Android, the proxy resolvers will run in the browser process, and on other -+// platforms, they'll all be run in the same utility process. Utility process -+// crashes are detected and the utility process is automatically restarted. -+class ChromeMojoProxyResolverFactory : public net::MojoProxyResolverFactory { -+ public: -+ static ChromeMojoProxyResolverFactory* GetInstance(); -+ -+ // Overridden from net::MojoProxyResolverFactory: -+ std::unique_ptr<base::ScopedClosureRunner> CreateResolver( -+ const std::string& pac_script, -+ mojo::InterfaceRequest<net::interfaces::ProxyResolver> req, -+ net::interfaces::ProxyResolverFactoryRequestClientPtr client) override; -+ -+ private: -+ friend struct base::DefaultSingletonTraits<ChromeMojoProxyResolverFactory>; -+ ChromeMojoProxyResolverFactory(); -+ ~ChromeMojoProxyResolverFactory() override; -+ -+ // Creates the proxy resolver factory. On desktop, creates a new utility -+ // process before creating it out of process. On Android, creates it on the -+ // current thread. -+ void CreateFactory(); -+ -+ // Destroys |resolver_factory_|. -+ void DestroyFactory(); -+ -+ // Invoked each time a proxy resolver is destroyed. -+ void OnResolverDestroyed(); -+ -+ // Invoked once an idle timeout has elapsed after all proxy resolvers are -+ // destroyed. -+ void OnIdleTimeout(); -+ -+ net::interfaces::ProxyResolverFactoryPtr resolver_factory_; -+ -+ base::WeakPtr<content::UtilityProcessHost> weak_utility_process_host_; -+ -+ size_t num_proxy_resolvers_ = 0; -+ -+ base::OneShotTimer idle_timer_; -+ -+ base::ThreadChecker thread_checker_; -+ -+ DISALLOW_COPY_AND_ASSIGN(ChromeMojoProxyResolverFactory); -+}; -+ -+#endif // BRIGHTRAY_BROWSER_NET_CHROME_MOJO_PROXY_RESOLVER_FACTORY_H_ -changed in both - base 100644 7a798ae98e6c180c5a60e0a32ce6393532e83468 brightray/browser/net_log.cc - our 100644 fb443ea0b72b9659d98d1873fad1a714483bb13f brightray/browser/net_log.cc - their 100644 978667acb61b0330d6bf48bb7e814bbdef50b904 brightray/browser/net_log.cc -@@ -45,11 +45,16 @@ - return; - - base::FilePath log_path = -+<<<<<<< .our - command_line->GetSwitchValuePath(network::switches::kLogNetLog); - if (log_path.empty()) - return; - - std::unique_ptr<base::Value> constants(GetConstants()); // Net constants -+======= -+ command_line->GetSwitchValuePath(switches::kLogNetLog); -+ std::unique_ptr<base::Value> constants(GetConstants()); -+>>>>>>> .their - net::NetLogCaptureMode capture_mode = net::NetLogCaptureMode::Default(); - - file_net_log_observer_ = -changed in both - base 100644 28e988f4b49cd35507e4972c19122bbe604f2690 brightray/browser/url_request_context_getter.cc - our 100644 c07ba80cbc522030af580adc5d8676ed31d592d1 brightray/browser/url_request_context_getter.cc - their 100644 972d8054221e95442456559ada46ba62e6f75b79 brightray/browser/url_request_context_getter.cc -@@ -12,7 +12,13 @@ - #include "base/strings/string_util.h" - #include "base/task_scheduler/post_task.h" - #include "brightray/browser/browser_client.h" -+<<<<<<< .our - #include "brightray/browser/browser_context.h" -+======= -+#include "brightray/browser/net/chrome_mojo_proxy_resolver_factory.h" -+#include "brightray/browser/net/devtools_network_controller_handle.h" -+#include "brightray/browser/net/devtools_network_transaction_factory.h" -+>>>>>>> .their - #include "brightray/browser/net/require_ct_delegate.h" - #include "brightray/browser/net_log.h" - #include "brightray/common/switches.h" -@@ -35,11 +41,20 @@ - #include "net/http/http_auth_preferences.h" - #include "net/http/http_server_properties_impl.h" - #include "net/log/net_log.h" -+<<<<<<< .our - #include "net/proxy_resolution/dhcp_pac_file_fetcher_factory.h" - #include "net/proxy_resolution/pac_file_fetcher_impl.h" - #include "net/proxy_resolution/proxy_config.h" - #include "net/proxy_resolution/proxy_config_service.h" - #include "net/proxy_resolution/proxy_service.h" -+======= -+#include "net/proxy/dhcp_proxy_script_fetcher_factory.h" -+#include "net/proxy/proxy_config.h" -+#include "net/proxy/proxy_config_service.h" -+#include "net/proxy/proxy_script_fetcher_impl.h" -+#include "net/proxy/proxy_service.h" -+#include "net/proxy/proxy_service_mojo.h" -+>>>>>>> .their - #include "net/ssl/channel_id_service.h" - #include "net/ssl/default_channel_id_store.h" - #include "net/ssl/ssl_config_service_defaults.h" -@@ -276,9 +291,18 @@ - storage_->set_proxy_resolution_service( - net::ProxyResolutionService::CreateFixed(proxy_config)); - } else { -+<<<<<<< .our - storage_->set_proxy_resolution_service( - net::ProxyResolutionService::CreateUsingSystemProxyResolver( - std::move(proxy_config_service_), net_log_)); -+======= -+ storage_->set_proxy_service(net::CreateProxyServiceUsingMojoFactory( -+ ChromeMojoProxyResolverFactory::GetInstance(), -+ std::move(proxy_config_service_), -+ new net::ProxyScriptFetcherImpl(url_request_context_.get()), -+ dhcp_factory.Create(url_request_context_.get()), host_resolver.get(), -+ nullptr, url_request_context_->network_delegate())); -+>>>>>>> .their - } - - std::vector<std::string> schemes; -changed in both - base 100644 04033f451e045ee7211f0a7152d46c5010a55b72 brightray/browser/url_request_context_getter.h - our 100644 941a5782b14a941bb25a7a9ef6ca6d73f8bc3ec1 brightray/browser/url_request_context_getter.h - their 100644 1a26704d380ab7d113c4e2b0deb940a2d674f96b brightray/browser/url_request_context_getter.h -@@ -76,11 +76,14 @@ - const override; - - net::URLRequestJobFactory* job_factory() const { return job_factory_; } -+<<<<<<< .our - void set_delegate(Delegate* delegate) { delegate_ = delegate; } - - // Discard reference to URLRequestContext and inform observers to - // shutdown. Must be called only on IO thread. - void NotifyContextShuttingDown(std::unique_ptr<ResourceContext>); -+======= -+>>>>>>> .their - - private: - friend class BrowserContext; -changed in both - base 100644 08b203a23291ba0e2ba254873074178da4921123 brightray/common/application_info_win.cc - our 100644 a0256372bbdbbc1d77cb84885faab42a27f55c9f brightray/common/application_info_win.cc - their 100644 89ea0aceb6784119ad65783cfd1c019e7aedbf57 brightray/common/application_info_win.cc -changed in both - base 100644 6a7d91f135c4b904e6d3172da91e7813793a2fba brightray/filenames.gypi - our 100644 b9e2d96175f8ee2d407db9c49b2e2b74756327de brightray/filenames.gypi - their 100644 e3f2aa5f5bc6f7443df50b88c1ab498d2de0a6f1 brightray/filenames.gypi -@@ -47,6 +47,27 @@ - 'browser/media/media_device_id_salt.h', - 'browser/media/media_stream_devices_controller.cc', - 'browser/media/media_stream_devices_controller.h', -+<<<<<<< .our -+======= -+ 'browser/net/devtools_network_conditions.cc', -+ 'browser/net/devtools_network_conditions.h', -+ 'browser/net/devtools_network_controller.cc', -+ 'browser/net/devtools_network_controller.h', -+ 'browser/net/devtools_network_controller_handle.cc', -+ 'browser/net/devtools_network_controller_handle.h', -+ 'browser/net/devtools_network_interceptor.cc', -+ 'browser/net/devtools_network_interceptor.h', -+ 'browser/net/devtools_network_protocol_handler.cc', -+ 'browser/net/devtools_network_protocol_handler.h', -+ 'browser/net/devtools_network_transaction_factory.cc', -+ 'browser/net/devtools_network_transaction_factory.h', -+ 'browser/net/devtools_network_transaction.cc', -+ 'browser/net/devtools_network_transaction.h', -+ 'browser/net/devtools_network_upload_data_stream.cc', -+ 'browser/net/devtools_network_upload_data_stream.h', -+ 'browser/net/chrome_mojo_proxy_resolver_factory.cc', -+ 'browser/net/chrome_mojo_proxy_resolver_factory.h', -+>>>>>>> .their - 'browser/net/require_ct_delegate.cc', - 'browser/net/require_ct_delegate.h', - 'browser/net_log.cc', -changed in both - base 100644 233e21047718c9bbbc9056f79aecf51657886b92 common.gypi - our 100644 676d1e904127066e4a3d313106f15406fcbed8b6 common.gypi - their 100644 acad39d991479147b9bc2ee2c5a51fbd8693a689 common.gypi -changed in both - base 100644 e0e8b153ae51d917f37ba50967e2ef9e5b74254d docs/README.md - our 100644 f7b956e8feb95ceb64743ad260a1759e5a298afe docs/README.md - their 100644 436188887e5dad0a4ae291e5221e3eb8644bc56e docs/README.md -@@ -16,6 +16,7 @@ - - * [Electron FAQ](faq.md) - -+<<<<<<< .our - ## Guides and Tutorials - - * [Setting up the Development Environment](tutorial/development-environment.md) -@@ -66,6 +67,12 @@ - * [Mac App Store](tutorial/mac-app-store-submission-guide.md) - * [Windows Store](tutorial/windows-store-guide.md) - * [Snapcraft](tutorial/snapcraft.md) -+======= -+## Guides -+ -+* [Glossary of Terms](glossary.md) -+* [Support](tutorial/support.md) -+>>>>>>> .their - * [Security](tutorial/security.md) - * [Reporting Security Issues](tutorial/security.md#reporting-security-issues) - * [Chromium Security Issues and Upgrades](tutorial/security.md#chromium-security-issues-and-upgrades) -changed in both - base 100644 926d1dde8ffc33d99c48cb55bbc2d0f9c2087ad4 docs/api/app.md - our 100644 14dc557e237404cbbd5bcebabb0e65486dc36926 docs/api/app.md - their 100644 40fdf2669442ca48fd1fc9a3b4aede6a199df4f1 docs/api/app.md -changed in both - base 100644 2be2da597664c1913a665ad51de5becc42658d0f docs/api/browser-window.md - our 100644 dff61dd336f047cf2f6f06228b2df2b98ff2304d docs/api/browser-window.md - their 100644 38db79506b4dce32f9e6f4cf07e1d6fe72648a24 docs/api/browser-window.md -changed in both - base 100644 f9aaaa90ddd7b8887c5ed3fea371bf175e28c2e7 docs/api/in-app-purchase.md - our 100644 6e612a72e27159602400f4efa30d5bc2f3aa668f docs/api/in-app-purchase.md - their 100644 67109dc0f92d8c537c9a2f1fa5fa2ce223137964 docs/api/in-app-purchase.md -changed in both - base 100644 f130d127936331ab8c6cadd4672a7446a77a683a docs/api/tray.md - our 100644 c60f7ba4c9e9b6ad3fc1b2f717983b71bd286842 docs/api/tray.md - their 100644 5fb345538a7f29bb679223af1c4d9d3b099a9bf0 docs/api/tray.md -changed in both - base 100644 6aaa2bdd9b0ade84160b7449396d5ecd510f0e41 docs/api/web-contents.md - our 100644 8990fe2e97ab62eafdd3f7a4eb8ee782415124c5 docs/api/web-contents.md - their 100644 841acb4a506626c334004e28266ebed3845360d3 docs/api/web-contents.md -@@ -1385,6 +1385,26 @@ - - Shows pop-up dictionary that searches the selected word on the page. - -+<<<<<<< .our -+======= -+#### `contents.setSize(options)` -+ -+Set the size of the page. This is only supported for `<webview>` guest contents. -+ -+* `options` Object -+ * `enableAutoSize` Boolean (optional) - true to make the webview container automatically -+ resize within the bounds specified by the attributes normal, min and max. -+ * `normal` [Size](structures/size.md) (optional) - Normal size of the page. This can be used in -+ combination with the [`disableguestresize`](webview-tag.md#disableguestresize) -+ attribute to manually resize the webview guest contents. -+ * `min` [Size](structures/size.md) (optional) - Minimum size of the page. This can be used in -+ combination with the [`disableguestresize`](webview-tag.md#disableguestresize) -+ attribute to manually resize the webview guest contents. -+ * `max` [Size](structures/size.md) (optional) - Maximium size of the page. This can be used in -+ combination with the [`disableguestresize`](webview-tag.md#disableguestresize) -+ attribute to manually resize the webview guest contents. -+ -+>>>>>>> .their - #### `contents.isOffscreen()` - - Returns `Boolean` - Indicates whether *offscreen rendering* is enabled. -changed in both - base 100644 441e2b4d0533db1de59b7dd4e4a6e21a7fa52af1 docs/api/web-frame.md - our 100644 989060ef3e50c5d93db1a914997f1d190edf3cf5 docs/api/web-frame.md - their 100644 1c7bb83ad953a56561f2d86b3a4d89b37dceb560 docs/api/web-frame.md -changed in both - base 100644 afdff5615421e52b8750ea1de20b63941cbefb1f docs/development/releasing.md - our 100644 85a5fa0a935201521155dc60de45986db5829613 docs/development/releasing.md - their 100644 d27fb5022515cb80a829a80369fb6cb192003522 docs/development/releasing.md -@@ -8,16 +8,25 @@ - information. - - There are a handful of `*_TOKEN` environment variables needed by the release -+<<<<<<< .our - scripts: - - * `ELECTRON_GITHUB_TOKEN`: - Create this by visiting https://github.com/settings/tokens/new?scopes=repo -+======= -+scripts. Once you've generated these per-user tokens, you may want to keep -+them in a local file that you can `source` when starting a release. -+* `ELECTRON_GITHUB_TOKEN`: -+Create as described at https://github.com/settings/tokens/new, -+giving the token repo access scope. -+>>>>>>> .their - * `APPVEYOR_TOKEN`: - Create a token from https://windows-ci.electronjs.org/api-token - If you don't have an account, ask a team member to add you. - * `CIRCLE_TOKEN`: - Create a token from "Personal API Tokens" at https://circleci.com/account/api - * `VSTS_TOKEN`: -+<<<<<<< .our - Create a Personal Access Token at https://github.visualstudio.com/_usersSettings/tokens or https://github.visualstudio.com/_details/security/tokens - with the scope of `Build (read and execute)`. - * `ELECTRON_S3_BUCKET`: -@@ -29,6 +38,10 @@ - of the project. This file is gitignored, and will be loaded into the - environment by the release scripts. - -+======= -+Create a Personal Access Token at https://github.visualstudio.com/_usersSettings/tokens -+with the scope of `Build (read and execute)`. -+>>>>>>> .their - - ## Determine which branch to release from - -@@ -212,10 +225,13 @@ - ```sh - $ npm run release -- --validateRelease - ``` -+<<<<<<< .our - Note, if you need to run `--validateRelease` more than once to check the assets, - run it as above the first time, then `node ./script/release.js --validateRelease` - for subsequent calls so that you don't have to rebuild each time you want to - check the assets. -+======= -+>>>>>>> .their - - ## Publish the release - -@@ -258,6 +274,7 @@ - electron - $ npm run publish-to-npm - ``` -+<<<<<<< .our - - After publishing, you can check the `latest` release: - ```sh -@@ -273,6 +290,8 @@ - ```sh - $ npm dist-tag add electron@2.0.0 latest - ``` -+======= -+>>>>>>> .their - - [the releases page]: https://github.com/electron/electron/releases - [this bump commit]: https://github.com/electron/electron/commit/78ec1b8f89b3886b856377a1756a51617bc33f5a -@@ -303,7 +322,11 @@ - ``` - - Additionally you can pass a job name to the script to run an individual job, eg: -+<<<<<<< .our - ```sh -+======= -+````sh -+>>>>>>> .their - node script/ci-release-build.js --ci=AppVeyor --ghRelease --job=electron-x64 TARGET_BRANCH - ``` - -removed in local - base 100644 7dfc6084f5c94bfb924438e7efa50260d38b9144 docs/tutorial/planned-breaking-changes.md - their 100644 00e01f4f8c3a85f0e535a00c11e22f3595bff4b9 docs/tutorial/planned-breaking-changes.md -added in both - our 100644 bdb3b8678485feabfad2ce23309f5bcac6050f31 docs/tutorial/support.md - their 100644 306876fee9314fbca1779a6c41ff8c6381753bda docs/tutorial/support.md -@@ -91,4 +91,8 @@ - * Fedora 21 - * Debian 8 - -+<<<<<<< .our - [arm-breaking-change]: https://github.com/electron/electron/blob/master/docs/api/breaking-changes.md#duplicate-arm-assets -+======= -+[arm-breaking-change]: https://github.com/electron/electron/blob/master/docs/tutorial/planned-breaking-changes.md#duplicate-arm-assets -+>>>>>>> .their -changed in both - base 100644 53ad35c63321e74a5023197ef2e075584e0f268b electron.gyp - our 100644 944ddab2a3fd879044e31677e4bac2843fffbdee electron.gyp - their 100644 51af69bc0be042f22925ff23f7cb2fc832722ed8 electron.gyp -@@ -4,7 +4,11 @@ - 'product_name%': 'Electron', - 'company_name%': 'GitHub, Inc', - 'company_abbr%': 'github', -+<<<<<<< .our - 'version%': '4.0.0-nightly.20180821', -+======= -+ 'version%': '2.0.8', -+>>>>>>> .their - 'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c', - }, - 'includes': [ -changed in both - base 100644 ef3e8258584a5459b069e2006db44c0a8b66412d filenames.gypi - our 100644 f57860558f06b7e5d8a50f48cfc7e53044df0bc6 filenames.gypi - their 100644 acd43c97988952b9a2760b44d366bd87134a1d65 filenames.gypi -@@ -292,6 +292,8 @@ - 'atom/browser/net/http_protocol_handler.h', - 'atom/browser/net/js_asker.cc', - 'atom/browser/net/js_asker.h', -+ 'atom/browser/net/resolve_proxy_helper.cc', -+ 'atom/browser/net/resolve_proxy_helper.h', - 'atom/browser/net/url_request_about_job.cc', - 'atom/browser/net/url_request_about_job.h', - 'atom/browser/net/url_request_async_asar_job.cc', -changed in both - base 100644 381a2a866372ebe06f374529c634af411c864ba0 lib/browser/api/app.js - our 100644 66f6ae651acf10fb19b8ec068fc5280850dd3d91 lib/browser/api/app.js - their 100644 1ea1daddca84dfeba57b7b7883ebb754b8508d2d lib/browser/api/app.js -changed in both - base 100644 22565dcf9875b7f00acff192b10b05d27d6446a7 lib/browser/api/browser-window.js - our 100644 cb523496d65c7018c30054621cfdeb1281f9db6a lib/browser/api/browser-window.js - their 100644 c5faa0a2c131d633e7aea3a1850abab958d22a1d lib/browser/api/browser-window.js -changed in both - base 100644 da5ff57a113f7a063d1409ff56003db4bd04e68a lib/browser/api/menu.js - our 100644 506e3525c10ce142cafe3fc1bf4de1c255e48503 lib/browser/api/menu.js - their 100644 a87e0cd0436da2899b6402a06d370e755c2aac47 lib/browser/api/menu.js -@@ -47,7 +47,11 @@ - this.delegate = delegate - } - -+<<<<<<< .our - Menu.prototype.popup = function (options = {}) { -+======= -+Menu.prototype.popup = function (options) { -+>>>>>>> .their - if (options == null || typeof options !== 'object') { - throw new TypeError('Options must be an object') - } -@@ -156,7 +160,11 @@ - - Menu.buildFromTemplate = function (template) { - if (!Array.isArray(template)) { -+<<<<<<< .our - throw new TypeError('Invalid template for Menu: Menu template must be an array') -+======= -+ throw new TypeError('Invalid template for Menu') -+>>>>>>> .their - } - const menu = new Menu() - if (!areValidTemplateItems(template)) { -merged - result 100644 bbbc1bbe1727dd30352c4836cea489145cd7ad7d lib/browser/api/screen.js - our 100644 8287bfa8bfdc6db322a05059fd5c8ba58e802db9 lib/browser/api/screen.js -@@ -1,8 +1,17 @@ - const {EventEmitter} = require('events') -+const {deprecate} = require('electron') - const {screen, Screen} = process.atomBinding('screen') - - // Screen is an EventEmitter. - Object.setPrototypeOf(Screen.prototype, EventEmitter.prototype) - EventEmitter.call(screen) - -+const nativeFn = screen.getMenuBarHeight -+screen.getMenuBarHeight = function () { -+ if (!process.noDeprecations) { -+ deprecate.warn('screen.getMenuBarHeight', 'screen.getPrimaryDisplay().workArea') -+ } -+ return nativeFn.call(this) -+} -+ - module.exports = screen -changed in both - base 100644 0338b776f8938c1548ea9786385fe75db9db3403 lib/browser/guest-view-manager.js - our 100644 1e4029e39a981c85fb6ff18c5ccd52f81b3c56f2 lib/browser/guest-view-manager.js - their 100644 169a4ac1d175e9bbbf8a3d8a01612e079c9df635 lib/browser/guest-view-manager.js -@@ -316,6 +316,17 @@ - - ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST_SYNC', function (event, params) { - event.returnValue = createGuest(event.sender, params) -+<<<<<<< .our -+======= -+}) -+ -+ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', function (event, elementInstanceId, guestInstanceId, params) { -+ attachGuest(event, elementInstanceId, guestInstanceId, params) -+}) -+ -+ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_DESTROY_GUEST', function (event, guestInstanceId) { -+ destroyGuest(event.sender, guestInstanceId) -+>>>>>>> .their - }) - - ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', function (event, embedderFrameId, elementInstanceId, guestInstanceId, params) { -changed in both - base 100644 50e890e225a315718d04a0028fb6bf2feb4092ce lib/browser/guest-window-manager.js - our 100644 7253c1942b0956ae6b9b0c80a23470fc26669b8a lib/browser/guest-window-manager.js - their 100644 339b543dd485d3d708aa98a2eec834ab4d65da2b lib/browser/guest-window-manager.js -@@ -65,7 +65,11 @@ - // Inherit certain option values from parent window - const webPreferences = embedder.getLastWebPreferences() - for (const [name, value] of inheritedWebPreferences) { -+<<<<<<< .our - if (webPreferences[name] === value) { -+======= -+ if (embedder.getLastWebPreferences()[name] === value) { -+>>>>>>> .their - options.webPreferences[name] = value - } - } -changed in both - base 100644 24a86fdfee7b87cd8ad177363aec26b438fe79b7 lib/browser/init.js - our 100644 bed3d912ab8be3ca4f21de04e801bb42dc12a528 lib/browser/init.js - their 100644 344bcf16dceafc99dcc337a0d9113c8e764c6364 lib/browser/init.js -changed in both - base 100644 bfb9091e6584c43a19bf6283a79027274053239b lib/browser/objects-registry.js - our 100644 f03a23d2f6910d6555bb9469180d1b60b94bc313 lib/browser/objects-registry.js - their 100644 3fb0923df10da778f3e6bd096e771038fd026cb8 lib/browser/objects-registry.js -@@ -15,7 +15,11 @@ - this.storage = {} - - // Stores the IDs of objects referenced by WebContents. -+<<<<<<< .our - // (ownerKey) => [id] -+======= -+ // (webContentsContextId) => [id] -+>>>>>>> .their - this.owners = {} - } - -@@ -26,10 +30,17 @@ - const id = this.saveToStorage(obj) - - // Add object to the set of referenced objects. -+<<<<<<< .our - const ownerKey = getOwnerKey(webContents, contextId) - let owner = this.owners[ownerKey] - if (!owner) { - owner = this.owners[ownerKey] = new Set() -+======= -+ const webContentsContextId = `${webContents.id}-${contextId}` -+ let owner = this.owners[webContentsContextId] -+ if (!owner) { -+ owner = this.owners[webContentsContextId] = new Set() -+>>>>>>> .their - this.registerDeleteListener(webContents, contextId) - } - if (!owner.has(id)) { -@@ -50,8 +61,13 @@ - // Note that an object may be double-freed (cleared when page is reloaded, and - // then garbage collected in old page). - remove (webContents, contextId, id) { -+<<<<<<< .our - const ownerKey = getOwnerKey(webContents, contextId) - let owner = this.owners[ownerKey] -+======= -+ const webContentsContextId = `${webContents.id}-${contextId}` -+ let owner = this.owners[webContentsContextId] -+>>>>>>> .their - if (owner) { - // Remove the reference in owner. - owner.delete(id) -@@ -62,13 +78,22 @@ - - // Clear all references to objects refrenced by the WebContents. - clear (webContents, contextId) { -+<<<<<<< .our - const ownerKey = getOwnerKey(webContents, contextId) - let owner = this.owners[ownerKey] -+======= -+ const webContentsContextId = `${webContents.id}-${contextId}` -+ let owner = this.owners[webContentsContextId] -+>>>>>>> .their - if (!owner) return - - for (let id of owner) this.dereference(id) - -+<<<<<<< .our - delete this.owners[ownerKey] -+======= -+ delete this.owners[webContentsContextId] -+>>>>>>> .their - } - - // Private: Saves the object into storage and assigns an ID for it. -@@ -87,7 +112,10 @@ - - // Private: Dereference the object from store. - dereference (id) { -+<<<<<<< .our - // FIXME(MarshallOfSound): We should remove this once remote deref works well -+======= -+>>>>>>> .their - if (process.env.ELECTRON_DISABLE_REMOTE_DEREFERENCING) return - - let pointer = this.storage[id] -@@ -101,7 +129,11 @@ - } - } - -+<<<<<<< .our - // Private: Clear the storage when renderer process is destroyed. -+======= -+ // Private: Clear the storage when renderer process is destoryed. -+>>>>>>> .their - registerDeleteListener (webContents, contextId) { - const processId = webContents.getProcessId() - const listener = (event, deletedProcessId) => { -changed in both - base 100644 c0cd09dea4273642aa780756985e9c90dbe164d3 lib/browser/rpc-server.js - our 100644 ff9f77321de3a4145946b67f3fe2a597f98e2510 lib/browser/rpc-server.js - their 100644 612ec274ca13cdb7167a41fbacb711c3cc6cb9c3 lib/browser/rpc-server.js -@@ -84,7 +84,11 @@ - - // Fill the meta object according to value's type. - if (meta.type === 'array') { -+<<<<<<< .our - meta.members = value.map((el) => valueToMeta(sender, contextId, el, optimizeSimpleObject)) -+======= -+ meta.members = value.map((el) => valueToMeta(sender, contextId, el)) -+>>>>>>> .their - } else if (meta.type === 'object' || meta.type === 'function') { - meta.name = value.constructor ? value.constructor.name : '' - -@@ -210,9 +214,15 @@ - return rendererFunctions.get(objectId) - } - -+<<<<<<< .our - const processId = sender.getProcessId() - let callIntoRenderer = function (...args) { - if (!sender.isDestroyed() && processId === sender.getProcessId()) { -+======= -+ const webContentsId = sender.getId() -+ let callIntoRenderer = function (...args) { -+ if (!sender.isDestroyed() && webContentsId === sender.getId()) { -+>>>>>>> .their - sender.send('ELECTRON_RENDERER_CALLBACK', contextId, meta.id, valueToMeta(sender, contextId, args)) - } else { - removeRemoteListenersAndLogWarning(this, meta, callIntoRenderer) -@@ -234,8 +244,14 @@ - // Call a function and send reply asynchronously if it's a an asynchronous - // style function and the caller didn't pass a callback. - const callFunction = function (event, contextId, func, caller, args) { -+<<<<<<< .our - const funcMarkedAsync = v8Util.getHiddenValue(func, 'asynchronous') - const funcPassedCallback = typeof args[args.length - 1] === 'function' -+======= -+ let funcMarkedAsync, funcName, funcPassedCallback, ref, ret -+ funcMarkedAsync = v8Util.getHiddenValue(func, 'asynchronous') -+ funcPassedCallback = typeof args[args.length - 1] === 'function' -+>>>>>>> .their - try { - if (funcMarkedAsync && !funcPassedCallback) { - args.push(function (ret) { -@@ -243,7 +259,11 @@ - }) - func.apply(caller, args) - } else { -+<<<<<<< .our - const ret = func.apply(caller, args) -+======= -+ ret = func.apply(caller, args) -+>>>>>>> .their - event.returnValue = valueToMeta(event.sender, contextId, ret, true) - } - } catch (error) { -@@ -302,7 +322,14 @@ - throwRPCError(`Cannot call constructor on missing remote object ${id}`) - } - -+<<<<<<< .our - event.returnValue = valueToMeta(event.sender, contextId, new constructor(...args)) -+======= -+ // Call new with array of arguments. -+ // http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible -+ let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args)))() -+ event.returnValue = valueToMeta(event.sender, contextId, obj) -+>>>>>>> .their - } catch (error) { - event.returnValue = exceptionToMeta(event.sender, contextId, error) - } -@@ -332,7 +359,14 @@ - throwRPCError(`Cannot call constructor '${method}' on missing remote object ${id}`) - } - -+<<<<<<< .our - event.returnValue = valueToMeta(event.sender, contextId, new object[method](...args)) -+======= -+ // Call new with array of arguments. -+ let constructor = object[method] -+ let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args)))() -+ event.returnValue = valueToMeta(event.sender, contextId, obj) -+>>>>>>> .their - } catch (error) { - event.returnValue = exceptionToMeta(event.sender, contextId, error) - } -changed in both - base 100644 6dc774049def3acbd13b79dfd559c12d4eebd657 lib/common/api/crash-reporter.js - our 100644 1090d425e4c5cdf89a03d470718324ef16963472 lib/common/api/crash-reporter.js - their 100644 1b20fa52aab741e5dd34de7872f36798ec7c1c68 lib/common/api/crash-reporter.js -changed in both - base 100644 1b9a993a2e67a00c073a9df9883c7adc3c2fcf65 lib/common/asar.js - our 100644 41c3d0c85c69954dddad53c674f84051f25372e4 lib/common/asar.js - their 100644 6565ddab86e0d11953cbbb000420535e95602a5e lib/common/asar.js -changed in both - base 100644 a4f8072ed57642e1ca7d1066e132875da7ad3f46 lib/renderer/api/remote.js - our 100644 59117f8f2dd977fc1817a6b1d540b616ddcb0dae lib/renderer/api/remote.js - their 100644 4a38befb03cbdb560a3b34d8dd771d3d19c0bc3b lib/renderer/api/remote.js -changed in both - base 100644 1cb69436dd479baf54b9805c04c0c31b20f24fad lib/renderer/init.js - our 100644 2470a5e8be80e770b0c03f6a439a71e72ae12a1b lib/renderer/init.js - their 100644 93129849ae048c1c09f943b56e78562f46be04e8 lib/renderer/init.js -changed in both - base 100644 d2da884f1d9caf3d633de25837cb2128f564f2fb lib/renderer/security-warnings.js - our 100644 b24f9e28b879154457be0342b9d4b44c0e651253 lib/renderer/security-warnings.js - their 100644 4f7d6ef9e596cdc3a5c7e1f2b89b24b9cd67de1d lib/renderer/security-warnings.js -changed in both - base 100644 110b0e453afd07210c9fba0f93d8755b5fbc1a93 lib/renderer/web-view/guest-view-internal.js - our 100644 6e42c769b70e5223fe97397f87144ec342882f8d lib/renderer/web-view/guest-view-internal.js - their 100644 f7c6232d41a52ff4c2af71350d4ae43c05a3b12a lib/renderer/web-view/guest-view-internal.js -@@ -90,6 +90,16 @@ - }, - createGuestSync: function (params) { - return ipcRenderer.sendSync('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST_SYNC', params) -+<<<<<<< .our -+======= -+ }, -+ attachGuest: function (elementInstanceId, guestInstanceId, params) { -+ ipcRenderer.send('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', elementInstanceId, guestInstanceId, params) -+ webFrame.attachGuest(elementInstanceId) -+ }, -+ destroyGuest: function (guestInstanceId) { -+ ipcRenderer.send('ELECTRON_GUEST_VIEW_MANAGER_DESTROY_GUEST', guestInstanceId) -+>>>>>>> .their - }, - attachGuest: function (elementInstanceId, guestInstanceId, params, contentWindow) { - const embedderFrameId = webFrame.getWebFrameId(contentWindow) -changed in both - base 100644 16bfe7e61ac6e2c516f4523f2854a4f1db169c70 lib/renderer/web-view/web-view-attributes.js - our 100644 ad9970bd0b9355ac8163c82f6fa7f3ca08a05de6 lib/renderer/web-view/web-view-attributes.js - their 100644 204046bd60542657e9213f2b12e5c126ee10ea33 lib/renderer/web-view/web-view-attributes.js -changed in both - base 100644 544652e44756fc63747a5cf58548b87363508b4a lib/renderer/web-view/web-view.js - our 100644 574a2b545597f9d1c05ec9b7147585063e90ae89 lib/renderer/web-view/web-view.js - their 100644 1e2ea0adf5d85af68dbdf0e976d68753b4ae2572 lib/renderer/web-view/web-view.js -@@ -130,10 +130,60 @@ - this.attributes[attributeName].handleMutation(oldValue, newValue) - } - -+<<<<<<< .our - onElementResize () { - const resizeEvent = new Event('resize') - resizeEvent.newWidth = this.webviewNode.clientWidth - resizeEvent.newHeight = this.webviewNode.clientHeight -+======= -+ handleBrowserPluginAttributeMutation (attributeName, oldValue, newValue) { -+ if (attributeName === webViewConstants.ATTRIBUTE_INTERNALINSTANCEID && !oldValue && !!newValue) { -+ this.browserPluginNode.removeAttribute(webViewConstants.ATTRIBUTE_INTERNALINSTANCEID) -+ this.internalInstanceId = parseInt(newValue) -+ -+ // Track when the element resizes using the element resize callback. -+ webFrame.registerElementResizeCallback(this.internalInstanceId, this.onElementResize.bind(this)) -+ if (this.guestInstanceId) { -+ guestViewInternal.attachGuest(this.internalInstanceId, this.guestInstanceId, this.buildParams()) -+ } -+ } -+ } -+ -+ onSizeChanged (webViewEvent) { -+ const {newHeight, newWidth} = webViewEvent -+ const node = this.webviewNode -+ const width = node.offsetWidth -+ -+ // Check the current bounds to make sure we do not resize <webview> -+ // outside of current constraints. -+ const maxWidth = this.attributes[webViewConstants.ATTRIBUTE_MAXWIDTH].getValue() | width -+ const maxHeight = this.attributes[webViewConstants.ATTRIBUTE_MAXHEIGHT].getValue() | width -+ let minWidth = this.attributes[webViewConstants.ATTRIBUTE_MINWIDTH].getValue() | width -+ let minHeight = this.attributes[webViewConstants.ATTRIBUTE_MINHEIGHT].getValue() | width -+ minWidth = Math.min(minWidth, maxWidth) -+ minHeight = Math.min(minHeight, maxHeight) -+ if (!this.attributes[webViewConstants.ATTRIBUTE_AUTOSIZE].getValue() || (newWidth >= minWidth && newWidth <= maxWidth && newHeight >= minHeight && newHeight <= maxHeight)) { -+ node.style.width = `${newWidth}px` -+ node.style.height = `${newHeight}px` -+ -+ // Only fire the DOM event if the size of the <webview> has actually -+ // changed. -+ this.dispatchEvent(webViewEvent) -+ } -+ } -+ -+ onElementResize (newSize) { -+ // Dispatch the 'resize' event. -+ const resizeEvent = new Event('resize') -+ -+ // Using client size values, because when a webview is transformed `newSize` -+ // is incorrect -+ newSize.width = this.webviewNode.clientWidth -+ newSize.height = this.webviewNode.clientHeight -+ -+ resizeEvent.newWidth = newSize.width -+ resizeEvent.newHeight = newSize.height -+>>>>>>> .their - this.dispatchEvent(resizeEvent) - } - -@@ -144,7 +194,10 @@ - } - - createGuestSync () { -+<<<<<<< .our - this.beforeFirstNavigation = false -+======= -+>>>>>>> .their - this.attachGuestInstance(guestViewInternal.createGuestSync(this.buildParams())) - } - -changed in both - base 100644 119391e79462bfa8bb1494039bcb3522d97acead lib/sandboxed_renderer/init.js - our 100644 30a3fa55216f6bf7588c3accc07b150a31163b7c lib/sandboxed_renderer/init.js - their 100644 b45a105091446f1b1c3afd2f4905ccf7c0ef67b5 lib/sandboxed_renderer/init.js -@@ -35,10 +35,13 @@ - ['url', require('url')] - ]) - -+<<<<<<< .our - const { - preloadSrc, preloadError, process: processProps - } = electron.ipcRenderer.sendSync('ELECTRON_BROWSER_SANDBOX_LOAD') - -+======= -+>>>>>>> .their - require('../renderer/web-frame-init')() - - // Pass different process object to the preload script(which should not have -@@ -78,6 +81,7 @@ - require('../renderer/inspector') - } - -+<<<<<<< .our - if (binding.guestInstanceId) { - process.guestInstanceId = parseInt(binding.guestInstanceId) - } -@@ -88,6 +92,8 @@ - require('../renderer/web-view/web-view-attributes') - } - -+======= -+>>>>>>> .their - // Wrap the script into a function executed in global scope. It won't have - // access to the current scope, so we'll expose a few objects as arguments: - // -@@ -107,6 +113,7 @@ - // and any `require('electron')` calls in `preload.js` will work as expected - // since browserify won't try to include `electron` in the bundle, falling back - // to the `preloadRequire` function above. -+<<<<<<< .our - if (preloadSrc) { - const preloadWrapperSrc = `(function(require, process, Buffer, global, setImmediate, clearImmediate) { - ${preloadSrc} -@@ -118,4 +125,18 @@ - preloadFn(preloadRequire, preloadProcess, Buffer, global, setImmediate, clearImmediate) - } else if (preloadError) { - console.error(preloadError.stack) -+======= -+if (preloadPath) { -+ const preloadSrc = fs.readFileSync(preloadPath).toString() -+ const preloadWrapperSrc = `(function(require, process, Buffer, global, setImmediate) { -+ ${preloadSrc} -+ })` -+ -+ // eval in window scope: -+ // http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.2 -+ const geval = eval -+ const preloadFn = geval(preloadWrapperSrc) -+ const {setImmediate} = require('timers') -+ preloadFn(preloadRequire, preloadProcess, Buffer, global, setImmediate) -+>>>>>>> .their - } -changed in both - base 100755 8cb9ed8815f2a52964f6d7acfa30645908464c4f npm/install.js - our 100755 ed208de247ef151147c58d9efc4af9519e983f86 npm/install.js - their 100755 caa89deabeb8dc2ca28c2331cd8bcc28bb04cd52 npm/install.js -@@ -23,6 +23,12 @@ - process.exit(0) - } - -+var mirror -+ -+if (version.indexOf('nightly') !== -1) { -+ mirror = 'https://github.com/electron/nightlies/releases/download/v' -+} -+ - // downloads if not cached - download({ - cache: process.env.electron_config_cache, -@@ -31,7 +37,8 @@ - arch: process.env.npm_config_arch, - strictSSL: process.env.npm_config_strict_ssl === 'true', - force: process.env.force_no_cache === 'true', -- quiet: process.env.npm_config_loglevel === 'silent' || process.env.CI -+ quiet: process.env.npm_config_loglevel === 'silent' || process.env.CI, -+ mirror - }, extractFile) - - // unzips and makes path.txt point at the correct executable -changed in both - base 100644 9d3b0da9c80b223e4a1188311a1121796eb9f7ae package.json - our 100644 c081cd89450cd50efba1ec280ff1349a96ea3ce0 package.json - their 100644 5f07d696148bca95f5cea25505048fcf9ea64576 package.json -@@ -1,6 +1,10 @@ - { - "name": "electron", -+<<<<<<< .our - "version": "4.0.0-nightly.20180821", -+======= -+ "version": "2.0.8", -+>>>>>>> .their - "repository": "https://github.com/electron/electron", - "description": "Build cross platform desktop apps with JavaScript, HTML, and CSS", - "devDependencies": { -@@ -13,7 +17,11 @@ - "dugite": "^1.45.0", - "electabul": "~0.0.4", - "electron-docs-linter": "^2.3.4", -+<<<<<<< .our - "electron-typescript-definitions": "^1.3.6", -+======= -+ "electron-typescript-definitions": "1.3.2", -+>>>>>>> .their - "github": "^9.2.0", - "html-entities": "^1.2.1", - "husky": "^0.14.3", -@@ -25,8 +33,12 @@ - "remark-cli": "^4.0.0", - "remark-preset-lint-markdown-style-guide": "^2.1.1", - "request": "^2.68.0", -+<<<<<<< .our - "semver": "^5.5.0", - "serve": "^6.5.8", -+======= -+ "serve": "^6.5.3", -+>>>>>>> .their - "standard": "^10.0.0", - "standard-markdown": "^4.0.0", - "sumchecker": "^2.0.2", -changed in both - base 100755 4465b85c135ddb55a673c5180e15f05f09dac57e script/bootstrap.py - our 100755 e4aaf89e216b0164f15882a3040e8cac70bf1fd9 script/bootstrap.py - their 100755 c6ebe4ef6975efd1f6184159cc3d9d079bf3628d script/bootstrap.py -changed in both - base 100755 c97cd8336f7d7980911d0bdea93137e7bc95ba24 script/build.py - our 100755 fb2b95d3bb71a25ce1ca58acf596afdc0f2cc5bd script/build.py - their 100755 2a2231394207c28fcd2b86d3d9f9b079b08d637e script/build.py -@@ -40,6 +40,12 @@ - if is_verbose_mode(): - ninja.append('-v') - -+<<<<<<< .our -+======= -+ args = parse_args() -+ if args.ninja_path: -+ ninja = args.ninja_path -+>>>>>>> .their - if args.libcc: - if ('D' not in args.configuration - or not os.path.exists(GCLIENT_DONE) -@@ -93,12 +99,15 @@ - parser.add_argument('--ninja-path', - help='Path of ninja command to use.', - required=False) -+<<<<<<< .our - parser.add_argument('--compdb', - help=( - 'Generate JSON compilation database. This will not ' - 'trigger actual build. ' - ), - action='store_true', default=False) -+======= -+>>>>>>> .their - return parser.parse_args() - - -changed in both - base 100755 de3b9ffd48156379afd677b98c40c97532cb8367 script/create-dist.py - our 100755 4a6c0c7ce8f275175e48c4c380ff33627f7a5961 script/create-dist.py - their 100755 e8396a2e6d242b9deba3b6a7642060584cd1a605 script/create-dist.py -@@ -147,7 +147,11 @@ - - # Copy file and keep the executable bit. - shutil.copyfile(src, dest) -+<<<<<<< .our - add_exec_bit(dest) -+======= -+ os.chmod(dest, os.stat(dest).st_mode | stat.S_IEXEC) -+>>>>>>> .their - - def copy_vcruntime_binaries(): - arch = get_target_arch() -@@ -302,7 +306,11 @@ - dest = os.path.join(DIST_DIR, binary) - # Copy file and keep the executable bit. - shutil.copyfile(src, dest) -+<<<<<<< .our - add_exec_bit(dest) -+======= -+ os.chmod(dest, os.stat(dest).st_mode | stat.S_IEXEC) -+>>>>>>> .their - - dist_name = get_zip_name(binary, version) - zip_file = os.path.join(SOURCE_ROOT, 'dist', dist_name) -changed in both - base 100644 76f39fc26973e01145f7758785778075ddbaa648 script/lib/dbus_mock.py - our 100644 9b9c8029cb75a9d84c632d04f234c2020542ca68 script/lib/dbus_mock.py - their 100644 00b1fd98d7837cfef60460f9d456a5cb8340761c script/lib/dbus_mock.py -@@ -4,21 +4,29 @@ - import atexit - import os - import sys -+<<<<<<< .our -+======= -+ -+>>>>>>> .their - - - def stop(): - DBusTestCase.stop_dbus(DBusTestCase.system_bus_pid) - DBusTestCase.stop_dbus(DBusTestCase.session_bus_pid) -+<<<<<<< .our - - def start(): - dbusmock_log = sys.stdout if is_verbose_mode() else open(os.devnull, 'w') - - DBusTestCase.start_system_bus() - DBusTestCase.spawn_server_template('logind', None, dbusmock_log) -+======= -+>>>>>>> .their - - DBusTestCase.start_session_bus() - DBusTestCase.spawn_server_template('notification_daemon', None, dbusmock_log) - -+<<<<<<< .our - if __name__ == '__main__': - import subprocess - start() -@@ -26,3 +34,14 @@ - subprocess.check_call(sys.argv[1:]) - finally: - stop() -+======= -+atexit.register(cleanup) -+ -+dbusmock_log = sys.stdout if is_verbose_mode() else open(os.devnull, 'w') -+ -+DBusTestCase.start_system_bus() -+DBusTestCase.spawn_server_template('logind', None, dbusmock_log) -+ -+DBusTestCase.start_session_bus() -+DBusTestCase.spawn_server_template('notification_daemon', None, dbusmock_log) -+>>>>>>> .their -changed in both - base 100644 492c9a411caa8ac47919d2cfb56fa73575ac7f29 script/lib/util.py - our 100644 d479d5a9556534c5d98ae1fdc97397cdd14376f5 script/lib/util.py - their 100644 de595f7275c67c790fa4f869eba997090086f3bc script/lib/util.py -@@ -297,6 +297,7 @@ - else: - execute_stdout(args, env) - -+<<<<<<< .our - def add_exec_bit(filename): - os.chmod(filename, os.stat(filename).st_mode | stat.S_IEXEC) - -@@ -305,6 +306,13 @@ - - def is_stable(v): - return len(v.split(".")) == 3 -+======= -+def clean_parse_version(v): -+ return parse_version(v.split("-")[0]) -+ -+def is_stable(v): -+ return len(v.split(".")) == 3 -+>>>>>>> .their - - def is_beta(v): - return 'beta' in v -changed in both - base 100755 1f90ed795fcc3e739061cf4ae5c8ab9ea95a1236 script/test.py - our 100755 46cada435e1bd6ecaa2111cdf29e5aeb834b227e script/test.py - their 100755 cb17102557dca975208140b479168906100cfd74 script/test.py -changed in both - base 100755 a35eb2f5b90272c8369bcfd511f976a4f64fa57f script/update-clang.sh - our 100755 0c7ab60533381e33152b8735aaccf41d5f0d6676 script/update-clang.sh - their 100755 f7dce574f11b2fa901ee27aa4ca0a1731a0d7b1e script/update-clang.sh -@@ -8,10 +8,14 @@ - # Do NOT CHANGE this if you don't know what you're doing -- see - # https://code.google.com/p/chromium/wiki/UpdatingClang - # Reverting problematic clang rolls is safe, though. -+<<<<<<< .our - CLANG_REVISION=325667 -+======= -+CLANG_REVISION=308728 -+>>>>>>> .their - - # This is incremented when pushing a new build of Clang at the same revision. --CLANG_SUB_REVISION=1 -+CLANG_SUB_REVISION=3 - - PACKAGE_VERSION="${CLANG_REVISION}-${CLANG_SUB_REVISION}" - -changed in both - base 100755 4da630433812b51ff0ebbdf89f68c71d90ab8046 script/upload.py - our 100755 2d9eaa201265971ca01acaea6e84a440e5db0532 script/upload.py - their 100755 d58a22f4314346d48f1130dec04e5cc137e56397 script/upload.py -@@ -37,7 +37,11 @@ - args = parse_args() - if args.upload_to_s3: - utcnow = datetime.datetime.utcnow() -+<<<<<<< .our - args.upload_timestamp = utcnow.strftime('%Y%m%d') -+======= -+ args.upload_timestamp = utcnow.strftime('%Y-%m-%d_%H:%M:%S') -+>>>>>>> .their - - if not dist_newer_than_head(): - run_python_script('create-dist.py') -@@ -79,6 +83,14 @@ - upload_electron(release, os.path.join(DIST_DIR, chromedriver), args) - mksnapshot = get_zip_name('mksnapshot', ELECTRON_VERSION) - upload_electron(release, os.path.join(DIST_DIR, mksnapshot), args) -+<<<<<<< .our -+======= -+ -+ if get_target_arch().startswith('arm'): -+ # Upload the x64 binary for arm/arm64 mksnapshot -+ mksnapshot = get_zip_name('mksnapshot', ELECTRON_VERSION, 'x64') -+ upload_electron(release, os.path.join(DIST_DIR, mksnapshot), args) -+>>>>>>> .their - - if get_target_arch().startswith('arm'): - # Upload the x64 binary for arm/arm64 mksnapshot -@@ -170,7 +182,19 @@ - # Upload the checksum file. - upload_sha256_checksum(args.version, file_path) - -+<<<<<<< .our -+ -+======= -+ # Upload ARM assets without the v7l suffix for backwards compatibility -+ # TODO Remove for 2.0 -+ if 'armv7l' in filename: -+ arm_filename = filename.replace('armv7l', 'arm') -+ arm_file_path = os.path.join(os.path.dirname(file_path), arm_filename) -+ shutil.copy2(file_path, arm_file_path) -+ upload_electron(release, arm_file_path, args) -+ - -+>>>>>>> .their - def upload_io_to_github(release, filename, filepath, version): - print 'Uploading %s to Github' % \ - (filename) -changed in both - base 100644 0eda951b15d6fff609b6612589e222adb4f0720e spec/api-app-spec.js - our 100644 d224eda2989332c18d655cef05a8bacc2eb6d4b8 spec/api-app-spec.js - their 100644 5c2e0a0c7e6184e780b7ec031f9788f1f54eaca9 spec/api-app-spec.js -@@ -9,7 +9,10 @@ - const {ipcRenderer, remote} = require('electron') - const {closeWindow} = require('./window-helpers') - -+<<<<<<< .our - const {expect} = chai -+======= -+>>>>>>> .their - const {app, BrowserWindow, Menu, ipcMain} = remote - - const isCI = remote.getGlobal('isCi') -@@ -186,11 +189,19 @@ - - // Singleton will send us greeting data to let us know it's running. - // After that, ask it to exit gracefully and confirm that it does. -+<<<<<<< .our - appProcess.stdout.on('data', data => appProcess.kill()) - appProcess.on('exit', (code, sig) => { - const message = `code:\n${code}\nsig:\n${sig}` - expect(code).to.equal(0, message) - expect(sig).to.be.null(message) -+======= -+ appProcess.stdout.on('data', (data) => appProcess.kill()) -+ appProcess.on('exit', (code, sig) => { -+ let message = ['code:', code, 'sig:', sig].join('\n') -+ assert.equal(code, 0, message) -+ assert.equal(sig, null, message) -+>>>>>>> .their - done() - }) - }) -@@ -948,4 +959,18 @@ - return expect(app.whenReady()).to.be.eventually.fulfilled - }) - }) -+ -+ describe('dock.setMenu', () => { -+ before(function () { -+ if (process.platform !== 'darwin') { -+ this.skip() -+ } -+ }) -+ -+ it('keeps references to the menu', () => { -+ app.dock.setMenu(new Menu()) -+ const v8Util = process.atomBinding('v8_util') -+ v8Util.requestGarbageCollectionForTesting() -+ }) -+ }) - }) -changed in both - base 100644 ab96021ebf4c4360fa581b5a695249456a9afeda spec/api-browser-view-spec.js - our 100644 968912a4abf3d759a1363e2420d2c21b7923dbd6 spec/api-browser-view-spec.js - their 100644 df239a8914527a2d62f652b878c97a7791f63a9d spec/api-browser-view-spec.js -@@ -44,9 +44,15 @@ - describe('BrowserView.isDestroyed()', () => { - it('returns correct value', () => { - view = new BrowserView() -+<<<<<<< .our - expect(view.isDestroyed()).to.be.false() - view.destroy() - expect(view.isDestroyed()).to.be.true() -+======= -+ assert.ok(!view.isDestroyed()) -+ view.destroy() -+ assert.ok(view.isDestroyed()) -+>>>>>>> .their - }) - }) - -changed in both - base 100644 3033eb6a1f6cca3cf4874a54dd217ec62d2d82cd spec/api-browser-window-spec.js - our 100644 f4cba12ec19d224bc46fca898db42a99baf4972e spec/api-browser-window-spec.js - their 100644 4807094095a591ca716d520aef51a25af6ff9687 spec/api-browser-window-spec.js -@@ -409,12 +409,34 @@ - }) - }) - -+<<<<<<< .our - // TODO(alexeykuzmin): [Ch66] Enable the test. Passes locally. - xdescribe('BrowserWindow.getFocusedWindow()', (done) => { -+======= -+ describe('BrowserWindow.getFocusedWindow()', (done) => { -+>>>>>>> .their - it('returns the opener window when dev tools window is focused', (done) => { - w.show() - w.webContents.once('devtools-focused', () => { - assert.deepEqual(BrowserWindow.getFocusedWindow(), w) -+<<<<<<< .our -+======= -+ done() -+ }) -+ w.webContents.openDevTools({mode: 'undocked'}) -+ }) -+ }) -+ -+ describe('BrowserWindow.capturePage(rect, callback)', () => { -+ it('calls the callback with a Buffer', (done) => { -+ w.capturePage({ -+ x: 0, -+ y: 0, -+ width: 100, -+ height: 100 -+ }, (image) => { -+ assert.equal(image.isEmpty(), true) -+>>>>>>> .their - done() - }) - w.webContents.openDevTools({mode: 'undocked'}) -@@ -453,6 +475,29 @@ - // Values can be 0,2,3,4, or 6. We want 6, which is RGB + Alpha - expect(imgBuffer[25]).to.equal(6) - }) -+ -+ it('preserves transparency', (done) => { -+ w.close() -+ const width = 400 -+ const height = 400 -+ w = new BrowserWindow({ -+ show: false, -+ width: width, -+ height: height, -+ transparent: true -+ }) -+ w.loadURL('data:text/html,<html><body background-color: rgba(255,255,255,0)></body></html>') -+ w.once('ready-to-show', () => { -+ w.show() -+ w.capturePage((image) => { -+ let imgBuffer = image.toPNG() -+ // Check 25th byte in the PNG -+ // Values can be 0,2,3,4, or 6. We want 6, which is RGB + Alpha -+ assert.equal(imgBuffer[25], 6) -+ done() -+ }) -+ }) -+ }) - }) - - describe('BrowserWindow.setSize(width, height)', () => { -@@ -763,6 +808,7 @@ - w.addTabbedWindow(w) - }, /AddTabbedWindow cannot be called by a window on itself./) - }) -+<<<<<<< .our - }) - - describe('BrowserWindow.setWindowButtonVisibility()', () => { -@@ -790,6 +836,8 @@ - w.setWindowButtonVisibility(true) - }, /Not supported for this window/) - }) -+======= -+>>>>>>> .their - }) - - describe('BrowserWindow.setVibrancy(type)', () => { -changed in both - base 100644 b4d55cd70b70b42d52a026ff7b4ff3c47d1671df spec/api-crash-reporter-spec.js - our 100644 dd31b91e1244785412b87db96bb141599e5ccb0f spec/api-crash-reporter-spec.js - their 100644 ffa3c0370595f32b0c7d476b82bea133d6a87000 spec/api-crash-reporter-spec.js -@@ -266,6 +266,7 @@ - describe('getLastCrashReport', () => { - it('correctly returns the most recent report', () => { - const reports = crashReporter.getUploadedReports() -+<<<<<<< .our - expect(reports).to.be.an('array') - expect(reports).to.have.lengthOf.at.least(2, - 'There are not enough reports for this test') -@@ -275,16 +276,31 @@ - - // Let's find the newest report. - const {report: newestReport} = reports.reduce((acc, cur) => { -+======= -+ const lastReport = crashReporter.getLastCrashReport() -+ -+ // Let's find the newest report -+ const newestReport = reports.reduce((acc, cur) => { -+>>>>>>> .their - const timestamp = new Date(cur.date).getTime() - return (timestamp > acc.timestamp) - ? { report: cur, timestamp: timestamp } - : acc -+<<<<<<< .our - }, { timestamp: -Infinity }) - assert(newestReport, 'Hey!') - - expect(lastReport.date.getTime()).to.be.equal( - newestReport.date.getTime(), - 'Last report is not the newest.') -+======= -+ }, { timestamp: 0 }) -+ -+ assert(reports.length > 1, 'has more than 1 report') -+ assert(lastReport != null, 'found a last report') -+ assert(lastReport.date.toString() === newestReport.report.date.toString(), -+ 'last report is correct') -+>>>>>>> .their - }) - }) - -changed in both - base 100644 667f098bc4b9974a142435e7d3ddb762ac0f54a2 spec/api-menu-spec.js - our 100644 ed2749700c6c8bf299f507d52606c1ae3f597e5c spec/api-menu-spec.js - their 100644 3efb6ed8745843bb7e221fe25b3c75761a085759 spec/api-menu-spec.js -@@ -649,6 +649,7 @@ - }) - - it('throws an error if options is not an object', () => { -+<<<<<<< .our - expect(() => { - menu.popup('this is a string, not an object') - }).to.throw(/Options must be an object/) -@@ -658,6 +659,11 @@ - expect(() => { - menu.popup({}) - }).to.not.throw() -+======= -+ assert.throws(() => { -+ menu.popup() -+ }, /Options must be an object/) -+>>>>>>> .their - }) - - it('should emit menu-will-show event', (done) => { -added in both - our 100644 9ab56d88e50ae5891364cb271362e5ec0c0edd26 spec/api-notification-dbus-spec.js - their 100644 81c1b68f31d0c9490742d3bd4b4227abaaf72ca3 spec/api-notification-dbus-spec.js -@@ -6,7 +6,11 @@ - // - // See https://pypi.python.org/pypi/python-dbusmock to read about dbusmock. - -+<<<<<<< .our - const {expect} = require('chai') -+======= -+const assert = require('assert') -+>>>>>>> .their - const dbus = require('dbus-native') - const Promise = require('bluebird') - -@@ -27,12 +31,20 @@ - before(async () => { - // init app - app.setName(appName) -+<<<<<<< .our - app.setDesktopName(`${appName}.desktop`) -+======= -+ app.setDesktopName(appName + '.desktop') -+>>>>>>> .their - // init dbus - const path = '/org/freedesktop/Notifications' - const iface = 'org.freedesktop.DBus.Mock' - const bus = dbus.sessionBus() -+<<<<<<< .our - console.log(`session bus: ${process.env.DBUS_SESSION_BUS_ADDRESS}`) -+======= -+ console.log('session bus: ' + process.env.DBUS_SESSION_BUS_ADDRESS) -+>>>>>>> .their - const service = bus.getService(serviceName) - const getInterface = Promise.promisify(service.getInterface, {context: service}) - mock = await getInterface(path, iface) -@@ -48,10 +60,17 @@ - app.setVersion(realAppVersion) - }) - -+<<<<<<< .our - describe(`Notification module using ${serviceName}`, () => { - function onMethodCalled (done) { - function cb (name) { - console.log(`onMethodCalled: ${name}`) -+======= -+ describe('Notification module using ' + serviceName, () => { -+ function onMethodCalled (done) { -+ function cb (name) { -+ console.log('onMethodCalled: ' + name) -+>>>>>>> .their - if (name === 'Notify') { - mock.removeListener('MethodCalled', cb) - console.log('done') -@@ -83,7 +102,11 @@ - } - } - -+<<<<<<< .our - before(done => { -+======= -+ before((done) => { -+>>>>>>> .their - mock.on('MethodCalled', onMethodCalled(done)) - // lazy load Notification after we listen to MethodCalled mock signal - Notification = require('electron').remote.Notification -@@ -98,6 +121,7 @@ - n.show() - }) - -+<<<<<<< .our - it(`should call ${serviceName} to show notifications`, async () => { - const calls = await getCalls() - expect(calls).to.be.an('array').of.lengthOf.at.least(1) -@@ -108,6 +132,16 @@ - - let args = unmarshalDBusNotifyArgs(lastCall[2]) - expect(args).to.deep.equal({ -+======= -+ it('should call ' + serviceName + ' to show notifications', async () => { -+ const calls = await getCalls() -+ assert(calls.length >= 1) -+ let lastCall = calls[calls.length - 1] -+ let methodName = lastCall[1] -+ assert.equal(methodName, 'Notify') -+ let args = unmarshalDBusNotifyArgs(lastCall[2]) -+ assert.deepEqual(args, { -+>>>>>>> .their - app_name: appName, - replaces_id: 0, - app_icon: '', -changed in both - base 100644 122170292838e951ade4989669c87a7531e89ba7 spec/api-web-contents-spec.js - our 100644 be02cb3f84001a541d64b11fe6eda50fc32e8afd spec/api-web-contents-spec.js - their 100644 cbb45f5d84f1b11c8c27c56515d5daffa23d0c04 spec/api-web-contents-spec.js -@@ -122,6 +122,7 @@ - }) - }) - -+<<<<<<< .our - // Disabled because flaky. See #13969 - xdescribe('isCurrentlyAudible() API', () => { - it('returns whether audio is playing', async () => { -@@ -138,6 +139,8 @@ - }) - }) - -+======= -+>>>>>>> .their - describe('getWebPreferences() API', () => { - it('should not crash when called for devTools webContents', (done) => { - w.webContents.openDevTools() -@@ -730,6 +733,7 @@ - }) - }) - -+<<<<<<< .our - describe('referrer', () => { - it('propagates referrer information to new target=_blank windows', (done) => { - const server = http.createServer((req, res) => { -@@ -776,6 +780,8 @@ - }) - }) - -+======= -+>>>>>>> .their - describe('webframe messages in sandboxed contents', () => { - it('responds to executeJavaScript', (done) => { - w.destroy() -changed in both - base 100644 f87554f32e267b46fe3501405617a289b6cccedb spec/asar-spec.js - our 100644 489f68c96d41e80c308560a98486a07756a03be7 spec/asar-spec.js - their 100644 a82e73071e13d2289087d346a00ef62eacd71f6e spec/asar-spec.js -@@ -900,6 +900,18 @@ - }) - }) - -+ describe('util.promisify', function () { -+ it('can promisify all fs functions', function () { -+ const originalFs = require('original-fs') -+ -+ for (const key in originalFs) { -+ if (originalFs[key][util.promisify.custom] && !fs[key][util.promisify.custom]) { -+ assert(false, `fs.${key}[util.promisify.custom] missing`) -+ } -+ } -+ }) -+ }) -+ - describe('process.noAsar', function () { - var errorName = process.platform === 'win32' ? 'ENOENT' : 'ENOTDIR' - -changed in both - base 100644 2d388ca3b5744ea69d96ef71da6ade70e3dd001b spec/chromium-spec.js - our 100644 d90269769d269e4054d25cba4b6c4ac8a1929aa6 spec/chromium-spec.js - their 100644 25bef2e689e5ecbcd1485a042e84691db9400659 spec/chromium-spec.js -@@ -319,8 +319,12 @@ - b = window.open(windowUrl, '', 'nodeIntegration=no,show=no') - }) - -+<<<<<<< .our - // TODO(codebytere): re-enable this test - xit('disables node integration when it is disabled on the parent window for chrome devtools URLs', (done) => { -+======= -+ it('disables node integration when it is disabled on the parent window for chrome devtools URLs', (done) => { -+>>>>>>> .their - let b - app.once('web-contents-created', (event, contents) => { - contents.once('did-finish-load', () => { -changed in both - base 100644 07176e0097efa17e8f8aea5bb059a2739b8c3336 spec/fixtures/api/singleton/main.js - our 100644 3202a7a180d6d48c70706d5ef244652872b24bbc spec/fixtures/api/singleton/main.js - their 100644 cbf3da1117d91eb8df1b1e6363737a210b7eae78 spec/fixtures/api/singleton/main.js -@@ -3,8 +3,11 @@ - app.once('ready', () => { - console.log('started') // ping parent - }) -+<<<<<<< .our - - const gotTheLock = app.requestSingleInstanceLock() -+======= -+>>>>>>> .their - - app.on('second-instance', () => { - setImmediate(() => app.exit(0)) -changed in both - base 100644 cfe840ca0a44c5766509b2865034d98e375da1a1 spec/modules-spec.js - our 100644 b996b8f4839bff2160bffb69e55263b16a4178d7 spec/modules-spec.js - their 100644 28f2602acff67b2da9accd0574d64d386e0795a7 spec/modules-spec.js -changed in both - base 100644 e2d7d001eb49a9b01edcf9590ccdcb7ac8cc669c spec/node-spec.js - our 100644 9bb03494a56ffacec075c40bebde39a3b57ac734 spec/node-spec.js - their 100644 2c849bc3a442f8d1f800efce17cde212fc676531 spec/node-spec.js -changed in both - base 100644 feac23db7e06d3e49f8d5be7e9b3f08a204f262f spec/security-warnings-spec.js - our 100644 6315a9420e01b5db19596f0dd5731d47ce02acf6 spec/security-warnings-spec.js - their 100644 85fd0973b60cd6e27becbeef75415560b4061d24 spec/security-warnings-spec.js -@@ -142,7 +142,11 @@ - } - }) - w.webContents.once('console-message', (e, level, message) => { -+<<<<<<< .our - assert(message.includes('enableBlinkFeatures'), message) -+======= -+ assert(message.includes('blinkFeatures'), message) -+>>>>>>> .their - done() - }) - -changed in both - base 100644 ca5cc28d4f9f860947454dfc964208dd13ba1434 spec/static/index.html - our 100644 fc1e153c0af2908cf7ee4c3ea4f05522de04f0f8 spec/static/index.html - their 100644 e9d779f061cd5bdf00667d0b7942c6c30de81092 spec/static/index.html -@@ -51,7 +51,11 @@ - if (!process.env.MOCHA_REPORTER) { - mocha.ui('bdd').reporter(isCi ? 'tap' : 'html') - } -- mocha.timeout(isCi ? 30000 : 10000) -+ if (process.env.MOCHA_TIMEOUT && process.env.MOCHA_TIMEOUT > 0) { -+ mocha.timeout(process.env.MOCHA_TIMEOUT) -+ } else { -+ mocha.timeout(isCi ? 30000 : 10000) -+ } - - const query = Mocha.utils.parseQuery(window.location.search || '') - if (query.grep) mocha.grep(query.grep) -changed in both - base 100644 7050f3a7e43070e9c1ae924d1cd314ad8214e2d3 spec/static/main.js - our 100644 5659c44c8de4456a25e0026e29199b827c89cb08 spec/static/main.js - their 100644 6dc8a4550ebab1e0c5b562ab776d9f1a2a2d13d7 spec/static/main.js -changed in both - base 100644 73df333dd2b24e1b32931498ebe41557c3d24d0e spec/webview-spec.js - our 100644 db75a4e3754e24a5e6740be61be4f4098c58006e spec/webview-spec.js - their 100644 dfb3965a5a56a99a8299eb2ae9016822421245a4 spec/webview-spec.js -@@ -696,6 +696,7 @@ - xdescribe('setDevToolsWebContents() API', () => { - it('sets webContents of webview as devtools', async () => { - const webview2 = new WebView() -+<<<<<<< .our - loadWebView(webview2) - - // Setup an event handler for further usage. -@@ -720,6 +721,24 @@ - document.body.removeChild(webview2) - - expect(name).to.be.equal('InspectorFrontendHostImpl') -+======= -+ document.body.appendChild(webview2) -+ webview2.addEventListener('dom-ready', () => { -+ const devtools = webview2.getWebContents() -+ assert.ok(devtools.getURL().startsWith('chrome-devtools://devtools')) -+ devtools.executeJavaScript('InspectorFrontendHost.constructor.name', (name) => { -+ assert.ok(name, 'InspectorFrontendHostImpl') -+ document.body.removeChild(webview2) -+ done() -+ }) -+ }) -+ webview.addEventListener('dom-ready', () => { -+ webview.getWebContents().setDevToolsWebContents(webview2.getWebContents()) -+ webview.getWebContents().openDevTools() -+ }) -+ webview.src = 'about:blank' -+ document.body.appendChild(webview) -+>>>>>>> .their - }) - }) - -@@ -1182,6 +1201,7 @@ - - describe('will-attach-webview event', () => { - it('does not emit when src is not changed', (done) => { -+<<<<<<< .our - loadWebView(webview) - setTimeout(() => { - const expectedErrorMessage = -@@ -1189,6 +1209,21 @@ - 'The WebView must be attached to the DOM ' + - 'and the dom-ready event emitted before this method can be called.' - expect(() => { webview.stop() }).to.throw(expectedErrorMessage) -+======= -+ document.body.appendChild(webview) -+ setTimeout(() => { -+ assert.throws(() => { -+ webview.stop() -+ }, 'Cannot call stop because the webContents is unavailable. The WebView must be attached to the DOM and the dom-ready event emitted before this method can be called.') -+ done() -+ }) -+ }) -+ -+ it('supports changing the web preferences', (done) => { -+ ipcRenderer.send('disable-node-on-next-will-attach-webview') -+ webview.addEventListener('console-message', (event) => { -+ assert.equal(event.message, 'undefined undefined undefined undefined') -+>>>>>>> .their - done() - }) - }) -@@ -1251,9 +1286,260 @@ - - w.loadURL(`file://${fixtures}/pages/webview-devtools.html`) - -+<<<<<<< .our - const [, {runtimeId, tabId}] = await emittedOnce(ipcMain, 'answer') - expect(runtimeId).to.equal('foo') - expect(tabId).to.be.not.equal(w.webContents.id) -+======= -+ ipcMain.once('answer', (event, message) => { -+ assert.equal(message.runtimeId, 'foo') -+ assert.notEqual(message.tabId, w.webContents.id) -+ done() -+ }) -+ }) -+ -+ describe('guestinstance attribute', () => { -+ it('before loading there is no attribute', () => { -+ document.body.appendChild(webview) -+ assert(!webview.hasAttribute('guestinstance')) -+ }) -+ -+ it('loading a page sets the guest view', (done) => { -+ const loadListener = () => { -+ webview.removeEventListener('did-finish-load', loadListener, false) -+ const instance = webview.getAttribute('guestinstance') -+ assert.equal(instance, parseInt(instance)) -+ -+ const guest = getGuestWebContents(parseInt(instance)) -+ assert.equal(guest, webview.getWebContents()) -+ done() -+ } -+ webview.addEventListener('did-finish-load', loadListener, false) -+ webview.src = `file://${fixtures}/api/blank.html` -+ document.body.appendChild(webview) -+ }) -+ -+ it('deleting the attribute destroys the webview', (done) => { -+ const loadListener = () => { -+ webview.removeEventListener('did-finish-load', loadListener, false) -+ const destroyListener = () => { -+ webview.removeEventListener('destroyed', destroyListener, false) -+ assert.equal(getGuestWebContents(instance), null) -+ done() -+ } -+ webview.addEventListener('destroyed', destroyListener, false) -+ -+ const instance = parseInt(webview.getAttribute('guestinstance')) -+ webview.removeAttribute('guestinstance') -+ } -+ webview.addEventListener('did-finish-load', loadListener, false) -+ webview.src = `file://${fixtures}/api/blank.html` -+ document.body.appendChild(webview) -+ }) -+ -+ it('setting the attribute on a new webview moves the contents', (done) => { -+ const loadListener = () => { -+ webview.removeEventListener('did-finish-load', loadListener, false) -+ const webContents = webview.getWebContents() -+ const instance = webview.getAttribute('guestinstance') -+ -+ const destroyListener = () => { -+ webview.removeEventListener('destroyed', destroyListener, false) -+ assert.equal(webContents, webview2.getWebContents()) -+ // Make sure that events are hooked up to the right webview now -+ webview2.addEventListener('console-message', (e) => { -+ assert.equal(e.message, 'a') -+ document.body.removeChild(webview2) -+ done() -+ }) -+ -+ webview2.src = `file://${fixtures}/pages/a.html` -+ } -+ webview.addEventListener('destroyed', destroyListener, false) -+ -+ const webview2 = new WebView() -+ webview2.setAttribute('guestinstance', instance) -+ document.body.appendChild(webview2) -+ } -+ webview.addEventListener('did-finish-load', loadListener, false) -+ webview.src = `file://${fixtures}/api/blank.html` -+ document.body.appendChild(webview) -+ }) -+ -+ it('setting the attribute to an invalid guestinstance does nothing', (done) => { -+ const loadListener = () => { -+ webview.removeEventListener('did-finish-load', loadListener, false) -+ webview.setAttribute('guestinstance', 55) -+ -+ // Make sure that events are still hooked up to the webview -+ webview.addEventListener('console-message', (e) => { -+ assert.equal(e.message, 'a') -+ done() -+ }) -+ webview.src = `file://${fixtures}/pages/a.html` -+ } -+ webview.addEventListener('did-finish-load', loadListener, false) -+ -+ webview.src = `file://${fixtures}/api/blank.html` -+ document.body.appendChild(webview) -+ }) -+ -+ it('setting the attribute on an existing webview moves the contents', (done) => { -+ const load1Listener = () => { -+ webview.removeEventListener('did-finish-load', load1Listener, false) -+ const webContents = webview.getWebContents() -+ const instance = webview.getAttribute('guestinstance') -+ let destroyedInstance -+ -+ const destroyListener = () => { -+ webview.removeEventListener('destroyed', destroyListener, false) -+ assert.equal(webContents, webview2.getWebContents()) -+ assert.equal(null, getGuestWebContents(parseInt(destroyedInstance))) -+ -+ // Make sure that events are hooked up to the right webview now -+ webview2.addEventListener('console-message', (e) => { -+ assert.equal(e.message, 'a') -+ document.body.removeChild(webview2) -+ done() -+ }) -+ -+ webview2.src = 'file://' + fixtures + '/pages/a.html' -+ } -+ webview.addEventListener('destroyed', destroyListener, false) -+ -+ const webview2 = new WebView() -+ const load2Listener = () => { -+ webview2.removeEventListener('did-finish-load', load2Listener, false) -+ destroyedInstance = webview2.getAttribute('guestinstance') -+ assert.notEqual(instance, destroyedInstance) -+ -+ webview2.setAttribute('guestinstance', instance) -+ } -+ webview2.addEventListener('did-finish-load', load2Listener, false) -+ webview2.src = 'file://' + fixtures + '/api/blank.html' -+ document.body.appendChild(webview2) -+ } -+ webview.addEventListener('did-finish-load', load1Listener, false) -+ webview.src = 'file://' + fixtures + '/api/blank.html' -+ document.body.appendChild(webview) -+ }) -+ -+ it('moving a guest back to its original webview should work', (done) => { -+ const loadListener = () => { -+ webview.removeEventListener('did-finish-load', loadListener, false) -+ const webContents = webview.getWebContents() -+ const instance = webview.getAttribute('guestinstance') -+ -+ const destroy1Listener = () => { -+ webview.removeEventListener('destroyed', destroy1Listener, false) -+ assert.equal(webContents, webview2.getWebContents()) -+ assert.notStrictEqual(webContents, webview.getWebContents()) -+ -+ const destroy2Listener = () => { -+ webview2.removeEventListener('destroyed', destroy2Listener, false) -+ assert.equal(webContents, webview.getWebContents()) -+ assert.notStrictEqual(webContents, webview2.getWebContents()) -+ -+ // Make sure that events are hooked up to the right webview now -+ webview.addEventListener('console-message', (e) => { -+ assert.equal(e.message, 'a') -+ document.body.removeChild(webview2) -+ done() -+ }) -+ -+ webview.src = `file://${fixtures}/pages/a.html` -+ } -+ webview2.addEventListener('destroyed', destroy2Listener, false) -+ webview.setAttribute('guestinstance', instance) -+ } -+ webview.addEventListener('destroyed', destroy1Listener, false) -+ -+ const webview2 = new WebView() -+ webview2.setAttribute('guestinstance', instance) -+ document.body.appendChild(webview2) -+ } -+ webview.addEventListener('did-finish-load', loadListener, false) -+ webview.src = `file://${fixtures}/api/blank.html` -+ document.body.appendChild(webview) -+ }) -+ -+ it('setting the attribute on a webview in a different window moves the contents', (done) => { -+ const loadListener = () => { -+ webview.removeEventListener('did-finish-load', loadListener, false) -+ const instance = webview.getAttribute('guestinstance') -+ -+ w = new BrowserWindow({ show: false }) -+ w.webContents.once('did-finish-load', () => { -+ ipcMain.once('pong', () => { -+ assert(!webview.hasAttribute('guestinstance')) -+ done() -+ }) -+ -+ w.webContents.send('guestinstance', instance) -+ }) -+ w.loadURL(`file://${fixtures}/pages/webview-move-to-window.html`) -+ } -+ webview.addEventListener('did-finish-load', loadListener, false) -+ webview.src = `file://${fixtures}/api/blank.html` -+ document.body.appendChild(webview) -+ }) -+ -+ it('does not delete the guestinstance attribute when moving the webview to another parent node', (done) => { -+ webview.addEventListener('dom-ready', function domReadyListener () { -+ webview.addEventListener('did-attach', () => { -+ assert(webview.guestinstance != null) -+ assert(webview.getWebContents() != null) -+ done() -+ }) -+ -+ document.body.replaceChild(webview, div) -+ }) -+ webview.src = `file://${fixtures}/pages/a.html` -+ -+ const div = document.createElement('div') -+ div.appendChild(webview) -+ document.body.appendChild(div) -+ }) -+ -+ it('does not destroy the webContents when hiding/showing the webview (regression)', (done) => { -+ webview.addEventListener('dom-ready', function domReadyListener () { -+ const instance = webview.getAttribute('guestinstance') -+ assert(instance != null) -+ -+ // Wait for event directly since attach happens asynchronously over IPC -+ ipcMain.once('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', () => { -+ assert(webview.getWebContents() != null) -+ assert.equal(instance, webview.getAttribute('guestinstance')) -+ done() -+ }) -+ -+ webview.style.display = 'none' -+ webview.offsetHeight // eslint-disable-line -+ webview.style.display = 'block' -+ }) -+ webview.src = `file://${fixtures}/pages/a.html` -+ document.body.appendChild(webview) -+ }) -+ -+ it('does not reload the webContents when hiding/showing the webview (regression)', (done) => { -+ webview.addEventListener('dom-ready', function domReadyListener () { -+ webview.addEventListener('did-start-loading', () => { -+ done(new Error('webview started loading unexpectedly')) -+ }) -+ -+ // Wait for event directly since attach happens asynchronously over IPC -+ webview.addEventListener('did-attach', () => { -+ done() -+ }) -+ -+ webview.style.display = 'none' -+ webview.offsetHeight // eslint-disable-line -+ webview.style.display = 'block' -+ }) -+ webview.src = `file://${fixtures}/pages/a.html` -+ document.body.appendChild(webview) -+ }) -+>>>>>>> .their - }) - - describe('DOM events', () => { -changed in both - base 100644 6580f18a1ad9e53ab3f2ae88cb7ea023bcf9579c toolchain.gypi - our 100644 697add78e42191741cee1b015cdcf4f801c570e7 toolchain.gypi - their 100644 8ed945a57c8875bae06cef74dc5d44afcc586d1d toolchain.gypi -changed in both - base 160000 db1b314c019f6acbd4d1be273b63521cc6051d3c vendor/libchromiumcontent - our 160000 c85470a1c379b1c4bedb372c146521bc4be9b75d vendor/libchromiumcontent - their 160000 657a0c84482e296e2a4df63b49e4638faa8fee72 vendor/libchromiumcontent -removed in local - base 160000 99d9e262eb36cb9dc8e83f61e026d2a7ad1e96ab vendor/native_mate - their 160000 6a3d238b7e1e3742f2bb495336a84021d927a24f vendor/native_mate -changed in both - base 160000 bf06b641574a6e2a8357ca4b44defac4a83f1dda vendor/node - our 160000 ece0a06ac8147efb5b5af431c21f312f1884616e vendor/node - their 160000 f2bcc6b58293287e2a6e592bd296aa55bb37b801 vendor/node -added in both - our 100644 84bd69c2b2868ac23bc30061aa208ad38fbb9506 vsts.yml - their 100644 aaee2e6522650cd470f09e43b74b4d0a126c2128 vsts.yml -@@ -59,7 +59,11 @@ - - bash: | - echo 'Verifying ffmpeg on build' - if [ "$ELECTRON_RELEASE" == "1" ]; then -+<<<<<<< .our - script/verify-ffmpeg.py -c R -+======= -+ script/verify-ffmpeg.py -R -+>>>>>>> .their - else - script/verify-ffmpeg.py - fi -@@ -69,6 +73,7 @@ - - task: PublishTestResults@2 - displayName: Publish Test Results - inputs: -+<<<<<<< .our - testResultsFiles: '**/test-*.xml' - condition: and(always(), eq(variables['MOCHA_FILE'], 'test-results.xml')) - -@@ -93,5 +98,18 @@ - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/out' - ArtifactName: out -+======= -+ testResultsFiles: 'test-results.xml' -+ searchFolder: junit -+ condition: and(always(), ne(variables['ELECTRON_RELEASE'], '1')) -+ -+- task: kasunkodagoda.slack-notification.slack-notification-task.SlackNotification@3 -+ displayName: Post Slack Notification -+ inputs: -+ SlackApiToken: '$(slack_token)' -+ Channel: '#bot-nightly-releases' -+ Message: '$(Build.DefinitionName)-$(Build.BuildNumber) finished with a $(Agent.JobStatus) status.' -+ condition: and(always(), eq(variables['Build.Reason'], 'Schedule')) -+>>>>>>> .their - - - task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3 diff --git a/app/test/fixtures/merge-parser/electron/merge-2-1-x-into-master.txt b/app/test/fixtures/merge-parser/electron/merge-2-1-x-into-master.txt deleted file mode 100644 index 6209c33677c..00000000000 --- a/app/test/fixtures/merge-parser/electron/merge-2-1-x-into-master.txt +++ /dev/null @@ -1,7326 +0,0 @@ -changed in both - base 100644 d4f98eab95b73b59018f170b09b9132d4d03477b .circleci/config.yml - our 100644 6d44d618aabcce04c60344f2274dec5b0c2a1f68 .circleci/config.yml - their 100644 8d065e3f257178d4706dcbd1340326be42b2e2e2 .circleci/config.yml -@@ -19,6 +19,7 @@ - fi - when: on_success - -+<<<<<<< .our - build-steps: &build-steps - steps: - - checkout -@@ -92,6 +93,13 @@ - fi - - run: - name: Test -+======= -+version: 2 -+jobs: -+ electron-linux-arm: -+ docker: -+ - image: electronbuilds/electron:0.0.7 -+>>>>>>> .their - environment: - MOCHA_FILE: junit/test-results.xml - MOCHA_REPORTER: mocha-junit-reporter -@@ -110,6 +118,7 @@ - echo 'Skipping tests on GitHub release' - fi - fi -+<<<<<<< .our - else - echo 'Skipping tests due to configuration' - fi -@@ -117,6 +126,76 @@ - name: Verify FFmpeg - command: | - if [ "$RUN_TESTS" == "true" ]; then -+======= -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Optionally finish release -+ shell: /bin/sh -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then -+ echo 'Trying to finish release' -+ node script/release.js --validateRelease --automaticRelease -+ releaseExitCode=$? -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release is ready to go; releasing' -+ node script/release.js--automaticRelease -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release successful, now publishing to npm' -+ echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc -+ npm run publish-to-npm -+ echo 'Release has been published to npm' -+ fi -+ else -+ echo 'Release is not complete, skipping publish for now' -+ fi -+ else -+ echo 'Skipping finishing release because build is not for release' -+ fi -+ - run: -+ name: Zip out directory -+ command: | -+>>>>>>> .their - if [ "$ELECTRON_RELEASE" != "1" ]; then - echo 'Verifying ffmpeg on debug build' - script/verify-ffmpeg.py -@@ -391,11 +470,105 @@ - resource_class: 2xlarge - - electron-linux-arm64: -+<<<<<<< .our - environment: - TARGET_ARCH: arm64 - <<: *build-defaults - resource_class: 2xlarge - -+======= -+ docker: -+ - image: electronbuilds/electron:0.0.7 -+ environment: -+ TARGET_ARCH: arm64 -+ resource_class: 2xlarge -+ steps: -+ - checkout -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Optionally finish release -+ shell: /bin/sh -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then -+ echo 'Trying to finish release' -+ node script/release.js --validateRelease --automaticRelease -+ releaseExitCode=$? -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release is ready to go; releasing' -+ node script/release.js--automaticRelease -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release successful, now publishing to npm' -+ echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc -+ npm run publish-to-npm -+ echo 'Release has been published to npm' -+ fi -+ else -+ echo 'Release is not complete, skipping publish for now' -+ fi -+ else -+ echo 'Skipping finishing release because build is not for release' -+ fi -+ - run: -+ name: Zip out directory -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ zip -r electron.zip out/D -+ fi -+ - persist_to_workspace: -+ root: /home/builduser -+ paths: -+ - project/out -+ - store_artifacts: -+ path: electron.zip -+>>>>>>> .their - electron-linux-arm64-test: - machine: true - steps: -@@ -430,6 +603,7 @@ - resource_class: 2xlarge - - electron-linux-ia32: -+<<<<<<< .our - environment: - TARGET_ARCH: ia32 - DISPLAY: ':99.0' -@@ -469,10 +643,317 @@ - NIGHTLY_BUILD: true - <<: *build-defaults - resource_class: xlarge -+======= -+ docker: -+ - image: electronbuilds/electron:0.0.7 -+ environment: -+ TARGET_ARCH: ia32 -+ DISPLAY: ':99.0' -+ resource_class: xlarge -+ steps: -+ - checkout -+ - run: -+ name: Setup for headless testing -+ command: sh -e /etc/init.d/xvfb start -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Optionally finish release -+ shell: /bin/sh -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then -+ echo 'Trying to finish release' -+ node script/release.js --validateRelease --automaticRelease -+ releaseExitCode=$? -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release is ready to go; releasing' -+ node script/release.js--automaticRelease -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release successful, now publishing to npm' -+ echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc -+ npm run publish-to-npm -+ echo 'Release has been published to npm' -+ fi -+ else -+ echo 'Release is not complete, skipping publish for now' -+ fi -+ else -+ echo 'Skipping finishing release because build is not for release' -+ fi -+ - run: -+ name: Test -+ environment: -+ MOCHA_FILE: junit/test-results.xml -+ MOCHA_REPORTER: mocha-junit-reporter -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Testing Electron debug build' -+ out/D/electron --version -+ mkdir junit -+ script/test.py --ci --rebuild_native_modules -+ else -+ echo 'Skipping testing on release build' -+ fi -+ - run: -+ name: Verify FFmpeg -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Verifying ffmpeg on debug build' -+ script/verify-ffmpeg.py -+ else -+ echo 'Skipping verify ffmpeg on release build' -+ fi -+ electron-linux-mips64el: -+ docker: -+ - image: electronbuilds/electron:0.0.7 -+ environment: -+ TARGET_ARCH: mips64el -+ resource_class: xlarge -+ steps: -+ - checkout -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Optionally finish release -+ shell: /bin/sh -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then -+ echo 'Trying to finish release' -+ node script/release.js --validateRelease --automaticRelease -+ releaseExitCode=$? -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release is ready to go; releasing' -+ node script/release.js--automaticRelease -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release successful, now publishing to npm' -+ echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc -+ npm run publish-to-npm -+ echo 'Release has been published to npm' -+ fi -+ else -+ echo 'Release is not complete, skipping publish for now' -+ fi -+ else -+ echo 'Skipping finishing release because build is not for release' -+ fi -+ -+ electron-linux-x64: -+ docker: -+ - image: electronbuilds/electron:0.0.7 -+ environment: -+ TARGET_ARCH: x64 -+ DISPLAY: ':99.0' -+ resource_class: xlarge -+ steps: -+ - checkout -+ - run: -+ name: Setup for headless testing -+ command: sh -e /etc/init.d/xvfb start -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Optionally finish release -+ shell: /bin/sh -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then -+ echo 'Trying to finish release' -+ node script/release.js --validateRelease --automaticRelease -+ releaseExitCode=$? -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release is ready to go; releasing' -+ node script/release.js--automaticRelease -+ if [ $releaseExitCode -eq 0 ]; then -+ echo 'Release successful, now publishing to npm' -+ echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc -+ npm run publish-to-npm -+ echo 'Release has been published to npm' -+ fi -+ else -+ echo 'Release is not complete, skipping publish for now' -+ fi -+ else -+ echo 'Skipping finishing release because build is not for release' -+ fi -+ - run: -+ name: Test -+ environment: -+ MOCHA_FILE: junit/test-results.xml -+ MOCHA_REPORTER: mocha-junit-reporter -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Testing Electron debug build' -+ mkdir junit -+ script/test.py --ci --rebuild_native_modules -+ else -+ echo 'Skipping testing on release build' -+ fi -+ - run: -+ name: Verify FFmpeg -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Verifying ffmpeg on debug build' -+ script/verify-ffmpeg.py -+ else -+ echo 'Skipping verify ffmpeg on release build' -+ fi -+ - run: -+ name: Generate Typescript Definitions -+ command: npm run create-typescript-definitions -+ - store_test_results: -+ path: junit -+ - store_artifacts: -+ path: junit -+ - store_artifacts: -+ path: out/electron.d.ts -+ - store_artifacts: -+ path: out/electron-api.json -+>>>>>>> .their - - electron-osx-x64: - environment: - TARGET_ARCH: x64 -+<<<<<<< .our - RUN_TESTS: true - INSTALL_MACOS_NODE: true - macos: -@@ -488,11 +969,107 @@ - macos: - xcode: "8.3.3" - <<: *build-steps -+======= -+ macos: -+ xcode: "9.0" -+ steps: -+ - checkout -+ - run: -+ name: Reclaim disk space -+ command: | -+ df -h -+ sudo rm -rf /Library/Developer/CoreSimulator -+ df -h -+ sysctl -n hw.ncpu -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Test -+ environment: -+ MOCHA_FILE: junit/test-results.xml -+ MOCHA_REPORTER: mocha-junit-reporter -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Testing Electron debug build' -+ mkdir junit -+ script/test.py --ci --rebuild_native_modules -+ else -+ echo 'Skipping testing on release build' -+ fi -+ - run: -+ name: Verify FFmpeg -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Verifying ffmpeg on debug build' -+ script/verify-ffmpeg.py -+ else -+ echo 'Skipping verify ffmpeg on release build' -+ fi -+ - run: -+ name: Generate Typescript Definitions -+ command: npm run create-typescript-definitions -+ - store_test_results: -+ path: junit -+ - store_artifacts: -+ path: junit -+ - store_artifacts: -+ path: out/electron.d.ts -+ - store_artifacts: -+ path: out/electron-api.json -+>>>>>>> .their - - electron-mas-x64: - environment: - TARGET_ARCH: x64 - MAS_BUILD: 1 -+<<<<<<< .our - RUN_TESTS: true - INSTALL_MACOS_NODE: true - macos: -@@ -668,6 +1245,101 @@ - GN_EXTRA_ARGS: 'is_mas_build = true' - <<: *gn-mac-build-machine - <<: *gn-mac-build-steps -+======= -+ macos: -+ xcode: "9.0" -+ steps: -+ - checkout -+ - run: -+ name: Reclaim disk space -+ command: | -+ df -h -+ sudo rm -rf /Library/Developer/CoreSimulator -+ df -h -+ sysctl -n hw.ncpu -+ - run: -+ name: Check for release -+ command: | -+ if [ -n "${RUN_RELEASE_BUILD}" ]; then -+ echo 'release build triggered from api' -+ echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV -+ fi -+ - run: -+ name: Bootstrap -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Bootstrapping Electron for release build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH -+ else -+ echo 'Bootstrapping Electron for debug build' -+ script/bootstrap.py --target_arch=$TARGET_ARCH --dev -+ fi -+ - run: npm run lint -+ - run: -+ name: Build -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Building Electron for release' -+ script/build.py -c R -+ else -+ echo 'Building Electron for debug' -+ script/build.py -c D -+ fi -+ - run: -+ name: Create distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ]; then -+ echo 'Creating Electron release distribution' -+ script/create-dist.py -+ else -+ echo 'Skipping create distribution because build is not for release' -+ fi -+ - run: -+ name: Upload distribution -+ command: | -+ if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then -+ echo 'Uploading Electron release distribution to github releases' -+ script/upload.py -+ elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then -+ echo 'Uploading Electron release distribution to s3' -+ script/upload.py --upload_to_s3 -+ else -+ echo 'Skipping upload distribution because build is not for release' -+ fi -+ - run: -+ name: Test -+ environment: -+ MOCHA_FILE: junit/test-results.xml -+ MOCHA_REPORTER: mocha-junit-reporter -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Testing Electron debug build' -+ mkdir junit -+ script/test.py --ci --rebuild_native_modules -+ else -+ echo 'Skipping testing on release build' -+ fi -+ - run: -+ name: Verify FFmpeg -+ command: | -+ if [ "$ELECTRON_RELEASE" != "1" ]; then -+ echo 'Verifying ffmpeg on debug build' -+ script/verify-ffmpeg.py -+ else -+ echo 'Skipping verify ffmpeg on release build' -+ fi -+ - run: -+ name: Generate Typescript Definitions -+ command: npm run create-typescript-definitions -+ - store_test_results: -+ path: junit -+ - store_artifacts: -+ path: junit -+ - store_artifacts: -+ path: out/electron.d.ts -+ - store_artifacts: -+ path: out/electron-api.json -+>>>>>>> .their - - workflows: - version: 2 -@@ -695,6 +1367,7 @@ - build-mas-x64: - jobs: - - electron-mas-x64 -+<<<<<<< .our - build-gn-linux: - jobs: - - electron-gn-linux-x64-debug-fyi -@@ -745,3 +1418,5 @@ - - electron-gn-linux-arm64-release-fyi - - electron-gn-mas-release-fyi - - electron-gn-osx-release-fyi -+======= -+>>>>>>> .their -changed in both - base 100644 8632e8e30869d32176552cd218560f5016a24300 .gitignore - our 100644 f393b1cdcef87b41bb3ed47ebae59757fed3a780 .gitignore - their 100644 f82d92052e4f7ac936637ac2c163633e02588f12 .gitignore -changed in both - base 100644 5d04da05397c4c74ce00d6d6c8969ce370adb32d CONTRIBUTING.md - our 100644 414f83db905db904728facf3b40e70e7b7973193 CONTRIBUTING.md - their 100644 0955f68c4f2b1097e770398cf51d3af811f53050 CONTRIBUTING.md -changed in both - base 100644 4cfea0e70f9af56ba746347b4cae410970f3d900 Dockerfile - our 100644 74e5eeedea9bea87cd7a98ac2cb63f4376275a2a Dockerfile - their 100644 2d74e16915d2e89e1e1e7f3ffd259cc448e1b864 Dockerfile -@@ -7,8 +7,13 @@ - RUN chmod a+rwx /home - - # Install node.js -+<<<<<<< .our - RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - - RUN apt-get install -y nodejs -+======= -+RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - -+RUN apt-get update && apt-get install -y nodejs -+>>>>>>> .their - - # Install wget used by crash reporter - RUN apt-get install -y wget -changed in both - base 100644 271947c56e39b91fc23bf10579f61cab50b0f4dc Dockerfile.circleci - our 100644 d369c8c640161fc3ba65935297aec7dd27eb1e9f Dockerfile.circleci - their 100644 0cdb1e88c24f01a5acdfd8ef348126819f593454 Dockerfile.circleci -@@ -3,8 +3,13 @@ - USER root - - # Install node.js -+<<<<<<< .our - RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - - RUN apt-get install -y nodejs -+======= -+RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - -+RUN apt-get update && apt-get install -y nodejs -+>>>>>>> .their - - # Install wget used by crash reporter - RUN apt-get install -y wget -added in remote - their 100644 c6d558f7f3518ea2924fa9075ed38ab48d70d204 Jenkinsfile.arm64 -@@ -0,0 +1,36 @@ -+pipeline { -+ agent { -+ docker { -+ image 'electronbuilds/arm64v8:0.0.2' -+ args '--privileged' -+ } -+ } -+ environment { -+ TARGET_ARCH='arm64' -+ DISPLAY=':99.0' -+ MOCHA_TIMEOUT='60000' -+ } -+ stages { -+ stage('Bootstrap') { -+ steps { -+ sh 'script/bootstrap.py -v --dev --target_arch=$TARGET_ARCH' -+ } -+ } -+ stage('Build') { -+ steps { -+ sh 'script/build.py -c D --ninja-path /usr/local/ninja/ninja' -+ } -+ } -+ stage('Test') { -+ steps { -+ sh '/etc/init.d/xvfb start' -+ sh 'script/test.py --ci' -+ } -+ } -+ } -+ post { -+ always { -+ cleanWs() -+ } -+ } -+} -changed in both - base 100644 160dae7908236105f8534f9448f4111da1bcb014 README.md - our 100644 ec09364417b767ac59b2d970fee5e2ab2db2173b README.md - their 100644 a7b4fa6ed40a6449245cfdbdace8bb38945284d2 README.md -added in both - our 100644 67a2b2124619d866f67d849f57f3548ba28be26a appveyor.yml - their 100644 2ed4ebcf4b90c2c28d9fd36af13198be5a08e5ad appveyor.yml -@@ -1,3 +1,4 @@ -+<<<<<<< .our - version: 1.0.{build} - branches: - except: -@@ -71,3 +72,63 @@ - & python script\upload.py - } - } -+======= -+build_cloud: electron-16 -+image: electron-16-vs2015 -+build_script: -+- ps: >- -+ if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) { -+ Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild -+ } else { -+ Add-Path "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64" -+ $env:path = "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64;$env:path" -+ if($env:APPVEYOR_SCHEDULED_BUILD -eq 'True') { -+ $env:RUN_RELEASE_BUILD = "1" -+ } -+ $Message = (git log --format=%B -n 1 HEAD) | Out-String -+ if ((Test-Path Env:\RUN_RELEASE_BUILD)) { -+ $env:ELECTRON_RELEASE = '1' -+ Write-Output "release build triggered from api" -+ } -+ if ((Test-Path Env:\ELECTRON_RELEASE)) { -+ Write-Output "Running release build" -+ python script\bootstrap.py --target_arch=$env:TARGET_ARCH -+ python script\build.py -c R -+ python script\create-dist.py -+ } else { -+ Write-Output "Running debug build" -+ python script\bootstrap.py --target_arch=$env:TARGET_ARCH --dev -+ python script\build.py -c D -+ } -+ if ($? -ne 'True') { -+ throw "Build failed with exit code $?" -+ } else { -+ "Build succeeded." -+ } -+ Push-AppveyorArtifact out -+ } -+test_script: -+- ps: >- -+ if (Test-Path Env:\ELECTRON_RELEASE) { -+ Write-Output "Skipping tests for release build" -+ } else { -+ Write-Output "Running tests for debug build" -+ python script\test.py --ci --rebuild_native_modules -+ if ($LASTEXITCODE -ne '0') { -+ throw "Tests failed with exit code $LASTEXITCODE" -+ } else { -+ Write-Output "Tests succeeded." -+ } -+ python script\verify-ffmpeg.py -+ if ($LASTEXITCODE -ne '0') { -+ throw "Verify ffmpeg failed with exit code $LASTEXITCODE" -+ } else { -+ "Verify ffmpeg succeeded." -+ } -+ } -+artifacts: -+- path: test-results.xml -+ name: test-results.xml -+deploy_script: -+- ps: "if (Test-Path Env:\\ELECTRON_RELEASE) {\n if (Test-Path Env:\\RUN_RELEASE_BUILD) {\n Write-Output \"Uploading Electron release distribution to s3\"\n & python script\\upload.py --upload_to_s3\n } else {\n Write-Output \"Uploading Electron release distribution to github releases\"\n & python script\\upload.py\n if (Test-Path Env:\\AUTO_RELEASE) {\n node script\\release.js --validateRelease --automaticRelease\n if ($? -eq 'True') {\n echo 'Release is ready to go; now running release'\n node script\\release.js --automaticRelease\n if ($? -eq 'True') { \n echo 'Release successful, now publishing to npm' \n $npmfile = \"$HOME\\.npmrc\"\n \"//registry.npmjs.org/:_authToken=$env:ELECTRON_NPM_TOKEN\" > $npmfile\n npm run publish-to-npm\n }\n } else {\n echo 'Release is not complete, skipping publish for now.'\n }\n }\n }\n} else {\n Write-Output \"Skipping upload distribution because build is not for release\"\n}" -+>>>>>>> .their -changed in both - base 100644 9472d1cb9fd76beca4047bb24db024b9c6378aae atom/app/command_line_args.cc - our 100644 23e870cf4a32aecfc246a81edad46971b4456a55 atom/app/command_line_args.cc - their 100644 be171457726a09cde9eb7a090ba1e2a67f4cb9cb atom/app/command_line_args.cc -@@ -31,6 +31,1376 @@ - return false; - } - -+<<<<<<< .our -+======= -+/* -+ * The blacklist of command line switches, must be sorted. -+ * Update the list by pasting the following command into bash -+ * in libchromiumcontent/src/: -+ -+ (find ./ \( -name "*switches.cc" -o -name "*switch_list.h" \) | \ -+ xargs grep -P --no-filename '"\S+"[);]$' | \ -+ perl -pe 's|^.*?"(\S+)"[);]$| "$1",|'; \ -+ echo ' "inspect",'; \ -+ echo ' "inspect-brk",') | \ -+ LANG="C" sort | \ -+ uniq > blacklist-switches.txt -+ -+ */ -+const char* kBlacklist[] = { -+ "/prefetch:1", -+ "/prefetch:2", -+ "/prefetch:3", -+ "/prefetch:4", -+ "/prefetch:5", -+ "/prefetch:6", -+ "/prefetch:8", -+ "0", -+ "?", -+ "BlacklistOnly", -+ "ChromeOSMemoryPressureHandling", -+ "Disabled", -+ "OnlineCheckOnly", -+ "SafeSites", -+ "accept-resource-provider", -+ "account-consistency", -+ "adaboost", -+ "aec-refined-adaptive-filter", -+ "agc-startup-min-volume", -+ "aggressive", -+ "aggressive-cache-discard", -+ "aggressive-tab-discard", -+ "all-toolchains", -+ "allarticles", -+ "allow-cross-origin-auth-prompt", -+ "allow-external-pages", -+ "allow-failed-policy-fetch-for-test", -+ "allow-file-access-from-files", -+ "allow-hidden-media-playback", -+ "allow-http-background-page", -+ "allow-http-screen-capture", -+ "allow-insecure-localhost", -+ "allow-legacy-extension-manifests", -+ "allow-loopback-in-peer-connection", -+ "allow-nacl-crxfs-api", -+ "allow-nacl-file-handle-api", -+ "allow-nacl-socket-api", -+ "allow-no-sandbox-job", -+ "allow-outdated-plugins", -+ "allow-ra-in-dev-mode", -+ "allow-running-insecure-content", -+ "allow-sandbox-debugging", -+ "allow-silent-push", -+ "alsa-check-close-timeout", -+ "alsa-enable-upsampling", -+ "alsa-fixed-output-sample-rate", -+ "alsa-input-device", -+ "alsa-mute-device-name", -+ "alsa-mute-element-name", -+ "alsa-output-avail-min", -+ "alsa-output-buffer-size", -+ "alsa-output-device", -+ "alsa-output-period-size", -+ "alsa-output-start-threshold", -+ "alsa-volume-device-name", -+ "alsa-volume-element-name", -+ "also-emit-success-logs", -+ "alternative", -+ "always-authorize-plugins", -+ "always-on", -+ "always-use-complex-text", -+ "alwaystrue", -+ "android-fonts-path", -+ "android-stderr-port", -+ "android-stdin-port", -+ "android-stdout-port", -+ "angle", -+ "app", -+ "app-auto-launched", -+ "app-id", -+ "app-mode-auth-code", -+ "app-mode-oauth-token", -+ "app-mode-oem-manifest", -+ "app-shell-allow-roaming", -+ "app-shell-host-window-size", -+ "app-shell-preferred-network", -+ "app-shell-refresh-token", -+ "app-shell-user", -+ "apple", -+ "apps-gallery-download-url", -+ "apps-gallery-update-url", -+ "apps-gallery-url", -+ "apps-keep-chrome-alive-in-tests", -+ "arc-availability", -+ "arc-available", -+ "arc-start-mode", -+ "arc-transition-migration-required", -+ "args", -+ "artifacts-dir", -+ "ash-animate-from-boot-splash-screen", -+ "ash-constrain-pointer-to-root", -+ "ash-copy-host-background-at-boot", -+ "ash-debug-shortcuts", -+ "ash-dev-shortcuts", -+ "ash-disable-smooth-screen-rotation", -+ "ash-disable-touch-exploration-mode", -+ "ash-enable-magnifier-key-scroller", -+ "ash-enable-mirrored-screen", -+ "ash-enable-night-light", -+ "ash-enable-palette-on-all-displays", -+ "ash-enable-scale-settings-tray", -+ "ash-enable-software-mirroring", -+ "ash-enable-unified-desktop", -+ "ash-estimated-presentation-delay", -+ "ash-hide-notifications-for-factory", -+ "ash-host-window-bounds", -+ "ash-shelf-color", -+ "ash-shelf-color-scheme", -+ "ash-touch-hud", -+ "ash-webui-init", -+ "attestation-server", -+ "audio-buffer-size", -+ "audio-output-channels", -+ "aura-legacy-power-button", -+ "auth-ext-path", -+ "auth-server-whitelist", -+ "auth-spnego-account-type", -+ "auto", -+ "auto-open-devtools-for-tabs", -+ "auto-select-desktop-capture-source", -+ "autoplay-policy", -+ "blink-settings", -+ "bootstrap", -+ "browser-subprocess-path", -+ "browser-test", -+ "bwsi", -+ "bypass-app-banner-engagement-checks", -+ "canvas-msaa-sample-count", -+ "cast-initial-screen-height", -+ "cast-initial-screen-width", -+ "cc-layer-tree-test-long-timeout", -+ "cc-layer-tree-test-no-timeout", -+ "cc-rebaseline-pixeltests", -+ "cellular-first", -+ "cellular-only", -+ "check-for-update-interval", -+ "check-layout-test-sys-deps", -+ "child-wallpaper-large", -+ "child-wallpaper-small", -+ "chrome-home-swipe-logic", -+ "cipher-suite-blacklist", -+ "clamshell", -+ "class", -+ "clear-token-service", -+ "cloud-print-file", -+ "cloud-print-file-type", -+ "cloud-print-job-title", -+ "cloud-print-print-ticket", -+ "cloud-print-setup-proxy", -+ "cloud-print-url", -+ "cloud-print-xmpp-endpoint", -+ "color", -+ "compensate-for-unstable-pinch-zoom", -+ "compile-shader-always-succeeds", -+ "component-updater", -+ "connectivity-check-url", -+ "conservative", -+ "content-image-texture-target", -+ "content-shell-host-window-size", -+ "controller", -+ "crash-dumps-dir", -+ "crash-on-failure", -+ "crash-on-hang-threads", -+ "crash-server-url", -+ "crash-test", -+ "crashpad-handler", -+ "create-browser-on-startup-for-tests", -+ "create-default-gl-context", -+ "cros-gaia-api-v1", -+ "cros-region", -+ "cros-regions-mode", -+ "crosh-command", -+ "cryptauth-http-host", -+ "custom-devtools-frontend", -+ "custom-launcher-page", -+ "custom_summary", -+ "d3d11", -+ "d3d9", -+ "daemon", -+ "dark_muted", -+ "dark_vibrant", -+ "data-path", -+ "data-reduction-proxy-config-url", -+ "data-reduction-proxy-experiment", -+ "data-reduction-proxy-http-proxies", -+ "data-reduction-proxy-lo-fi", -+ "data-reduction-proxy-pingback-url", -+ "data-reduction-proxy-secure-proxy-check-url", -+ "data-reduction-proxy-server-experiments-disabled", -+ "dbus-stub", -+ "debug-devtools", -+ "debug-enable-frame-toggle", -+ "debug-packed-apps", -+ "debug-print", -+ "default", -+ "default-background-color", -+ "default-tile-height", -+ "default-tile-width", -+ "default-wallpaper-is-oem", -+ "default-wallpaper-large", -+ "default-wallpaper-small", -+ "delay-reload-stop-button-change", -+ "demo", -+ "derelict-detection-timeout", -+ "derelict-idle-timeout", -+ "desktop", -+ "desktop-window-1080p", -+ "deterministic-fetch", -+ "device-management-url", -+ "device-scale-factor", -+ "devtools-flags", -+ "diagnostics", -+ "diagnostics-format", -+ "diagnostics-recovery", -+ "dice", -+ "disable", -+ "disable-2d-canvas-clip-aa", -+ "disable-2d-canvas-image-chromium", -+ "disable-3d-apis", -+ "disable-accelerated-2d-canvas", -+ "disable-accelerated-jpeg-decoding", -+ "disable-accelerated-mjpeg-decode", -+ "disable-accelerated-video-decode", -+ "disable-app-info-dialog-mac", -+ "disable-app-list-dismiss-on-blur", -+ "disable-app-window-cycling", -+ "disable-appcontainer", -+ "disable-arc-data-wipe", -+ "disable-arc-opt-in-verification", -+ "disable-audio-support-for-desktop-share", -+ "disable-avfoundation-overlays", -+ "disable-background-networking", -+ "disable-background-timer-throttling", -+ "disable-backgrounding-occluded-windows", -+ "disable-backing-store-limit", -+ "disable-blink-features", -+ "disable-bookmark-reordering", -+ "disable-boot-animation", -+ "disable-breakpad", -+ "disable-browser-task-scheduler", -+ "disable-bundled-ppapi-flash", -+ "disable-canvas-aa", -+ "disable-captive-portal-bypass-proxy", -+ "disable-cast-streaming-hw-encoding", -+ "disable-checker-imaging", -+ "disable-clear-browsing-data-counters", -+ "disable-client-side-phishing-detection", -+ "disable-cloud-import", -+ "disable-component-cloud-policy", -+ "disable-component-extensions-with-background-pages", -+ "disable-component-update", -+ "disable-composited-antialiasing", -+ "disable-contextual-search", -+ "disable-d3d11", -+ "disable-databases", -+ "disable-datasaver-prompt", -+ "disable-default-apps", -+ "disable-demo-mode", -+ "disable-device-disabling", -+ "disable-device-discovery-notifications", -+ "disable-dinosaur-easter-egg", -+ "disable-direct-composition", -+ "disable-direct-composition-layers", -+ "disable-directwrite-for-ui", -+ "disable-display-color-calibration", -+ "disable-display-list-2d-canvas", -+ "disable-distance-field-text", -+ "disable-domain-blocking-for-3d-apis", -+ "disable-domain-reliability", -+ "disable-drive-search-in-app-launcher", -+ "disable-dwm-composition", -+ "disable-encryption-migration", -+ "disable-eol-notification", -+ "disable-es3-apis", -+ "disable-es3-gl-context", -+ "disable-extensions", -+ "disable-extensions-except", -+ "disable-extensions-file-access-check", -+ "disable-extensions-http-throttling", -+ "disable-fast-web-scroll-view-insets", -+ "disable-features", -+ "disable-field-trial-config", -+ "disable-file-manager-touch-mode", -+ "disable-file-system", -+ "disable-flash-3d", -+ "disable-flash-stage3d", -+ "disable-fullscreen-low-power-mode", -+ "disable-fullscreen-tab-detaching", -+ "disable-gaia-services", -+ "disable-gesture-editing", -+ "disable-gesture-requirement-for-presentation", -+ "disable-gesture-typing", -+ "disable-gl-drawing-for-tests", -+ "disable-gl-error-limit", -+ "disable-gl-extensions", -+ "disable-glsl-translator", -+ "disable-gpu", -+ "disable-gpu-compositing", -+ "disable-gpu-driver-bug-workarounds", -+ "disable-gpu-early-init", -+ "disable-gpu-memory-buffer-compositor-resources", -+ "disable-gpu-memory-buffer-video-frames", -+ "disable-gpu-process-crash-limit", -+ "disable-gpu-program-cache", -+ "disable-gpu-rasterization", -+ "disable-gpu-sandbox", -+ "disable-gpu-shader-disk-cache", -+ "disable-gpu-vsync", -+ "disable-gpu-watchdog", -+ "disable-hang-monitor", -+ "disable-hid-detection-on-oobe", -+ "disable-histogram-customizer", -+ "disable-hosted-app-shim-creation", -+ "disable-hosted-apps-in-windows", -+ "disable-http2", -+ "disable-in-process-stack-traces", -+ "disable-infobars", -+ "disable-input-ime-api", -+ "disable-input-view", -+ "disable-ios-password-generation", -+ "disable-ios-password-suggestions", -+ "disable-ios-physical-web", -+ "disable-javascript-harmony-shipping", -+ "disable-kill-after-bad-ipc", -+ "disable-lcd-text", -+ "disable-legacy-window", -+ "disable-local-storage", -+ "disable-lock-screen-apps", -+ "disable-logging", -+ "disable-logging-redirect", -+ "disable-login-animations", -+ "disable-login-screen-apps", -+ "disable-low-end-device-mode", -+ "disable-low-latency-dxva", -+ "disable-low-res-tiling", -+ "disable-lru-snapshot-cache", -+ "disable-mac-overlays", -+ "disable-mac-views-native-app-windows", -+ "disable-machine-cert-request", -+ "disable-main-frame-before-activation", -+ "disable-md-error-screen", -+ "disable-md-oobe", -+ "disable-media-session-api", -+ "disable-media-suspend", -+ "disable-merge-key-char-events", -+ "disable-mojo-local-storage", -+ "disable-mojo-renderer", -+ "disable-mtp-write-support", -+ "disable-multi-display-layout", -+ "disable-namespace-sandbox", -+ "disable-native-gpu-memory-buffers", -+ "disable-network-portal-notification", -+ "disable-new-channel-switcher-ui", -+ "disable-new-korean-ime", -+ "disable-new-virtual-keyboard-behavior", -+ "disable-new-zip-unpacker", -+ "disable-notifications", -+ "disable-ntp-most-likely-favicons-from-server", -+ "disable-ntp-popular-sites", -+ "disable-nv12-dxgi-video", -+ "disable-offer-store-unmasked-wallet-cards", -+ "disable-offer-upload-credit-cards", -+ "disable-office-editing-component-extension", -+ "disable-offline-auto-reload", -+ "disable-offline-auto-reload-visible-only", -+ "disable-origin-trial-controlled-blink-features", -+ "disable-overscroll-edge-effect", -+ "disable-panel-fitting", -+ "disable-partial-raster", -+ "disable-password-generation", -+ "disable-pepper-3d", -+ "disable-pepper-3d-image-chromium", -+ "disable-permission-action-reporting", -+ "disable-permissions-api", -+ "disable-physical-keyboard-autocorrect", -+ "disable-pinch", -+ "disable-pnacl-crash-throttling", -+ "disable-popup-blocking", -+ "disable-prefer-compositing-to-lcd-text", -+ "disable-presentation-api", -+ "disable-print-preview", -+ "disable-prompt-on-repost", -+ "disable-proximity-auth-bluetooth-low-energy-discovery", -+ "disable-pull-to-refresh-effect", -+ "disable-push-api-background-mode", -+ "disable-quic", -+ "disable-reading-from-canvas", -+ "disable-remote-core-animation", -+ "disable-remote-fonts", -+ "disable-remote-playback-api", -+ "disable-renderer-accessibility", -+ "disable-renderer-backgrounding", -+ "disable-renderer-priority-management", -+ "disable-request-mobile-site", -+ "disable-resize-lock", -+ "disable-rgba-4444-textures", -+ "disable-rollback-option", -+ "disable-rtc-smoothness-algorithm", -+ "disable-screen-orientation-lock", -+ "disable-search-geolocation-disclosure", -+ "disable-seccomp-filter-sandbox", -+ "disable-settings-window", -+ "disable-setuid-sandbox", -+ "disable-shader-name-hashing", -+ "disable-shared-workers", -+ "disable-signin-promo", -+ "disable-signin-scoped-device-id", -+ "disable-single-click-autofill", -+ "disable-skia-runtime-opts", -+ "disable-slim-navigation-manager", -+ "disable-slimming-paint-invalidation", -+ "disable-smooth-scrolling", -+ "disable-software-rasterizer", -+ "disable-speech-api", -+ "disable-suggestions-ui", -+ "disable-sync", -+ "disable-sync-app-list", -+ "disable-sync-types", -+ "disable-system-timezone-automatic-detection", -+ "disable-tab-for-desktop-share", -+ "disable-tab-strip-autoscroll-new-tabs", -+ "disable-third-party-keyboard-workaround", -+ "disable-threaded-animation", -+ "disable-threaded-compositing", -+ "disable-threaded-scrolling", -+ "disable-touch-adjustment", -+ "disable-touch-drag-drop", -+ "disable-translate-new-ux", -+ "disable-usb-keyboard-detect", -+ "disable-v8-idle-tasks", -+ "disable-vaapi-accelerated-video-encode", -+ "disable-virtual-keyboard-overscroll", -+ "disable-voice-input", -+ "disable-volume-adjust-sound", -+ "disable-wake-on-wifi", -+ "disable-web-notification-custom-layouts", -+ "disable-web-security", -+ "disable-webgl", -+ "disable-webgl-image-chromium", -+ "disable-webrtc-encryption", -+ "disable-webrtc-hw-decoding", -+ "disable-webrtc-hw-encoding", -+ "disable-win32k-lockdown", -+ "disable-xss-auditor", -+ "disable-zero-browsers-open-for-tests", -+ "disable-zero-copy", -+ "disable-zero-copy-dxgi-video", -+ "disabled", -+ "disabled-new-style-notification", -+ "disallow-non-exact-resource-reuse", -+ "disk-cache-dir", -+ "disk-cache-size", -+ "display", -+ "dmg-device", -+ "dns-log-details", -+ "document-user-activation-required", -+ "dom-automation", -+ "dotfile", -+ "draft", -+ "draw-view-bounds-rects", -+ "duck-flash", -+ "dump-blink-runtime-call-stats", -+ "dump-browser-histograms", -+ "dump-dom", -+ "eafe-path", -+ "eafe-url", -+ "easy-unlock-app-path", -+ "edge-touch-filtering", -+ "egl", -+ "elevate", -+ "embedded-extension-options", -+ "emphasize-titles-in-omnibox-dropdown", -+ "emulate-shader-precision", -+ "enable-accelerated-2d-canvas", -+ "enable-accelerated-vpx-decode", -+ "enable-accessibility-tab-switcher", -+ "enable-adaptive-selection-handle-orientation", -+ "enable-aggressive-domstorage-flushing", -+ "enable-android-wallpapers-app", -+ "enable-app-info-dialog-mac", -+ "enable-app-list", -+ "enable-app-window-cycling", -+ "enable-appcontainer", -+ "enable-arc", -+ "enable-arc-oobe-optin", -+ "enable-audio-debug-recordings-from-extension", -+ "enable-audio-focus", -+ "enable-automation", -+ "enable-benchmarking", -+ "enable-ble-advertising-in-apps", -+ "enable-blink-features", -+ "enable-bookmark-reordering", -+ "enable-bookmark-undo", -+ "enable-browser-side-navigation", -+ "enable-browser-task-scheduler", -+ "enable-checker-imaging", -+ "enable-chromevox-arc-support", -+ "enable-clear-browsing-data-counters", -+ "enable-cloud-print-proxy", -+ "enable-cloud-print-xps", -+ "enable-consumer-kiosk", -+ "enable-contextual-search", -+ "enable-crash-reporter", -+ "enable-crash-reporter-for-testing", -+ "enable-crx-hash-check", -+ "enable-data-reduction-proxy-bypass-warning", -+ "enable-data-reduction-proxy-force-pingback", -+ "enable-data-reduction-proxy-lite-page", -+ "enable-data-reduction-proxy-savings-promo", -+ "enable-datasaver-prompt", -+ "enable-device-discovery-notifications", -+ "enable-devtools-experiments", -+ "enable-direct-composition-layers", -+ "enable-display-list-2d-canvas", -+ "enable-distance-field-text", -+ "enable-distillability-service", -+ "enable-dom-distiller", -+ "enable-domain-reliability", -+ "enable-drive-search-in-app-launcher", -+ "enable-drm-atomic", -+ "enable-embedded-extension-options", -+ "enable-encryption-migration", -+ "enable-encryption-selection", -+ "enable-es3-apis", -+ "enable-exclusive-audio", -+ "enable-experimental-accessibility-features", -+ "enable-experimental-canvas-features", -+ "enable-experimental-extension-apis", -+ "enable-experimental-fullscreen-exit-ui", -+ "enable-experimental-input-view-features", -+ "enable-experimental-web-platform-features", -+ "enable-extension-activity-log-testing", -+ "enable-extension-activity-logging", -+ "enable-extension-assets-sharing", -+ "enable-fast-unload", -+ "enable-fast-web-scroll-view-insets", -+ "enable-features", -+ "enable-file-manager-touch-mode", -+ "enable-first-run-ui-transitions", -+ "enable-floating-virtual-keyboard", -+ "enable-font-antialiasing", -+ "enable-fullscreen-tab-detaching", -+ "enable-fullscreen-toolbar-reveal", -+ "enable-google-branded-context-menu", -+ "enable-gpu-async-worker-context", -+ "enable-gpu-benchmarking", -+ "enable-gpu-client-logging", -+ "enable-gpu-client-tracing", -+ "enable-gpu-command-logging", -+ "enable-gpu-debugging", -+ "enable-gpu-driver-debug-logging", -+ "enable-gpu-memory-buffer-compositor-resources", -+ "enable-gpu-memory-buffer-video-frames", -+ "enable-gpu-rasterization", -+ "enable-gpu-service-logging", -+ "enable-gpu-service-tracing", -+ "enable-hardware-overlays", -+ "enable-harfbuzz-rendertext", -+ "enable-hdr", -+ "enable-heap-profiling", -+ "enable-hosted-app-quit-notification", -+ "enable-hosted-apps-in-windows", -+ "enable-hotword-hardware", -+ "enable-hung-renderer-infobar", -+ "enable-inband-text-tracks", -+ "enable-input-ime-api", -+ "enable-internal-media-session", -+ "enable-ios-handoff-to-other-devices", -+ "enable-ios-password-generation", -+ "enable-ios-physical-web", -+ "enable-layer-lists", -+ "enable-lcd-text", -+ "enable-leak-detection", -+ "enable-local-file-accesses", -+ "enable-local-sync-backend", -+ "enable-logging", -+ "enable-longpress-drag-selection", -+ "enable-low-end-device-mode", -+ "enable-low-res-tiling", -+ "enable-lru-snapshot-cache", -+ "enable-mac-views-native-app-windows", -+ "enable-main-frame-before-activation", -+ "enable-md-feedback", -+ "enable-md-policy-page", -+ "enable-media-suspend", -+ "enable-merge-key-char-events", -+ "enable-message-center-always-scroll-up-upon-notification-removal", -+ "enable-nacl", -+ "enable-nacl-debug", -+ "enable-nacl-nonsfi-mode", -+ "enable-native-gpu-memory-buffers", -+ "enable-natural-scroll-default", -+ "enable-navigation-tracing", -+ "enable-net-benchmarking", -+ "enable-network-information-downlink-max", -+ "enable-network-portal-notification", -+ "enable-new-app-menu-icon", -+ "enable-ntp-most-likely-favicons-from-server", -+ "enable-ntp-popular-sites", -+ "enable-ntp-search-engine-country-detection", -+ "enable-offer-store-unmasked-wallet-cards", -+ "enable-offer-upload-credit-cards", -+ "enable-offline-auto-reload", -+ "enable-offline-auto-reload-visible-only", -+ "enable-osk-overscroll", -+ "enable-override-bookmarks-ui", -+ "enable-partial-raster", -+ "enable-password-generation", -+ "enable-pepper-testing", -+ "enable-permission-action-reporting", -+ "enable-physical-keyboard-autocorrect", -+ "enable-picture-in-picture", -+ "enable-pinch", -+ "enable-pixel-output-in-tests", -+ "enable-plugin-placeholder-testing", -+ "enable-potentially-annoying-security-features", -+ "enable-power-overlay", -+ "enable-precise-memory-info", -+ "enable-prefer-compositing-to-lcd-text", -+ "enable-print-browser", -+ "enable-print-preview-register-promos", -+ "enable-profile-shortcut-manager", -+ "enable-profiling", -+ "enable-push-api-background-mode", -+ "enable-quic", -+ "enable-reader-mode-toolbar-icon", -+ "enable-refresh-token-annotation-request", -+ "enable-request-tablet-site", -+ "enable-rgba-4444-textures", -+ "enable-sandbox", -+ "enable-sandbox-logging", -+ "enable-screenshot-testing-with-mode", -+ "enable-scripts-require-action", -+ "enable-scroll-prediction", -+ "enable-service-manager-tracing", -+ "enable-settings-window", -+ "enable-sgi-video-sync", -+ "enable-signin-promo", -+ "enable-single-click-autofill", -+ "enable-site-settings", -+ "enable-skia-benchmarking", -+ "enable-slim-navigation-manager", -+ "enable-slimming-paint-invalidation", -+ "enable-slimming-paint-v2", -+ "enable-smooth-scrolling", -+ "enable-spatial-navigation", -+ "enable-spdy-proxy-auth", -+ "enable-speech-dispatcher", -+ "enable-spelling-feedback-field-trial", -+ "enable-spotlight-actions", -+ "enable-stats-collection-bindings", -+ "enable-stats-table", -+ "enable-strict-mixed-content-checking", -+ "enable-strict-powerful-feature-restrictions", -+ "enable-suggestions-ui", -+ "enable-suggestions-with-substring-match", -+ "enable-supervised-user-managed-bookmarks-folder", -+ "enable-surface-synchronization", -+ "enable-swap-buffers-with-bounds", -+ "enable-sync-app-list", -+ "enable-sync-articles", -+ "enable-tab-audio-muting", -+ "enable-tablet-splitview", -+ "enable-tcp-fastopen", -+ "enable-third-party-keyboard-workaround", -+ "enable-threaded-compositing", -+ "enable-threaded-texture-mailboxes", -+ "enable-tile-compression", -+ "enable-touch-calibration-setting", -+ "enable-touch-drag-drop", -+ "enable-touchpad-three-finger-click", -+ "enable-touchview", -+ "enable-trace-app-source", -+ "enable-tracing", -+ "enable-tracing-output", -+ "enable-translate-new-ux", -+ "enable-ui-devtools", -+ "enable-use-zoom-for-dsf", -+ "enable-user-controlled-alternate-protocol-ports", -+ "enable-user-metrics", -+ "enable-usermedia-screen-capturing", -+ "enable-video-player-chromecast-support", -+ "enable-viewport", -+ "enable-virtual-keyboard", -+ "enable-voice-interaction", -+ "enable-vtune-support", -+ "enable-vulkan", -+ "enable-wayland-server", -+ "enable-web-notification-custom-layouts", -+ "enable-webfonts-intervention-trigger", -+ "enable-webfonts-intervention-v2", -+ "enable-webgl-draft-extensions", -+ "enable-webgl-image-chromium", -+ "enable-webrtc-event-logging-from-extension", -+ "enable-webrtc-srtp-aes-gcm", -+ "enable-webrtc-stun-origin", -+ "enable-webview-finch", -+ "enable-webvr", -+ "enable-wifi-credential-sync", -+ "enable-win7-webrtc-hw-h264-decoding", -+ "enable-zero-copy", -+ "enable-zip-archiver-on-file-manager", -+ "enabled", -+ "enabled-2g", -+ "enabled-3g", -+ "enabled-new-style-notification", -+ "enabled-slow2g", -+ "encode-binary", -+ "enforce", -+ "enforce-gl-minimums", -+ "enforce-webrtc-ip-permission-check", -+ "enforce_strict", -+ "enterprise-disable-arc", -+ "enterprise-enable-forced-re-enrollment", -+ "enterprise-enable-license-type-selection", -+ "enterprise-enable-zero-touch-enrollment", -+ "enterprise-enrollment-initial-modulus", -+ "enterprise-enrollment-modulus-limit", -+ "error-console", -+ "experiment", -+ "explicitly-allowed-ports", -+ "expose-internals-for-testing", -+ "extension-content-verification", -+ "extension-process", -+ "extensions-install-verification", -+ "extensions-multi-account", -+ "extensions-not-webstore", -+ "extensions-on-chrome-urls", -+ "extensions-update-frequency", -+ "extra-search-query-params", -+ "fail-on-unused-args", -+ "fake-variations-channel", -+ "false", -+ "fast", -+ "fast-start", -+ "feedback-server", -+ "field-trial-handle", -+ "first-exec-after-boot", -+ "flag-switches-begin", -+ "flag-switches-end", -+ "font-cache-shared-handle", -+ "force-android-app-mode", -+ "force-app-mode", -+ "force-clamshell-power-button", -+ "force-color-profile", -+ "force-desktop-ios-promotion", -+ "force-dev-mode-highlighting", -+ "force-device-scale-factor", -+ "force-display-list-2d-canvas", -+ "force-effective-connection-type", -+ "force-enable-metrics-reporting", -+ "force-enable-stylus-tools", -+ "force-fieldtrial-params", -+ "force-fieldtrials", -+ "force-first-run", -+ "force-first-run-ui", -+ "force-gpu-mem-available-mb", -+ "force-gpu-rasterization", -+ "force-happiness-tracking-system", -+ "force-load-easy-unlock-app-in-tests", -+ "force-local-ntp", -+ "force-login-manager-in-tests", -+ "force-mediafoundation", -+ "force-overlay-fullscreen-video", -+ "force-password-reauth", -+ "force-pnacl-subzero", -+ "force-renderer-accessibility", -+ "force-show-update-menu-badge", -+ "force-show-update-menu-item", -+ "force-system-compositor-mode", -+ "force-tablet-mode", -+ "force-text-direction", -+ "force-ui-direction", -+ "force-variation-ids", -+ "force-video-overlays", -+ "force-wave-audio", -+ "force-webrtc-ip-handling-policy", -+ "full-memory-crash-report", -+ "gaia-url", -+ "gcm-checkin-url", -+ "gcm-mcs-endpoint", -+ "gcm-registration-url", -+ "generate-accessibility-test-expectations", -+ "gl", -+ "gl-composited-overlay-candidate-quad-border", -+ "gl-shader-interm-output", -+ "gles", -+ "golden-screenshots-dir", -+ "google-apis-url", -+ "google-base-url", -+ "google-doodle-url", -+ "google-url", -+ "gpu-active-device-id", -+ "gpu-active-vendor-id", -+ "gpu-device-id", -+ "gpu-driver-bug-workarounds", -+ "gpu-driver-date", -+ "gpu-driver-vendor", -+ "gpu-driver-version", -+ "gpu-launcher", -+ "gpu-no-complete-info-collection", -+ "gpu-no-context-lost", -+ "gpu-process", -+ "gpu-program-cache-size-kb", -+ "gpu-rasterization-msaa-sample-count", -+ "gpu-sandbox-allow-sysv-shm", -+ "gpu-sandbox-failures-fatal", -+ "gpu-sandbox-start-early", -+ "gpu-secondary-device-ids", -+ "gpu-secondary-vendor-ids", -+ "gpu-startup-dialog", -+ "gpu-testing-device-id", -+ "gpu-testing-driver-date", -+ "gpu-testing-gl-renderer", -+ "gpu-testing-gl-vendor", -+ "gpu-testing-gl-version", -+ "gpu-testing-os-version", -+ "gpu-testing-secondary-device-ids", -+ "gpu-testing-secondary-vendor-ids", -+ "gpu-testing-vendor-id", -+ "gpu-vendor-id", -+ "guest-wallpaper-large", -+ "guest-wallpaper-small", -+ "h", -+ "has-chromeos-diamond-key", -+ "has-chromeos-keyboard", -+ "has-internal-stylus", -+ "headless", -+ "help", -+ "hide", -+ "hide-icons", -+ "hide-scrollbars", -+ "history-entry-requires-user-gesture", -+ "homedir", -+ "homepage", -+ "host", -+ "host-pairing-oobe", -+ "host-resolver-rules", -+ "host-rules", -+ "icu-data-dir", -+ "ignore-autocomplete-off-autofill", -+ "ignore-autoplay-restrictions", -+ "ignore-certificate-errors", -+ "ignore-certificate-errors-spki-list", -+ "ignore-gpu-blacklist", -+ "ignore-urlfetcher-cert-requests", -+ "ignore-user-profile-mapping-for-tests", -+ "in-process-gpu", -+ "incognito", -+ "input", -+ "inspect", -+ "inspect-brk", -+ "install-chrome-app", -+ "install-supervised-user-whitelists", -+ "instant-process", -+ "invalidation-use-gcm-channel", -+ "ipc-connection-timeout", -+ "ipc-dump-directory", -+ "ipc-fuzzer-testcase", -+ "is-running-in-mash", -+ "isolate-origins", -+ "isolate-sites-for-testing", -+ "javascript-harmony", -+ "js-flags", -+ "keep-alive-for-test", -+ "kiosk", -+ "kiosk-printing", -+ "lang", -+ "last-launched-app", -+ "layer", -+ "light_muted", -+ "light_vibrant", -+ "limit-fps", -+ "load-and-launch-app", -+ "load-apps", -+ "load-extension", -+ "load-media-router-component-extension", -+ "local-heuristics-only-for-password-generation", -+ "local-ntp-reload", -+ "local-sync-backend-dir", -+ "log-gpu-control-list-decisions", -+ "log-level", -+ "log-net-log", -+ "login-manager", -+ "login-profile", -+ "login-user", -+ "lso-url", -+ "ltr", -+ "main-frame-resizes-are-orientation-changes", -+ "make-chrome-default", -+ "make-default-browser", -+ "managed-user-id", -+ "managed-user-sync-token", -+ "mark-non-secure-as", -+ "markdown", -+ "market-url-for-testing", -+ "mash", -+ "material", -+ "material-design-ink-drop-animation-speed", -+ "material-hybrid", -+ "max-gum-fps", -+ "max-output-volume-dba1m", -+ "max-untiled-layer-height", -+ "max-untiled-layer-width", -+ "media-cache-size", -+ "mem-pressure-system-reserved-kb", -+ "memlog", -+ "memlog-pipe", -+ "memory-pressure-off", -+ "memory-pressure-thresholds", -+ "memory-pressure-thresholds-mb", -+ "message-center-changes-while-open", -+ "metrics-client-id", -+ "metrics-recording-only", -+ "mhtml-generator-option", -+ "mirror", -+ "mock", -+ "mojo-local-storage", -+ "mojo-pipe-token", -+ "monitoring-destination-id", -+ "mse-audio-buffer-size-limit", -+ "mse-video-buffer-size-limit", -+ "mus", -+ "mus-config", -+ "mute-audio", -+ "nacl-broker", -+ "nacl-dangerous-no-sandbox-nonsfi", -+ "nacl-debug-mask", -+ "nacl-gdb", -+ "nacl-gdb-script", -+ "nacl-loader", -+ "nacl-loader-nonsfi", -+ "native", -+ "native-crx-bindings", -+ "need-arc-migration-policy-check", -+ "net-log-capture-mode", -+ "netifs-to-ignore", -+ "network-country-iso", -+ "network-settings-config", -+ "new-window", -+ "no-default-browser-check", -+ "no-experiments", -+ "no-first-run", -+ "no-managed-user-acknowledgment-check", -+ "no-network-profile-warning", -+ "no-pings", -+ "no-proxy-server", -+ "no-referrers", -+ "no-sandbox", -+ "no-service-autorun", -+ "no-session-id", -+ "no-startup-window", -+ "no-user-gesture-required", -+ "no-wifi", -+ "no-zygote", -+ "nocolor", -+ "noerrdialogs", -+ "non-material", -+ "non-secure", -+ "non-secure-after-editing", -+ "non-secure-while-incognito", -+ "non-secure-while-incognito-or-editing", -+ "none", -+ "normal_muted", -+ "normal_vibrant", -+ "note-taking-app-ids", -+ "ntp-snippets-add-incomplete", -+ "ntp-switch-to-existing-tab", -+ "null", -+ "num-raster-threads", -+ "oauth2-client-id", -+ "oauth2-client-secret", -+ "off", -+ "on", -+ "oobe-bootstrapping-master", -+ "oobe-force-show-screen", -+ "oobe-guest-session", -+ "oobe-skip-postlogin", -+ "oobe-timer-interval", -+ "open-ash", -+ "opengraph", -+ "origin-to-force-quic-on", -+ "origin-trial-disabled-features", -+ "origin-trial-disabled-tokens", -+ "origin-trial-public-key", -+ "original-process-start-time", -+ "osmesa", -+ "output", -+ "override", -+ "override-metrics-upload-url", -+ "override-plugin-power-saver-for-testing", -+ "override-use-software-gl-for-tests", -+ "overscroll-history-navigation", -+ "overscroll-start-threshold", -+ "ozone-dump-file", -+ "ozone-platform", -+ "pack-extension", -+ "pack-extension-key", -+ "parent-profile", -+ "parent-window", -+ "passive-listeners-default", -+ "password-store", -+ "permission-request-api-scope", -+ "permission-request-api-url", -+ "ppapi", -+ "ppapi-antialiased-text-enabled", -+ "ppapi-broker", -+ "ppapi-flash-args", -+ "ppapi-flash-path", -+ "ppapi-flash-version", -+ "ppapi-in-process", -+ "ppapi-plugin-launcher", -+ "ppapi-startup-dialog", -+ "ppapi-subpixel-rendering-setting", -+ "prerender-from-omnibox", -+ "previous-app", -+ "primary", -+ "print-to-pdf", -+ "privet-ipv6-only", -+ "process-per-site", -+ "process-per-tab", -+ "product-version", -+ "profile-directory", -+ "profiler-timing", -+ "profiling", -+ "profiling-at-start", -+ "profiling-file", -+ "profiling-flush", -+ "progress-bar-animation", -+ "progress-bar-completion", -+ "prompt-for-external-extensions", -+ "proxy-auto-detect", -+ "proxy-bypass-list", -+ "proxy-pac-url", -+ "proxy-server", -+ "q", -+ "quic-connection-options", -+ "quic-max-packet-length", -+ "quic-version", -+ "rdp_desktop_session", -+ "reader-mode-feedback", -+ "reader-mode-heuristics", -+ "rebaseline-pixel-tests", -+ "record-type", -+ "reduce-security-for-testing", -+ "reduced-referrer-granularity", -+ "register-font-files", -+ "register-pepper-plugins", -+ "relauncher", -+ "remote-debugging-address", -+ "remote-debugging-port", -+ "remote-debugging-socket-fd", -+ "remote-debugging-socket-name", -+ "remote-debugging-targets", -+ "renderer", -+ "renderer-client-id", -+ "renderer-cmd-prefix", -+ "renderer-process-limit", -+ "renderer-startup-dialog", -+ "renderer-wait-for-java-debugger", -+ "renderpass", -+ "repl", -+ "report-vp9-as-an-unsupported-mime-type", -+ "require-audio-hardware-for-testing", -+ "reset-app-list-install-state", -+ "reset-variation-state", -+ "restore-last-session", -+ "root", -+ "root-layer-scrolls", -+ "rtl", -+ "run-layout-test", -+ "runtime-deps-list-file", -+ "safebrowsing-disable-auto-update", -+ "safebrowsing-disable-download-protection", -+ "safebrowsing-disable-extension-blacklist", -+ "safebrowsing-manual-download-blacklist", -+ "sandbox-ipc", -+ "save-page-as-mhtml", -+ "screen-config", -+ "screenshot", -+ "script-executable", -+ "scripts-require-action", -+ "scroll-end-effect", -+ "search-provider-logo-url", -+ "secondary", -+ "secondary-display-layout", -+ "secondary-ui-md", -+ "service", -+ "service-manager", -+ "service-name", -+ "service-pipe-token", -+ "service-request-channel-token", -+ "service-runner", -+ "shared-files", -+ "shill-stub", -+ "show-app-list", -+ "show-autofill-signatures", -+ "show-autofill-type-predictions", -+ "show-cert-link", -+ "show-component-extension-options", -+ "show-composited-layer-borders", -+ "show-fps-counter", -+ "show-icons", -+ "show-layer-animation-bounds", -+ "show-login-dev-overlay", -+ "show-mac-overlay-borders", -+ "show-md-login", -+ "show-non-md-login", -+ "show-overdraw-feedback", -+ "show-paint-rects", -+ "show-property-changed-rects", -+ "show-saved-copy", -+ "show-screenspace-rects", -+ "show-surface-damage-rects", -+ "silent-debugger-extension-api", -+ "silent-launch", -+ "simulate-critical-update", -+ "simulate-elevated-recovery", -+ "simulate-outdated", -+ "simulate-outdated-no-au", -+ "simulate-upgrade", -+ "single-process", -+ "site-per-process", -+ "skip-gpu-data-loading", -+ "skip-nostore-all", -+ "skip-nostore-main", -+ "skip-reencoding-on-skp-capture", -+ "slow", -+ "slow-connections-only", -+ "slow-down-raster-scale-factor", -+ "sms-test-messages", -+ "spdy-proxy-auth-fallback", -+ "spdy-proxy-auth-origin", -+ "spdy-proxy-auth-value", -+ "spelling-service-feedback-interval-seconds", -+ "spelling-service-feedback-url", -+ "spurious-power-button-accel-count", -+ "spurious-power-button-keyboard-accel", -+ "spurious-power-button-lid-angle-change", -+ "spurious-power-button-screen-accel", -+ "spurious-power-button-window", -+ "ssl-key-log-file", -+ "ssl-version-max", -+ "ssl-version-min", -+ "stable-release-mode", -+ "start-fullscreen", -+ "start-maximized", -+ "start-stack-profiler", -+ "started", -+ "stub", -+ "stub-cros-settings", -+ "supports-dual-gpus", -+ "surface", -+ "swiftshader", -+ "swiftshader-webgl", -+ "sync-allow-insecure-xmpp-connection", -+ "sync-deferred-startup-timeout-seconds", -+ "sync-disable-deferred-startup", -+ "sync-enable-get-update-avoidance", -+ "sync-notification-host-port", -+ "sync-on-draw-hardware", -+ "sync-short-initial-retry-override", -+ "sync-short-nudge-delay-for-test", -+ "sync-url", -+ "system-developer-mode", -+ "system-log-upload-frequency", -+ "tab-management-experiment-type-disabled", -+ "tab-management-experiment-type-elderberry", -+ "task-profiler", -+ "team-drives", -+ "test-auto-update-ui", -+ "test-child-process", -+ "test-cros-gaia-id-migration", -+ "test-do-not-initialize-icu", -+ "test-encryption-migration-ui", -+ "test-gl-lib", -+ "test-launcher-batch-limit", -+ "test-launcher-bot-mode", -+ "test-launcher-debug-launcher", -+ "test-launcher-filter-file", -+ "test-launcher-force-run-broken-tests", -+ "test-launcher-jobs", -+ "test-launcher-list-tests", -+ "test-launcher-output", -+ "test-launcher-print-test-stdio", -+ "test-launcher-print-writable-path", -+ "test-launcher-retry-limit", -+ "test-launcher-shard-index", -+ "test-launcher-summary-output", -+ "test-launcher-test-part-results-limit", -+ "test-launcher-timeout", -+ "test-launcher-total-shards", -+ "test-launcher-trace", -+ "test-name", -+ "test-tiny-timeout", -+ "test-type", -+ "testing-fixed-http-port", -+ "testing-fixed-https-port", -+ "tether-stub", -+ "threads", -+ "time", -+ "timeout", -+ "tls1", -+ "tls1.1", -+ "tls1.2", -+ "tls1.3", -+ "tls13-variant", -+ "top-chrome-md", -+ "top-controls-hide-threshold", -+ "top-controls-show-threshold", -+ "touch-calibration", -+ "touch-devices", -+ "touch-events", -+ "touch-noise-filtering", -+ "touch-selection-strategy", -+ "touch_view", -+ "trace-config-file", -+ "trace-export-events-to-etw", -+ "trace-shutdown", -+ "trace-shutdown-file", -+ "trace-startup", -+ "trace-startup-duration", -+ "trace-startup-file", -+ "trace-to-console", -+ "trace-to-file", -+ "trace-to-file-name", -+ "trace-upload-url", -+ "tracelog", -+ "translate-ranker-model-url", -+ "translate-script-url", -+ "translate-security-origin", -+ "true", -+ "trusted-download-sources", -+ "try-chrome-again", -+ "try-supported-channel-layouts", -+ "type", -+ "ui-disable-partial-swap", -+ "ui-enable-layer-lists", -+ "ui-enable-rgba-4444-textures", -+ "ui-enable-zero-copy", -+ "ui-prioritize-in-gpu-process", -+ "ui-show-composited-layer-borders", -+ "ui-show-fps-counter", -+ "ui-show-layer-animation-bounds", -+ "ui-show-paint-rects", -+ "ui-show-property-changed-rects", -+ "ui-show-screenspace-rects", -+ "ui-show-surface-damage-rects", -+ "ui-slow-animations", -+ "ui-test-action-max-timeout", -+ "ui-test-action-timeout", -+ "uninstall", -+ "unlimited-storage", -+ "unsafe-pac-url", -+ "unsafely-allow-protected-media-identifier-for-domain", -+ "unsafely-treat-insecure-origin-as-secure", -+ "use-angle", -+ "use-cras", -+ "use-double-buffering", -+ "use-fake-device-for-media-stream", -+ "use-fake-jpeg-decode-accelerator", -+ "use-fake-ui-for-media-stream", -+ "use-file-for-fake-audio-capture", -+ "use-file-for-fake-video-capture", -+ "use-first-display-as-internal", -+ "use-gl", -+ "use-gpu-in-tests", -+ "use-ime-service", -+ "use-mobile-user-agent", -+ "use-mock-keychain", -+ "use-passthrough-cmd-decoder", -+ "use-simple-cache-backend", -+ "use-system-default-printer", -+ "use-test-config", -+ "user-agent", -+ "user-always-affiliated", -+ "user-data-dir", -+ "user-gesture-required", -+ "user-gesture-required-for-cross-origin", -+ "utility", -+ "utility-allowed-dir", -+ "utility-cmd-prefix", -+ "utility-run-elevated", -+ "v", -+ "v2-sandbox", -+ "v2-sandbox-enabled", -+ "v8-cache-options", -+ "v8-cache-strategies-for-cache-storage", -+ "validate-crx", -+ "validate-input-event-stream", -+ "variations-override-country", -+ "variations-server-url", -+ "version", -+ "video-image-texture-target", -+ "video-threads", -+ "video-underflow-threshold-ms", -+ "virtual-time-budget", -+ "vmodule", -+ "voice-interaction-supported-locales", -+ "wait-for-debugger", -+ "wait-for-debugger-children", -+ "wake-on-wifi-packet", -+ "wallet-service-use-sandbox", -+ "watcher", -+ "waveout-buffers", -+ "webapk-server-url", -+ "webrtc-max-cpu-consumption-percentage", -+ "webrtc-stun-probe-trial", -+ "webview-enable-safebrowsing-support", -+ "webview-sandboxed-renderer", -+ "whitelisted-extension-id", -+ "win-jumplist-action", -+ "window-position", -+ "window-size", -+ "window-workspace", -+ "windows10-custom-titlebar", -+ "winhttp-proxy-resolver", -+ "wm-window-animations-disabled", -+ "yield-between-content-script-runs", -+ "zygote", -+ "zygote-cmd-prefix", -+}; -+ -+bool IsBlacklistedArg(const base::CommandLine::CharType* arg) { -+#if defined(OS_WIN) -+ const auto converted = base::WideToUTF8(arg); -+ const char* a = converted.c_str(); -+#else -+ const char* a = arg; -+#endif -+ -+ static const char* prefixes[] = {"--", "-", "/"}; -+ -+ int prefix_length = 0; -+ for (auto& prefix : prefixes) { -+ if (base::StartsWith(a, prefix, base::CompareCase::SENSITIVE)) { -+ prefix_length = strlen(prefix); -+ break; -+ } -+ } -+ -+ if (prefix_length > 0) { -+ a += prefix_length; -+ std::string switch_name = -+ base::ToLowerASCII(base::StringPiece(a, strcspn(a, "="))); -+ return std::binary_search(std::begin(kBlacklist), std::end(kBlacklist), -+ switch_name); -+ } -+ -+ return false; -+} -+ -+>>>>>>> .their - } // namespace - - namespace atom { -changed in both - base 100644 4bd88a5a43c03ceba308ec06fdf0cbadeddcaae3 atom/browser/api/atom_api_browser_view.cc - our 100644 bd83208694c61c4d7c43ce4be26939c2682b2a13 atom/browser/api/atom_api_browser_view.cc - their 100644 41f0e99cdd79bf1ad2c4c8c0db5aaa97ac5e1297 atom/browser/api/atom_api_browser_view.cc -changed in both - base 100644 b5daaaee05f9b5041ff0eebc65048c2c7b72b6f4 atom/browser/api/atom_api_desktop_capturer.cc - our 100644 135b4edd11048a4635f9017f569f4b4ae644a09c atom/browser/api/atom_api_desktop_capturer.cc - their 100644 3aa2227cfcf110d7b9cf7be6393d61e5e98fc907 atom/browser/api/atom_api_desktop_capturer.cc -@@ -57,6 +57,7 @@ - cap->Emit("finished", sources); - } - -+<<<<<<< .our - void StartHandlingTask(bool capture_window, - bool capture_screen, - const gfx::Size& thumbnail_size, -@@ -71,6 +72,23 @@ - webrtc::ScreenCapturerWinDirectx::IsSupported(); - } - #endif // defined(OS_WIN) -+======= -+void DesktopCapturer::StartHandling(bool capture_window, -+ bool capture_screen, -+ const gfx::Size& thumbnail_size) { -+ webrtc::DesktopCaptureOptions options = -+ content::CreateDesktopCaptureOptions(); -+#if defined(OS_WIN) -+ if (options.allow_directx_capturer()) { -+ // DxgiDuplicatorController should be alive in this scope according to -+ // screen_capturer_win.cc. -+ auto duplicator = webrtc::DxgiDuplicatorController::Instance(); -+ using_directx_capturer_ = -+ webrtc::ScreenCapturerWinDirectx::IsSupported(); -+ } -+#endif // defined(OS_WIN) -+ -+>>>>>>> .their - std::unique_ptr<webrtc::DesktopCapturer> screen_capturer( - capture_screen ? content::desktop_capture::CreateScreenCapturer() - : nullptr); -@@ -168,8 +186,58 @@ - void DesktopCapturer::OnSourceThumbnailChanged(int index) {} - - bool DesktopCapturer::OnRefreshFinished() { -+<<<<<<< .our - capture_thread_->PostTask(FROM_HERE, - base::BindOnce(OnRefreshFinishedTask, this)); -+======= -+ const auto media_list_sources = media_list_->GetSources(); -+ std::vector<DesktopCapturer::Source> sources; -+ for (const auto& media_list_source : media_list_sources) { -+ sources.emplace_back( -+ DesktopCapturer::Source{media_list_source, std::string()}); -+ } -+ -+#if defined(OS_WIN) -+ // Gather the same unique screen IDs used by the electron.screen API in order -+ // to provide an association between it and desktopCapturer/getUserMedia. -+ // This is only required when using the DirectX capturer, otherwise the IDs -+ // across the APIs already match. -+ if (using_directx_capturer_) { -+ std::vector<std::string> device_names; -+ // Crucially, this list of device names will be in the same order as -+ // |media_list_sources|. -+ webrtc::DxgiDuplicatorController::Instance()->GetDeviceNames(&device_names); -+ int device_name_index = 0; -+ for (auto& source : sources) { -+ if (source.media_list_source.id.type == -+ content::DesktopMediaID::TYPE_SCREEN) { -+ const auto& device_name = device_names[device_name_index++]; -+ std::wstring wide_device_name; -+ base::UTF8ToWide(device_name.c_str(), device_name.size(), -+ &wide_device_name); -+ const int64_t device_id = -+ display::win::DisplayInfo::DeviceIdFromDeviceName( -+ wide_device_name.c_str()); -+ source.display_id = base::Int64ToString(device_id); -+ } -+ } -+ } -+#elif defined(OS_MACOSX) -+ // On Mac, the IDs across the APIs match. -+ for (auto& source : sources) { -+ if (source.media_list_source.id.type == -+ content::DesktopMediaID::TYPE_SCREEN) { -+ source.display_id = -+ base::Int64ToString(source.media_list_source.id.id); -+ } -+ } -+#endif // defined(OS_WIN) -+// TODO(ajmacd): Add Linux support. The IDs across APIs differ but Chrome only -+// supports capturing the entire desktop on Linux. Revisit this if individual -+// screen support is added. -+ -+ Emit("finished", sources); -+>>>>>>> .their - return false; - } - -changed in both - base 100644 571f08bcfc63c3da3e9c6d24617ead4526da8819 atom/browser/api/atom_api_desktop_capturer.h - our 100644 88960e46d49dd0b68c51647be18066a2d097ce79 atom/browser/api/atom_api_desktop_capturer.h - their 100644 fdc35b6b1fd7348da01307f1ddfd4823d7b00f69 atom/browser/api/atom_api_desktop_capturer.h -@@ -52,7 +52,14 @@ - bool OnRefreshFinished() override; - - private: -+<<<<<<< .our - scoped_refptr<base::SequencedTaskRunner> capture_thread_; -+======= -+ std::unique_ptr<DesktopMediaList> media_list_; -+#if defined(OS_WIN) -+ bool using_directx_capturer_ = false; -+#endif // defined(OS_WIN) -+>>>>>>> .their - - DISALLOW_COPY_AND_ASSIGN(DesktopCapturer); - }; -changed in both - base 100644 cb5b9af26d8f21040a45ad7d1f0c4a23e7c8c445 atom/browser/api/atom_api_menu_mac.mm - our 100644 2b63b8a6cefe6265d96399dc6b70ab3ffdc352c3 atom/browser/api/atom_api_menu_mac.mm - their 100644 a2919e65d1b4ded98cb50884ead6763ed288e7c7 atom/browser/api/atom_api_menu_mac.mm -@@ -135,9 +135,15 @@ - // static - void Menu::SetApplicationMenu(Menu* base_menu) { - MenuMac* menu = static_cast<MenuMac*>(base_menu); -+<<<<<<< .our - base::scoped_nsobject<AtomMenuController> menu_controller([ - [AtomMenuController alloc] initWithModel:menu->model_.get() - useDefaultAccelerator:YES]); -+======= -+ base::scoped_nsobject<AtomMenuController> menu_controller( -+ [[AtomMenuController alloc] initWithModel:menu->model_.get() -+ useDefaultAccelerator:YES]); -+>>>>>>> .their - - NSRunLoop* currentRunLoop = [NSRunLoop currentRunLoop]; - [currentRunLoop cancelPerformSelector:@selector(setMainMenu:) -changed in both - base 100644 ced1cb31d8df7689f7652111720ba20fb029b1fe atom/browser/api/atom_api_menu_views.cc - our 100644 3da7dc2842fa4561e037aa67f290d0cc6ca71014 atom/browser/api/atom_api_menu_views.cc - their 100644 fa178e57d82413544b92172ae0ed4401ea5f178b atom/browser/api/atom_api_menu_views.cc -@@ -49,8 +49,16 @@ - menu_runners_[window_id] = - std::make_unique<MenuRunner>(model(), flags, close_callback); - menu_runners_[window_id]->RunMenuAt( -+<<<<<<< .our - native_window->widget(), NULL, gfx::Rect(location, gfx::Size()), - views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE); -+======= -+ native_window->widget(), -+ NULL, -+ gfx::Rect(location, gfx::Size()), -+ views::MENU_ANCHOR_TOPLEFT, -+ ui::MENU_SOURCE_MOUSE); -+>>>>>>> .their - } - - void MenuViews::ClosePopupAt(int32_t window_id) { -removed in local - base 100644 0d22fad5b8b5e3ed7711d55aa763f930014a75d7 atom/browser/api/atom_api_screen_mac.mm - their 100644 056b775fdfc221cb0501ba5b7afd8de01f2d4d63 atom/browser/api/atom_api_screen_mac.mm -changed in both - base 100644 6e5c4b9cbe77c1a4004bbc2bf7b0f0089ffb9004 atom/browser/api/atom_api_session.cc - our 100644 658f913bb60b66ae1bf3aae97d7d9158e56f7ee0 atom/browser/api/atom_api_session.cc - their 100644 d36812daa35dc795b667c190952b980f25d9e618 atom/browser/api/atom_api_session.cc -@@ -29,7 +29,6 @@ - #include "base/guid.h" - #include "base/strings/string_number_conversions.h" - #include "base/strings/string_util.h" --#include "base/threading/thread_task_runner_handle.h" - #include "brightray/browser/media/media_device_id_salt.h" - #include "chrome/browser/browser_process.h" - #include "chrome/common/pref_names.h" -@@ -46,8 +45,12 @@ - #include "net/dns/host_cache.h" - #include "net/http/http_auth_handler_factory.h" - #include "net/http/http_auth_preferences.h" -+<<<<<<< .our - #include "net/proxy_resolution/proxy_config_service_fixed.h" - #include "net/proxy_resolution/proxy_service.h" -+======= -+#include "net/proxy/proxy_config_service_fixed.h" -+>>>>>>> .their - #include "net/url_request/static_http_user_agent_settings.h" - #include "net/url_request/url_request_context.h" - #include "net/url_request/url_request_context_getter.h" -@@ -236,6 +239,7 @@ - // Referenced session objects. - std::map<uint32_t, v8::Global<v8::Object>> g_sessions; - -+<<<<<<< .our - class ResolveProxyHelper { - public: - ResolveProxyHelper(AtomBrowserContext* browser_context, -@@ -286,6 +290,8 @@ - DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper); - }; - -+======= -+>>>>>>> .their - // Runs the callback in UI thread. - void RunCallbackInUI(const base::Callback<void()>& callback) { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); -@@ -451,6 +457,7 @@ - AtomNetworkDelegate* network_delegate = - static_cast<AtomNetworkDelegate*>(context->network_delegate()); - network_delegate->SetDevToolsNetworkEmulationClientId(client_id); -+<<<<<<< .our - } - - void DestroyGlobalHandle(v8::Isolate* isolate, -@@ -468,6 +475,8 @@ - object->SetAlignedPointerInInternalField(0, nullptr); - } - } -+======= -+>>>>>>> .their - } - - } // namespace -@@ -513,8 +522,10 @@ - } - } - --void Session::ResolveProxy(const GURL& url, ResolveProxyCallback callback) { -- new ResolveProxyHelper(browser_context(), url, callback); -+void Session::ResolveProxy( -+ const GURL& url, -+ const ResolveProxyHelper::ResolveProxyCallback& callback) { -+ browser_context_->GetResolveProxyHelper()->ResolveProxy(url, callback); - } - - template <Session::CacheAction action> -changed in both - base 100644 d56c2400d4df9d197a03335c4e2b7e735065f301 atom/browser/api/atom_api_session.h - our 100644 6c8247c5c4a90e643712dd47d000d37d181a147b atom/browser/api/atom_api_session.h - their 100644 547f0e627b0ecf23e808b85cbd5173892479673f atom/browser/api/atom_api_session.h -@@ -10,6 +10,7 @@ - - #include "atom/browser/api/trackable_object.h" - #include "atom/browser/atom_blob_reader.h" -+#include "atom/browser/net/resolve_proxy_helper.h" - #include "base/values.h" - #include "content/public/browser/download_manager.h" - #include "native_mate/handle.h" -@@ -39,8 +40,6 @@ - class Session : public mate::TrackableObject<Session>, - public content::DownloadManager::Observer { - public: -- using ResolveProxyCallback = base::Callback<void(std::string)>; -- - enum class CacheAction { - CLEAR, - STATS, -@@ -63,8 +62,14 @@ - v8::Local<v8::FunctionTemplate> prototype); - - // Methods. -+<<<<<<< .our - void ResolveProxy(const GURL& url, ResolveProxyCallback callback); - template <CacheAction action> -+======= -+ void ResolveProxy(const GURL& url, -+ const ResolveProxyHelper::ResolveProxyCallback& callback); -+ template<CacheAction action> -+>>>>>>> .their - void DoCacheAction(const net::CompletionCallback& callback); - void ClearStorageData(mate::Arguments* args); - void FlushStorageData(); -changed in both - base 100644 d3607e7283ccb8c5119c793bdda4c476baae1c7f atom/browser/api/atom_api_url_request.cc - our 100644 9f18d97d2656fbc5dc62b7bcea05a8acab63e847 atom/browser/api/atom_api_url_request.cc - their 100644 f4660abe1873766b9ba93f17f066c64a8f22b136 atom/browser/api/atom_api_url_request.cc -changed in both - base 100644 372ac98ac6578d7c757bcb47288a6a310cad3134 atom/browser/api/atom_api_url_request.h - our 100644 4a5a2b65160bf0590c9e890e52d0531b799b583a atom/browser/api/atom_api_url_request.h - their 100644 13d3e18811c566bbd3e8ff4d5bb7bc271bfab4a7 atom/browser/api/atom_api_url_request.h -changed in both - base 100644 83adf62eee8301c49799b5397f2dcf6bfdbbd295 atom/browser/api/atom_api_web_contents.cc - our 100644 20a1ac2e672f08ffea528b6e094ba530ff8083d1 atom/browser/api/atom_api_web_contents.cc - their 100644 9a19b727a82229565ec37e6a436bdbec4e670925 atom/browser/api/atom_api_web_contents.cc -@@ -124,6 +124,30 @@ - struct Converter<PrintSettings> { - static bool FromV8(v8::Isolate* isolate, - v8::Local<v8::Value> val, -+<<<<<<< .our -+======= -+ atom::SetSizeParams* out) { -+ mate::Dictionary params; -+ if (!ConvertFromV8(isolate, val, ¶ms)) -+ return false; -+ bool autosize; -+ if (params.Get("enableAutoSize", &autosize)) -+ out->enable_auto_size.reset(new bool(autosize)); -+ gfx::Size size; -+ if (params.Get("min", &size)) -+ out->min_size.reset(new gfx::Size(size)); -+ if (params.Get("max", &size)) -+ out->max_size.reset(new gfx::Size(size)); -+ if (params.Get("normal", &size)) -+ out->normal_size.reset(new gfx::Size(size)); -+ return true; -+ } -+}; -+ -+template<> -+struct Converter<PrintSettings> { -+ static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val, -+>>>>>>> .their - PrintSettings* out) { - mate::Dictionary dict; - if (!ConvertFromV8(isolate, val, &dict)) -@@ -280,7 +304,12 @@ - - // Called when CapturePage is done. - void OnCapturePageDone(const base::Callback<void(const gfx::Image&)>& callback, -+<<<<<<< .our - const SkBitmap& bitmap) { -+======= -+ const SkBitmap& bitmap, -+ content::ReadbackResponse response) { -+>>>>>>> .their - // Hack to enable transparency in captured image - // TODO(nitsakh) Remove hack once fixed in chromium - const_cast<SkBitmap&>(bitmap).setAlphaType(kPremul_SkAlphaType); -@@ -1015,6 +1044,18 @@ - content::RenderFrameHost* frame_host) { - bool handled = true; - FrameDispatchHelper helper = {this, frame_host}; -+<<<<<<< .our -+======= -+ auto relay = NativeWindowRelay::FromWebContents(web_contents()); -+ if (relay) { -+ IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(NativeWindow, message, frame_host) -+ IPC_MESSAGE_FORWARD(AtomAutofillFrameHostMsg_HidePopup, -+ relay->window.get(), NativeWindow::HideAutofillPopup) -+ IPC_MESSAGE_UNHANDLED(handled = false) -+ IPC_END_MESSAGE_MAP() -+ } -+ -+>>>>>>> .their - IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(WebContents, message, frame_host) - IPC_MESSAGE_HANDLER(AtomFrameHostMsg_Message, OnRendererMessage) - IPC_MESSAGE_FORWARD_DELAY_REPLY(AtomFrameHostMsg_Message_Sync, &helper, -@@ -1024,10 +1065,14 @@ - FrameDispatchHelper::OnSetTemporaryZoomLevel) - IPC_MESSAGE_FORWARD_DELAY_REPLY(AtomFrameHostMsg_GetZoomLevel, &helper, - FrameDispatchHelper::OnGetZoomLevel) -+<<<<<<< .our - #if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX) - IPC_MESSAGE_HANDLER(AtomAutofillFrameHostMsg_ShowPopup, ShowAutofillPopup) - IPC_MESSAGE_HANDLER(AtomAutofillFrameHostMsg_HidePopup, HideAutofillPopup) - #endif -+======= -+ IPC_MESSAGE_HANDLER(AtomAutofillFrameHostMsg_ShowPopup, ShowAutofillPopup) -+>>>>>>> .their - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - -@@ -1075,6 +1120,20 @@ - details.is_same_document, details.did_replace_entry); - } - -+<<<<<<< .our -+======= -+int64_t WebContents::GetIDForContents(content::WebContents* web_contents) { -+ int64_t process_id = web_contents->GetRenderProcessHost()->GetID(); -+ int64_t routing_id = web_contents->GetMainFrame()->GetRoutingID(); -+ int64_t rv = (process_id << 32) + routing_id; -+ return rv; -+} -+ -+int64_t WebContents::GetID() const { -+ return WebContents::GetIDForContents(web_contents()); -+} -+ -+>>>>>>> .their - int WebContents::GetProcessID() const { - return web_contents()->GetMainFrame()->GetProcess()->GetID(); - } -@@ -1552,7 +1611,11 @@ - bool WebContents::SendIPCMessage(bool all_frames, - const base::string16& channel, - const base::ListValue& args) { -+<<<<<<< .our - auto* frame_host = web_contents()->GetMainFrame(); -+======= -+ auto frame_host = web_contents()->GetMainFrame(); -+>>>>>>> .their - if (frame_host) { - return frame_host->Send(new AtomFrameMsg_Message( - frame_host->GetRoutingID(), all_frames, channel, args)); -@@ -1853,6 +1916,7 @@ - rfh->Send(reply_msg); - } - -+<<<<<<< .our - v8::Local<v8::Value> WebContents::GetPreloadPath(v8::Isolate* isolate) const { - if (auto* web_preferences = WebContentsPreferences::From(web_contents())) { - base::FilePath::StringType preload; -@@ -1880,6 +1944,25 @@ - } - - v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() const { -+======= -+v8::Local<v8::Value> WebContents::GetWebPreferences(v8::Isolate* isolate) { -+ WebContentsPreferences* web_preferences = -+ WebContentsPreferences::FromWebContents(web_contents()); -+ if (!web_preferences) -+ return v8::Null(isolate); -+ return mate::ConvertToV8(isolate, *web_preferences->web_preferences()); -+} -+ -+v8::Local<v8::Value> WebContents::GetLastWebPreferences(v8::Isolate* isolate) { -+ WebContentsPreferences* web_preferences = -+ WebContentsPreferences::FromWebContents(web_contents()); -+ if (!web_preferences) -+ return v8::Null(isolate); -+ return mate::ConvertToV8(isolate, *web_preferences->last_web_preferences()); -+} -+ -+v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() { -+>>>>>>> .their - if (owner_window()) - return BrowserWindow::From(isolate(), owner_window()); - else -@@ -2013,7 +2096,10 @@ - .SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription) - .SetMethod("startDrag", &WebContents::StartDrag) - .SetMethod("isGuest", &WebContents::IsGuest) -+<<<<<<< .our - .SetMethod("attachToIframe", &WebContents::AttachToIframe) -+======= -+>>>>>>> .their - .SetMethod("isOffscreen", &WebContents::IsOffScreen) - .SetMethod("startPainting", &WebContents::StartPainting) - .SetMethod("stopPainting", &WebContents::StopPainting) -changed in both - base 100644 16f23210557ca816cdeadd50b9332447eca8815f atom/browser/api/atom_api_web_contents.h - our 100644 7939f8268aa8c3371623e0c15f3b6001d7f1efa4 atom/browser/api/atom_api_web_contents.h - their 100644 027332a3706d5ac43a4a769234d361304bdc0350 atom/browser/api/atom_api_web_contents.h -@@ -97,6 +97,8 @@ - static void BuildPrototype(v8::Isolate* isolate, - v8::Local<v8::FunctionTemplate> prototype); - -+ static int64_t GetIDForContents(content::WebContents* web_contents); -+ - // Notifies to destroy any guest web contents before destroying self. - void DestroyWebContents(bool async); - -@@ -234,8 +236,13 @@ - v8::Local<v8::Value> GetPreloadPath(v8::Isolate* isolate) const; - - // Returns the web preferences of current WebContents. -+<<<<<<< .our - v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate) const; - v8::Local<v8::Value> GetLastWebPreferences(v8::Isolate* isolate) const; -+======= -+ v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate); -+ v8::Local<v8::Value> GetLastWebPreferences(v8::Isolate* isolate); -+>>>>>>> .their - - // Returns the owner window. - v8::Local<v8::Value> GetOwnerBrowserWindow() const; -changed in both - base 100644 3f53f4d3d7204f59037ba80556a2c9896e23aae4 atom/browser/api/atom_api_web_request.cc - our 100644 c088196f833160ac964e67030fa083302dd090b0 atom/browser/api/atom_api_web_request.cc - their 100644 ac84ac196b69a121a54dc64b87b7c2c1d6df21b5 atom/browser/api/atom_api_web_request.cc -@@ -40,7 +40,11 @@ - - namespace { - -+<<<<<<< .our - template <typename Method, typename Event, typename Listener> -+======= -+template<typename Method, typename Event, typename Listener> -+>>>>>>> .their - void CallNetworkDelegateMethod( - brightray::URLRequestContextGetter* url_request_context_getter, - Method method, -@@ -95,14 +99,24 @@ - } - - brightray::URLRequestContextGetter* url_request_context_getter = -+<<<<<<< .our - browser_context_->GetRequestContext(); -+======= -+ browser_context_->url_request_context_getter(); -+>>>>>>> .their - if (!url_request_context_getter) - return; - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, -+<<<<<<< .our - base::BindOnce(&CallNetworkDelegateMethod<Method, Event, Listener>, - base::RetainedRef(url_request_context_getter), method, - type, std::move(patterns), std::move(listener))); -+======= -+ base::Bind(&CallNetworkDelegateMethod<Method, Event, Listener>, -+ base::RetainedRef(url_request_context_getter), -+ method, type, std::move(patterns), std::move(listener))); -+>>>>>>> .their - } - - // static -removed in local - base 100644 993f9680ccb475f8870a2e3b4da2d20472531d91 atom/browser/api/atom_api_window.cc - their 100644 d82dc76f802bf17c5d0cb159fdd5aa7a334b9675 atom/browser/api/atom_api_window.cc -removed in local - base 100644 f86c387a34afb15920738413c6819176081b5ee7 atom/browser/api/atom_api_window.h - their 100644 7abebe798c261c64d9634dbdd46aba182175c4d3 atom/browser/api/atom_api_window.h -changed in both - base 100644 8810fed4b9aef78842fb65db93ed2efebabb6928 atom/browser/api/event.cc - our 100644 7b617034eca5a229fc9323bfd6d531ebded752d6 atom/browser/api/event.cc - their 100644 1ee0d57e36068c9b6427c278e9a7a5a66b7f8f79 atom/browser/api/event.cc -@@ -6,7 +6,10 @@ - - #include "atom/common/api/api_messages.h" - #include "atom/common/native_mate_converters/string16_converter.h" -+<<<<<<< .our - #include "atom/common/native_mate_converters/value_converter.h" -+======= -+>>>>>>> .their - #include "content/public/browser/render_frame_host.h" - #include "content/public/browser/web_contents.h" - #include "native_mate/object_template_builder.h" -@@ -27,6 +30,7 @@ - message_ = message; - - Observe(content::WebContents::FromRenderFrameHost(sender)); -+<<<<<<< .our - } - - void Event::RenderFrameDeleted(content::RenderFrameHost* rfh) { -@@ -42,6 +46,23 @@ - sender_ = new_rfh; - } - -+======= -+} -+ -+void Event::RenderFrameDeleted(content::RenderFrameHost* rfh) { -+ if (sender_ != rfh) -+ return; -+ sender_ = nullptr; -+ message_ = nullptr; -+} -+ -+void Event::RenderFrameHostChanged(content::RenderFrameHost* old_rfh, -+ content::RenderFrameHost* new_rfh) { -+ if (sender_ && sender_ == old_rfh) -+ sender_ = new_rfh; -+} -+ -+>>>>>>> .their - void Event::FrameDeleted(content::RenderFrameHost* rfh) { - if (sender_ != rfh) - return; -@@ -57,7 +78,11 @@ - if (message_ == nullptr || sender_ == nullptr) - return false; - -+<<<<<<< .our - AtomFrameHostMsg_Message_Sync::WriteReplyParams(message_, result); -+======= -+ AtomFrameHostMsg_Message_Sync::WriteReplyParams(message_, json); -+>>>>>>> .their - bool success = sender_->Send(message_); - message_ = nullptr; - sender_ = nullptr; -changed in both - base 100644 d73bd2f64b55b5eb0827f819805578559b947f46 atom/browser/api/event.h - our 100644 fbec8f27574691005d203adbafb50709f5c2d010 atom/browser/api/event.h - their 100644 05ad7daff8ac524294c1cacb66f876efc9716dd4 atom/browser/api/event.h -@@ -44,8 +44,13 @@ - - private: - // Replyer for the synchronous messages. -+<<<<<<< .our - content::RenderFrameHost* sender_ = nullptr; - IPC::Message* message_ = nullptr; -+======= -+ content::RenderFrameHost* sender_; -+ IPC::Message* message_; -+>>>>>>> .their - - DISALLOW_COPY_AND_ASSIGN(Event); - }; -changed in both - base 100644 3dbcd0601ef8a63cd6712b566cdc7f388c85e3ee atom/browser/api/event_emitter.cc - our 100644 c6e810b51225c8f89eaf53ac3e46381b52ba63b5 atom/browser/api/event_emitter.cc - their 100644 91769cbb94794a978732773612a3fec245acd750 atom/browser/api/event_emitter.cc -changed in both - base 100644 8d9d2960df35a33a09dfc79c4c35d424738df43f atom/browser/api/event_emitter.h - our 100644 5e4ca3b4ffcb184583ef386100eabda7a9e00da0 atom/browser/api/event_emitter.h - their 100644 8145113084a9c0c34ea808e3712879f5f70737c9 atom/browser/api/event_emitter.h -changed in both - base 100644 c83a99c2b38708ca296b4c9215e26cb58eb9a7d2 atom/browser/atom_browser_client.cc - our 100644 57c4ee582405e6d501ec23940ccb10689ecd64a1 atom/browser/atom_browser_client.cc - their 100644 5c442b32d70e1e1a51b79bfd2d093479ab518060 atom/browser/atom_browser_client.cc -@@ -343,6 +343,11 @@ - web_preferences->AppendCommandLineSwitches(command_line); - SessionPreferences::AppendExtraCommandLineSwitches( - web_contents->GetBrowserContext(), command_line); -+ -+ auto context_id = atom::api::WebContents::GetIDForContents( -+ web_contents); -+ command_line->AppendSwitchASCII(switches::kContextId, -+ base::IntToString(context_id)); - } - } - -@@ -497,7 +502,6 @@ - - brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts( - const content::MainFunctionParams&) { -- v8::V8::Initialize(); // Init V8 before creating main parts. - return new AtomBrowserMainParts; - } - -changed in both - base 100644 07b351b551b609e8b7201753b8969ad9dc6f6a52 atom/browser/atom_browser_context.cc - our 100644 e036cbc8103f19a034ce386940462f8a23ea6807 atom/browser/atom_browser_context.cc - their 100644 f297fbef0a6e75cdb5ca00c86090eb27e44031a7 atom/browser/atom_browser_context.cc -@@ -9,8 +9,18 @@ - #include "atom/browser/atom_download_manager_delegate.h" - #include "atom/browser/atom_permission_manager.h" - #include "atom/browser/browser.h" -+<<<<<<< .our - #include "atom/browser/request_context_delegate.h" - #include "atom/browser/special_storage_policy.h" -+======= -+#include "atom/browser/net/about_protocol_handler.h" -+#include "atom/browser/net/asar/asar_protocol_handler.h" -+#include "atom/browser/net/atom_cert_verifier.h" -+#include "atom/browser/net/atom_network_delegate.h" -+#include "atom/browser/net/atom_url_request_job_factory.h" -+#include "atom/browser/net/http_protocol_handler.h" -+#include "atom/browser/net/resolve_proxy_helper.h" -+>>>>>>> .their - #include "atom/browser/web_view_manager.h" - #include "atom/common/atom_version.h" - #include "atom/common/chrome_version.h" -@@ -133,6 +143,14 @@ - return blob_reader_.get(); - } - -+ResolveProxyHelper* AtomBrowserContext::GetResolveProxyHelper() { -+ if (!resolve_proxy_helper_.get()) { -+ resolve_proxy_helper_ = -+ base::MakeRefCounted<ResolveProxyHelper>(url_request_context_getter()); -+ } -+ return resolve_proxy_helper_.get(); -+} -+ - // static - scoped_refptr<AtomBrowserContext> AtomBrowserContext::From( - const std::string& partition, -changed in both - base 100644 359d3d6b71a5ea1d606b59d7f9b158a15baf1942 atom/browser/atom_browser_context.h - our 100644 9e6a841ceb8d11069a1a094bf7dbbd3a788918b3 atom/browser/atom_browser_context.h - their 100644 77469254db0a598a714d5c9ac3abefbe41ed89af atom/browser/atom_browser_context.h -@@ -20,8 +20,12 @@ - class AtomBlobReader; - class AtomDownloadManagerDelegate; - class AtomPermissionManager; -+<<<<<<< .our - class RequestContextDelegate; - class SpecialStoragePolicy; -+======= -+class ResolveProxyHelper; -+>>>>>>> .their - class WebViewManager; - - class AtomBrowserContext : public brightray::BrowserContext { -@@ -49,8 +53,16 @@ - void OnMainRequestContextCreated( - brightray::URLRequestContextGetter* getter) override; - -+<<<<<<< .our - RequestContextDelegate* GetRequestContextDelegate() const { - return request_context_delegate_.get(); -+======= -+ ResolveProxyHelper* GetResolveProxyHelper(); -+ -+ AtomBlobReader* GetBlobReader(); -+ AtomCookieDelegate* cookie_delegate() const { -+ return cookie_delegate_.get(); -+>>>>>>> .their - } - - protected: -@@ -60,8 +72,12 @@ - ~AtomBrowserContext() override; - - private: -+<<<<<<< .our - brightray::URLRequestContextGetter* url_request_context_getter_; - -+======= -+ scoped_refptr<ResolveProxyHelper> resolve_proxy_helper_; -+>>>>>>> .their - std::unique_ptr<AtomDownloadManagerDelegate> download_manager_delegate_; - std::unique_ptr<WebViewManager> guest_manager_; - std::unique_ptr<AtomPermissionManager> permission_manager_; -changed in both - base 100644 86d50d3c78bda4f4c61dedf43904f9243633d946 atom/browser/atom_browser_main_parts.cc - our 100644 5229b19ca9af7845a3f2f13b7e0913f633b68b1d atom/browser/atom_browser_main_parts.cc - their 100644 4ecd61b3ab14ceeebab78f95f44b0f1153ccb350 atom/browser/atom_browser_main_parts.cc -changed in both - base 100644 f16ee50158508565cc1e043d3257ad687cc69215 atom/browser/browser.cc - our 100644 ce35de64d60c6767ac52596c1b32e7bde5ceefa0 atom/browser/browser.cc - their 100644 3ba915f91eb3403df9630697e77cce9ed7fa3307 atom/browser/browser.cc -changed in both - base 100644 0970b26b776b34f68e5f22776e74c19ddcc039ad atom/browser/browser.h - our 100644 aed7d25c37da59c0dd5e09940a064c329353a0b2 atom/browser/browser.h - their 100644 a8c1a8c5e7c4409e3a78279da46fb2ba6112f409 atom/browser/browser.h -@@ -277,7 +277,11 @@ - bool is_ready_ = false; - - // The browser is being shutdown. -+<<<<<<< .our - bool is_shutdown_ = false; -+======= -+ bool is_shutdown_; -+>>>>>>> .their - - int badge_count_ = 0; - -changed in both - base 100644 0faeee36f9390b36bc5963b2f90d2063e3603109 atom/browser/browser_mac.mm - our 100644 27e347eccebf006336d5d110c81717ecc45af9c3 atom/browser/browser_mac.mm - their 100644 e47b8cb9d3c7fcf24279cd6e973a1b00a85ea25a atom/browser/browser_mac.mm -changed in both - base 100644 7c154b60b00e25c42847ceefb98723b50ea03dd0 atom/browser/native_browser_view.h - our 100644 56937e4c8c69e3605d2b6cc71a0877b74ff4e83d atom/browser/native_browser_view.h - their 100644 cab6980fa2cf035c1a5ca6b4aee822a0ee604fd4 atom/browser/native_browser_view.h -changed in both - base 100644 17b0a1ee9006dd70888165a9209076fd7065f3cc atom/browser/native_browser_view_mac.mm - our 100644 0416e26e89f1e0f37366ef1798b4359da0729225 atom/browser/native_browser_view_mac.mm - their 100644 86df632638ef7772270569824515b251470d0c08 atom/browser/native_browser_view_mac.mm -changed in both - base 100644 78e788b3019c23bce13fdc8d94385d4a3937cf22 atom/browser/native_browser_view_views.cc - our 100644 6414005a1e40d80ae86102b12edee0255cab9adb atom/browser/native_browser_view_views.cc - their 100644 def64d12e3520fa15a2b6779147a819a6eaec2f8 atom/browser/native_browser_view_views.cc -changed in both - base 100644 5dcda13447cde098fccaf8782fefb97d861d47f4 atom/browser/native_browser_view_views.h - our 100644 8f8e860292baddad1156c50ae7cfaa0fd6e87d99 atom/browser/native_browser_view_views.h - their 100644 abf47178302ad7527c1640a3f41492f871f137e5 atom/browser/native_browser_view_views.h -changed in both - base 100644 34778fb6434707e6ae3c70ab55e48e87eb556448 atom/browser/native_window.cc - our 100644 4ff2bcfcabfd34d8563f9ed213c03655a99dd9c6 atom/browser/native_window.cc - their 100644 26ac44607ebceadcde1d4c038890d914c888a0d5 atom/browser/native_window.cc -@@ -21,6 +21,11 @@ - #include "ui/display/win/screen_win.h" - #endif - -+#if defined(OS_WIN) -+#include "ui/base/win/shell.h" -+#include "ui/display/win/screen_win.h" -+#endif -+ - DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::NativeWindowRelay); - - namespace atom { -@@ -45,9 +50,29 @@ - - } // namespace - -+<<<<<<< .our - NativeWindow::NativeWindow(const mate::Dictionary& options, - NativeWindow* parent) - : widget_(new views::Widget), parent_(parent), weak_factory_(this) { -+======= -+NativeWindow::NativeWindow( -+ brightray::InspectableWebContents* inspectable_web_contents, -+ const mate::Dictionary& options, -+ NativeWindow* parent) -+ : content::WebContentsObserver(inspectable_web_contents->GetWebContents()), -+ has_frame_(true), -+ transparent_(false), -+ enable_larger_than_screen_(false), -+ is_closed_(false), -+ sheet_offset_x_(0.0), -+ sheet_offset_y_(0.0), -+ aspect_ratio_(0.0), -+ parent_(parent), -+ is_modal_(false), -+ is_osr_dummy_(false), -+ inspectable_web_contents_(inspectable_web_contents), -+ weak_factory_(this) { -+>>>>>>> .their - options.Get(options::kFrame, &has_frame_); - options.Get(options::kTransparent, &transparent_); - options.Get(options::kEnableLargerThanScreen, &enable_larger_than_screen_); -changed in both - base 100644 d1cfa7cc352971772689ecd60a110b48ef1a7eaa atom/browser/native_window.h - our 100644 35b67e2dd230692c415a32aae5f0a5e99ab74ac0 atom/browser/native_window.h - their 100644 61922aea78e3b61db614354e6a578fcda925096b atom/browser/native_window.h -@@ -220,6 +220,17 @@ - virtual void HandleKeyboardEvent( - content::WebContents*, - const content::NativeWebKeyboardEvent& event) {} -+<<<<<<< .our -+======= -+ virtual void ShowAutofillPopup(content::RenderFrameHost* frame_host, -+ content::WebContents* web_contents, -+ const gfx::RectF& bounds, -+ const std::vector<base::string16>& values, -+ const std::vector<base::string16>& labels) {} -+ virtual void HideAutofillPopup(content::RenderFrameHost* frame_host) {} -+>>>>>>> .their -+ -+ virtual void UpdateDraggableRegionViews() {} - - // Public API used by platform-dependent delegates and observers to send UI - // related notifications. -@@ -340,8 +351,13 @@ - class NativeWindowRelay - : public content::WebContentsUserData<NativeWindowRelay> { - public: -+<<<<<<< .our - explicit NativeWindowRelay(base::WeakPtr<NativeWindow> window); - ~NativeWindowRelay() override; -+======= -+ explicit NativeWindowRelay(base::WeakPtr<NativeWindow> window) -+ : key(UserDataKey()), window(window) {} -+>>>>>>> .their - - static void* UserDataKey() { - return content::WebContentsUserData<NativeWindowRelay>::UserDataKey(); -changed in both - base 100644 60d8fc23f59a842c100412b1c236b87d0815a7a0 atom/browser/native_window_mac.h - our 100644 44a78198f44cdba9875e3fb27c8e2c87eaa6f33b atom/browser/native_window_mac.h - their 100644 9e8c3aef87dd8d2d4a3260587b7013d260649b55 atom/browser/native_window_mac.h -@@ -118,8 +118,11 @@ - void MoveTabToNewWindow() override; - void ToggleTabBar() override; - bool AddTabbedWindow(NativeWindow* window) override; -+<<<<<<< .our - - bool SetWindowButtonVisibility(bool visible) override; -+======= -+>>>>>>> .their - - void SetVibrancy(const std::string& type) override; - void SetTouchBar( -@@ -130,8 +133,19 @@ - gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) const override; - gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) const override; - -+<<<<<<< .our - // Use a custom content view instead of Chromium's BridgedContentView. - void OverrideNSWindowContentView(); -+======= -+ // content::WebContentsObserver: -+ void RenderViewHostChanged(content::RenderViewHost* old_host, -+ content::RenderViewHost* new_host) override; -+ -+ // Refresh the DraggableRegion views. -+ void UpdateDraggableRegionViews() override { -+ UpdateDraggableRegionViews(draggable_regions_); -+ } -+>>>>>>> .their - - // Set the attribute of NSWindow while work around a bug of zoom button. - void SetStyleMask(bool on, NSUInteger flag); -changed in both - base 100644 ad1713e401240dbc1c2054551d0caeb41aea2884 atom/browser/native_window_mac.mm - our 100644 004263ec127709067e903ffbf31003b8844226b4 atom/browser/native_window_mac.mm - their 100644 0397c62d8df94b3ce66482c0d9c4b3b87ac97a45 atom/browser/native_window_mac.mm -@@ -28,9 +28,12 @@ - #include "skia/ext/skia_utils_mac.h" - #include "ui/gfx/skia_util.h" - #include "ui/gl/gpu_switching_manager.h" -+<<<<<<< .our - #include "ui/views/background.h" - #include "ui/views/cocoa/bridged_native_widget.h" - #include "ui/views/widget/widget.h" -+======= -+>>>>>>> .their - - // This view always takes the size of its superview. It is intended to be used - // as a NSWindow's contentView. It is needed because NSWindow's implementation -@@ -1144,10 +1147,17 @@ - } - - bool NativeWindowMac::AddTabbedWindow(NativeWindow* window) { -+<<<<<<< .our - if (window_ == window->GetNativeWindow()) { - return false; - } else { - if (@available(macOS 10.12, *)) -+======= -+ if (window_.get() == window->GetNativeWindow()) { -+ return false; -+ } else { -+ if ([window_ respondsToSelector:@selector(addTabbedWindow:ordered:)]) -+>>>>>>> .their - [window_ addTabbedWindow:window->GetNativeWindow() ordered:NSWindowAbove]; - } - return true; -@@ -1185,15 +1195,22 @@ - return; - } - -+<<<<<<< .our - background_color_before_vibrancy_.reset([[window_ backgroundColor] retain]); - transparency_before_vibrancy_ = [window_ titlebarAppearsTransparent]; - ui::GpuSwitchingManager::SetTransparent(true); -+======= -+ [vibrant_view removeFromSuperview]; -+ [window_ setVibrantView:nil]; -+ ui::GpuSwitchingManager::SetTransparent(transparent()); -+>>>>>>> .their - - if (title_bar_style_ != NORMAL) { - [window_ setTitlebarAppearsTransparent:YES]; - [window_ setBackgroundColor:[NSColor clearColor]]; - } - -+<<<<<<< .our - NSVisualEffectView* effect_view = (NSVisualEffectView*)vibrant_view; - if (effect_view == nil) { - effect_view = [[[NSVisualEffectView alloc] -@@ -1208,6 +1225,31 @@ - positioned:NSWindowBelow - relativeTo:nil]; - } -+======= -+ SetRenderWidgetHostOpaque(false); -+ background_color_before_vibrancy_.reset([window_ backgroundColor]); -+ transparency_before_vibrancy_ = [window_ titlebarAppearsTransparent]; -+ ui::GpuSwitchingManager::SetTransparent(true); -+ -+ if (title_bar_style_ != NORMAL) { -+ [window_ setTitlebarAppearsTransparent:YES]; -+ [window_ setBackgroundColor:[NSColor clearColor]]; -+ } -+ -+ NSVisualEffectView* effect_view = (NSVisualEffectView*)vibrant_view; -+ if (effect_view == nil) { -+ effect_view = [[[NSVisualEffectView alloc] -+ initWithFrame: [[window_ contentView] bounds]] autorelease]; -+ [window_ setVibrantView:(NSView*)effect_view]; -+ -+ [effect_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; -+ [effect_view setBlendingMode:NSVisualEffectBlendingModeBehindWindow]; -+ [effect_view setState:NSVisualEffectStateActive]; -+ [[window_ contentView] addSubview:effect_view -+ positioned:NSWindowBelow -+ relativeTo:nil]; -+ } -+>>>>>>> .their - - NSVisualEffectMaterial vibrancyType = NSVisualEffectMaterialLight; - -@@ -1387,6 +1429,7 @@ - [parent->GetNativeWindow() addChildWindow:window_ ordered:NSWindowAbove]; - } - -+<<<<<<< .our - void NativeWindowMac::ShowWindowButton(NSWindowButton button) { - auto view = [window_ standardWindowButton:button]; - [view.superview addSubview:view positioned:NSWindowAbove relativeTo:nil]; -@@ -1395,6 +1438,35 @@ - void NativeWindowMac::SetForwardMouseMessages(bool forward) { - [window_ setAcceptsMouseMovedEvents:forward]; - } -+======= -+ // Remove all ControlRegionViews that are added last time. -+ // Note that [webView subviews] returns the view's mutable internal array and -+ // it should be copied to avoid mutating the original array while enumerating -+ // it. -+ base::scoped_nsobject<NSArray> subviews([[webView subviews] copy]); -+ for (NSView* subview in subviews.get()) -+ if ([subview isKindOfClass:[ControlRegionView class]]) -+ [subview removeFromSuperview]; -+ -+ // Draggable regions is implemented by having the whole web view draggable -+ // (mouseDownCanMoveWindow) and overlaying regions that are not draggable. -+ std::vector<gfx::Rect> drag_exclude_rects = -+ CalculateNonDraggableRegions(regions, webViewWidth, webViewHeight); -+ -+ if (browser_view_) { -+ browser_view_->UpdateDraggableRegions(drag_exclude_rects); -+ } -+ -+ // Create and add a ControlRegionView for each region that needs to be -+ // excluded from the dragging. -+ for (const auto& rect : drag_exclude_rects) { -+ base::scoped_nsobject<NSView> controlRegion( -+ [[ControlRegionView alloc] initWithFrame:NSZeroRect]); -+ [controlRegion setFrame:NSMakeRect(rect.x(), webViewHeight - rect.bottom(), -+ rect.width(), rect.height())]; -+ [webView addSubview:controlRegion]; -+ } -+>>>>>>> .their - - void NativeWindowMac::OverrideNSWindowContentView() { - // When using `views::Widget` to hold WebContents, Chromium would use -changed in both - base 100644 008109970ec8d3c55a2028a173c3b941908d78a7 atom/browser/native_window_views.cc - our 100644 0dba39942f92d54ba34db7709b73012055680d94 atom/browser/native_window_views.cc - their 100644 f3e6fc09c5850cbc3d6989a2a94607b1f9a5d514 atom/browser/native_window_views.cc -@@ -1115,7 +1115,11 @@ - if (!active && IsMenuBarAutoHide() && IsMenuBarVisible()) - SetMenuBarVisibility(false); - -+<<<<<<< .our - root_view_->ResetAltState(); -+======= -+ menu_bar_alt_pressed_ = false; -+>>>>>>> .their - } - - void NativeWindowViews::OnWidgetBoundsChanged(views::Widget* changed_widget, -@@ -1237,9 +1241,138 @@ - void NativeWindowViews::HandleKeyboardEvent( - content::WebContents*, - const content::NativeWebKeyboardEvent& event) { -+<<<<<<< .our - keyboard_event_handler_->HandleKeyboardEvent(event, - root_view_->GetFocusManager()); - root_view_->HandleKeyEvent(event); -+======= -+ keyboard_event_handler_->HandleKeyboardEvent(event, GetFocusManager()); -+ -+ if (!menu_bar_) -+ return; -+ -+ // Show accelerator when "Alt" is pressed. -+ if (menu_bar_visible_ && IsAltKey(event)) -+ menu_bar_->SetAcceleratorVisibility( -+ event.GetType() == blink::WebInputEvent::kRawKeyDown); -+ -+ // Show the submenu when "Alt+Key" is pressed. -+ if (event.GetType() == blink::WebInputEvent::kRawKeyDown && -+ !IsAltKey(event) && IsAltModifier(event)) { -+ if (!menu_bar_visible_ && -+ (menu_bar_->HasAccelerator(event.windows_key_code))) -+ SetMenuBarVisibility(true); -+ menu_bar_->ActivateAccelerator(event.windows_key_code); -+ return; -+ } -+ -+ if (!menu_bar_autohide_) -+ return; -+ -+ // Toggle the menu bar only when a single Alt is released. -+ if (event.GetType() == blink::WebInputEvent::kRawKeyDown && IsAltKey(event)) { -+ // When a single Alt is pressed: -+ menu_bar_alt_pressed_ = true; -+ } else if (event.GetType() == blink::WebInputEvent::kKeyUp && -+ IsAltKey(event) && menu_bar_alt_pressed_) { -+ // When a single Alt is released right after a Alt is pressed: -+ menu_bar_alt_pressed_ = false; -+ SetMenuBarVisibility(!menu_bar_visible_); -+ } else { -+ // When any other keys except single Alt have been pressed/released: -+ menu_bar_alt_pressed_ = false; -+ } -+} -+ -+void NativeWindowViews::ShowAutofillPopup( -+ content::RenderFrameHost* frame_host, -+ content::WebContents* web_contents, -+ const gfx::RectF& bounds, -+ const std::vector<base::string16>& values, -+ const std::vector<base::string16>& labels) { -+ bool is_offsceen = false; -+ bool is_embedder_offscreen = false; -+ -+ auto* web_contents_preferences = -+ WebContentsPreferences::FromWebContents(web_contents); -+ if (web_contents_preferences) { -+ const auto* web_preferences = web_contents_preferences->web_preferences(); -+ -+ web_preferences->GetBoolean("offscreen", &is_offsceen); -+ int guest_instance_id = 0; -+ web_preferences->GetInteger(options::kGuestInstanceID, &guest_instance_id); -+ -+ if (guest_instance_id) { -+ auto manager = WebViewManager::GetWebViewManager(web_contents); -+ if (manager) { -+ auto embedder = manager->GetEmbedder(guest_instance_id); -+ if (embedder) { -+ is_embedder_offscreen = WebContentsPreferences::IsPreferenceEnabled( -+ "offscreen", embedder); -+ } -+ } -+ } -+ } -+ -+ autofill_popup_->CreateView( -+ frame_host, -+ is_offsceen || is_embedder_offscreen, -+ widget(), -+ bounds); -+ autofill_popup_->SetItems(values, labels); -+ autofill_popup_->UpdatePopupBounds(menu_bar_visible_ ? 0 : kMenuBarHeight); -+} -+ -+void NativeWindowViews::HideAutofillPopup( -+ content::RenderFrameHost* frame_host) { -+ autofill_popup_->Hide(); -+} -+ -+void NativeWindowViews::Layout() { -+ const auto size = GetContentsBounds().size(); -+ const auto menu_bar_bounds = -+ menu_bar_visible_ ? gfx::Rect(0, 0, size.width(), kMenuBarHeight) -+ : gfx::Rect(); -+ if (menu_bar_) { -+ menu_bar_->SetBoundsRect(menu_bar_bounds); -+ } -+ -+ if (web_view_) { -+ web_view_->SetBoundsRect( -+ gfx::Rect(0, menu_bar_bounds.height(), size.width(), -+ size.height() - menu_bar_bounds.height())); -+ } -+ -+ if (autofill_popup_.get()) -+ autofill_popup_->UpdatePopupBounds(menu_bar_visible_ ? 0 : kMenuBarHeight); -+} -+ -+gfx::Size NativeWindowViews::GetMinimumSize() const { -+ return NativeWindow::GetMinimumSize(); -+} -+ -+gfx::Size NativeWindowViews::GetMaximumSize() const { -+ return NativeWindow::GetMaximumSize(); -+} -+ -+bool NativeWindowViews::AcceleratorPressed(const ui::Accelerator& accelerator) { -+ return accelerator_util::TriggerAcceleratorTableCommand( -+ &accelerator_table_, accelerator); -+} -+ -+void NativeWindowViews::RegisterAccelerators(AtomMenuModel* menu_model) { -+ // Clear previous accelerators. -+ views::FocusManager* focus_manager = GetFocusManager(); -+ accelerator_table_.clear(); -+ focus_manager->UnregisterAccelerators(this); -+ -+ // Register accelerators with focus manager. -+ accelerator_util::GenerateAcceleratorTable(&accelerator_table_, menu_model); -+ for (const auto& iter : accelerator_table_) { -+ focus_manager->RegisterAccelerator( -+ iter.first, ui::AcceleratorManager::kNormalPriority, this); -+ } -+>>>>>>> .their - } - - ui::WindowShowState NativeWindowViews::GetRestoredState() { -changed in both - base 100644 a39e84ce5b8d7b757233dab4bed646e08cb8c76a atom/browser/net/asar/url_request_asar_job.cc - our 100644 85eb2e1dd142b6d64aafb5350ae47603db989e8f atom/browser/net/asar/url_request_asar_job.cc - their 100644 a6fe5e26540c9533f16dcf56fc955d0025de3b4a atom/browser/net/asar/url_request_asar_job.cc -changed in both - base 100644 9b0f3a98dc53b922c0d070244f8f7457f332d850 atom/browser/net/atom_network_delegate.cc - our 100644 e71ea74317b69f31a5aac8e723902748972fed8f atom/browser/net/atom_network_delegate.cc - their 100644 239a64016febb8f9d81206d7f2a7d100ccd1f293 atom/browser/net/atom_network_delegate.cc -@@ -250,6 +250,7 @@ - - AtomNetworkDelegate::~AtomNetworkDelegate() {} - -+<<<<<<< .our - void AtomNetworkDelegate::SetSimpleListenerInIO(SimpleEvent type, - URLPatterns patterns, - SimpleListener callback) { -@@ -266,6 +267,26 @@ - response_listeners_.erase(type); - else - response_listeners_[type] = {std::move(patterns), std::move(callback)}; -+======= -+void AtomNetworkDelegate::SetSimpleListenerInIO( -+ SimpleEvent type, -+ URLPatterns patterns, -+ SimpleListener callback) { -+ if (callback.is_null()) -+ simple_listeners_.erase(type); -+ else -+ simple_listeners_[type] = { std::move(patterns), std::move(callback) }; -+} -+ -+void AtomNetworkDelegate::SetResponseListenerInIO( -+ ResponseEvent type, -+ URLPatterns patterns, -+ ResponseListener callback) { -+ if (callback.is_null()) -+ response_listeners_.erase(type); -+ else -+ response_listeners_[type] = { std::move(patterns), std::move(callback) }; -+>>>>>>> .their - } - - void AtomNetworkDelegate::SetDevToolsNetworkEmulationClientId( -changed in both - base 100644 e00c26ff2cbc134b987b4361896971e48056951d atom/browser/net/atom_network_delegate.h - our 100644 39a7a8ddfcda17fd7d022331132b54485d07a279 atom/browser/net/atom_network_delegate.h - their 100644 ad37a926d4732d94526f74b2f927e35504d2efe3 atom/browser/net/atom_network_delegate.h -changed in both - base 100644 1f0bdae4c08aa70faa5d6d3771a9af3b2a92f6ff atom/browser/net/atom_url_request.cc - our 100644 5ffbfd65a48b4459b2ebca66a5c2259f18ed80a8 atom/browser/net/atom_url_request.cc - their 100644 7c5ded81aa3cf6c3052c63cf2383bbb7aa8c39f1 atom/browser/net/atom_url_request.cc -changed in both - base 100644 654798d8aac82409d3959cd06077c568f1e064d6 atom/browser/net/atom_url_request.h - our 100644 fde7b161385fb431b2d807012a00679a4bdb507a atom/browser/net/atom_url_request.h - their 100644 8c6ced8af6907d2a2bf079ca52ad9850763780a6 atom/browser/net/atom_url_request.h -added in remote - their 100644 fde8718f89c5d4d4a6dd0a9b08353832c07902c5 atom/browser/net/resolve_proxy_helper.cc -@@ -0,0 +1,85 @@ -+// Copyright (c) 2018 GitHub, Inc. -+// Use of this source code is governed by the MIT license that can be -+// found in the LICENSE file. -+ -+#include "atom/browser/net/resolve_proxy_helper.h" -+ -+#include "base/threading/thread_task_runner_handle.h" -+#include "net/url_request/url_request_context.h" -+#include "net/url_request/url_request_context_getter.h" -+ -+namespace atom { -+ -+ResolveProxyHelper::ResolveProxyHelper(net::URLRequestContextGetter* getter) -+ : context_getter_(getter), -+ original_thread_(base::ThreadTaskRunnerHandle::Get()) {} -+ -+ResolveProxyHelper::~ResolveProxyHelper() { -+ // Clear all pending requests if the ProxyService is still alive. -+ pending_requests_.clear(); -+} -+ -+void ResolveProxyHelper::ResolveProxy(const GURL& url, -+ const ResolveProxyCallback& callback) { -+ // Enqueue the pending request. -+ pending_requests_.push_back(PendingRequest(url, callback)); -+ -+ // If nothing is in progress, start. -+ if (pending_requests_.size() == 1) -+ StartPendingRequest(); -+} -+ -+void ResolveProxyHelper::SendProxyResult(const std::string& proxy) { -+ CHECK(!pending_requests_.empty()); -+ -+ const auto& completed_request = pending_requests_.front(); -+ if (!completed_request.callback.is_null()) -+ completed_request.callback.Run(proxy); -+ -+ // Clear the current (completed) request. -+ pending_requests_.pop_front(); -+ -+ // Start the next request. -+ if (!pending_requests_.empty()) -+ StartPendingRequest(); -+} -+ -+void ResolveProxyHelper::StartPendingRequest() { -+ auto& request = pending_requests_.front(); -+ context_getter_->GetNetworkTaskRunner()->PostTask( -+ FROM_HERE, -+ base::BindOnce(&ResolveProxyHelper::StartPendingRequestInIO, -+ base::Unretained(this), request.url, request.pac_req)); -+} -+ -+void ResolveProxyHelper::OnResolveProxyCompleted(int result) { -+ std::string proxy; -+ if (result == net::OK) -+ proxy = proxy_info_.ToPacString(); -+ -+ original_thread_->PostTask( -+ FROM_HERE, base::BindOnce(&ResolveProxyHelper::SendProxyResult, -+ base::Unretained(this), proxy)); -+} -+ -+void ResolveProxyHelper::StartPendingRequestInIO( -+ const GURL& url, -+ net::ProxyService::PacRequest* pac_req) { -+ // Verify the request wasn't started yet. -+ DCHECK(nullptr == pac_req); -+ -+ auto proxy_service = context_getter_->GetURLRequestContext()->proxy_service(); -+ -+ // Start the request. -+ int result = proxy_service->ResolveProxy( -+ url, std::string(), &proxy_info_, -+ base::Bind(&ResolveProxyHelper::OnResolveProxyCompleted, -+ base::Unretained(this)), -+ &pac_req, nullptr, net::NetLogWithSource()); -+ -+ // Completed synchronously. -+ if (result != net::ERR_IO_PENDING) -+ OnResolveProxyCompleted(result); -+} -+ -+} // namespace atom -added in remote - their 100644 cc85d4ff62ce753ff4ba1fc5979760b5e5d768a6 atom/browser/net/resolve_proxy_helper.h -@@ -0,0 +1,59 @@ -+// Copyright (c) 2018 GitHub, Inc. -+// Use of this source code is governed by the MIT license that can be -+// found in the LICENSE file. -+ -+#ifndef ATOM_BROWSER_NET_RESOLVE_PROXY_HELPER_H_ -+#define ATOM_BROWSER_NET_RESOLVE_PROXY_HELPER_H_ -+ -+#include <deque> -+#include <string> -+ -+#include "base/memory/ref_counted.h" -+#include "net/proxy/proxy_service.h" -+#include "url/gurl.h" -+ -+namespace net { -+class URLRequestContextGetter; -+} -+ -+namespace atom { -+ -+class ResolveProxyHelper -+ : public base::RefCountedThreadSafe<ResolveProxyHelper> { -+ public: -+ using ResolveProxyCallback = base::Callback<void(std::string)>; -+ explicit ResolveProxyHelper(net::URLRequestContextGetter* getter); -+ -+ void ResolveProxy(const GURL& url, const ResolveProxyCallback& callback); -+ -+ private: -+ friend class base::RefCountedThreadSafe<ResolveProxyHelper>; -+ struct PendingRequest { -+ public: -+ PendingRequest(const GURL& url, const ResolveProxyCallback& callback) -+ : url(url), callback(callback), pac_req(nullptr) {} -+ -+ GURL url; -+ ResolveProxyCallback callback; -+ net::ProxyService::PacRequest* pac_req; -+ }; -+ -+ ~ResolveProxyHelper(); -+ -+ void StartPendingRequest(); -+ void StartPendingRequestInIO(const GURL& request, -+ net::ProxyService::PacRequest* pac_req); -+ void SendProxyResult(const std::string& proxy); -+ void OnResolveProxyCompleted(int result); -+ -+ net::ProxyInfo proxy_info_; -+ std::deque<PendingRequest> pending_requests_; -+ scoped_refptr<net::URLRequestContextGetter> context_getter_; -+ scoped_refptr<base::SingleThreadTaskRunner> original_thread_; -+ -+ DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper); -+}; -+ -+} // namespace atom -+ -+#endif // ATOM_BROWSER_NET_RESOLVE_PROXY_HELPER_H_ -changed in both - base 100644 3313eba36bb903426778fac6cd18258a95fec677 atom/browser/resources/mac/Info.plist - our 100644 9094f0f7335edf833d51f688851e6a105de60433 atom/browser/resources/mac/Info.plist - their 100644 0c499f8929996fb2ba2b15387221957cbff42adf atom/browser/resources/mac/Info.plist -@@ -17,9 +17,15 @@ - <key>CFBundleIconFile</key> - <string>electron.icns</string> - <key>CFBundleVersion</key> -+<<<<<<< .our - <string>4.0.0</string> - <key>CFBundleShortVersionString</key> - <string>4.0.0</string> -+======= -+ <string>2.1.0</string> -+ <key>CFBundleShortVersionString</key> -+ <string>2.1.0</string> -+>>>>>>> .their - <key>LSApplicationCategoryType</key> - <string>public.app-category.developer-tools</string> - <key>LSMinimumSystemVersion</key> -changed in both - base 100644 c349f99d712ff69960d35b18587ddb6c417f7cd5 atom/browser/resources/win/atom.rc - our 100644 c0bd831e8bddf10180f75cd40694831e2e98622d atom/browser/resources/win/atom.rc - their 100644 95e13b65e49c1942380686821715c30f6ddb4023 atom/browser/resources/win/atom.rc -@@ -56,8 +56,13 @@ - // - - VS_VERSION_INFO VERSIONINFO -+<<<<<<< .our - FILEVERSION 4,0,0,20180821 - PRODUCTVERSION 4,0,0,20180821 -+======= -+ FILEVERSION 2,1,0,20180809 -+ PRODUCTVERSION 2,1,0,20180809 -+>>>>>>> .their - FILEFLAGSMASK 0x3fL - #ifdef _DEBUG - FILEFLAGS 0x1L -@@ -74,12 +79,20 @@ - BEGIN - VALUE "CompanyName", "GitHub, Inc." - VALUE "FileDescription", "Electron" -+<<<<<<< .our - VALUE "FileVersion", "4.0.0" -+======= -+ VALUE "FileVersion", "2.1.0" -+>>>>>>> .their - VALUE "InternalName", "electron.exe" - VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." - VALUE "OriginalFilename", "electron.exe" - VALUE "ProductName", "Electron" -+<<<<<<< .our - VALUE "ProductVersion", "4.0.0" -+======= -+ VALUE "ProductVersion", "2.1.0" -+>>>>>>> .their - VALUE "SquirrelAwareVersion", "1" - END - END -changed in both - base 100644 8bdf4e0c2be32fc7d704bc989d7ccec5dd5db672 atom/browser/ui/cocoa/atom_menu_controller.mm - our 100644 cecf30ce1c88e007957a65427648941765a6067e atom/browser/ui/cocoa/atom_menu_controller.mm - their 100644 ea141b495e710222f12913f35625cf435b947e18 atom/browser/ui/cocoa/atom_menu_controller.mm -@@ -334,8 +334,13 @@ - if (isMenuOpen_) { - isMenuOpen_ = NO; - model_->MenuWillClose(); -+<<<<<<< .our - // Post async task so that itemSelected runs before the close callback - // deletes the controller from the map which deallocates it -+======= -+ // Post async task so that itemSelected runs before the close callback -+ // deletes the controller from the map which deallocates it -+>>>>>>> .their - if (!closeCallback.is_null()) { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, closeCallback); - } -changed in both - base 100644 b26d472db131f7be9d5bfbbd1cebfc992743d312 atom/browser/ui/file_dialog_mac.mm - our 100644 18b18a8b240cda5512ae49e0afde5c749bdf75c0 atom/browser/ui/file_dialog_mac.mm - their 100644 89ecaf46ec7f32ca4f3a3a89de13efcbdad5619f atom/browser/ui/file_dialog_mac.mm -@@ -27,9 +27,12 @@ - - @implementation PopUpButtonHandler - -+<<<<<<< .our - @synthesize savePanel; - @synthesize fileTypesList; - -+======= -+>>>>>>> .their - - (instancetype)initWithPanel:(NSSavePanel*)panel - andTypesList:(NSArray*)typesList { - self = [super init]; -@@ -55,6 +58,7 @@ - } - - @end -+<<<<<<< .our - - // Manages the PopUpButtonHandler. - @interface AtomAccessoryView : NSView -@@ -65,6 +69,17 @@ - - (void)dealloc { - auto* popupButton = - static_cast<NSPopUpButton*>([[self subviews] objectAtIndex:1]); -+======= -+ -+// Manages the PopUpButtonHandler. -+@interface AtomAccessoryView : NSView -+@end -+ -+@implementation AtomAccessoryView -+ -+- (void)dealloc { -+ auto* popupButton = static_cast<NSPopUpButton*>([[self subviews] objectAtIndex: 1]); -+>>>>>>> .their - [[popupButton target] release]; - [super dealloc]; - } -@@ -76,8 +91,11 @@ - DialogSettings::DialogSettings() = default; - DialogSettings::~DialogSettings() = default; - -+<<<<<<< .our - namespace { - -+======= -+>>>>>>> .their - void SetAllowedFileTypes(NSSavePanel* dialog, const Filters& filters) { - NSMutableArray* file_types_list = [NSMutableArray array]; - NSMutableArray* filter_names = [NSMutableArray array]; -@@ -85,9 +103,18 @@ - // Create array to keep file types and their name. - for (const Filter& filter : filters) { - NSMutableSet* file_type_set = [NSMutableSet set]; -+<<<<<<< .our - [filter_names addObject:@(filter.first.c_str())]; - for (const std::string& ext : filter.second) { - [file_type_set addObject:@(ext.c_str())]; -+======= -+ base::ScopedCFTypeRef<CFStringRef> name_cf( -+ base::SysUTF8ToCFStringRef(filter.first)); -+ [filter_names addObject:base::mac::CFToNSCast(name_cf.get())]; -+ for (const std::string& ext : filter.second) { -+ base::ScopedCFTypeRef<CFStringRef> ext_cf(base::SysUTF8ToCFStringRef(ext)); -+ [file_type_set addObject:base::mac::CFToNSCast(ext_cf.get())]; -+>>>>>>> .their - } - [file_types_list addObject:[file_type_set allObjects]]; - } -@@ -119,12 +146,19 @@ - [label setBezeled:NO]; - [label setDrawsBackground:NO]; - -+<<<<<<< .our - NSPopUpButton* popupButton = - [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) - pullsDown:NO]; - PopUpButtonHandler* popUpButtonHandler = - [[PopUpButtonHandler alloc] initWithPanel:dialog - andTypesList:file_types_list]; -+======= -+ NSPopUpButton* popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) -+ pullsDown:NO]; -+ PopUpButtonHandler* popUpButtonHandler = [[PopUpButtonHandler alloc] initWithPanel:dialog -+ andTypesList:file_types_list]; -+>>>>>>> .their - [popupButton addItemsWithTitles:filter_names]; - [popupButton setTarget:popUpButtonHandler]; - [popupButton setAction:@selector(selectFormat:)]; -changed in both - base 100644 a358f676a8c41d15bb9c3157cce4a62ef8356855 atom/browser/ui/tray_icon_cocoa.mm - our 100644 2c434d7a9e312adfb3802628a3d092a95d4ac49f atom/browser/ui/tray_icon_cocoa.mm - their 100644 aedce38f656eaab389502df98bb20b28e3e3619a atom/browser/ui/tray_icon_cocoa.mm -@@ -240,13 +240,22 @@ - } - - // check title_ being nil -+<<<<<<< .our - NSString* title = @""; -+======= -+ NSString *title = @""; -+>>>>>>> .their - if (title_) - title = title_; - - attributedTitle_.reset([[NSMutableAttributedString alloc] -+<<<<<<< .our - initWithString:title - attributes:attributes]); -+======= -+ initWithString:title -+ attributes:attributes]); -+>>>>>>> .their - - // NSFontAttributeName:[NSFont menuBarFontOfSize:0], - // NSForegroundColorAttributeName:[self colorWithHighlight: highlight] -changed in both - base 100644 e1836ad68985f6068a5ea4be76d6f58682056d04 atom/browser/ui/tray_icon_gtk.cc - our 100644 4c780285c80a157afca74b0927175ba3b045def9 atom/browser/ui/tray_icon_gtk.cc - their 100644 eb7be1ed3b4345cf825075785c1c1708a7b69d30 atom/browser/ui/tray_icon_gtk.cc -@@ -36,9 +36,16 @@ - if (libgtkui::AppIndicatorIcon::CouldOpen()) { - ++indicators_count; - icon_.reset(new libgtkui::AppIndicatorIcon( -+<<<<<<< .our - base::StringPrintf("%s%d", Browser::Get()->GetName().c_str(), - indicators_count), - image.AsImageSkia(), toolTip)); -+======= -+ base::StringPrintf( -+ "%s%d", Browser::Get()->GetName().c_str(), indicators_count), -+ image.AsImageSkia(), -+ toolTip)); -+>>>>>>> .their - } else { - icon_.reset(new libgtkui::Gtk2StatusIcon(image.AsImageSkia(), toolTip)); - } -changed in both - base 100644 5182e1a0f7f141e8ddfa95fd8cca8771f2cabd9f atom/browser/ui/views/frameless_view.cc - our 100644 8959ee13612979d2819621acc14ebf641fb7f116 atom/browser/ui/views/frameless_view.cc - their 100644 b78e897b8f51747fbeb86cdf1e507ecf5be0bf9b atom/browser/ui/views/frameless_view.cc -changed in both - base 100644 f2ab22f70a6fa08ff1315d197ff3ff3cb700733f atom/browser/ui/views/global_menu_bar_x11.cc - our 100644 656bd8f991f87c06a240cdc09a3bfcd500d1c1c8 atom/browser/ui/views/global_menu_bar_x11.cc - their 100644 eaeefbd1fb411fca13d6de5dbbc17806d271affd atom/browser/ui/views/global_menu_bar_x11.cc -changed in both - base 100644 bf9801a1457740da391c75621214b8d91cb7467d atom/browser/ui/views/menu_bar.cc - our 100644 e838d3cc217b5ffdb77226beff0d7217539f23f9 atom/browser/ui/views/menu_bar.cc - their 100644 d963c121bbd29bf3f67b488666297c86b4fee225 atom/browser/ui/views/menu_bar.cc -@@ -18,11 +18,17 @@ - - namespace { - -+<<<<<<< .our -+======= -+const char kViewClassName[] = "ElectronMenuBar"; -+ -+>>>>>>> .their - // Default color of the menu bar. - const SkColor kDefaultColor = SkColorSetARGB(255, 233, 233, 233); - - } // namespace - -+<<<<<<< .our - const char MenuBar::kViewClassName[] = "ElectronMenuBar"; - - MenuBar::MenuBar(views::View* window) -@@ -32,12 +38,35 @@ - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); - window_->GetFocusManager()->AddFocusChangeListener(this); -+======= -+MenuBar::MenuBar(NativeWindow* window) -+ : background_color_(kDefaultColor), menu_model_(NULL), window_(window) { -+ RefreshColorCache(); -+ UpdateViewColors(); -+ SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal)); -+>>>>>>> .their - } - - MenuBar::~MenuBar() { - window_->GetFocusManager()->RemoveFocusChangeListener(this); - } - -+<<<<<<< .our -+======= -+void MenuBar::AddedToWidget() { -+ auto fm = GetFocusManager(); -+ fm->AddFocusChangeListener(this); -+ // Note that we don't own fm -- this manages the _connection_ -+ focus_manager_.reset(fm, [this](views::FocusManager* fm) { -+ fm->RemoveFocusChangeListener(this); -+ }); -+} -+ -+void MenuBar::RemovedFromWidget() { -+ focus_manager_.reset(); -+} -+ -+>>>>>>> .their - void MenuBar::SetMenu(AtomMenuModel* model) { - menu_model_ = model; - RebuildChildren(); -@@ -61,7 +90,11 @@ - } - - void MenuBar::ActivateAccelerator(base::char16 key) { -+<<<<<<< .our - auto* child = FindAccelChild(key); -+======= -+ auto child = FindAccelChild(key); -+>>>>>>> .their - if (child) - static_cast<SubmenuButton*>(child)->Activate(nullptr); - } -@@ -151,7 +184,11 @@ - void MenuBar::RebuildChildren() { - RemoveAllChildViews(true); - for (int i = 0, n = GetItemCount(); i < n; ++i) { -+<<<<<<< .our - auto* button = -+======= -+ auto button = -+>>>>>>> .their - new SubmenuButton(menu_model_->GetLabelAt(i), this, background_color_); - button->set_tag(i); - AddChildView(button); -@@ -169,7 +206,11 @@ - #if defined(USE_X11) - const auto& textColor = has_focus_ ? enabled_color_ : disabled_color_; - for (auto* child : GetChildrenInZOrder()) { -+<<<<<<< .our - auto* button = static_cast<SubmenuButton*>(child); -+======= -+ auto button = static_cast<SubmenuButton*>(child); -+>>>>>>> .their - button->SetTextColor(views::Button::STATE_NORMAL, textColor); - button->SetTextColor(views::Button::STATE_DISABLED, disabled_color_); - button->SetTextColor(views::Button::STATE_PRESSED, enabled_color_); -@@ -178,7 +219,11 @@ - } - #elif defined(OS_WIN) - for (auto* child : GetChildrenInZOrder()) { -+<<<<<<< .our - auto* button = static_cast<SubmenuButton*>(child); -+======= -+ auto button = static_cast<SubmenuButton*>(child); -+>>>>>>> .their - button->SetUnderlineColor(color_utils::GetSysSkColor(COLOR_MENUTEXT)); - } - #endif -changed in both - base 100644 761e31b98ea75f44bcd016da3b34b7615f3b409f atom/browser/ui/views/menu_bar.h - our 100644 2b10ba3e3bf2ccfc0453fdb59ad022ef7da8ed5b atom/browser/ui/views/menu_bar.h - their 100644 13cfa32f3988881e3aa87cae6cae65656fa68d70 atom/browser/ui/views/menu_bar.h -@@ -5,6 +5,12 @@ - #ifndef ATOM_BROWSER_UI_VIEWS_MENU_BAR_H_ - #define ATOM_BROWSER_UI_VIEWS_MENU_BAR_H_ - -+<<<<<<< .our -+======= -+#include <memory> -+ -+#include "atom/browser/native_window.h" -+>>>>>>> .their - #include "atom/browser/ui/atom_menu_model.h" - #include "ui/views/controls/button/menu_button_listener.h" - #include "ui/views/focus/focus_manager.h" -@@ -49,7 +55,9 @@ - - protected: - // views::View: -+ void AddedToWidget() override; - const char* GetClassName() const override; -+ void RemovedFromWidget() override; - - // views::MenuButtonListener: - void OnMenuButtonClicked(views::MenuButton* source, -@@ -79,6 +87,11 @@ - - bool has_focus_ = true; - -+ View* FindAccelChild(base::char16 key); -+ -+ std::shared_ptr<views::FocusManager> focus_manager_; -+ bool has_focus_ = true; -+ - DISALLOW_COPY_AND_ASSIGN(MenuBar); - }; - -changed in both - base 100644 3c3cff3c65410f2e61bdade6e457a096ffba3a54 atom/browser/ui/views/submenu_button.cc - our 100644 1124d3d01471876fefa2757570ba3cff796a991c atom/browser/ui/views/submenu_button.cc - their 100644 baee28f2cd6931611e048ec46c83e602b95b4b59 atom/browser/ui/views/submenu_button.cc -@@ -82,8 +82,12 @@ - - bool SubmenuButton::GetUnderlinePosition(const base::string16& text, - base::char16* accelerator, -+<<<<<<< .our - int* start, - int* end) const { -+======= -+ int* start, int* end) const { -+>>>>>>> .their - int pos, span; - base::string16 trimmed = gfx::RemoveAcceleratorChar(text, '&', &pos, &span); - if (pos > -1 && span != 0) { -@@ -96,9 +100,14 @@ - return false; - } - -+<<<<<<< .our - void SubmenuButton::GetCharacterPosition(const base::string16& text, - int index, - int* pos) const { -+======= -+void SubmenuButton::GetCharacterPosition( -+ const base::string16& text, int index, int* pos) const { -+>>>>>>> .their - int height = 0; - gfx::Canvas::SizeStringInt(text.substr(0, index), gfx::FontList(), pos, - &height, 0, 0); -changed in both - base 100644 5c05481cbbfb85b5d77511cb91cc19cc8ef0e626 atom/browser/ui/views/submenu_button.h - our 100644 d8b7785da131271e88533879d090badfd6e49dd5 atom/browser/ui/views/submenu_button.h - their 100644 0f7eddf4c914790675f0c9bfab696b2a96b91f74 atom/browser/ui/views/submenu_button.h -@@ -33,11 +33,17 @@ - private: - bool GetUnderlinePosition(const base::string16& text, - base::char16* accelerator, -+<<<<<<< .our - int* start, - int* end) const; - void GetCharacterPosition(const base::string16& text, - int index, - int* pos) const; -+======= -+ int* start, int* end) const; -+ void GetCharacterPosition( -+ const base::string16& text, int index, int* pos) const; -+>>>>>>> .their - - base::char16 accelerator_ = 0; - -changed in both - base 100644 84a6d9aa3e50ced33616fb4b78e124f39461cd0e atom/browser/ui/win/atom_desktop_window_tree_host_win.cc - our 100644 97857d6515aa5617cf8c1972690a1dcdfd645ac1 atom/browser/ui/win/atom_desktop_window_tree_host_win.cc - their 100644 3da0241a27a9d272c09db30db068939c1bc66d19 atom/browser/ui/win/atom_desktop_window_tree_host_win.cc -changed in both - base 100644 47e4cb6aed2a962bfdd2a92edaca74b452d15c4d atom/browser/ui/win/atom_desktop_window_tree_host_win.h - our 100644 30af3cc162b4429cb3335c6864b801eac1d5f963 atom/browser/ui/win/atom_desktop_window_tree_host_win.h - their 100644 b0164f2ab6ca9580d11ae1aaff68d9caae314d54 atom/browser/ui/win/atom_desktop_window_tree_host_win.h -@@ -25,10 +25,15 @@ - ~AtomDesktopWindowTreeHostWin() override; - - protected: -+<<<<<<< .our - bool PreHandleMSG(UINT message, - WPARAM w_param, - LPARAM l_param, - LRESULT* result) override; -+======= -+ bool PreHandleMSG( -+ UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) override; -+>>>>>>> .their - bool HasNativeFrame() const override; - - private: -changed in both - base 100644 2cbf07be86a812f07105846dc8caf8226a8595df atom/browser/web_contents_preferences.cc - our 100644 c21c93383155091a7481cdd4e741cefad90a4a55 atom/browser/web_contents_preferences.cc - their 100644 98b39fee234cb15ac0da99fd5639c7b8265d71b0 atom/browser/web_contents_preferences.cc -@@ -97,6 +97,7 @@ - instances_.push_back(this); - - // Set WebPreferences defaults onto the JS object -+<<<<<<< .our - SetDefaultBoolIfUndefined(options::kPlugins, false); - SetDefaultBoolIfUndefined(options::kExperimentalFeatures, false); - bool node = SetDefaultBoolIfUndefined(options::kNodeIntegration, true); -@@ -104,12 +105,23 @@ - SetDefaultBoolIfUndefined(options::kWebviewTag, node); - SetDefaultBoolIfUndefined(options::kSandbox, false); - SetDefaultBoolIfUndefined(options::kNativeWindowOpen, false); -+======= -+ SetDefaultBoolIfUndefined("plugins", false); -+ SetDefaultBoolIfUndefined(options::kExperimentalFeatures, false); -+ SetDefaultBoolIfUndefined(options::kExperimentalCanvasFeatures, false); -+ bool node = SetDefaultBoolIfUndefined(options::kNodeIntegration, true); -+ SetDefaultBoolIfUndefined(options::kNodeIntegrationInWorker, false); -+ SetDefaultBoolIfUndefined(options::kWebviewTag, node); -+ SetDefaultBoolIfUndefined("sandbox", false); -+ SetDefaultBoolIfUndefined("nativeWindowOpen", false); -+>>>>>>> .their - SetDefaultBoolIfUndefined(options::kContextIsolation, false); - SetDefaultBoolIfUndefined("javascript", true); - SetDefaultBoolIfUndefined("images", true); - SetDefaultBoolIfUndefined("textAreasAreResizable", true); - SetDefaultBoolIfUndefined("webgl", true); - bool webSecurity = true; -+<<<<<<< .our - SetDefaultBoolIfUndefined(options::kWebSecurity, webSecurity); - // If webSecurity was explicity set to false, let's inherit that into - // insecureContent -@@ -125,6 +137,21 @@ - SetDefaultBoolIfUndefined(options::kOffscreen, false); - - last_preference_ = preference_.Clone(); -+======= -+ SetDefaultBoolIfUndefined("webSecurity", webSecurity); -+ // If webSecurity was explicity set to false, let's inherit that into -+ // insecureContent -+ if (web_preferences.Get("webSecurity", &webSecurity) && !webSecurity) { -+ SetDefaultBoolIfUndefined("allowRunningInsecureContent", true); -+ } else { -+ SetDefaultBoolIfUndefined("allowRunningInsecureContent", false); -+ } -+ #if defined(OS_MACOSX) -+ SetDefaultBoolIfUndefined(options::kScrollBounce, false); -+ #endif -+ SetDefaultBoolIfUndefined("offscreen", false); -+ last_web_preferences_.MergeDictionary(&web_preferences_); -+>>>>>>> .their - } - - WebContentsPreferences::~WebContentsPreferences() { -@@ -154,6 +181,16 @@ - return default_value; - } - -+bool WebContentsPreferences::SetDefaultBoolIfUndefined(const std::string key, -+ bool val) { -+ bool existing; -+ if (!web_preferences_.GetBoolean(key, &existing)) { -+ web_preferences_.SetBoolean(key, val); -+ return val; -+ } -+ return existing; -+} -+ - void WebContentsPreferences::Merge(const base::DictionaryValue& extend) { - if (preference_.is_dict()) - static_cast<base::DictionaryValue*>(&preference_)->MergeDictionary(&extend); -@@ -212,8 +249,18 @@ - return FromWebContents(web_contents); - } - -+<<<<<<< .our - void WebContentsPreferences::AppendCommandLineSwitches( - base::CommandLine* command_line) { -+======= -+ // We are appending args to a webContents so let's save the current state -+ // of our preferences object so that during the lifetime of the WebContents -+ // we can fetch the options used to initally configure the WebContents -+ self->last_web_preferences_.Clear(); -+ self->last_web_preferences_.MergeDictionary(&web_preferences); -+ -+ bool b; -+>>>>>>> .their - // Check if plugins are enabled. - if (IsEnabled(options::kPlugins)) - command_line->AppendSwitch(switches::kEnablePlugins); -changed in both - base 100644 94dd8dc598bef5cc35383d69d20ade8d644a7ef5 atom/browser/web_contents_preferences.h - our 100644 d835347afcd259f473f95271a2c19e42afcc6f2b atom/browser/web_contents_preferences.h - their 100644 28ee9a85485e26b33b8a7852a4a212b4c11b71a0 atom/browser/web_contents_preferences.h -@@ -59,25 +59,45 @@ - bool GetPreloadPath(base::FilePath::StringType* path) const; - - // Returns the web preferences. -+<<<<<<< .our - base::Value* preference() { return &preference_; } - base::Value* last_preference() { return &last_preference_; } -+======= -+ base::DictionaryValue* web_preferences() { return &web_preferences_; } -+ base::DictionaryValue* last_web_preferences() { -+ return &last_web_preferences_; -+ } -+>>>>>>> .their - - private: - friend class content::WebContentsUserData<WebContentsPreferences>; - friend class AtomBrowserClient; - -+<<<<<<< .our - // Get WebContents according to process ID. - static content::WebContents* GetWebContentsFromProcessID(int process_id); - - // Set preference value to given bool if user did not provide value - bool SetDefaultBoolIfUndefined(const base::StringPiece& key, bool val); -+======= -+ // Set preference value to given bool if user did not provide value -+ bool SetDefaultBoolIfUndefined(const std::string key, bool val); -+ -+ // Get preferences value as integer possibly coercing it from a string -+ bool GetInteger(const std::string& attributeName, int* intValue); -+>>>>>>> .their - - static std::vector<WebContentsPreferences*> instances_; - - content::WebContents* web_contents_; -+<<<<<<< .our - - base::Value preference_ = base::Value(base::Value::Type::DICTIONARY); - base::Value last_preference_ = base::Value(base::Value::Type::DICTIONARY); -+======= -+ base::DictionaryValue web_preferences_; -+ base::DictionaryValue last_web_preferences_; -+>>>>>>> .their - - DISALLOW_COPY_AND_ASSIGN(WebContentsPreferences); - }; -changed in both - base 100644 1dd479883d872dc6d76ef069782aad6dc4f731da atom/browser/web_dialog_helper.cc - our 100644 74c8573d13f15bcaa189abdc40fa0cd8e48f89be atom/browser/web_dialog_helper.cc - their 100644 c76b48a74b3629b9b8588983cb4563aada6d28b9 atom/browser/web_dialog_helper.cc -changed in both - base 100644 ad8c1d49bbc049b89eb4c69224b42fb51906c726 atom/common/api/api_messages.h - our 100644 6131a7a473c68e31790fcd8697c8f380c65ad275 atom/common/api/api_messages.h - their 100644 46e6142260d67b6408060ccaf328ee1f74335fe4 atom/common/api/api_messages.h -@@ -59,6 +59,7 @@ - - // Sent by renderer to set the temporary zoom level. - IPC_SYNC_MESSAGE_ROUTED1_1(AtomFrameHostMsg_SetTemporaryZoomLevel, -+<<<<<<< .our - double /* zoom level */, - double /* result */) - -@@ -69,3 +70,10 @@ - IPC_MESSAGE_ROUTED2(AtomFrameHostMsg_PDFSaveURLAs, - GURL /* url */, - content::Referrer /* referrer */) -+======= -+ double /* zoom level */, -+ double /* result */) -+ -+// Sent by renderer to get the zoom level. -+IPC_SYNC_MESSAGE_ROUTED0_1(AtomFrameHostMsg_GetZoomLevel, double /* result */) -+>>>>>>> .their -changed in both - base 100644 a01ca8f84d917f6402a2e8d0aa153c6f7be9a3c5 atom/common/api/atom_api_v8_util.cc - our 100644 3d80db0c0a4cdbb4c7a78fa7e4266fc6fc87193f atom/common/api/atom_api_v8_util.cc - their 100644 b579d6f7d66c9d28006029ac78a6837007dbb217 atom/common/api/atom_api_v8_util.cc -changed in both - base 100644 d1a185d51f394b1828d66cbcf2a1d1cc278de23d atom/common/api/remote_callback_freer.cc - our 100644 eba828591353dae53d1b7cdaa60fee52166d7473 atom/common/api/remote_callback_freer.cc - their 100644 099e2160cc0d28322a60e4a9891a22b29ab841f9 atom/common/api/remote_callback_freer.cc -@@ -29,7 +29,12 @@ - : ObjectLifeMonitor(isolate, target), - content::WebContentsObserver(web_contents), - context_id_(context_id), -+<<<<<<< .our - object_id_(object_id) {} -+======= -+ object_id_(object_id) { -+} -+>>>>>>> .their - - RemoteCallbackFreer::~RemoteCallbackFreer() {} - -@@ -39,7 +44,11 @@ - base::ListValue args; - args.AppendString(context_id_); - args.AppendInteger(object_id_); -+<<<<<<< .our - auto* frame_host = web_contents()->GetMainFrame(); -+======= -+ auto frame_host = web_contents()->GetMainFrame(); -+>>>>>>> .their - if (frame_host) { - frame_host->Send(new AtomFrameMsg_Message(frame_host->GetRoutingID(), false, - channel, args)); -changed in both - base 100644 315127822d1709802abf317c4d8cf49ec7e2bfaa atom/common/api/remote_object_freer.cc - our 100644 8afe8b9a32bc4ba4d5cdfc66ecf7036b8553cb48 atom/common/api/remote_object_freer.cc - their 100644 6e9778994ff21fb3c6be3dd27dbf7cbe2c4c94d6 atom/common/api/remote_object_freer.cc -changed in both - base 100644 5fa39680ca814675d344665b3b2a6ce5d94e625f atom/common/atom_version.h - our 100644 65e7d19911559a40b1b258319df5fe0fa180354f atom/common/atom_version.h - their 100644 8827e576b1a71b91a6003714fd15039e03ff814e atom/common/atom_version.h -@@ -5,10 +5,17 @@ - #ifndef ATOM_COMMON_ATOM_VERSION_H_ - #define ATOM_COMMON_ATOM_VERSION_H_ - -+<<<<<<< .our - #define ATOM_MAJOR_VERSION 4 - #define ATOM_MINOR_VERSION 0 - #define ATOM_PATCH_VERSION 0 - #define ATOM_PRE_RELEASE_VERSION -nightly.20180821 -+======= -+#define ATOM_MAJOR_VERSION 2 -+#define ATOM_MINOR_VERSION 1 -+#define ATOM_PATCH_VERSION 0 -+#define ATOM_PRE_RELEASE_VERSION -unsupported.20180809 -+>>>>>>> .their - - #ifndef ATOM_STRINGIFY - #define ATOM_STRINGIFY(n) ATOM_STRINGIFY_HELPER(n) -changed in both - base 100644 a7908ef30c6bafc4aca1da9a870f7ae12703fe04 atom/common/crash_reporter/crash_reporter_win.cc - our 100644 c574da71c9de9bd8c7b7cad57d3a0f84708fb97c atom/common/crash_reporter/crash_reporter_win.cc - their 100644 49f90b7e6665727b697a243414544bae304fde6e atom/common/crash_reporter/crash_reporter_win.cc -changed in both - base 100644 cff228ba49068a8a683257e9ac50778437a56c45 atom/common/linux/application_info.cc - our 100644 3354c73b8b60f77cf054f975ea713d96b7e7683e atom/common/linux/application_info.cc - their 100644 05bd7f6fc15015a4f570e36801aea622a8f0cb3a atom/common/linux/application_info.cc -@@ -19,7 +19,11 @@ - namespace { - - GDesktopAppInfo* get_desktop_app_info() { -+<<<<<<< .our - GDesktopAppInfo* ret = nullptr; -+======= -+ GDesktopAppInfo * ret = nullptr; -+>>>>>>> .their - - std::string desktop_id; - if (brightray::platform_util::GetDesktopName(&desktop_id)) -changed in both - base 100644 eed6e7bc092f84bd1bde673c27f5fe5363c7783c atom/common/options_switches.cc - our 100644 8b1836f80c583e4db68971ff1b00ca4f86356b45 atom/common/options_switches.cc - their 100644 c1cd185443c0fdbadeb7ba2e174d2048ab2d45d7 atom/common/options_switches.cc -@@ -188,6 +188,9 @@ - // The application path - const char kAppPath[] = "app-path"; - -+// The context ID for this process -+const char kContextId[] = "context-id"; -+ - // The command line switch versions of the options. - const char kBackgroundColor[] = "background-color"; - const char kPreloadScript[] = "preload"; -changed in both - base 100644 525301971c8a05c45e12aada7d0534b84307aebf atom/common/options_switches.h - our 100644 5f6d7e9d38120668ed06922ced2f8d6a6e27a52b atom/common/options_switches.h - their 100644 9d65bc376925906063c24a9a254b2c31c7e22c34 atom/common/options_switches.h -@@ -92,6 +92,7 @@ - extern const char kSecureSchemes[]; - extern const char kAppUserModelId[]; - extern const char kAppPath[]; -+extern const char kContextId[]; - - extern const char kBackgroundColor[]; - extern const char kPreloadScript[]; -changed in both - base 100644 7bee1411ba1c2fbac516ff8b65bcbd89f6132819 atom/renderer/api/atom_api_renderer_ipc.cc - our 100644 3e48a4f7d0c11f40e6360b0acc2c83c38e671319 atom/renderer/api/atom_api_renderer_ipc.cc - their 100644 ad6a12b90d525e9c6a49fac7a5d122b8c2c295f9 atom/renderer/api/atom_api_renderer_ipc.cc -@@ -12,8 +12,13 @@ - #include "native_mate/dictionary.h" - #include "third_party/WebKit/public/web/WebLocalFrame.h" - -+<<<<<<< .our - using blink::WebLocalFrame; - using content::RenderFrame; -+======= -+using content::RenderFrame; -+using blink::WebLocalFrame; -+>>>>>>> .their - - namespace atom { - -@@ -48,10 +53,17 @@ - - RenderFrame* render_frame = GetCurrentRenderFrame(); - if (render_frame == nullptr) -+<<<<<<< .our - return result; - - IPC::SyncMessage* message = new AtomFrameHostMsg_Message_Sync( - render_frame->GetRoutingID(), channel, arguments, &result); -+======= -+ return json; -+ -+ IPC::SyncMessage* message = new AtomFrameHostMsg_Message_Sync( -+ render_frame->GetRoutingID(), channel, arguments, &json); -+>>>>>>> .their - bool success = render_frame->Send(message); - - if (!success) -changed in both - base 100644 d0164f44a0a523b26a919e02b5b7add25a0e7224 atom/renderer/api/atom_api_web_frame.cc - our 100644 f0f7ef249d73876f7107d3d3865e8fc71ee33945 atom/renderer/api/atom_api_web_frame.cc - their 100644 c36d1a06491994f126333c98796f6ff64cfc6506 atom/renderer/api/atom_api_web_frame.cc -changed in both - base 100644 1971a26c1c5d4f5c5f5f029e6334f157a16b5394 atom/renderer/atom_render_frame_observer.cc - our 100644 ea2355fd968339600ae8093524f1c3dcfd2f4ff3 atom/renderer/atom_render_frame_observer.cc - their 100644 4ddf9186b723091ef91d69cfaedc4fbdd1ac09fa atom/renderer/atom_render_frame_observer.cc -@@ -7,6 +7,8 @@ - #include <string> - #include <vector> - -+#include "atom/common/native_mate_converters/string16_converter.h" -+ - #include "atom/common/api/api_messages.h" - #include "atom/common/api/event_emitter_caller.h" - #include "atom/common/native_mate_converters/value_converter.h" -@@ -72,7 +74,12 @@ - RendererClientBase* renderer_client) - : content::RenderFrameObserver(frame), - render_frame_(frame), -+<<<<<<< .our - renderer_client_(renderer_client) { -+======= -+ renderer_client_(renderer_client), -+ document_created_(false) { -+>>>>>>> .their - // Initialise resource for directory listing. - net::NetModule::SetResourceProvider(NetResourceProvider); - } -@@ -195,8 +202,13 @@ - } - - void AtomRenderFrameObserver::EmitIPCEvent(blink::WebLocalFrame* frame, -+<<<<<<< .our - const base::string16& channel, - const base::ListValue& args) { -+======= -+ const base::string16& channel, -+ const base::ListValue& args) { -+>>>>>>> .their - if (!frame) - return; - -changed in both - base 100644 248d5a68096dedea0f6ffb3c9df38ff3373e7c18 atom/renderer/atom_render_frame_observer.h - our 100644 e774741c019956a3bff00db2f6d2b133bf1be6de atom/renderer/atom_render_frame_observer.h - their 100644 d4f3d0c7d5c454bb65a190f59b26501137dd04e0 atom/renderer/atom_render_frame_observer.h -@@ -56,7 +56,11 @@ - - content::RenderFrame* render_frame_; - RendererClientBase* renderer_client_; -+<<<<<<< .our - bool document_created_ = false; -+======= -+ bool document_created_; -+>>>>>>> .their - - DISALLOW_COPY_AND_ASSIGN(AtomRenderFrameObserver); - }; -changed in both - base 100644 4d3e7cba7a65330a45a5f2aebba90c257b206e35 atom/renderer/atom_render_view_observer.h - our 100644 097616e12369662473c12645a93e27cffcb55e3b atom/renderer/atom_render_view_observer.h - their 100644 ca9fb01288e3bd4788c7718f0feb8b37307383e6 atom/renderer/atom_render_view_observer.h -@@ -14,7 +14,11 @@ - explicit AtomRenderViewObserver(content::RenderView* render_view); - - protected: -+<<<<<<< .our - ~AtomRenderViewObserver() override; -+======= -+ virtual ~AtomRenderViewObserver(); -+>>>>>>> .their - - private: - // content::RenderViewObserver implementation. -changed in both - base 100644 82ba9d024350009ae86bc5406513c8086073990a atom/renderer/atom_renderer_client.cc - our 100644 204f17c2cf0d2d4ec4a71bdbecfcd1cbdc5fc8be atom/renderer/atom_renderer_client.cc - their 100644 9241410d7516bcfecc945e2659e02c178ddad2a7 atom/renderer/atom_renderer_client.cc -@@ -77,8 +77,12 @@ - } - - void AtomRendererClient::DidCreateScriptContext( -+<<<<<<< .our - v8::Handle<v8::Context> context, - content::RenderFrame* render_frame) { -+======= -+ v8::Handle<v8::Context> context, content::RenderFrame* render_frame) { -+>>>>>>> .their - RendererClientBase::DidCreateScriptContext(context, render_frame); - - // Only allow node integration for the main frame, unless it is a devtools -changed in both - base 100644 07d20bda8b00b1acdb823546f5e606154278cd4e atom/renderer/atom_sandboxed_renderer_client.cc - our 100644 6e29fe45a69f44856d7fca449ec1be4eaf6970a2 atom/renderer/atom_sandboxed_renderer_client.cc - their 100644 f3642244f7847fc3f16144a40d2560478c276fa9 atom/renderer/atom_sandboxed_renderer_client.cc -@@ -12,11 +12,16 @@ - #include "atom/common/options_switches.h" - #include "atom/renderer/api/atom_api_renderer_ipc.h" - #include "atom/renderer/atom_render_frame_observer.h" -+<<<<<<< .our - #include "base/base_paths.h" - #include "base/command_line.h" - #include "base/files/file_path.h" - #include "base/path_service.h" - #include "base/process/process_handle.h" -+======= -+#include "base/command_line.h" -+#include "base/files/file_path.h" -+>>>>>>> .their - #include "chrome/renderer/printing/print_web_view_helper.h" - #include "content/public/renderer/render_frame.h" - #include "native_mate/dictionary.h" -@@ -34,8 +39,13 @@ - const std::string kModuleCacheKey = "native-module-cache"; - - bool IsDevTools(content::RenderFrame* render_frame) { -+<<<<<<< .our - return render_frame->GetWebFrame()->GetDocument().Url().ProtocolIs( - "chrome-devtools"); -+======= -+ return render_frame->GetWebFrame()->GetDocument().Url() -+ .ProtocolIs("chrome-devtools"); -+>>>>>>> .their - } - - v8::Local<v8::Object> GetModuleCache(v8::Isolate* isolate) { -@@ -102,12 +112,19 @@ - AtomSandboxedRenderFrameObserver(content::RenderFrame* render_frame, - AtomSandboxedRendererClient* renderer_client) - : AtomRenderFrameObserver(render_frame, renderer_client), -+<<<<<<< .our - renderer_client_(renderer_client) {} -+======= -+ v8_converter_(new atom::V8ValueConverter), -+ renderer_client_(renderer_client) { -+ v8_converter_->SetDisableNode(true); -+ } -+>>>>>>> .their - - protected: - void EmitIPCEvent(blink::WebLocalFrame* frame, - const base::string16& channel, -- const base::ListValue& args) override { -+ const base::ListValue& args) { - if (!frame) - return; - -@@ -176,6 +193,7 @@ - } - - void AtomSandboxedRendererClient::DidCreateScriptContext( -+<<<<<<< .our - v8::Handle<v8::Context> context, - content::RenderFrame* render_frame) { - RendererClientBase::DidCreateScriptContext(context, render_frame); -@@ -184,6 +202,19 @@ - // For devtools we still want to run the preload_bundle script - if (!render_frame->IsMainFrame() && !IsDevTools(render_frame)) - return; -+======= -+ v8::Handle<v8::Context> context, content::RenderFrame* render_frame) { -+ RendererClientBase::DidCreateScriptContext(context, render_frame); -+ -+ // Only allow preload for the main frame or -+ // For devtools we still want to run the preload_bundle script -+ if (!render_frame->IsMainFrame() && !IsDevTools(render_frame)) -+ return; -+ -+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); -+ base::FilePath preload_script_path = command_line->GetSwitchValuePath( -+ switches::kPreloadScript); -+>>>>>>> .their - - auto* isolate = context->GetIsolate(); - v8::HandleScope handle_scope(isolate); -@@ -203,7 +234,14 @@ - auto binding = v8::Object::New(isolate); - InitializeBindings(binding, context); - AddRenderBindings(isolate, binding); -+<<<<<<< .our - v8::Local<v8::Value> args[] = {binding}; -+======= -+ v8::Local<v8::Value> args[] = { -+ binding, -+ mate::ConvertToV8(isolate, preload_script_path.value()) -+ }; -+>>>>>>> .their - // Execute the function with proper arguments - ignore_result( - func->Call(context, v8::Null(isolate), node::arraysize(args), args)); -changed in both - base 100644 89af0932d10a598f87dd28ec4b32ae3b2e0eadca atom/renderer/renderer_client_base.cc - our 100644 69490420ef5b8f87e7cb8fd97ebd5ec4509fa1ae atom/renderer/renderer_client_base.cc - their 100644 dbb39a363cd31b6de64f52b5854225d35bcc5a54 atom/renderer/renderer_client_base.cc -@@ -16,6 +16,10 @@ - #include "atom/renderer/content_settings_observer.h" - #include "atom/renderer/preferences_manager.h" - #include "base/command_line.h" -+<<<<<<< .our -+======= -+#include "base/memory/ptr_util.h" -+>>>>>>> .their - #include "base/process/process_handle.h" - #include "base/strings/string_split.h" - #include "base/strings/stringprintf.h" -@@ -42,6 +46,7 @@ - #include <shlobj.h> - #endif - -+<<<<<<< .our - #if defined(ENABLE_PDF_VIEWER) - #include "atom/common/atom_constants.h" - #endif // defined(ENABLE_PDF_VIEWER) -@@ -50,6 +55,8 @@ - #include "chrome/renderer/pepper/pepper_helper.h" - #endif // defined(ENABLE_PEPPER_FLASH) - -+======= -+>>>>>>> .their - // This is defined in later versions of Chromium, remove this if you see - // compiler complaining duplicate defines. - #if defined(OS_WIN) || defined(OS_FUCHSIA) -@@ -105,6 +112,19 @@ - context->Global()->SetPrivate(context, private_key, value); - } - -+void RendererClientBase::DidCreateScriptContext( -+ v8::Handle<v8::Context> context, -+ content::RenderFrame* render_frame) { -+ // global.setHidden("contextId", `${processId}-${++nextContextId}`) -+ std::string context_id = base::StringPrintf( -+ "%" CrPRIdPid "-%d", base::GetCurrentProcId(), ++next_context_id_); -+ v8::Isolate* isolate = context->GetIsolate(); -+ v8::Local<v8::String> key = mate::StringToSymbol(isolate, "contextId"); -+ v8::Local<v8::Private> private_key = v8::Private::ForApi(isolate, key); -+ v8::Local<v8::Value> value = mate::ConvertToV8(isolate, context_id); -+ context->Global()->SetPrivate(context, private_key, value); -+} -+ - void RendererClientBase::AddRenderBindings( - v8::Isolate* isolate, - v8::Local<v8::Object> binding_object) { -@@ -161,7 +181,10 @@ - - void RendererClientBase::RenderFrameCreated( - content::RenderFrame* render_frame) { -+<<<<<<< .our - #if defined(TOOLKIT_VIEWS) -+======= -+>>>>>>> .their - new AutofillAgent(render_frame); - #endif - #if defined(ENABLE_PEPPER_FLASH) -changed in both - base 100644 ba302e6a34498cb59cfa8cbf8636044691ee904c atom/renderer/renderer_client_base.h - our 100644 f04be0a0fb555fce88aa006c6c6623cc8730d4ed atom/renderer/renderer_client_base.h - their 100644 70db197294b7d2491d9c1eaf008ac8b36796f418 atom/renderer/renderer_client_base.h -@@ -20,10 +20,17 @@ - RendererClientBase(); - ~RendererClientBase() override; - -+<<<<<<< .our - virtual void DidCreateScriptContext(v8::Handle<v8::Context> context, - content::RenderFrame* render_frame); - virtual void WillReleaseScriptContext(v8::Handle<v8::Context> context, - content::RenderFrame* render_frame) = 0; -+======= -+ virtual void DidCreateScriptContext( -+ v8::Handle<v8::Context> context, content::RenderFrame* render_frame); -+ virtual void WillReleaseScriptContext( -+ v8::Handle<v8::Context> context, content::RenderFrame* render_frame) = 0; -+>>>>>>> .their - virtual void DidClearWindowObject(content::RenderFrame* render_frame); - virtual void SetupMainWorldOverrides(v8::Handle<v8::Context> context) = 0; - -changed in both - base 100644 653aca2b86182a17d5a1a53aeda6d441bfd3652a atom/utility/atom_content_utility_client.cc - our 100644 e2a856d53ae243de988c43b0a3335b9391e54b4e atom/utility/atom_content_utility_client.cc - their 100644 91168f7fc2da98546864d12f03d1e0f75a7ca64f atom/utility/atom_content_utility_client.cc -@@ -4,12 +4,29 @@ - - #include "atom/utility/atom_content_utility_client.h" - -+#include "content/public/common/service_manager_connection.h" -+#include "content/public/common/simple_connection_filter.h" -+#include "content/public/utility/utility_thread.h" -+#include "mojo/public/cpp/bindings/strong_binding.h" -+#include "net/proxy/mojo_proxy_resolver_factory_impl.h" -+#include "services/service_manager/public/cpp/binder_registry.h" -+ - #if defined(OS_WIN) - #include "chrome/utility/printing_handler_win.h" - #endif - - namespace atom { - -+namespace { -+ -+void CreateProxyResolverFactory( -+ net::interfaces::ProxyResolverFactoryRequest request) { -+ mojo::MakeStrongBinding(base::MakeUnique<net::MojoProxyResolverFactoryImpl>(), -+ std::move(request)); -+} -+ -+} // namespace -+ - AtomContentUtilityClient::AtomContentUtilityClient() { - #if defined(OS_WIN) - handlers_.push_back(std::make_unique<printing::PrintingHandlerWin>()); -@@ -18,7 +35,29 @@ - - AtomContentUtilityClient::~AtomContentUtilityClient() {} - -+<<<<<<< .our - bool AtomContentUtilityClient::OnMessageReceived(const IPC::Message& message) { -+======= -+void AtomContentUtilityClient::UtilityThreadStarted() { -+ content::ServiceManagerConnection* connection = -+ content::ChildThread::Get()->GetServiceManagerConnection(); -+ -+ // NOTE: Some utility process instances are not connected to the Service -+ // Manager. Nothing left to do in that case. -+ if (!connection) -+ return; -+ -+ auto registry = base::MakeUnique<service_manager::BinderRegistry>(); -+ registry->AddInterface<net::interfaces::ProxyResolverFactory>( -+ base::Bind(CreateProxyResolverFactory), -+ base::ThreadTaskRunnerHandle::Get()); -+ connection->AddConnectionFilter( -+ base::MakeUnique<content::SimpleConnectionFilter>(std::move(registry))); -+} -+ -+bool AtomContentUtilityClient::OnMessageReceived( -+ const IPC::Message& message) { -+>>>>>>> .their - #if defined(OS_WIN) - for (const auto& handler : handlers_) { - if (handler->OnMessageReceived(message)) -merged - result 100644 75359a2456129dd0caeb03a37eebf7bbfb9a2e21 atom/utility/atom_content_utility_client.h - our 100644 7694970457b745a84ecab24a2f0ec8eaefa8a1ad atom/utility/atom_content_utility_client.h -@@ -20,6 +20,7 @@ - AtomContentUtilityClient(); - ~AtomContentUtilityClient() override; - -+ void UtilityThreadStarted() override; - bool OnMessageReceived(const IPC::Message& message) override; - - private: -changed in both - base 100644 065fe818a64586b6f786cdaa163c40b8a3aacabe brightray/brightray.gyp - our 100644 f233257e88bad8f0ff703034bea02e4715a5b5b9 brightray/brightray.gyp - their 100644 03d48ccef48fccb58bd39f9604e73b872f825d76 brightray/brightray.gyp -@@ -127,6 +127,8 @@ - '<(libchromiumcontent_dir)/libviz_service.a', - # services/device/wake_lock/power_save_blocker/ - '<(libchromiumcontent_dir)/libpower_save_blocker.a', -+ # net/proxy/mojo_* -+ '<(libchromiumcontent_dir)/libnet_proxy_service.a', - # Friends of libpdf.a: - # On Linux we have to use "--whole-archive" to include - # all symbols, otherwise there will be plenty of -@@ -178,6 +180,7 @@ - ], - }, - }], -+<<<<<<< .our - # Due to strange linker behavior, component build of arm needs to - # be linked with libjpeg.a explicitly. - ['target_arch=="arm" and libchromiumcontent_component==1', { -@@ -187,6 +190,8 @@ - ], - }, - }], -+======= -+>>>>>>> .their - ], - }], # OS=="linux" - ['OS=="mac"', { -@@ -221,6 +226,8 @@ - '<(libchromiumcontent_dir)/libviz_service.a', - # services/device/wake_lock/power_save_blocker/ - '<(libchromiumcontent_dir)/libpower_save_blocker.a', -+ # net/proxy/mojo_* -+ '<(libchromiumcontent_dir)/libnet_proxy_service.a', - # Friends of libpdf.a: - '<(libchromiumcontent_dir)/libpdf.a', - '<(libchromiumcontent_dir)/libppapi_cpp_objects.a', -@@ -288,6 +295,20 @@ - ], - }, - }], -+ # In the OSX 10.10 SDK, CoreBluetooth became a top level framework. -+ # Previously, it was nested in IOBluetooth. In order for Chrome to run on -+ # OSes older than OSX 10.10, the top level CoreBluetooth framework must be -+ # weakly linked. -+ ['mac_sdk=="10.10" and libchromiumcontent_component==0', { -+ 'direct_dependent_settings': { -+ 'xcode_settings': { -+ 'OTHER_LDFLAGS': [ -+ '-weak_framework', -+ 'CoreBluetooth', -+ ], -+ }, -+ }, -+ }], - ] - }], # OS=="mac" - ['OS=="win"', { -@@ -359,6 +380,8 @@ - '<(libchromiumcontent_dir)/viz_service.lib', - # services/device/wake_lock/power_save_blocker/ - '<(libchromiumcontent_dir)/power_save_blocker.lib', -+ # net/proxy/mojo_* -+ '<(libchromiumcontent_dir)/net_proxy_service.lib', - # Friends of pdf.lib: - '<(libchromiumcontent_dir)/pdf.lib', - '<(libchromiumcontent_dir)/ppapi_cpp_objects.lib', -changed in both - base 100644 d7a4c672926c03dcf4c1a4df1a9e5fa09b19d272 brightray/browser/browser_context.cc - our 100644 1eff7344e9aef78bb88720c38c0f75fb92e6bc09 brightray/browser/browser_context.cc - their 100644 241398ce96efbe0e4f2203acd86f224c910443e2 brightray/browser/browser_context.cc -@@ -89,6 +89,7 @@ - } - - void BrowserContext::InitPrefs() { -+ base::ThreadRestrictions::ScopedAllowIO allow_io; - auto prefs_path = GetPath().Append(FILE_PATH_LITERAL("Preferences")); - base::ThreadRestrictions::ScopedAllowIO allow_io; - PrefServiceFactory prefs_factory; -changed in both - base 100644 642734aa4db9fd3c8025986bb987d79102b27dd5 brightray/browser/browser_main_parts.cc - our 100644 78d0ef15ef1343e7db123f97182bac7f9a98b3eb brightray/browser/browser_main_parts.cc - their 100644 c79ce69b4b3566b21e5411f2a477b52bcf5ce899 brightray/browser/browser_main_parts.cc -@@ -183,18 +183,29 @@ - auto* cmd_line = base::CommandLine::ForCurrentProcess(); - const auto enable_features = - cmd_line->GetSwitchValueASCII(switches::kEnableFeatures); -+<<<<<<< .our - auto disable_features = - cmd_line->GetSwitchValueASCII(switches::kDisableFeatures); - auto feature_list = std::make_unique<base::FeatureList>(); -+======= -+ const auto disable_features = -+ cmd_line->GetSwitchValueASCII(switches::kDisableFeatures); -+ -+ std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); -+>>>>>>> .their - feature_list->InitializeFromCommandLine(enable_features, disable_features); - base::FeatureList::SetInstance(std::move(feature_list)); - } - -+<<<<<<< .our - bool BrowserMainParts::ShouldContentCreateFeatureList() { - return false; - } - - int BrowserMainParts::PreEarlyInitialization() { -+======= -+void BrowserMainParts::PreEarlyInitialization() { -+>>>>>>> .their - InitializeFeatureList(); - OverrideAppLogsPath(); - #if defined(USE_X11) -changed in both - base 100644 f69682ce51610a754dcaa4f9751c7a22b9a359b2 brightray/browser/browser_main_parts.h - our 100644 cf8e0296585b17f1e7dab1717e0aa80293d902dd brightray/browser/browser_main_parts.h - their 100644 df8234995d6ed3258d94bf0ebf88112629629f07 brightray/browser/browser_main_parts.h -changed in both - base 100644 143a5fdea3eb6ad7709fa8383298029a24c1b407 brightray/browser/linux/libnotify_notification.cc - our 100644 0725ffded989d3c6bce753a210e464deca346ad1 brightray/browser/linux/libnotify_notification.cc - their 100644 7f9fb35e434f7cc85cf4145661e754ff4a0d84fc brightray/browser/linux/libnotify_notification.cc -added in remote - their 100644 def1fc7f25e6fa60aa4a548d4ddbe9c2f5633289 brightray/browser/net/chrome_mojo_proxy_resolver_factory.cc -@@ -0,0 +1,117 @@ -+// Copyright 2015 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "brightray/browser/net/chrome_mojo_proxy_resolver_factory.h" -+ -+#include <utility> -+ -+#include "base/logging.h" -+#include "base/memory/ptr_util.h" -+#include "base/memory/singleton.h" -+#include "base/single_thread_task_runner.h" -+#include "base/strings/utf_string_conversions.h" -+#include "base/threading/thread_task_runner_handle.h" -+#include "content/public/browser/browser_thread.h" -+#include "content/public/browser/utility_process_host.h" -+#include "content/public/browser/utility_process_host_client.h" -+#include "services/service_manager/public/cpp/interface_provider.h" -+ -+namespace { -+const int kUtilityProcessIdleTimeoutSeconds = 5; -+} -+ -+// static -+ChromeMojoProxyResolverFactory* ChromeMojoProxyResolverFactory::GetInstance() { -+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO); -+ return base::Singleton< -+ ChromeMojoProxyResolverFactory, -+ base::LeakySingletonTraits<ChromeMojoProxyResolverFactory>>::get(); -+} -+ -+ChromeMojoProxyResolverFactory::ChromeMojoProxyResolverFactory() { -+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO); -+} -+ -+ChromeMojoProxyResolverFactory::~ChromeMojoProxyResolverFactory() { -+ DCHECK(thread_checker_.CalledOnValidThread()); -+} -+ -+std::unique_ptr<base::ScopedClosureRunner> -+ChromeMojoProxyResolverFactory::CreateResolver( -+ const std::string& pac_script, -+ mojo::InterfaceRequest<net::interfaces::ProxyResolver> req, -+ net::interfaces::ProxyResolverFactoryRequestClientPtr client) { -+ DCHECK(thread_checker_.CalledOnValidThread()); -+ if (!resolver_factory_) -+ CreateFactory(); -+ -+ if (!resolver_factory_) { -+ // If factory creation failed, close |req|'s message pipe, which should -+ // cause a connection error. -+ req = nullptr; -+ return nullptr; -+ } -+ idle_timer_.Stop(); -+ num_proxy_resolvers_++; -+ resolver_factory_->CreateResolver(pac_script, std::move(req), -+ std::move(client)); -+ return base::MakeUnique<base::ScopedClosureRunner>( -+ base::Bind(&ChromeMojoProxyResolverFactory::OnResolverDestroyed, -+ base::Unretained(this))); -+} -+ -+void ChromeMojoProxyResolverFactory::CreateFactory() { -+ DCHECK(thread_checker_.CalledOnValidThread()); -+ DCHECK(!resolver_factory_); -+ DCHECK(!weak_utility_process_host_); -+ -+ DVLOG(1) << "Attempting to create utility process for proxy resolver"; -+ content::UtilityProcessHost* utility_process_host = -+ content::UtilityProcessHost::Create( -+ scoped_refptr<content::UtilityProcessHostClient>(), -+ base::ThreadTaskRunnerHandle::Get()); -+ utility_process_host->SetName(base::ASCIIToUTF16("Electron Proxy Resolver")); -+ bool process_started = utility_process_host->Start(); -+ if (process_started) { -+ BindInterface(utility_process_host, &resolver_factory_); -+ weak_utility_process_host_ = utility_process_host->AsWeakPtr(); -+ } else { -+ LOG(ERROR) << "Unable to connect to utility process"; -+ return; -+ } -+ -+ resolver_factory_.set_connection_error_handler(base::Bind( -+ &ChromeMojoProxyResolverFactory::DestroyFactory, base::Unretained(this))); -+} -+ -+void ChromeMojoProxyResolverFactory::DestroyFactory() { -+ resolver_factory_.reset(); -+ delete weak_utility_process_host_.get(); -+ weak_utility_process_host_.reset(); -+} -+ -+void ChromeMojoProxyResolverFactory::OnResolverDestroyed() { -+ DCHECK(thread_checker_.CalledOnValidThread()); -+ DCHECK_GT(num_proxy_resolvers_, 0u); -+ if (--num_proxy_resolvers_ == 0) { -+ // When all proxy resolvers have been destroyed, the proxy resolver factory -+ // is no longer needed. However, new proxy resolvers may be created -+ // shortly after being destroyed (e.g. due to a network change). -+ // -+ // On desktop, where a utility process is used, if the utility process is -+ // shut down immediately, this would cause unnecessary process churn, so -+ // wait for an idle timeout before shutting down the proxy resolver utility -+ // process. -+ idle_timer_.Start( -+ FROM_HERE, -+ base::TimeDelta::FromSeconds(kUtilityProcessIdleTimeoutSeconds), this, -+ &ChromeMojoProxyResolverFactory::OnIdleTimeout); -+ } -+} -+ -+void ChromeMojoProxyResolverFactory::OnIdleTimeout() { -+ DCHECK(thread_checker_.CalledOnValidThread()); -+ DCHECK_EQ(num_proxy_resolvers_, 0u); -+ DestroyFactory(); -+} -added in remote - their 100644 47e51efebf3285c981ab71ba344d27bcd89c52e6 brightray/browser/net/chrome_mojo_proxy_resolver_factory.h -@@ -0,0 +1,73 @@ -+// Copyright 2015 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef BRIGHTRAY_BROWSER_NET_CHROME_MOJO_PROXY_RESOLVER_FACTORY_H_ -+#define BRIGHTRAY_BROWSER_NET_CHROME_MOJO_PROXY_RESOLVER_FACTORY_H_ -+ -+#include <stddef.h> -+#include <string> -+ -+#include "base/macros.h" -+#include "base/memory/weak_ptr.h" -+#include "base/threading/thread_checker.h" -+#include "base/timer/timer.h" -+#include "net/proxy/mojo_proxy_resolver_factory.h" -+ -+namespace content { -+class UtilityProcessHost; -+} -+ -+namespace base { -+template <typename Type> -+struct DefaultSingletonTraits; -+} // namespace base -+ -+// A factory used to create connections to Mojo proxy resolver services. On -+// Android, the proxy resolvers will run in the browser process, and on other -+// platforms, they'll all be run in the same utility process. Utility process -+// crashes are detected and the utility process is automatically restarted. -+class ChromeMojoProxyResolverFactory : public net::MojoProxyResolverFactory { -+ public: -+ static ChromeMojoProxyResolverFactory* GetInstance(); -+ -+ // Overridden from net::MojoProxyResolverFactory: -+ std::unique_ptr<base::ScopedClosureRunner> CreateResolver( -+ const std::string& pac_script, -+ mojo::InterfaceRequest<net::interfaces::ProxyResolver> req, -+ net::interfaces::ProxyResolverFactoryRequestClientPtr client) override; -+ -+ private: -+ friend struct base::DefaultSingletonTraits<ChromeMojoProxyResolverFactory>; -+ ChromeMojoProxyResolverFactory(); -+ ~ChromeMojoProxyResolverFactory() override; -+ -+ // Creates the proxy resolver factory. On desktop, creates a new utility -+ // process before creating it out of process. On Android, creates it on the -+ // current thread. -+ void CreateFactory(); -+ -+ // Destroys |resolver_factory_|. -+ void DestroyFactory(); -+ -+ // Invoked each time a proxy resolver is destroyed. -+ void OnResolverDestroyed(); -+ -+ // Invoked once an idle timeout has elapsed after all proxy resolvers are -+ // destroyed. -+ void OnIdleTimeout(); -+ -+ net::interfaces::ProxyResolverFactoryPtr resolver_factory_; -+ -+ base::WeakPtr<content::UtilityProcessHost> weak_utility_process_host_; -+ -+ size_t num_proxy_resolvers_ = 0; -+ -+ base::OneShotTimer idle_timer_; -+ -+ base::ThreadChecker thread_checker_; -+ -+ DISALLOW_COPY_AND_ASSIGN(ChromeMojoProxyResolverFactory); -+}; -+ -+#endif // BRIGHTRAY_BROWSER_NET_CHROME_MOJO_PROXY_RESOLVER_FACTORY_H_ -changed in both - base 100644 7a798ae98e6c180c5a60e0a32ce6393532e83468 brightray/browser/net_log.cc - our 100644 fb443ea0b72b9659d98d1873fad1a714483bb13f brightray/browser/net_log.cc - their 100644 978667acb61b0330d6bf48bb7e814bbdef50b904 brightray/browser/net_log.cc -@@ -45,11 +45,16 @@ - return; - - base::FilePath log_path = -+<<<<<<< .our - command_line->GetSwitchValuePath(network::switches::kLogNetLog); - if (log_path.empty()) - return; - - std::unique_ptr<base::Value> constants(GetConstants()); // Net constants -+======= -+ command_line->GetSwitchValuePath(switches::kLogNetLog); -+ std::unique_ptr<base::Value> constants(GetConstants()); -+>>>>>>> .their - net::NetLogCaptureMode capture_mode = net::NetLogCaptureMode::Default(); - - file_net_log_observer_ = -changed in both - base 100644 28e988f4b49cd35507e4972c19122bbe604f2690 brightray/browser/url_request_context_getter.cc - our 100644 c07ba80cbc522030af580adc5d8676ed31d592d1 brightray/browser/url_request_context_getter.cc - their 100644 972d8054221e95442456559ada46ba62e6f75b79 brightray/browser/url_request_context_getter.cc -@@ -12,7 +12,13 @@ - #include "base/strings/string_util.h" - #include "base/task_scheduler/post_task.h" - #include "brightray/browser/browser_client.h" -+<<<<<<< .our - #include "brightray/browser/browser_context.h" -+======= -+#include "brightray/browser/net/chrome_mojo_proxy_resolver_factory.h" -+#include "brightray/browser/net/devtools_network_controller_handle.h" -+#include "brightray/browser/net/devtools_network_transaction_factory.h" -+>>>>>>> .their - #include "brightray/browser/net/require_ct_delegate.h" - #include "brightray/browser/net_log.h" - #include "brightray/common/switches.h" -@@ -35,11 +41,20 @@ - #include "net/http/http_auth_preferences.h" - #include "net/http/http_server_properties_impl.h" - #include "net/log/net_log.h" -+<<<<<<< .our - #include "net/proxy_resolution/dhcp_pac_file_fetcher_factory.h" - #include "net/proxy_resolution/pac_file_fetcher_impl.h" - #include "net/proxy_resolution/proxy_config.h" - #include "net/proxy_resolution/proxy_config_service.h" - #include "net/proxy_resolution/proxy_service.h" -+======= -+#include "net/proxy/dhcp_proxy_script_fetcher_factory.h" -+#include "net/proxy/proxy_config.h" -+#include "net/proxy/proxy_config_service.h" -+#include "net/proxy/proxy_script_fetcher_impl.h" -+#include "net/proxy/proxy_service.h" -+#include "net/proxy/proxy_service_mojo.h" -+>>>>>>> .their - #include "net/ssl/channel_id_service.h" - #include "net/ssl/default_channel_id_store.h" - #include "net/ssl/ssl_config_service_defaults.h" -@@ -276,9 +291,18 @@ - storage_->set_proxy_resolution_service( - net::ProxyResolutionService::CreateFixed(proxy_config)); - } else { -+<<<<<<< .our - storage_->set_proxy_resolution_service( - net::ProxyResolutionService::CreateUsingSystemProxyResolver( - std::move(proxy_config_service_), net_log_)); -+======= -+ storage_->set_proxy_service(net::CreateProxyServiceUsingMojoFactory( -+ ChromeMojoProxyResolverFactory::GetInstance(), -+ std::move(proxy_config_service_), -+ new net::ProxyScriptFetcherImpl(url_request_context_.get()), -+ dhcp_factory.Create(url_request_context_.get()), host_resolver.get(), -+ nullptr, url_request_context_->network_delegate())); -+>>>>>>> .their - } - - std::vector<std::string> schemes; -changed in both - base 100644 04033f451e045ee7211f0a7152d46c5010a55b72 brightray/browser/url_request_context_getter.h - our 100644 941a5782b14a941bb25a7a9ef6ca6d73f8bc3ec1 brightray/browser/url_request_context_getter.h - their 100644 1a26704d380ab7d113c4e2b0deb940a2d674f96b brightray/browser/url_request_context_getter.h -@@ -76,11 +76,14 @@ - const override; - - net::URLRequestJobFactory* job_factory() const { return job_factory_; } -+<<<<<<< .our - void set_delegate(Delegate* delegate) { delegate_ = delegate; } - - // Discard reference to URLRequestContext and inform observers to - // shutdown. Must be called only on IO thread. - void NotifyContextShuttingDown(std::unique_ptr<ResourceContext>); -+======= -+>>>>>>> .their - - private: - friend class BrowserContext; -changed in both - base 100644 08b203a23291ba0e2ba254873074178da4921123 brightray/common/application_info_win.cc - our 100644 a0256372bbdbbc1d77cb84885faab42a27f55c9f brightray/common/application_info_win.cc - their 100644 89ea0aceb6784119ad65783cfd1c019e7aedbf57 brightray/common/application_info_win.cc -changed in both - base 100644 6a7d91f135c4b904e6d3172da91e7813793a2fba brightray/filenames.gypi - our 100644 b9e2d96175f8ee2d407db9c49b2e2b74756327de brightray/filenames.gypi - their 100644 e3f2aa5f5bc6f7443df50b88c1ab498d2de0a6f1 brightray/filenames.gypi -@@ -47,6 +47,27 @@ - 'browser/media/media_device_id_salt.h', - 'browser/media/media_stream_devices_controller.cc', - 'browser/media/media_stream_devices_controller.h', -+<<<<<<< .our -+======= -+ 'browser/net/devtools_network_conditions.cc', -+ 'browser/net/devtools_network_conditions.h', -+ 'browser/net/devtools_network_controller.cc', -+ 'browser/net/devtools_network_controller.h', -+ 'browser/net/devtools_network_controller_handle.cc', -+ 'browser/net/devtools_network_controller_handle.h', -+ 'browser/net/devtools_network_interceptor.cc', -+ 'browser/net/devtools_network_interceptor.h', -+ 'browser/net/devtools_network_protocol_handler.cc', -+ 'browser/net/devtools_network_protocol_handler.h', -+ 'browser/net/devtools_network_transaction_factory.cc', -+ 'browser/net/devtools_network_transaction_factory.h', -+ 'browser/net/devtools_network_transaction.cc', -+ 'browser/net/devtools_network_transaction.h', -+ 'browser/net/devtools_network_upload_data_stream.cc', -+ 'browser/net/devtools_network_upload_data_stream.h', -+ 'browser/net/chrome_mojo_proxy_resolver_factory.cc', -+ 'browser/net/chrome_mojo_proxy_resolver_factory.h', -+>>>>>>> .their - 'browser/net/require_ct_delegate.cc', - 'browser/net/require_ct_delegate.h', - 'browser/net_log.cc', -changed in both - base 100644 233e21047718c9bbbc9056f79aecf51657886b92 common.gypi - our 100644 676d1e904127066e4a3d313106f15406fcbed8b6 common.gypi - their 100644 acad39d991479147b9bc2ee2c5a51fbd8693a689 common.gypi -changed in both - base 100644 e0e8b153ae51d917f37ba50967e2ef9e5b74254d docs/README.md - our 100644 f7b956e8feb95ceb64743ad260a1759e5a298afe docs/README.md - their 100644 436188887e5dad0a4ae291e5221e3eb8644bc56e docs/README.md -@@ -16,6 +16,7 @@ - - * [Electron FAQ](faq.md) - -+<<<<<<< .our - ## Guides and Tutorials - - * [Setting up the Development Environment](tutorial/development-environment.md) -@@ -66,6 +67,12 @@ - * [Mac App Store](tutorial/mac-app-store-submission-guide.md) - * [Windows Store](tutorial/windows-store-guide.md) - * [Snapcraft](tutorial/snapcraft.md) -+======= -+## Guides -+ -+* [Glossary of Terms](glossary.md) -+* [Support](tutorial/support.md) -+>>>>>>> .their - * [Security](tutorial/security.md) - * [Reporting Security Issues](tutorial/security.md#reporting-security-issues) - * [Chromium Security Issues and Upgrades](tutorial/security.md#chromium-security-issues-and-upgrades) -changed in both - base 100644 926d1dde8ffc33d99c48cb55bbc2d0f9c2087ad4 docs/api/app.md - our 100644 14dc557e237404cbbd5bcebabb0e65486dc36926 docs/api/app.md - their 100644 40fdf2669442ca48fd1fc9a3b4aede6a199df4f1 docs/api/app.md -changed in both - base 100644 2be2da597664c1913a665ad51de5becc42658d0f docs/api/browser-window.md - our 100644 dff61dd336f047cf2f6f06228b2df2b98ff2304d docs/api/browser-window.md - their 100644 b9664cb4eff53f133822767b9006d596072c9a40 docs/api/browser-window.md -changed in both - base 100644 f9aaaa90ddd7b8887c5ed3fea371bf175e28c2e7 docs/api/in-app-purchase.md - our 100644 6e612a72e27159602400f4efa30d5bc2f3aa668f docs/api/in-app-purchase.md - their 100644 67109dc0f92d8c537c9a2f1fa5fa2ce223137964 docs/api/in-app-purchase.md -changed in both - base 100644 f130d127936331ab8c6cadd4672a7446a77a683a docs/api/tray.md - our 100644 c60f7ba4c9e9b6ad3fc1b2f717983b71bd286842 docs/api/tray.md - their 100644 5fb345538a7f29bb679223af1c4d9d3b099a9bf0 docs/api/tray.md -changed in both - base 100644 6aaa2bdd9b0ade84160b7449396d5ecd510f0e41 docs/api/web-contents.md - our 100644 8990fe2e97ab62eafdd3f7a4eb8ee782415124c5 docs/api/web-contents.md - their 100644 841acb4a506626c334004e28266ebed3845360d3 docs/api/web-contents.md -@@ -1385,6 +1385,26 @@ - - Shows pop-up dictionary that searches the selected word on the page. - -+<<<<<<< .our -+======= -+#### `contents.setSize(options)` -+ -+Set the size of the page. This is only supported for `<webview>` guest contents. -+ -+* `options` Object -+ * `enableAutoSize` Boolean (optional) - true to make the webview container automatically -+ resize within the bounds specified by the attributes normal, min and max. -+ * `normal` [Size](structures/size.md) (optional) - Normal size of the page. This can be used in -+ combination with the [`disableguestresize`](webview-tag.md#disableguestresize) -+ attribute to manually resize the webview guest contents. -+ * `min` [Size](structures/size.md) (optional) - Minimum size of the page. This can be used in -+ combination with the [`disableguestresize`](webview-tag.md#disableguestresize) -+ attribute to manually resize the webview guest contents. -+ * `max` [Size](structures/size.md) (optional) - Maximium size of the page. This can be used in -+ combination with the [`disableguestresize`](webview-tag.md#disableguestresize) -+ attribute to manually resize the webview guest contents. -+ -+>>>>>>> .their - #### `contents.isOffscreen()` - - Returns `Boolean` - Indicates whether *offscreen rendering* is enabled. -changed in both - base 100644 afdff5615421e52b8750ea1de20b63941cbefb1f docs/development/releasing.md - our 100644 85a5fa0a935201521155dc60de45986db5829613 docs/development/releasing.md - their 100644 d27fb5022515cb80a829a80369fb6cb192003522 docs/development/releasing.md -@@ -8,16 +8,25 @@ - information. - - There are a handful of `*_TOKEN` environment variables needed by the release -+<<<<<<< .our - scripts: - - * `ELECTRON_GITHUB_TOKEN`: - Create this by visiting https://github.com/settings/tokens/new?scopes=repo -+======= -+scripts. Once you've generated these per-user tokens, you may want to keep -+them in a local file that you can `source` when starting a release. -+* `ELECTRON_GITHUB_TOKEN`: -+Create as described at https://github.com/settings/tokens/new, -+giving the token repo access scope. -+>>>>>>> .their - * `APPVEYOR_TOKEN`: - Create a token from https://windows-ci.electronjs.org/api-token - If you don't have an account, ask a team member to add you. - * `CIRCLE_TOKEN`: - Create a token from "Personal API Tokens" at https://circleci.com/account/api - * `VSTS_TOKEN`: -+<<<<<<< .our - Create a Personal Access Token at https://github.visualstudio.com/_usersSettings/tokens or https://github.visualstudio.com/_details/security/tokens - with the scope of `Build (read and execute)`. - * `ELECTRON_S3_BUCKET`: -@@ -29,6 +38,10 @@ - of the project. This file is gitignored, and will be loaded into the - environment by the release scripts. - -+======= -+Create a Personal Access Token at https://github.visualstudio.com/_usersSettings/tokens -+with the scope of `Build (read and execute)`. -+>>>>>>> .their - - ## Determine which branch to release from - -@@ -212,10 +225,13 @@ - ```sh - $ npm run release -- --validateRelease - ``` -+<<<<<<< .our - Note, if you need to run `--validateRelease` more than once to check the assets, - run it as above the first time, then `node ./script/release.js --validateRelease` - for subsequent calls so that you don't have to rebuild each time you want to - check the assets. -+======= -+>>>>>>> .their - - ## Publish the release - -@@ -258,6 +274,7 @@ - electron - $ npm run publish-to-npm - ``` -+<<<<<<< .our - - After publishing, you can check the `latest` release: - ```sh -@@ -273,6 +290,8 @@ - ```sh - $ npm dist-tag add electron@2.0.0 latest - ``` -+======= -+>>>>>>> .their - - [the releases page]: https://github.com/electron/electron/releases - [this bump commit]: https://github.com/electron/electron/commit/78ec1b8f89b3886b856377a1756a51617bc33f5a -@@ -303,7 +322,11 @@ - ``` - - Additionally you can pass a job name to the script to run an individual job, eg: -+<<<<<<< .our - ```sh -+======= -+````sh -+>>>>>>> .their - node script/ci-release-build.js --ci=AppVeyor --ghRelease --job=electron-x64 TARGET_BRANCH - ``` - -removed in local - base 100644 7dfc6084f5c94bfb924438e7efa50260d38b9144 docs/tutorial/planned-breaking-changes.md - their 100644 00e01f4f8c3a85f0e535a00c11e22f3595bff4b9 docs/tutorial/planned-breaking-changes.md -added in both - our 100644 bdb3b8678485feabfad2ce23309f5bcac6050f31 docs/tutorial/support.md - their 100644 306876fee9314fbca1779a6c41ff8c6381753bda docs/tutorial/support.md -@@ -91,4 +91,8 @@ - * Fedora 21 - * Debian 8 - -+<<<<<<< .our - [arm-breaking-change]: https://github.com/electron/electron/blob/master/docs/api/breaking-changes.md#duplicate-arm-assets -+======= -+[arm-breaking-change]: https://github.com/electron/electron/blob/master/docs/tutorial/planned-breaking-changes.md#duplicate-arm-assets -+>>>>>>> .their -changed in both - base 100644 53ad35c63321e74a5023197ef2e075584e0f268b electron.gyp - our 100644 944ddab2a3fd879044e31677e4bac2843fffbdee electron.gyp - their 100644 a367ca027fa553f0d56d0f2192e76acbd294ffcc electron.gyp -@@ -4,7 +4,11 @@ - 'product_name%': 'Electron', - 'company_name%': 'GitHub, Inc', - 'company_abbr%': 'github', -+<<<<<<< .our - 'version%': '4.0.0-nightly.20180821', -+======= -+ 'version%': '2.1.0-unsupported.20180809', -+>>>>>>> .their - 'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c', - }, - 'includes': [ -changed in both - base 100644 ef3e8258584a5459b069e2006db44c0a8b66412d filenames.gypi - our 100644 f57860558f06b7e5d8a50f48cfc7e53044df0bc6 filenames.gypi - their 100644 acd43c97988952b9a2760b44d366bd87134a1d65 filenames.gypi -@@ -292,6 +292,8 @@ - 'atom/browser/net/http_protocol_handler.h', - 'atom/browser/net/js_asker.cc', - 'atom/browser/net/js_asker.h', -+ 'atom/browser/net/resolve_proxy_helper.cc', -+ 'atom/browser/net/resolve_proxy_helper.h', - 'atom/browser/net/url_request_about_job.cc', - 'atom/browser/net/url_request_about_job.h', - 'atom/browser/net/url_request_async_asar_job.cc', -changed in both - base 100644 381a2a866372ebe06f374529c634af411c864ba0 lib/browser/api/app.js - our 100644 66f6ae651acf10fb19b8ec068fc5280850dd3d91 lib/browser/api/app.js - their 100644 1ea1daddca84dfeba57b7b7883ebb754b8508d2d lib/browser/api/app.js -changed in both - base 100644 22565dcf9875b7f00acff192b10b05d27d6446a7 lib/browser/api/browser-window.js - our 100644 cb523496d65c7018c30054621cfdeb1281f9db6a lib/browser/api/browser-window.js - their 100644 c5faa0a2c131d633e7aea3a1850abab958d22a1d lib/browser/api/browser-window.js -changed in both - base 100644 da5ff57a113f7a063d1409ff56003db4bd04e68a lib/browser/api/menu.js - our 100644 506e3525c10ce142cafe3fc1bf4de1c255e48503 lib/browser/api/menu.js - their 100644 a87e0cd0436da2899b6402a06d370e755c2aac47 lib/browser/api/menu.js -@@ -47,7 +47,11 @@ - this.delegate = delegate - } - -+<<<<<<< .our - Menu.prototype.popup = function (options = {}) { -+======= -+Menu.prototype.popup = function (options) { -+>>>>>>> .their - if (options == null || typeof options !== 'object') { - throw new TypeError('Options must be an object') - } -@@ -156,7 +160,11 @@ - - Menu.buildFromTemplate = function (template) { - if (!Array.isArray(template)) { -+<<<<<<< .our - throw new TypeError('Invalid template for Menu: Menu template must be an array') -+======= -+ throw new TypeError('Invalid template for Menu') -+>>>>>>> .their - } - const menu = new Menu() - if (!areValidTemplateItems(template)) { -merged - result 100644 bbbc1bbe1727dd30352c4836cea489145cd7ad7d lib/browser/api/screen.js - our 100644 8287bfa8bfdc6db322a05059fd5c8ba58e802db9 lib/browser/api/screen.js -@@ -1,8 +1,17 @@ - const {EventEmitter} = require('events') -+const {deprecate} = require('electron') - const {screen, Screen} = process.atomBinding('screen') - - // Screen is an EventEmitter. - Object.setPrototypeOf(Screen.prototype, EventEmitter.prototype) - EventEmitter.call(screen) - -+const nativeFn = screen.getMenuBarHeight -+screen.getMenuBarHeight = function () { -+ if (!process.noDeprecations) { -+ deprecate.warn('screen.getMenuBarHeight', 'screen.getPrimaryDisplay().workArea') -+ } -+ return nativeFn.call(this) -+} -+ - module.exports = screen -changed in both - base 100644 0338b776f8938c1548ea9786385fe75db9db3403 lib/browser/guest-view-manager.js - our 100644 1e4029e39a981c85fb6ff18c5ccd52f81b3c56f2 lib/browser/guest-view-manager.js - their 100644 169a4ac1d175e9bbbf8a3d8a01612e079c9df635 lib/browser/guest-view-manager.js -@@ -316,6 +316,17 @@ - - ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST_SYNC', function (event, params) { - event.returnValue = createGuest(event.sender, params) -+<<<<<<< .our -+======= -+}) -+ -+ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', function (event, elementInstanceId, guestInstanceId, params) { -+ attachGuest(event, elementInstanceId, guestInstanceId, params) -+}) -+ -+ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_DESTROY_GUEST', function (event, guestInstanceId) { -+ destroyGuest(event.sender, guestInstanceId) -+>>>>>>> .their - }) - - ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', function (event, embedderFrameId, elementInstanceId, guestInstanceId, params) { -changed in both - base 100644 50e890e225a315718d04a0028fb6bf2feb4092ce lib/browser/guest-window-manager.js - our 100644 7253c1942b0956ae6b9b0c80a23470fc26669b8a lib/browser/guest-window-manager.js - their 100644 339b543dd485d3d708aa98a2eec834ab4d65da2b lib/browser/guest-window-manager.js -@@ -65,7 +65,11 @@ - // Inherit certain option values from parent window - const webPreferences = embedder.getLastWebPreferences() - for (const [name, value] of inheritedWebPreferences) { -+<<<<<<< .our - if (webPreferences[name] === value) { -+======= -+ if (embedder.getLastWebPreferences()[name] === value) { -+>>>>>>> .their - options.webPreferences[name] = value - } - } -changed in both - base 100644 24a86fdfee7b87cd8ad177363aec26b438fe79b7 lib/browser/init.js - our 100644 bed3d912ab8be3ca4f21de04e801bb42dc12a528 lib/browser/init.js - their 100644 344bcf16dceafc99dcc337a0d9113c8e764c6364 lib/browser/init.js -changed in both - base 100644 bfb9091e6584c43a19bf6283a79027274053239b lib/browser/objects-registry.js - our 100644 f03a23d2f6910d6555bb9469180d1b60b94bc313 lib/browser/objects-registry.js - their 100644 c6afe2616153dfd82b190b02f1c4fce582727a76 lib/browser/objects-registry.js -@@ -15,7 +15,11 @@ - this.storage = {} - - // Stores the IDs of objects referenced by WebContents. -+<<<<<<< .our - // (ownerKey) => [id] -+======= -+ // (webContentsContextId) => [id] -+>>>>>>> .their - this.owners = {} - } - -@@ -26,10 +30,17 @@ - const id = this.saveToStorage(obj) - - // Add object to the set of referenced objects. -+<<<<<<< .our - const ownerKey = getOwnerKey(webContents, contextId) - let owner = this.owners[ownerKey] - if (!owner) { - owner = this.owners[ownerKey] = new Set() -+======= -+ const webContentsContextId = `${webContents.id}-${contextId}` -+ let owner = this.owners[webContentsContextId] -+ if (!owner) { -+ owner = this.owners[webContentsContextId] = new Set() -+>>>>>>> .their - this.registerDeleteListener(webContents, contextId) - } - if (!owner.has(id)) { -@@ -50,8 +61,13 @@ - // Note that an object may be double-freed (cleared when page is reloaded, and - // then garbage collected in old page). - remove (webContents, contextId, id) { -+<<<<<<< .our - const ownerKey = getOwnerKey(webContents, contextId) - let owner = this.owners[ownerKey] -+======= -+ const webContentsContextId = `${webContents.id}-${contextId}` -+ let owner = this.owners[webContentsContextId] -+>>>>>>> .their - if (owner) { - // Remove the reference in owner. - owner.delete(id) -@@ -62,13 +78,22 @@ - - // Clear all references to objects refrenced by the WebContents. - clear (webContents, contextId) { -+<<<<<<< .our - const ownerKey = getOwnerKey(webContents, contextId) - let owner = this.owners[ownerKey] -+======= -+ const webContentsContextId = `${webContents.id}-${contextId}` -+ let owner = this.owners[webContentsContextId] -+>>>>>>> .their - if (!owner) return - - for (let id of owner) this.dereference(id) - -+<<<<<<< .our - delete this.owners[ownerKey] -+======= -+ delete this.owners[webContentsContextId] -+>>>>>>> .their - } - - // Private: Saves the object into storage and assigns an ID for it. -@@ -101,7 +126,11 @@ - } - } - -+<<<<<<< .our - // Private: Clear the storage when renderer process is destroyed. -+======= -+ // Private: Clear the storage when renderer process is destoryed. -+>>>>>>> .their - registerDeleteListener (webContents, contextId) { - const processId = webContents.getProcessId() - const listener = (event, deletedProcessId) => { -changed in both - base 100644 c0cd09dea4273642aa780756985e9c90dbe164d3 lib/browser/rpc-server.js - our 100644 ff9f77321de3a4145946b67f3fe2a597f98e2510 lib/browser/rpc-server.js - their 100644 612ec274ca13cdb7167a41fbacb711c3cc6cb9c3 lib/browser/rpc-server.js -@@ -84,7 +84,11 @@ - - // Fill the meta object according to value's type. - if (meta.type === 'array') { -+<<<<<<< .our - meta.members = value.map((el) => valueToMeta(sender, contextId, el, optimizeSimpleObject)) -+======= -+ meta.members = value.map((el) => valueToMeta(sender, contextId, el)) -+>>>>>>> .their - } else if (meta.type === 'object' || meta.type === 'function') { - meta.name = value.constructor ? value.constructor.name : '' - -@@ -210,9 +214,15 @@ - return rendererFunctions.get(objectId) - } - -+<<<<<<< .our - const processId = sender.getProcessId() - let callIntoRenderer = function (...args) { - if (!sender.isDestroyed() && processId === sender.getProcessId()) { -+======= -+ const webContentsId = sender.getId() -+ let callIntoRenderer = function (...args) { -+ if (!sender.isDestroyed() && webContentsId === sender.getId()) { -+>>>>>>> .their - sender.send('ELECTRON_RENDERER_CALLBACK', contextId, meta.id, valueToMeta(sender, contextId, args)) - } else { - removeRemoteListenersAndLogWarning(this, meta, callIntoRenderer) -@@ -234,8 +244,14 @@ - // Call a function and send reply asynchronously if it's a an asynchronous - // style function and the caller didn't pass a callback. - const callFunction = function (event, contextId, func, caller, args) { -+<<<<<<< .our - const funcMarkedAsync = v8Util.getHiddenValue(func, 'asynchronous') - const funcPassedCallback = typeof args[args.length - 1] === 'function' -+======= -+ let funcMarkedAsync, funcName, funcPassedCallback, ref, ret -+ funcMarkedAsync = v8Util.getHiddenValue(func, 'asynchronous') -+ funcPassedCallback = typeof args[args.length - 1] === 'function' -+>>>>>>> .their - try { - if (funcMarkedAsync && !funcPassedCallback) { - args.push(function (ret) { -@@ -243,7 +259,11 @@ - }) - func.apply(caller, args) - } else { -+<<<<<<< .our - const ret = func.apply(caller, args) -+======= -+ ret = func.apply(caller, args) -+>>>>>>> .their - event.returnValue = valueToMeta(event.sender, contextId, ret, true) - } - } catch (error) { -@@ -302,7 +322,14 @@ - throwRPCError(`Cannot call constructor on missing remote object ${id}`) - } - -+<<<<<<< .our - event.returnValue = valueToMeta(event.sender, contextId, new constructor(...args)) -+======= -+ // Call new with array of arguments. -+ // http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible -+ let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args)))() -+ event.returnValue = valueToMeta(event.sender, contextId, obj) -+>>>>>>> .their - } catch (error) { - event.returnValue = exceptionToMeta(event.sender, contextId, error) - } -@@ -332,7 +359,14 @@ - throwRPCError(`Cannot call constructor '${method}' on missing remote object ${id}`) - } - -+<<<<<<< .our - event.returnValue = valueToMeta(event.sender, contextId, new object[method](...args)) -+======= -+ // Call new with array of arguments. -+ let constructor = object[method] -+ let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args)))() -+ event.returnValue = valueToMeta(event.sender, contextId, obj) -+>>>>>>> .their - } catch (error) { - event.returnValue = exceptionToMeta(event.sender, contextId, error) - } -changed in both - base 100644 6dc774049def3acbd13b79dfd559c12d4eebd657 lib/common/api/crash-reporter.js - our 100644 1090d425e4c5cdf89a03d470718324ef16963472 lib/common/api/crash-reporter.js - their 100644 1b20fa52aab741e5dd34de7872f36798ec7c1c68 lib/common/api/crash-reporter.js -changed in both - base 100644 1b9a993a2e67a00c073a9df9883c7adc3c2fcf65 lib/common/asar.js - our 100644 41c3d0c85c69954dddad53c674f84051f25372e4 lib/common/asar.js - their 100644 f47c6757d48c967db3ed00ab3474ea05ce034371 lib/common/asar.js -changed in both - base 100644 a4f8072ed57642e1ca7d1066e132875da7ad3f46 lib/renderer/api/remote.js - our 100644 59117f8f2dd977fc1817a6b1d540b616ddcb0dae lib/renderer/api/remote.js - their 100644 4a38befb03cbdb560a3b34d8dd771d3d19c0bc3b lib/renderer/api/remote.js -changed in both - base 100644 1cb69436dd479baf54b9805c04c0c31b20f24fad lib/renderer/init.js - our 100644 2470a5e8be80e770b0c03f6a439a71e72ae12a1b lib/renderer/init.js - their 100644 93129849ae048c1c09f943b56e78562f46be04e8 lib/renderer/init.js -changed in both - base 100644 d2da884f1d9caf3d633de25837cb2128f564f2fb lib/renderer/security-warnings.js - our 100644 b24f9e28b879154457be0342b9d4b44c0e651253 lib/renderer/security-warnings.js - their 100644 4f7d6ef9e596cdc3a5c7e1f2b89b24b9cd67de1d lib/renderer/security-warnings.js -changed in both - base 100644 110b0e453afd07210c9fba0f93d8755b5fbc1a93 lib/renderer/web-view/guest-view-internal.js - our 100644 6e42c769b70e5223fe97397f87144ec342882f8d lib/renderer/web-view/guest-view-internal.js - their 100644 f7c6232d41a52ff4c2af71350d4ae43c05a3b12a lib/renderer/web-view/guest-view-internal.js -@@ -90,6 +90,16 @@ - }, - createGuestSync: function (params) { - return ipcRenderer.sendSync('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST_SYNC', params) -+<<<<<<< .our -+======= -+ }, -+ attachGuest: function (elementInstanceId, guestInstanceId, params) { -+ ipcRenderer.send('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', elementInstanceId, guestInstanceId, params) -+ webFrame.attachGuest(elementInstanceId) -+ }, -+ destroyGuest: function (guestInstanceId) { -+ ipcRenderer.send('ELECTRON_GUEST_VIEW_MANAGER_DESTROY_GUEST', guestInstanceId) -+>>>>>>> .their - }, - attachGuest: function (elementInstanceId, guestInstanceId, params, contentWindow) { - const embedderFrameId = webFrame.getWebFrameId(contentWindow) -changed in both - base 100644 16bfe7e61ac6e2c516f4523f2854a4f1db169c70 lib/renderer/web-view/web-view-attributes.js - our 100644 ad9970bd0b9355ac8163c82f6fa7f3ca08a05de6 lib/renderer/web-view/web-view-attributes.js - their 100644 204046bd60542657e9213f2b12e5c126ee10ea33 lib/renderer/web-view/web-view-attributes.js -changed in both - base 100644 544652e44756fc63747a5cf58548b87363508b4a lib/renderer/web-view/web-view.js - our 100644 574a2b545597f9d1c05ec9b7147585063e90ae89 lib/renderer/web-view/web-view.js - their 100644 a703230fd4a461d3fb548663ef7b495a133377b6 lib/renderer/web-view/web-view.js -@@ -144,7 +144,10 @@ - } - - createGuestSync () { -+<<<<<<< .our - this.beforeFirstNavigation = false -+======= -+>>>>>>> .their - this.attachGuestInstance(guestViewInternal.createGuestSync(this.buildParams())) - } - -changed in both - base 100644 119391e79462bfa8bb1494039bcb3522d97acead lib/sandboxed_renderer/init.js - our 100644 30a3fa55216f6bf7588c3accc07b150a31163b7c lib/sandboxed_renderer/init.js - their 100644 b45a105091446f1b1c3afd2f4905ccf7c0ef67b5 lib/sandboxed_renderer/init.js -@@ -35,10 +35,13 @@ - ['url', require('url')] - ]) - -+<<<<<<< .our - const { - preloadSrc, preloadError, process: processProps - } = electron.ipcRenderer.sendSync('ELECTRON_BROWSER_SANDBOX_LOAD') - -+======= -+>>>>>>> .their - require('../renderer/web-frame-init')() - - // Pass different process object to the preload script(which should not have -@@ -78,6 +81,7 @@ - require('../renderer/inspector') - } - -+<<<<<<< .our - if (binding.guestInstanceId) { - process.guestInstanceId = parseInt(binding.guestInstanceId) - } -@@ -88,6 +92,8 @@ - require('../renderer/web-view/web-view-attributes') - } - -+======= -+>>>>>>> .their - // Wrap the script into a function executed in global scope. It won't have - // access to the current scope, so we'll expose a few objects as arguments: - // -@@ -107,6 +113,7 @@ - // and any `require('electron')` calls in `preload.js` will work as expected - // since browserify won't try to include `electron` in the bundle, falling back - // to the `preloadRequire` function above. -+<<<<<<< .our - if (preloadSrc) { - const preloadWrapperSrc = `(function(require, process, Buffer, global, setImmediate, clearImmediate) { - ${preloadSrc} -@@ -118,4 +125,18 @@ - preloadFn(preloadRequire, preloadProcess, Buffer, global, setImmediate, clearImmediate) - } else if (preloadError) { - console.error(preloadError.stack) -+======= -+if (preloadPath) { -+ const preloadSrc = fs.readFileSync(preloadPath).toString() -+ const preloadWrapperSrc = `(function(require, process, Buffer, global, setImmediate) { -+ ${preloadSrc} -+ })` -+ -+ // eval in window scope: -+ // http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.2 -+ const geval = eval -+ const preloadFn = geval(preloadWrapperSrc) -+ const {setImmediate} = require('timers') -+ preloadFn(preloadRequire, preloadProcess, Buffer, global, setImmediate) -+>>>>>>> .their - } -changed in both - base 100644 9d3b0da9c80b223e4a1188311a1121796eb9f7ae package.json - our 100644 c081cd89450cd50efba1ec280ff1349a96ea3ce0 package.json - their 100644 c276f9b9a0bb61257eeaaadd9757ee2ac5a8f8f5 package.json -@@ -1,6 +1,10 @@ - { - "name": "electron", -+<<<<<<< .our - "version": "4.0.0-nightly.20180821", -+======= -+ "version": "2.1.0-unsupported.20180809", -+>>>>>>> .their - "repository": "https://github.com/electron/electron", - "description": "Build cross platform desktop apps with JavaScript, HTML, and CSS", - "devDependencies": { -@@ -13,7 +17,11 @@ - "dugite": "^1.45.0", - "electabul": "~0.0.4", - "electron-docs-linter": "^2.3.4", -+<<<<<<< .our - "electron-typescript-definitions": "^1.3.6", -+======= -+ "electron-typescript-definitions": "1.3.2", -+>>>>>>> .their - "github": "^9.2.0", - "html-entities": "^1.2.1", - "husky": "^0.14.3", -@@ -25,8 +33,12 @@ - "remark-cli": "^4.0.0", - "remark-preset-lint-markdown-style-guide": "^2.1.1", - "request": "^2.68.0", -+<<<<<<< .our - "semver": "^5.5.0", - "serve": "^6.5.8", -+======= -+ "serve": "^6.5.3", -+>>>>>>> .their - "standard": "^10.0.0", - "standard-markdown": "^4.0.0", - "sumchecker": "^2.0.2", -changed in both - base 100755 4465b85c135ddb55a673c5180e15f05f09dac57e script/bootstrap.py - our 100755 e4aaf89e216b0164f15882a3040e8cac70bf1fd9 script/bootstrap.py - their 100755 c6ebe4ef6975efd1f6184159cc3d9d079bf3628d script/bootstrap.py -changed in both - base 100755 c97cd8336f7d7980911d0bdea93137e7bc95ba24 script/build.py - our 100755 fb2b95d3bb71a25ce1ca58acf596afdc0f2cc5bd script/build.py - their 100755 2a2231394207c28fcd2b86d3d9f9b079b08d637e script/build.py -@@ -40,6 +40,12 @@ - if is_verbose_mode(): - ninja.append('-v') - -+<<<<<<< .our -+======= -+ args = parse_args() -+ if args.ninja_path: -+ ninja = args.ninja_path -+>>>>>>> .their - if args.libcc: - if ('D' not in args.configuration - or not os.path.exists(GCLIENT_DONE) -@@ -93,12 +99,15 @@ - parser.add_argument('--ninja-path', - help='Path of ninja command to use.', - required=False) -+<<<<<<< .our - parser.add_argument('--compdb', - help=( - 'Generate JSON compilation database. This will not ' - 'trigger actual build. ' - ), - action='store_true', default=False) -+======= -+>>>>>>> .their - return parser.parse_args() - - -changed in both - base 100755 28424aaa8ee614b0dfffc7468adb2266f05440cb script/bump-version.py - our 100755 564adb2116312b0f6d0351096bd89cb373cd3bab script/bump-version.py - their 100755 9e32709db12a5e831bf8d2a969a2885508a1b37f script/bump-version.py -@@ -84,12 +84,41 @@ - parser.print_help() - return 1 - -+<<<<<<< .our - versions = clean_parse_version(version) - suffix = '' - if '-' in version: - suffix = '-' + version.split('-')[1] - versions[3] = parse_version(version)[3] - version = version.split('-')[0] -+======= -+ increments = ['major', 'minor', 'patch', 'beta'] -+ -+ curr_version = get_electron_version() -+ versions = parse_version(re.sub('-beta', '', curr_version)) -+ -+ if args.bump in increments: -+ versions = increase_version(versions, increments.index(args.bump)) -+ if versions[3] == '0': -+ # beta starts at 1 -+ versions = increase_version(versions, increments.index('beta')) -+ -+ if args.stable == True: -+ versions[3] = '0' -+ -+ if args.new_version != None: -+ clean_version = re.sub('-beta', '', args.new_version) -+ clean_version = re.sub('-unsupported', '', clean_version) -+ versions = parse_version(clean_version) -+ -+ version = '.'.join(versions[:3]) -+ suffix = '' -+ -+ if args.new_version != None and '-unsupported' in args.new_version: -+ suffix = '-unsupported.' + versions[3] -+ elif versions[3] != '0': -+ suffix = '-beta.' + versions[3] -+>>>>>>> .their - - if args.dry_run: - print 'new version number would be: {0}\n'.format(version + suffix) -changed in both - base 100644 ec2459198bf254e7e380e4ae63097168041d0068 script/ci-release-build.js - our 100644 be9f9597387f5f8b7bfddc61c202f32ce4c6d478 script/ci-release-build.js - their 100644 1a15cd55b266363bea4394e970d274b2caa2d716 script/ci-release-build.js -@@ -51,6 +51,10 @@ - } - - async function circleCIcall (buildUrl, targetBranch, job, options) { -+<<<<<<< .our -+======= -+ assert(process.env.CIRCLE_TOKEN, 'CIRCLE_TOKEN not found in environment') -+>>>>>>> .their - console.log(`Triggering CircleCI to run build job: ${job} on branch: ${targetBranch} with release flag.`) - let buildRequest = { - 'build_parameters': { -@@ -80,6 +84,7 @@ - console.log('Error calling CircleCI:', err) - }) - console.log(`CircleCI release build request for ${job} successful. Check ${circleResponse.build_url} for status.`) -+<<<<<<< .our - } - - function buildAppVeyor (targetBranch, options) { -@@ -92,6 +97,21 @@ - } - } - -+======= -+} -+ -+function buildAppVeyor (targetBranch, options) { -+ assert(process.env.APPVEYOR_TOKEN, 'APPVEYOR_TOKEN not found in environment') -+ const validJobs = Object.keys(appVeyorJobs) -+ if (options.job) { -+ assert(validJobs.includes(options.job), `Unknown AppVeyor CI job name: ${options.job}. Valid values are: ${validJobs}.`) -+ callAppVeyor(targetBranch, options.job, options) -+ } else { -+ validJobs.forEach((job) => callAppVeyor(targetBranch, job, options)) -+ } -+} -+ -+>>>>>>> .their - async function callAppVeyor (targetBranch, job, options) { - console.log(`Triggering AppVeyor to run build job: ${job} on branch: ${targetBranch} with release flag.`) - let environmentVariables = {} -@@ -144,6 +164,10 @@ - assert(vstsJobs.includes(options.job), `Unknown VSTS CI job name: ${options.job}. Valid values are: ${vstsJobs}.`) - } - console.log(`Triggering VSTS to run build on branch: ${targetBranch} with release flag.`) -+<<<<<<< .our -+======= -+ assert(process.env.VSTS_TOKEN, 'VSTS_TOKEN not found in environment') -+>>>>>>> .their - let environmentVariables = {} - - if (!options.ghRelease) { -changed in both - base 100755 de3b9ffd48156379afd677b98c40c97532cb8367 script/create-dist.py - our 100755 4a6c0c7ce8f275175e48c4c380ff33627f7a5961 script/create-dist.py - their 100755 e8396a2e6d242b9deba3b6a7642060584cd1a605 script/create-dist.py -@@ -147,7 +147,11 @@ - - # Copy file and keep the executable bit. - shutil.copyfile(src, dest) -+<<<<<<< .our - add_exec_bit(dest) -+======= -+ os.chmod(dest, os.stat(dest).st_mode | stat.S_IEXEC) -+>>>>>>> .their - - def copy_vcruntime_binaries(): - arch = get_target_arch() -@@ -302,7 +306,11 @@ - dest = os.path.join(DIST_DIR, binary) - # Copy file and keep the executable bit. - shutil.copyfile(src, dest) -+<<<<<<< .our - add_exec_bit(dest) -+======= -+ os.chmod(dest, os.stat(dest).st_mode | stat.S_IEXEC) -+>>>>>>> .their - - dist_name = get_zip_name(binary, version) - zip_file = os.path.join(SOURCE_ROOT, 'dist', dist_name) -added in both - our 100644 d8cfb2be8af17bc5536e521848c64b14b155015a script/find-release.js - their 100644 3cfd79aae1427c3b432076a869e6cf689d79871f script/find-release.js -@@ -1,5 +1,8 @@ -+<<<<<<< .our - if (!process.env.CI) require('dotenv-safe').load() - -+======= -+>>>>>>> .their - const GitHub = require('github') - const github = new GitHub() - -@@ -14,7 +17,11 @@ - github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN}) - let releases = await github.repos.getReleases({ - owner: 'electron', -+<<<<<<< .our - repo: version.indexOf('nightly') > 0 ? 'nightlies' : 'electron' -+======= -+ repo: 'electron' -+>>>>>>> .their - }) - let targetRelease = releases.data.find(release => { - return release.tag_name === version -changed in both - base 100644 76f39fc26973e01145f7758785778075ddbaa648 script/lib/dbus_mock.py - our 100644 9b9c8029cb75a9d84c632d04f234c2020542ca68 script/lib/dbus_mock.py - their 100644 00b1fd98d7837cfef60460f9d456a5cb8340761c script/lib/dbus_mock.py -@@ -4,21 +4,29 @@ - import atexit - import os - import sys -+<<<<<<< .our -+======= -+ -+>>>>>>> .their - - - def stop(): - DBusTestCase.stop_dbus(DBusTestCase.system_bus_pid) - DBusTestCase.stop_dbus(DBusTestCase.session_bus_pid) -+<<<<<<< .our - - def start(): - dbusmock_log = sys.stdout if is_verbose_mode() else open(os.devnull, 'w') - - DBusTestCase.start_system_bus() - DBusTestCase.spawn_server_template('logind', None, dbusmock_log) -+======= -+>>>>>>> .their - - DBusTestCase.start_session_bus() - DBusTestCase.spawn_server_template('notification_daemon', None, dbusmock_log) - -+<<<<<<< .our - if __name__ == '__main__': - import subprocess - start() -@@ -26,3 +34,14 @@ - subprocess.check_call(sys.argv[1:]) - finally: - stop() -+======= -+atexit.register(cleanup) -+ -+dbusmock_log = sys.stdout if is_verbose_mode() else open(os.devnull, 'w') -+ -+DBusTestCase.start_system_bus() -+DBusTestCase.spawn_server_template('logind', None, dbusmock_log) -+ -+DBusTestCase.start_session_bus() -+DBusTestCase.spawn_server_template('notification_daemon', None, dbusmock_log) -+>>>>>>> .their -changed in both - base 100755 69882928765a56f50702a371af322710ef3ccf22 script/prepare-release.js - our 100755 72a28b719bf1ff7770692caef86c76746c4d8edf script/prepare-release.js - their 100755 c768c0ef0af4f4e5a518c940a8b70b3c2d568bf2 script/prepare-release.js -@@ -5,6 +5,10 @@ - const args = require('minimist')(process.argv.slice(2), { - boolean: ['automaticRelease', 'notesOnly', 'stable'] - }) -+<<<<<<< .our -+======= -+const assert = require('assert') -+>>>>>>> .their - const ciReleaseBuild = require('./ci-release-build') - const { execSync } = require('child_process') - const fail = '\u2717'.red -@@ -21,8 +25,13 @@ - // via conventional-recommended-bump - - if (!versionType && !args.notesOnly) { -+<<<<<<< .our - console.log(`Usage: prepare-release versionType [stable | beta | nightly]` + - ` (--stable) (--notesOnly) (--automaticRelease) (--branch)`) -+======= -+ console.log(`Usage: prepare-release versionType [major | minor | patch | beta | specificVersion]` + -+ ` (--stable) (--notesOnly) (--automaticRelease) (--branch) (--version)`) -+>>>>>>> .their - process.exit(1) - } - -@@ -35,7 +44,16 @@ - console.log(`Bumping for new "${versionType}" version.`) - } - let bumpScript = path.join(__dirname, 'bump-version.py') -+<<<<<<< .our - let scriptArgs = [bumpScript, '--bump', versionType] -+======= -+ let scriptArgs = [bumpScript] -+ if (versionType === 'specificVersion' && args.version) { -+ scriptArgs.push(`--version ${args.version}`) -+ } else { -+ scriptArgs.push(`--bump ${versionType}`) -+ } -+>>>>>>> .their - if (args.stable) { - scriptArgs.push('--stable') - } -@@ -222,7 +240,11 @@ - } - - async function verifyNewVersion () { -+<<<<<<< .our - let newVersion = await getNewVersion(true) -+======= -+ let newVersion = getNewVersion(true) -+>>>>>>> .their - let response - if (args.automaticRelease) { - response = 'y' -@@ -258,6 +280,7 @@ - } - - async function prepareRelease (isBeta, notesOnly) { -+<<<<<<< .our - if (args.dryRun) { - let newVersion = await getNewVersion(true) - console.log(newVersion) -@@ -278,6 +301,27 @@ - process.exit(1) - } - } -+======= -+ if (args.automaticRelease && (pkg.version.indexOf('beta') === -1 || -+ versionType !== 'beta')) { -+ console.log(`${fail} Automatic release is only supported for beta releases`) -+ process.exit(1) -+ } -+ let currentBranch -+ if (args.branch) { -+ currentBranch = args.branch -+ } else { -+ currentBranch = await getCurrentBranch(gitDir) -+ } -+ if (notesOnly) { -+ let releaseNotes = await getReleaseNotes(currentBranch) -+ console.log(`Draft release notes are: \n${releaseNotes}`) -+ } else { -+ await verifyNewVersion() -+ await createRelease(currentBranch, isBeta) -+ await pushRelease(currentBranch) -+ await runReleaseBuilds(currentBranch) -+>>>>>>> .their - } - } - -changed in both - base 100644 eb0702ff5ef265b545824ba21ffb4c5d760d5476 script/publish-to-npm.js - our 100644 27290c513bb28d9bd394575d833f1e6786e3b479 script/publish-to-npm.js - their 100644 ec3f131913e3a8d7b2bbb3d383f5a318ec881a23 script/publish-to-npm.js -@@ -1,3 +1,4 @@ -+const args = require('minimist')(process.argv.slice(2)) - const temp = require('temp') - const fs = require('fs') - const path = require('path') -@@ -108,6 +109,7 @@ - }) - }) - }) -+<<<<<<< .our - .then(async (release) => { - if (release.tag_name.indexOf('nightly') > 0) { - const currentBranch = await getCurrentBranch() -@@ -116,6 +118,11 @@ - } else { - npmTag = `nightly-${currentBranch}` - } -+======= -+.then((release) => { -+ if (args.tag) { -+ npmTag = args.tag -+>>>>>>> .their - } else { - npmTag = release.prerelease ? 'beta' : 'latest' - } -changed in both - base 100755 9863ef912cd5a940428e9ac22e1993494b2b1828 script/release.js - our 100755 84e00ad4f309201f151c3f8fcbaf9ee536c9b6cb script/release.js - their 100755 5858caf215a38e09d98c342bd74252b3dbd7ee71 script/release.js -@@ -95,6 +95,10 @@ - `electron-${version}-linux-armv7l.zip`, - `electron-${version}-linux-ia32-symbols.zip`, - `electron-${version}-linux-ia32.zip`, -+<<<<<<< .our -+======= -+// `electron-${version}-linux-mips64el.zip`, -+>>>>>>> .their - `electron-${version}-linux-x64-symbols.zip`, - `electron-${version}-linux-x64.zip`, - `electron-${version}-mas-x64-dsym.zip`, -@@ -112,6 +116,10 @@ - `ffmpeg-${version}-linux-arm64.zip`, - `ffmpeg-${version}-linux-armv7l.zip`, - `ffmpeg-${version}-linux-ia32.zip`, -+<<<<<<< .our -+======= -+// `ffmpeg-${version}-linux-mips64el.zip`, -+>>>>>>> .their - `ffmpeg-${version}-linux-x64.zip`, - `ffmpeg-${version}-mas-x64.zip`, - `ffmpeg-${version}-win32-ia32.zip`, -@@ -180,7 +188,15 @@ - function uploadIndexJson () { - console.log('Uploading index.json to S3.') - let scriptPath = path.join(__dirname, 'upload-index-json.py') -+<<<<<<< .our - runScript(scriptPath, [pkgVersion]) -+======= -+ let scriptArgs = [] -+ if (args.automaticRelease) { -+ scriptArgs.push('-R') -+ } -+ runScript(scriptPath, scriptArgs) -+>>>>>>> .their - console.log(`${pass} Done uploading index.json to S3.`) - } - -changed in both - base 100755 1f90ed795fcc3e739061cf4ae5c8ab9ea95a1236 script/test.py - our 100755 46cada435e1bd6ecaa2111cdf29e5aeb834b227e script/test.py - their 100755 cb17102557dca975208140b479168906100cfd74 script/test.py -changed in both - base 100755 a35eb2f5b90272c8369bcfd511f976a4f64fa57f script/update-clang.sh - our 100755 0c7ab60533381e33152b8735aaccf41d5f0d6676 script/update-clang.sh - their 100755 6e4cf08216616a4b6a2ee896bba47b1ba5d469b5 script/update-clang.sh -changed in both - base 100755 f5e5b3c7a6adcaf7005ad9242c1664ad2f243d1f script/upload-index-json.py - our 100755 55d0675d0707d34c806847f3a64aa77f20a4830d script/upload-index-json.py - their 100755 479e46bb811695482f5ea62060e4bef02af505f1 script/upload-index-json.py -@@ -8,7 +8,6 @@ - from lib.util import s3put, scoped_cwd, safe_mkdir - - SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) --OUT_DIR = os.path.join(SOURCE_ROOT, 'out', 'D') - - BASE_URL = 'https://electron-metadumper.herokuapp.com/?version=' - -@@ -35,6 +34,7 @@ - raise Exception("Please set META_DUMPER_AUTH_HEADER") - # Upload the index.json. - with scoped_cwd(SOURCE_ROOT): -+<<<<<<< .our - safe_mkdir(OUT_DIR) - index_json = os.path.relpath(os.path.join(OUT_DIR, 'index.json')) - -@@ -42,9 +42,27 @@ - - with open(index_json, "w") as f: - f.write(new_content) -+======= -+ if len(sys.argv) == 2 and sys.argv[1] == '-R': -+ config = 'R' -+ else: -+ config = 'D' -+ out_dir = os.path.join(SOURCE_ROOT, 'out', config) -+ if sys.platform == 'darwin': -+ electron = os.path.join(out_dir, '{0}.app'.format(PRODUCT_NAME), -+ 'Contents', 'MacOS', PRODUCT_NAME) -+ elif sys.platform == 'win32': -+ electron = os.path.join(out_dir, '{0}.exe'.format(PROJECT_NAME)) -+ else: -+ electron = os.path.join(out_dir, PROJECT_NAME) -+ index_json = os.path.relpath(os.path.join(out_dir, 'index.json')) -+ execute([electron, -+ os.path.join('tools', 'dump-version-info.js'), -+ index_json]) -+>>>>>>> .their - - bucket, access_key, secret_key = s3_config() -- s3put(bucket, access_key, secret_key, OUT_DIR, 'atom-shell/dist', -+ s3put(bucket, access_key, secret_key, out_dir, 'atom-shell/dist', - [index_json]) - - -changed in both - base 100755 4da630433812b51ff0ebbdf89f68c71d90ab8046 script/upload.py - our 100755 2d9eaa201265971ca01acaea6e84a440e5db0532 script/upload.py - their 100755 48f8d650eae7a9d46b45a353d68e0e7bef33d219 script/upload.py -@@ -37,7 +37,11 @@ - args = parse_args() - if args.upload_to_s3: - utcnow = datetime.datetime.utcnow() -+<<<<<<< .our - args.upload_timestamp = utcnow.strftime('%Y%m%d') -+======= -+ args.upload_timestamp = utcnow.strftime('%Y-%m-%d_%H:%M:%S') -+>>>>>>> .their - - if not dist_newer_than_head(): - run_python_script('create-dist.py') -@@ -79,6 +83,14 @@ - upload_electron(release, os.path.join(DIST_DIR, chromedriver), args) - mksnapshot = get_zip_name('mksnapshot', ELECTRON_VERSION) - upload_electron(release, os.path.join(DIST_DIR, mksnapshot), args) -+<<<<<<< .our -+======= -+ -+ if get_target_arch().startswith('arm'): -+ # Upload the x64 binary for arm/arm64 mksnapshot -+ mksnapshot = get_zip_name('mksnapshot', ELECTRON_VERSION, 'x64') -+ upload_electron(release, os.path.join(DIST_DIR, mksnapshot), args) -+>>>>>>> .their - - if get_target_arch().startswith('arm'): - # Upload the x64 binary for arm/arm64 mksnapshot -@@ -170,6 +182,16 @@ - # Upload the checksum file. - upload_sha256_checksum(args.version, file_path) - -+<<<<<<< .our -+======= -+ # Upload ARM assets without the v7l suffix for backwards compatibility -+ # TODO Remove for 2.0 -+ if 'armv7l' in filename: -+ arm_filename = filename.replace('armv7l', 'arm') -+ arm_file_path = os.path.join(os.path.dirname(file_path), arm_filename) -+ shutil.copy2(file_path, arm_file_path) -+ upload_electron(release, arm_file_path, args) -+>>>>>>> .their - - def upload_io_to_github(release, filename, filepath, version): - print 'Uploading %s to Github' % \ -changed in both - base 100644 0eda951b15d6fff609b6612589e222adb4f0720e spec/api-app-spec.js - our 100644 d224eda2989332c18d655cef05a8bacc2eb6d4b8 spec/api-app-spec.js - their 100644 5c2e0a0c7e6184e780b7ec031f9788f1f54eaca9 spec/api-app-spec.js -@@ -9,7 +9,10 @@ - const {ipcRenderer, remote} = require('electron') - const {closeWindow} = require('./window-helpers') - -+<<<<<<< .our - const {expect} = chai -+======= -+>>>>>>> .their - const {app, BrowserWindow, Menu, ipcMain} = remote - - const isCI = remote.getGlobal('isCi') -@@ -186,11 +189,19 @@ - - // Singleton will send us greeting data to let us know it's running. - // After that, ask it to exit gracefully and confirm that it does. -+<<<<<<< .our - appProcess.stdout.on('data', data => appProcess.kill()) - appProcess.on('exit', (code, sig) => { - const message = `code:\n${code}\nsig:\n${sig}` - expect(code).to.equal(0, message) - expect(sig).to.be.null(message) -+======= -+ appProcess.stdout.on('data', (data) => appProcess.kill()) -+ appProcess.on('exit', (code, sig) => { -+ let message = ['code:', code, 'sig:', sig].join('\n') -+ assert.equal(code, 0, message) -+ assert.equal(sig, null, message) -+>>>>>>> .their - done() - }) - }) -@@ -948,4 +959,18 @@ - return expect(app.whenReady()).to.be.eventually.fulfilled - }) - }) -+ -+ describe('dock.setMenu', () => { -+ before(function () { -+ if (process.platform !== 'darwin') { -+ this.skip() -+ } -+ }) -+ -+ it('keeps references to the menu', () => { -+ app.dock.setMenu(new Menu()) -+ const v8Util = process.atomBinding('v8_util') -+ v8Util.requestGarbageCollectionForTesting() -+ }) -+ }) - }) -changed in both - base 100644 ab96021ebf4c4360fa581b5a695249456a9afeda spec/api-browser-view-spec.js - our 100644 968912a4abf3d759a1363e2420d2c21b7923dbd6 spec/api-browser-view-spec.js - their 100644 df239a8914527a2d62f652b878c97a7791f63a9d spec/api-browser-view-spec.js -@@ -44,9 +44,15 @@ - describe('BrowserView.isDestroyed()', () => { - it('returns correct value', () => { - view = new BrowserView() -+<<<<<<< .our - expect(view.isDestroyed()).to.be.false() - view.destroy() - expect(view.isDestroyed()).to.be.true() -+======= -+ assert.ok(!view.isDestroyed()) -+ view.destroy() -+ assert.ok(view.isDestroyed()) -+>>>>>>> .their - }) - }) - -changed in both - base 100644 3033eb6a1f6cca3cf4874a54dd217ec62d2d82cd spec/api-browser-window-spec.js - our 100644 f4cba12ec19d224bc46fca898db42a99baf4972e spec/api-browser-window-spec.js - their 100644 4b93a6bb3f3624594c8bd42835735dd2625fc6b7 spec/api-browser-window-spec.js -@@ -409,12 +409,34 @@ - }) - }) - -+<<<<<<< .our - // TODO(alexeykuzmin): [Ch66] Enable the test. Passes locally. - xdescribe('BrowserWindow.getFocusedWindow()', (done) => { -+======= -+ describe('BrowserWindow.getFocusedWindow()', (done) => { -+>>>>>>> .their - it('returns the opener window when dev tools window is focused', (done) => { - w.show() - w.webContents.once('devtools-focused', () => { - assert.deepEqual(BrowserWindow.getFocusedWindow(), w) -+<<<<<<< .our -+======= -+ done() -+ }) -+ w.webContents.openDevTools({mode: 'undocked'}) -+ }) -+ }) -+ -+ describe('BrowserWindow.capturePage(rect, callback)', () => { -+ it('calls the callback with a Buffer', (done) => { -+ w.capturePage({ -+ x: 0, -+ y: 0, -+ width: 100, -+ height: 100 -+ }, (image) => { -+ assert.equal(image.isEmpty(), true) -+>>>>>>> .their - done() - }) - w.webContents.openDevTools({mode: 'undocked'}) -@@ -453,6 +475,29 @@ - // Values can be 0,2,3,4, or 6. We want 6, which is RGB + Alpha - expect(imgBuffer[25]).to.equal(6) - }) -+ -+ it('preserves transparency', (done) => { -+ w.close() -+ const width = 400 -+ const height = 400 -+ w = new BrowserWindow({ -+ show: false, -+ width: width, -+ height: height, -+ transparent: true -+ }) -+ w.loadURL('data:text/html,<html><body background-color: rgba(255,255,255,0)></body></html>') -+ w.once('ready-to-show', () => { -+ w.show() -+ w.capturePage((image) => { -+ let imgBuffer = image.toPNG() -+ // Check 25th byte in the PNG -+ // Values can be 0,2,3,4, or 6. We want 6, which is RGB + Alpha -+ assert.equal(imgBuffer[25], 6) -+ done() -+ }) -+ }) -+ }) - }) - - describe('BrowserWindow.setSize(width, height)', () => { -@@ -763,6 +808,7 @@ - w.addTabbedWindow(w) - }, /AddTabbedWindow cannot be called by a window on itself./) - }) -+<<<<<<< .our - }) - - describe('BrowserWindow.setWindowButtonVisibility()', () => { -@@ -790,6 +836,8 @@ - w.setWindowButtonVisibility(true) - }, /Not supported for this window/) - }) -+======= -+>>>>>>> .their - }) - - describe('BrowserWindow.setVibrancy(type)', () => { -changed in both - base 100644 b4d55cd70b70b42d52a026ff7b4ff3c47d1671df spec/api-crash-reporter-spec.js - our 100644 dd31b91e1244785412b87db96bb141599e5ccb0f spec/api-crash-reporter-spec.js - their 100644 ffa3c0370595f32b0c7d476b82bea133d6a87000 spec/api-crash-reporter-spec.js -@@ -266,6 +266,7 @@ - describe('getLastCrashReport', () => { - it('correctly returns the most recent report', () => { - const reports = crashReporter.getUploadedReports() -+<<<<<<< .our - expect(reports).to.be.an('array') - expect(reports).to.have.lengthOf.at.least(2, - 'There are not enough reports for this test') -@@ -275,16 +276,31 @@ - - // Let's find the newest report. - const {report: newestReport} = reports.reduce((acc, cur) => { -+======= -+ const lastReport = crashReporter.getLastCrashReport() -+ -+ // Let's find the newest report -+ const newestReport = reports.reduce((acc, cur) => { -+>>>>>>> .their - const timestamp = new Date(cur.date).getTime() - return (timestamp > acc.timestamp) - ? { report: cur, timestamp: timestamp } - : acc -+<<<<<<< .our - }, { timestamp: -Infinity }) - assert(newestReport, 'Hey!') - - expect(lastReport.date.getTime()).to.be.equal( - newestReport.date.getTime(), - 'Last report is not the newest.') -+======= -+ }, { timestamp: 0 }) -+ -+ assert(reports.length > 1, 'has more than 1 report') -+ assert(lastReport != null, 'found a last report') -+ assert(lastReport.date.toString() === newestReport.report.date.toString(), -+ 'last report is correct') -+>>>>>>> .their - }) - }) - -changed in both - base 100644 de623162e59d2c8fdd9ade3dbabe73f3500efc49 spec/api-desktop-capturer-spec.js - our 100644 339d9756e40f8a532322800349b36d4371a2c9b0 spec/api-desktop-capturer-spec.js - their 100644 c85220bce65785fc2face8a1d2934c9d9c204c79 spec/api-desktop-capturer-spec.js -@@ -1,3 +1,4 @@ -+<<<<<<< .our - const chai = require('chai') - const dirtyChai = require('dirty-chai') - const {desktopCapturer, remote, screen} = require('electron') -@@ -5,6 +6,10 @@ - - const {expect} = chai - chai.use(dirtyChai) -+======= -+const assert = require('assert') -+const {desktopCapturer, remote, screen} = require('electron') -+>>>>>>> .their - - const isCI = remote.getGlobal('isCi') - -@@ -51,7 +56,11 @@ - desktopCapturer.getSources({types: ['window', 'screen']}, callback) - }) - -+<<<<<<< .our - it('responds to subsequent calls of different options', done => { -+======= -+ it('responds to subsequent calls of different options', (done) => { -+>>>>>>> .their - let callCount = 0 - const callback = (error, sources) => { - callCount++ -@@ -63,11 +72,16 @@ - desktopCapturer.getSources({types: ['screen']}, callback) - }) - -+<<<<<<< .our - it('returns an empty display_id for window sources on Windows and Mac', done => { -+======= -+ it('returns an empty display_id for window sources on Windows and Mac', (done) => { -+>>>>>>> .their - // Linux doesn't return any window sources. - if (process.platform !== 'win32' && process.platform !== 'darwin') { - return done() - } -+<<<<<<< .our - - const { BrowserWindow } = remote - const w = new BrowserWindow({ width: 200, height: 200 }) -@@ -79,10 +93,17 @@ - for (const {display_id: displayId} of sources) { - expect(displayId).to.be.a('string').and.be.empty() - } -+======= -+ desktopCapturer.getSources({types: ['window']}, (error, sources) => { -+ assert.equal(error, null) -+ assert.notEqual(sources.length, 0) -+ sources.forEach((source) => { assert.equal(source.display_id.length, 0) }) -+>>>>>>> .their - done() - }) - }) - -+<<<<<<< .our - it('returns display_ids matching the Screen API on Windows and Mac', done => { - if (process.platform !== 'win32' && process.platform !== 'darwin') { - return done() -@@ -95,6 +116,19 @@ - - for (let i = 0; i < sources.length; i++) { - expect(sources[i].display_id).to.equal(displays[i].id.toString()) -+======= -+ it('returns display_ids matching the Screen API on Windows and Mac', (done) => { -+ if (process.platform !== 'win32' && process.platform !== 'darwin') { -+ return done() -+ } -+ const displays = screen.getAllDisplays() -+ desktopCapturer.getSources({types: ['screen']}, (error, sources) => { -+ assert.equal(error, null) -+ assert.notEqual(sources.length, 0) -+ assert.equal(sources.length, displays.length) -+ for (let i = 0; i < sources.length; i++) { -+ assert.equal(sources[i].display_id, displays[i].id) -+>>>>>>> .their - } - done() - }) -changed in both - base 100644 667f098bc4b9974a142435e7d3ddb762ac0f54a2 spec/api-menu-spec.js - our 100644 ed2749700c6c8bf299f507d52606c1ae3f597e5c spec/api-menu-spec.js - their 100644 3efb6ed8745843bb7e221fe25b3c75761a085759 spec/api-menu-spec.js -@@ -649,6 +649,7 @@ - }) - - it('throws an error if options is not an object', () => { -+<<<<<<< .our - expect(() => { - menu.popup('this is a string, not an object') - }).to.throw(/Options must be an object/) -@@ -658,6 +659,11 @@ - expect(() => { - menu.popup({}) - }).to.not.throw() -+======= -+ assert.throws(() => { -+ menu.popup() -+ }, /Options must be an object/) -+>>>>>>> .their - }) - - it('should emit menu-will-show event', (done) => { -added in both - our 100644 9ab56d88e50ae5891364cb271362e5ec0c0edd26 spec/api-notification-dbus-spec.js - their 100644 81c1b68f31d0c9490742d3bd4b4227abaaf72ca3 spec/api-notification-dbus-spec.js -@@ -6,7 +6,11 @@ - // - // See https://pypi.python.org/pypi/python-dbusmock to read about dbusmock. - -+<<<<<<< .our - const {expect} = require('chai') -+======= -+const assert = require('assert') -+>>>>>>> .their - const dbus = require('dbus-native') - const Promise = require('bluebird') - -@@ -27,12 +31,20 @@ - before(async () => { - // init app - app.setName(appName) -+<<<<<<< .our - app.setDesktopName(`${appName}.desktop`) -+======= -+ app.setDesktopName(appName + '.desktop') -+>>>>>>> .their - // init dbus - const path = '/org/freedesktop/Notifications' - const iface = 'org.freedesktop.DBus.Mock' - const bus = dbus.sessionBus() -+<<<<<<< .our - console.log(`session bus: ${process.env.DBUS_SESSION_BUS_ADDRESS}`) -+======= -+ console.log('session bus: ' + process.env.DBUS_SESSION_BUS_ADDRESS) -+>>>>>>> .their - const service = bus.getService(serviceName) - const getInterface = Promise.promisify(service.getInterface, {context: service}) - mock = await getInterface(path, iface) -@@ -48,10 +60,17 @@ - app.setVersion(realAppVersion) - }) - -+<<<<<<< .our - describe(`Notification module using ${serviceName}`, () => { - function onMethodCalled (done) { - function cb (name) { - console.log(`onMethodCalled: ${name}`) -+======= -+ describe('Notification module using ' + serviceName, () => { -+ function onMethodCalled (done) { -+ function cb (name) { -+ console.log('onMethodCalled: ' + name) -+>>>>>>> .their - if (name === 'Notify') { - mock.removeListener('MethodCalled', cb) - console.log('done') -@@ -83,7 +102,11 @@ - } - } - -+<<<<<<< .our - before(done => { -+======= -+ before((done) => { -+>>>>>>> .their - mock.on('MethodCalled', onMethodCalled(done)) - // lazy load Notification after we listen to MethodCalled mock signal - Notification = require('electron').remote.Notification -@@ -98,6 +121,7 @@ - n.show() - }) - -+<<<<<<< .our - it(`should call ${serviceName} to show notifications`, async () => { - const calls = await getCalls() - expect(calls).to.be.an('array').of.lengthOf.at.least(1) -@@ -108,6 +132,16 @@ - - let args = unmarshalDBusNotifyArgs(lastCall[2]) - expect(args).to.deep.equal({ -+======= -+ it('should call ' + serviceName + ' to show notifications', async () => { -+ const calls = await getCalls() -+ assert(calls.length >= 1) -+ let lastCall = calls[calls.length - 1] -+ let methodName = lastCall[1] -+ assert.equal(methodName, 'Notify') -+ let args = unmarshalDBusNotifyArgs(lastCall[2]) -+ assert.deepEqual(args, { -+>>>>>>> .their - app_name: appName, - replaces_id: 0, - app_icon: '', -changed in both - base 100644 122170292838e951ade4989669c87a7531e89ba7 spec/api-web-contents-spec.js - our 100644 be02cb3f84001a541d64b11fe6eda50fc32e8afd spec/api-web-contents-spec.js - their 100644 cbb45f5d84f1b11c8c27c56515d5daffa23d0c04 spec/api-web-contents-spec.js -@@ -122,6 +122,7 @@ - }) - }) - -+<<<<<<< .our - // Disabled because flaky. See #13969 - xdescribe('isCurrentlyAudible() API', () => { - it('returns whether audio is playing', async () => { -@@ -138,6 +139,8 @@ - }) - }) - -+======= -+>>>>>>> .their - describe('getWebPreferences() API', () => { - it('should not crash when called for devTools webContents', (done) => { - w.webContents.openDevTools() -@@ -730,6 +733,7 @@ - }) - }) - -+<<<<<<< .our - describe('referrer', () => { - it('propagates referrer information to new target=_blank windows', (done) => { - const server = http.createServer((req, res) => { -@@ -776,6 +780,8 @@ - }) - }) - -+======= -+>>>>>>> .their - describe('webframe messages in sandboxed contents', () => { - it('responds to executeJavaScript', (done) => { - w.destroy() -changed in both - base 100644 f87554f32e267b46fe3501405617a289b6cccedb spec/asar-spec.js - our 100644 489f68c96d41e80c308560a98486a07756a03be7 spec/asar-spec.js - their 100644 a82e73071e13d2289087d346a00ef62eacd71f6e spec/asar-spec.js -@@ -900,6 +900,18 @@ - }) - }) - -+ describe('util.promisify', function () { -+ it('can promisify all fs functions', function () { -+ const originalFs = require('original-fs') -+ -+ for (const key in originalFs) { -+ if (originalFs[key][util.promisify.custom] && !fs[key][util.promisify.custom]) { -+ assert(false, `fs.${key}[util.promisify.custom] missing`) -+ } -+ } -+ }) -+ }) -+ - describe('process.noAsar', function () { - var errorName = process.platform === 'win32' ? 'ENOENT' : 'ENOTDIR' - -changed in both - base 100644 2d388ca3b5744ea69d96ef71da6ade70e3dd001b spec/chromium-spec.js - our 100644 d90269769d269e4054d25cba4b6c4ac8a1929aa6 spec/chromium-spec.js - their 100644 25bef2e689e5ecbcd1485a042e84691db9400659 spec/chromium-spec.js -@@ -319,8 +319,12 @@ - b = window.open(windowUrl, '', 'nodeIntegration=no,show=no') - }) - -+<<<<<<< .our - // TODO(codebytere): re-enable this test - xit('disables node integration when it is disabled on the parent window for chrome devtools URLs', (done) => { -+======= -+ it('disables node integration when it is disabled on the parent window for chrome devtools URLs', (done) => { -+>>>>>>> .their - let b - app.once('web-contents-created', (event, contents) => { - contents.once('did-finish-load', () => { -changed in both - base 100644 07176e0097efa17e8f8aea5bb059a2739b8c3336 spec/fixtures/api/singleton/main.js - our 100644 3202a7a180d6d48c70706d5ef244652872b24bbc spec/fixtures/api/singleton/main.js - their 100644 cbf3da1117d91eb8df1b1e6363737a210b7eae78 spec/fixtures/api/singleton/main.js -@@ -3,8 +3,11 @@ - app.once('ready', () => { - console.log('started') // ping parent - }) -+<<<<<<< .our - - const gotTheLock = app.requestSingleInstanceLock() -+======= -+>>>>>>> .their - - app.on('second-instance', () => { - setImmediate(() => app.exit(0)) -changed in both - base 100644 cfe840ca0a44c5766509b2865034d98e375da1a1 spec/modules-spec.js - our 100644 b996b8f4839bff2160bffb69e55263b16a4178d7 spec/modules-spec.js - their 100644 28f2602acff67b2da9accd0574d64d386e0795a7 spec/modules-spec.js -changed in both - base 100644 e2d7d001eb49a9b01edcf9590ccdcb7ac8cc669c spec/node-spec.js - our 100644 9bb03494a56ffacec075c40bebde39a3b57ac734 spec/node-spec.js - their 100644 2c849bc3a442f8d1f800efce17cde212fc676531 spec/node-spec.js -changed in both - base 100644 feac23db7e06d3e49f8d5be7e9b3f08a204f262f spec/security-warnings-spec.js - our 100644 6315a9420e01b5db19596f0dd5731d47ce02acf6 spec/security-warnings-spec.js - their 100644 85fd0973b60cd6e27becbeef75415560b4061d24 spec/security-warnings-spec.js -@@ -142,7 +142,11 @@ - } - }) - w.webContents.once('console-message', (e, level, message) => { -+<<<<<<< .our - assert(message.includes('enableBlinkFeatures'), message) -+======= -+ assert(message.includes('blinkFeatures'), message) -+>>>>>>> .their - done() - }) - -changed in both - base 100644 ca5cc28d4f9f860947454dfc964208dd13ba1434 spec/static/index.html - our 100644 fc1e153c0af2908cf7ee4c3ea4f05522de04f0f8 spec/static/index.html - their 100644 e9d779f061cd5bdf00667d0b7942c6c30de81092 spec/static/index.html -@@ -51,7 +51,11 @@ - if (!process.env.MOCHA_REPORTER) { - mocha.ui('bdd').reporter(isCi ? 'tap' : 'html') - } -- mocha.timeout(isCi ? 30000 : 10000) -+ if (process.env.MOCHA_TIMEOUT && process.env.MOCHA_TIMEOUT > 0) { -+ mocha.timeout(process.env.MOCHA_TIMEOUT) -+ } else { -+ mocha.timeout(isCi ? 30000 : 10000) -+ } - - const query = Mocha.utils.parseQuery(window.location.search || '') - if (query.grep) mocha.grep(query.grep) -changed in both - base 100644 7050f3a7e43070e9c1ae924d1cd314ad8214e2d3 spec/static/main.js - our 100644 5659c44c8de4456a25e0026e29199b827c89cb08 spec/static/main.js - their 100644 6dc8a4550ebab1e0c5b562ab776d9f1a2a2d13d7 spec/static/main.js -changed in both - base 100644 73df333dd2b24e1b32931498ebe41557c3d24d0e spec/webview-spec.js - our 100644 db75a4e3754e24a5e6740be61be4f4098c58006e spec/webview-spec.js - their 100644 dfb3965a5a56a99a8299eb2ae9016822421245a4 spec/webview-spec.js -@@ -696,6 +696,7 @@ - xdescribe('setDevToolsWebContents() API', () => { - it('sets webContents of webview as devtools', async () => { - const webview2 = new WebView() -+<<<<<<< .our - loadWebView(webview2) - - // Setup an event handler for further usage. -@@ -720,6 +721,24 @@ - document.body.removeChild(webview2) - - expect(name).to.be.equal('InspectorFrontendHostImpl') -+======= -+ document.body.appendChild(webview2) -+ webview2.addEventListener('dom-ready', () => { -+ const devtools = webview2.getWebContents() -+ assert.ok(devtools.getURL().startsWith('chrome-devtools://devtools')) -+ devtools.executeJavaScript('InspectorFrontendHost.constructor.name', (name) => { -+ assert.ok(name, 'InspectorFrontendHostImpl') -+ document.body.removeChild(webview2) -+ done() -+ }) -+ }) -+ webview.addEventListener('dom-ready', () => { -+ webview.getWebContents().setDevToolsWebContents(webview2.getWebContents()) -+ webview.getWebContents().openDevTools() -+ }) -+ webview.src = 'about:blank' -+ document.body.appendChild(webview) -+>>>>>>> .their - }) - }) - -@@ -1182,6 +1201,7 @@ - - describe('will-attach-webview event', () => { - it('does not emit when src is not changed', (done) => { -+<<<<<<< .our - loadWebView(webview) - setTimeout(() => { - const expectedErrorMessage = -@@ -1189,6 +1209,21 @@ - 'The WebView must be attached to the DOM ' + - 'and the dom-ready event emitted before this method can be called.' - expect(() => { webview.stop() }).to.throw(expectedErrorMessage) -+======= -+ document.body.appendChild(webview) -+ setTimeout(() => { -+ assert.throws(() => { -+ webview.stop() -+ }, 'Cannot call stop because the webContents is unavailable. The WebView must be attached to the DOM and the dom-ready event emitted before this method can be called.') -+ done() -+ }) -+ }) -+ -+ it('supports changing the web preferences', (done) => { -+ ipcRenderer.send('disable-node-on-next-will-attach-webview') -+ webview.addEventListener('console-message', (event) => { -+ assert.equal(event.message, 'undefined undefined undefined undefined') -+>>>>>>> .their - done() - }) - }) -@@ -1251,9 +1286,260 @@ - - w.loadURL(`file://${fixtures}/pages/webview-devtools.html`) - -+<<<<<<< .our - const [, {runtimeId, tabId}] = await emittedOnce(ipcMain, 'answer') - expect(runtimeId).to.equal('foo') - expect(tabId).to.be.not.equal(w.webContents.id) -+======= -+ ipcMain.once('answer', (event, message) => { -+ assert.equal(message.runtimeId, 'foo') -+ assert.notEqual(message.tabId, w.webContents.id) -+ done() -+ }) -+ }) -+ -+ describe('guestinstance attribute', () => { -+ it('before loading there is no attribute', () => { -+ document.body.appendChild(webview) -+ assert(!webview.hasAttribute('guestinstance')) -+ }) -+ -+ it('loading a page sets the guest view', (done) => { -+ const loadListener = () => { -+ webview.removeEventListener('did-finish-load', loadListener, false) -+ const instance = webview.getAttribute('guestinstance') -+ assert.equal(instance, parseInt(instance)) -+ -+ const guest = getGuestWebContents(parseInt(instance)) -+ assert.equal(guest, webview.getWebContents()) -+ done() -+ } -+ webview.addEventListener('did-finish-load', loadListener, false) -+ webview.src = `file://${fixtures}/api/blank.html` -+ document.body.appendChild(webview) -+ }) -+ -+ it('deleting the attribute destroys the webview', (done) => { -+ const loadListener = () => { -+ webview.removeEventListener('did-finish-load', loadListener, false) -+ const destroyListener = () => { -+ webview.removeEventListener('destroyed', destroyListener, false) -+ assert.equal(getGuestWebContents(instance), null) -+ done() -+ } -+ webview.addEventListener('destroyed', destroyListener, false) -+ -+ const instance = parseInt(webview.getAttribute('guestinstance')) -+ webview.removeAttribute('guestinstance') -+ } -+ webview.addEventListener('did-finish-load', loadListener, false) -+ webview.src = `file://${fixtures}/api/blank.html` -+ document.body.appendChild(webview) -+ }) -+ -+ it('setting the attribute on a new webview moves the contents', (done) => { -+ const loadListener = () => { -+ webview.removeEventListener('did-finish-load', loadListener, false) -+ const webContents = webview.getWebContents() -+ const instance = webview.getAttribute('guestinstance') -+ -+ const destroyListener = () => { -+ webview.removeEventListener('destroyed', destroyListener, false) -+ assert.equal(webContents, webview2.getWebContents()) -+ // Make sure that events are hooked up to the right webview now -+ webview2.addEventListener('console-message', (e) => { -+ assert.equal(e.message, 'a') -+ document.body.removeChild(webview2) -+ done() -+ }) -+ -+ webview2.src = `file://${fixtures}/pages/a.html` -+ } -+ webview.addEventListener('destroyed', destroyListener, false) -+ -+ const webview2 = new WebView() -+ webview2.setAttribute('guestinstance', instance) -+ document.body.appendChild(webview2) -+ } -+ webview.addEventListener('did-finish-load', loadListener, false) -+ webview.src = `file://${fixtures}/api/blank.html` -+ document.body.appendChild(webview) -+ }) -+ -+ it('setting the attribute to an invalid guestinstance does nothing', (done) => { -+ const loadListener = () => { -+ webview.removeEventListener('did-finish-load', loadListener, false) -+ webview.setAttribute('guestinstance', 55) -+ -+ // Make sure that events are still hooked up to the webview -+ webview.addEventListener('console-message', (e) => { -+ assert.equal(e.message, 'a') -+ done() -+ }) -+ webview.src = `file://${fixtures}/pages/a.html` -+ } -+ webview.addEventListener('did-finish-load', loadListener, false) -+ -+ webview.src = `file://${fixtures}/api/blank.html` -+ document.body.appendChild(webview) -+ }) -+ -+ it('setting the attribute on an existing webview moves the contents', (done) => { -+ const load1Listener = () => { -+ webview.removeEventListener('did-finish-load', load1Listener, false) -+ const webContents = webview.getWebContents() -+ const instance = webview.getAttribute('guestinstance') -+ let destroyedInstance -+ -+ const destroyListener = () => { -+ webview.removeEventListener('destroyed', destroyListener, false) -+ assert.equal(webContents, webview2.getWebContents()) -+ assert.equal(null, getGuestWebContents(parseInt(destroyedInstance))) -+ -+ // Make sure that events are hooked up to the right webview now -+ webview2.addEventListener('console-message', (e) => { -+ assert.equal(e.message, 'a') -+ document.body.removeChild(webview2) -+ done() -+ }) -+ -+ webview2.src = 'file://' + fixtures + '/pages/a.html' -+ } -+ webview.addEventListener('destroyed', destroyListener, false) -+ -+ const webview2 = new WebView() -+ const load2Listener = () => { -+ webview2.removeEventListener('did-finish-load', load2Listener, false) -+ destroyedInstance = webview2.getAttribute('guestinstance') -+ assert.notEqual(instance, destroyedInstance) -+ -+ webview2.setAttribute('guestinstance', instance) -+ } -+ webview2.addEventListener('did-finish-load', load2Listener, false) -+ webview2.src = 'file://' + fixtures + '/api/blank.html' -+ document.body.appendChild(webview2) -+ } -+ webview.addEventListener('did-finish-load', load1Listener, false) -+ webview.src = 'file://' + fixtures + '/api/blank.html' -+ document.body.appendChild(webview) -+ }) -+ -+ it('moving a guest back to its original webview should work', (done) => { -+ const loadListener = () => { -+ webview.removeEventListener('did-finish-load', loadListener, false) -+ const webContents = webview.getWebContents() -+ const instance = webview.getAttribute('guestinstance') -+ -+ const destroy1Listener = () => { -+ webview.removeEventListener('destroyed', destroy1Listener, false) -+ assert.equal(webContents, webview2.getWebContents()) -+ assert.notStrictEqual(webContents, webview.getWebContents()) -+ -+ const destroy2Listener = () => { -+ webview2.removeEventListener('destroyed', destroy2Listener, false) -+ assert.equal(webContents, webview.getWebContents()) -+ assert.notStrictEqual(webContents, webview2.getWebContents()) -+ -+ // Make sure that events are hooked up to the right webview now -+ webview.addEventListener('console-message', (e) => { -+ assert.equal(e.message, 'a') -+ document.body.removeChild(webview2) -+ done() -+ }) -+ -+ webview.src = `file://${fixtures}/pages/a.html` -+ } -+ webview2.addEventListener('destroyed', destroy2Listener, false) -+ webview.setAttribute('guestinstance', instance) -+ } -+ webview.addEventListener('destroyed', destroy1Listener, false) -+ -+ const webview2 = new WebView() -+ webview2.setAttribute('guestinstance', instance) -+ document.body.appendChild(webview2) -+ } -+ webview.addEventListener('did-finish-load', loadListener, false) -+ webview.src = `file://${fixtures}/api/blank.html` -+ document.body.appendChild(webview) -+ }) -+ -+ it('setting the attribute on a webview in a different window moves the contents', (done) => { -+ const loadListener = () => { -+ webview.removeEventListener('did-finish-load', loadListener, false) -+ const instance = webview.getAttribute('guestinstance') -+ -+ w = new BrowserWindow({ show: false }) -+ w.webContents.once('did-finish-load', () => { -+ ipcMain.once('pong', () => { -+ assert(!webview.hasAttribute('guestinstance')) -+ done() -+ }) -+ -+ w.webContents.send('guestinstance', instance) -+ }) -+ w.loadURL(`file://${fixtures}/pages/webview-move-to-window.html`) -+ } -+ webview.addEventListener('did-finish-load', loadListener, false) -+ webview.src = `file://${fixtures}/api/blank.html` -+ document.body.appendChild(webview) -+ }) -+ -+ it('does not delete the guestinstance attribute when moving the webview to another parent node', (done) => { -+ webview.addEventListener('dom-ready', function domReadyListener () { -+ webview.addEventListener('did-attach', () => { -+ assert(webview.guestinstance != null) -+ assert(webview.getWebContents() != null) -+ done() -+ }) -+ -+ document.body.replaceChild(webview, div) -+ }) -+ webview.src = `file://${fixtures}/pages/a.html` -+ -+ const div = document.createElement('div') -+ div.appendChild(webview) -+ document.body.appendChild(div) -+ }) -+ -+ it('does not destroy the webContents when hiding/showing the webview (regression)', (done) => { -+ webview.addEventListener('dom-ready', function domReadyListener () { -+ const instance = webview.getAttribute('guestinstance') -+ assert(instance != null) -+ -+ // Wait for event directly since attach happens asynchronously over IPC -+ ipcMain.once('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', () => { -+ assert(webview.getWebContents() != null) -+ assert.equal(instance, webview.getAttribute('guestinstance')) -+ done() -+ }) -+ -+ webview.style.display = 'none' -+ webview.offsetHeight // eslint-disable-line -+ webview.style.display = 'block' -+ }) -+ webview.src = `file://${fixtures}/pages/a.html` -+ document.body.appendChild(webview) -+ }) -+ -+ it('does not reload the webContents when hiding/showing the webview (regression)', (done) => { -+ webview.addEventListener('dom-ready', function domReadyListener () { -+ webview.addEventListener('did-start-loading', () => { -+ done(new Error('webview started loading unexpectedly')) -+ }) -+ -+ // Wait for event directly since attach happens asynchronously over IPC -+ webview.addEventListener('did-attach', () => { -+ done() -+ }) -+ -+ webview.style.display = 'none' -+ webview.offsetHeight // eslint-disable-line -+ webview.style.display = 'block' -+ }) -+ webview.src = `file://${fixtures}/pages/a.html` -+ document.body.appendChild(webview) -+ }) -+>>>>>>> .their - }) - - describe('DOM events', () => { -changed in both - base 100644 6580f18a1ad9e53ab3f2ae88cb7ea023bcf9579c toolchain.gypi - our 100644 697add78e42191741cee1b015cdcf4f801c570e7 toolchain.gypi - their 100644 8ed945a57c8875bae06cef74dc5d44afcc586d1d toolchain.gypi -changed in both - base 160000 db1b314c019f6acbd4d1be273b63521cc6051d3c vendor/libchromiumcontent - our 160000 c85470a1c379b1c4bedb372c146521bc4be9b75d vendor/libchromiumcontent - their 160000 028b0af83076cec898f4ebce208b7fadb715656e vendor/libchromiumcontent -removed in local - base 160000 99d9e262eb36cb9dc8e83f61e026d2a7ad1e96ab vendor/native_mate - their 160000 6a3d238b7e1e3742f2bb495336a84021d927a24f vendor/native_mate -changed in both - base 160000 bf06b641574a6e2a8357ca4b44defac4a83f1dda vendor/node - our 160000 ece0a06ac8147efb5b5af431c21f312f1884616e vendor/node - their 160000 f2bcc6b58293287e2a6e592bd296aa55bb37b801 vendor/node -added in both - our 100644 84bd69c2b2868ac23bc30061aa208ad38fbb9506 vsts.yml - their 100644 5209acdec2eb8557ea55ce5281b7999b974aa5b6 vsts.yml -@@ -54,21 +54,32 @@ - script/test.py --ci --rebuild_native_modules - fi - name: Test -+<<<<<<< .our - condition: or(ne(variables['ELECTRON_RELEASE'], '1'), eq(variables['UPLOAD_TO_S3'], '1')) -+======= -+>>>>>>> .their - - - bash: | - echo 'Verifying ffmpeg on build' - if [ "$ELECTRON_RELEASE" == "1" ]; then -+<<<<<<< .our - script/verify-ffmpeg.py -c R -+======= -+ script/verify-ffmpeg.py -R -+>>>>>>> .their - else - script/verify-ffmpeg.py - fi - name: Verify_FFmpeg -+<<<<<<< .our - condition: or(ne(variables['ELECTRON_RELEASE'], '1'), eq(variables['UPLOAD_TO_S3'], '1')) -+======= -+>>>>>>> .their - - - task: PublishTestResults@2 - displayName: Publish Test Results - inputs: -+<<<<<<< .our - testResultsFiles: '**/test-*.xml' - condition: and(always(), eq(variables['MOCHA_FILE'], 'test-results.xml')) - -@@ -93,5 +104,18 @@ - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/out' - ArtifactName: out -+======= -+ testResultsFiles: 'test-results.xml' -+ searchFolder: junit -+ condition: and(always(), ne(variables['ELECTRON_RELEASE'], '1')) -+ -+- task: kasunkodagoda.slack-notification.slack-notification-task.SlackNotification@3 -+ displayName: Post Slack Notification -+ inputs: -+ SlackApiToken: '$(slack_token)' -+ Channel: '#bot-nightly-releases' -+ Message: '$(Build.DefinitionName)-$(Build.BuildNumber) finished with a $(Agent.JobStatus) status.' -+ condition: and(always(), eq(variables['Build.Reason'], 'Schedule')) -+>>>>>>> .their - - - task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3 diff --git a/app/test/fixtures/merge-parser/electron/merge-3-0-x-into-master.txt b/app/test/fixtures/merge-parser/electron/merge-3-0-x-into-master.txt deleted file mode 100644 index 508e29be736..00000000000 --- a/app/test/fixtures/merge-parser/electron/merge-3-0-x-into-master.txt +++ /dev/null @@ -1,15217 +0,0 @@ -added in both - our 100644 6d44d618aabcce04c60344f2274dec5b0c2a1f68 .circleci/config.yml - their 100644 7bc5ddc6be0269ab0ed88cc2a569de36ba93e5fa .circleci/config.yml -@@ -1,3 +1,4 @@ -+<<<<<<< .our - notify-slack-failure: ¬ify-slack-failure - run: - name: Send a slack notification on failure -@@ -19,6 +20,8 @@ - fi - when: on_success - -+======= -+>>>>>>> .their - build-steps: &build-steps - steps: - - checkout -@@ -122,7 +125,11 @@ - script/verify-ffmpeg.py - else - echo 'Verifying ffmpeg on release build' -+<<<<<<< .our - script/verify-ffmpeg.py -c R -+======= -+ script/verify-ffmpeg.py -R -+>>>>>>> .their - fi - else - echo 'Skipping tests due to configuration' -@@ -134,8 +141,11 @@ - if [ "$CREATE_TYPESCRIPT_DEFS" == "true" ]; then - npm run create-typescript-definitions - fi -+<<<<<<< .our - - <<: *notify-slack-failure - - <<: *notify-slack-success -+======= -+>>>>>>> .their - - persist_to_workspace: - root: out - paths: -@@ -147,6 +157,7 @@ - - store_artifacts: - path: out - -+<<<<<<< .our - gn-build-steps: &gn-build-steps - steps: - - run: -@@ -344,6 +355,8 @@ - xcode: "8.3.3" - resource_class: large - -+======= -+>>>>>>> .their - build-defaults: &build-defaults - docker: - - image: electronbuilds/electron:0.0.8 -@@ -386,7 +399,10 @@ - environment: - TARGET_ARCH: arm - RUN_RELEASE_BUILD: true -+<<<<<<< .our - NIGHTLY_BUILD: true -+======= -+>>>>>>> .their - <<: *build-defaults - resource_class: 2xlarge - -@@ -425,7 +441,10 @@ - environment: - TARGET_ARCH: arm64 - RUN_RELEASE_BUILD: true -+<<<<<<< .our - NIGHTLY_BUILD: true -+======= -+>>>>>>> .their - <<: *build-defaults - resource_class: 2xlarge - -@@ -442,7 +461,10 @@ - environment: - TARGET_ARCH: ia32 - RUN_RELEASE_BUILD: true -+<<<<<<< .our - NIGHTLY_BUILD: true -+======= -+>>>>>>> .their - <<: *build-defaults - resource_class: xlarge - -@@ -466,7 +488,10 @@ - environment: - TARGET_ARCH: x64 - RUN_RELEASE_BUILD: true -+<<<<<<< .our - NIGHTLY_BUILD: true -+======= -+>>>>>>> .their - <<: *build-defaults - resource_class: xlarge - -@@ -484,7 +509,10 @@ - TARGET_ARCH: x64 - RUN_RELEASE_BUILD: true - INSTALL_MACOS_NODE: true -+<<<<<<< .our - NIGHTLY_BUILD: true -+======= -+>>>>>>> .their - macos: - xcode: "8.3.3" - <<: *build-steps -@@ -505,11 +533,15 @@ - MAS_BUILD: 1 - RUN_RELEASE_BUILD: true - INSTALL_MACOS_NODE: true -+<<<<<<< .our - NIGHTLY_BUILD: true -+======= -+>>>>>>> .their - macos: - xcode: "8.3.3" - <<: *build-steps - -+<<<<<<< .our - electron-gn-linux-x64-debug-fyi: - environment: - DISPLAY: ':99.0' -@@ -668,6 +700,8 @@ - GN_EXTRA_ARGS: 'is_mas_build = true' - <<: *gn-mac-build-machine - <<: *gn-mac-build-steps -+======= -+>>>>>>> .their - - workflows: - version: 2 -@@ -695,6 +729,7 @@ - build-mas-x64: - jobs: - - electron-mas-x64 -+<<<<<<< .our - build-gn-linux: - jobs: - - electron-gn-linux-x64-debug-fyi -@@ -711,6 +746,8 @@ - - electron-gn-mas-testing-fyi - - electron-gn-osx-debug-fyi - - electron-gn-osx-testing-fyi -+======= -+>>>>>>> .their - - nightly-release-test: - triggers: -@@ -720,7 +757,10 @@ - branches: - only: - - master -+<<<<<<< .our - - 3-0-x -+======= -+>>>>>>> .their - - 2-0-x - - 1-8-x - - 1-7-x -@@ -730,6 +770,7 @@ - - electron-linux-ia32-release-nightly - - electron-linux-x64-release-nightly - -+<<<<<<< .our - nightly-gn-release-test: - triggers: - - schedule: -@@ -745,3 +786,13 @@ - - electron-gn-linux-arm64-release-fyi - - electron-gn-mas-release-fyi - - electron-gn-osx-release-fyi -+======= -+experimental: -+ notify: -+ branches: -+ only: -+ - master -+ - 2-0-x -+ - 1-8-x -+ - 1-7-x -+>>>>>>> .their -added in both - our 100644 cd15610276869944caf77c06906f6fb5315ebd3e .env.example - their 100644 c2af9cb1f737c66d0c2512f93ac1365b627f440f .env.example -@@ -4,4 +4,8 @@ - APPVEYOR_TOKEN= - CIRCLE_TOKEN= - ELECTRON_GITHUB_TOKEN= --VSTS_TOKEN= -\ No newline at end of file -+<<<<<<< .our -+VSTS_TOKEN= -+======= -+VSTS_TOKEN= -+>>>>>>> .their -added in both - our 100644 e9c110640201b62255ffa62eea2a6f4ccbadb34f .github/ISSUE_TEMPLATE.md - their 100644 7a21d0e22a6442a1cc509acbdb4ca9bf865a3014 .github/ISSUE_TEMPLATE.md -@@ -7,11 +7,19 @@ - - If you need general advice, join our Slack: http://atom-slack.herokuapp.com - --> - -+<<<<<<< .our - * Output of `node_modules/.bin/electron --version`: - * Operating System (Platform and Version): - - <!-- If this used to work --> - * Output of `node_modules/.bin/electron --version` on last known working Electron version (if applicable): -+======= -+* Electron version: -+* Operating system: -+ -+<!-- If this used to work --> -+* Last known working Electron version: -+>>>>>>> .their - - ### Expected behavior - -added in both - our 100644 10cb69a7a8e4ca3b2e9ca08515eacced297bb277 .github/ISSUE_TEMPLATE/Bug_report.md - their 100644 a5cad57bfaef1e29296926448a251d1fe3e5419f .github/ISSUE_TEMPLATE/Bug_report.md -@@ -1,3 +1,4 @@ -+<<<<<<< .our - --- - name: Bug report - about: Create a report to help us improve Electron -@@ -30,3 +31,37 @@ - - **Additional Information** - Add any other context about the problem here. -+======= -+--- -+name: Bug report -+about: Create a report to help us improve Electron -+ -+--- -+ -+* Electron Version: -+* Operating System (Platform and Version): -+* Last known working Electron version: -+ -+**Expected Behavior** -+A clear and concise description of what you expected to happen. -+ -+**Actual behavior** -+A clear and concise description of what actually happened. -+ -+**To Reproduce** -+Your best chance of getting this bug looked at quickly is to provide a REPOSITORY that can be cloned and run. -+ -+You can fork [electron-quick-start](https://github.com/electron/electron-quick-start) and include a link to the branch with your changes. -+ -+If you provide a URL, please list the commands required to clone/setup/run your repo e.g. -+```sh -+$ git clone $YOUR_URL -b $BRANCH -+$ npm install -+$ npm start || electron . -+``` -+**Screenshots** -+If applicable, add screenshots to help explain your problem. -+ -+**Additional Information** -+Add any other context about the problem here. -+>>>>>>> .their -added in both - our 100644 51c2e6c8d52c9343a0853d2d2ec5b205a3aca790 .github/ISSUE_TEMPLATE/Feature_request.md - their 100644 9f3aa9e21d7bf082f3d486f49603406bb10fd8f5 .github/ISSUE_TEMPLATE/Feature_request.md -@@ -1,3 +1,4 @@ -+<<<<<<< .our - --- - name: Feature request - about: Suggest an idea for Electron -@@ -15,3 +16,22 @@ - - **Additional context** - Add any other context or screenshots about the feature request here. -+======= -+--- -+name: Feature request -+about: Suggest an idea for Electron -+ -+--- -+ -+**Is your feature request related to a problem? Please describe.** -+A clear and concise description of what the problem is. -+ -+**Describe the solution you'd like** -+A clear and concise description of what you want to happen. -+ -+**Describe alternatives you've considered** -+A clear and concise description of any alternative solutions or features you've considered. -+ -+**Additional context** -+Add any other context or screenshots about the feature request here. -+>>>>>>> .their -added in both - our 100644 67a1646fee28c2c19cd1ec7301b587c0c8d6cb66 .github/PULL_REQUEST_TEMPLATE.md - their 100644 9a2d96970f629ee5eedadaac694d2423f6fb6005 .github/PULL_REQUEST_TEMPLATE.md -@@ -1,4 +1,7 @@ -+<<<<<<< .our - ##### Description of Change -+======= -+>>>>>>> .their - <!-- - Thank you for your Pull Request. Please provide a description above and review - the requirements below. -@@ -13,10 +16,14 @@ - - [ ] `npm test` passes - - [ ] tests are [changed or added](https://github.com/electron/electron/blob/master/docs/development/testing.md) - - [ ] relevant documentation is changed or added -+<<<<<<< .our - - [ ] PR title follows semantic [commit guidelines](https://github.com/electron/electron/blob/master/docs/development/pull-requests.md#commit-message-guidelines) - - - ##### Release Notes - <!-- Used to describe release notes for future release versions. See https://github.com/electron/clerk/blob/master/README.md for details. --> - --Notes: <!-- One-line Change Summary Here--> -\ No newline at end of file -+Notes: <!-- One-line Change Summary Here--> -+======= -+- [ ] commit messages or PR title follow semantic [commit guidelines](https://github.com/electron/electron/blob/master/docs/development/pull-requests.md#commit-message-guidelines) -+>>>>>>> .their -added in both - our 100644 ff8d1b64f1b2f68ceaf63ce74ede3b01625586ba .github/config.yml - their 100644 3c222c2f14dcbcab344059e6e4031edec6935f3c .github/config.yml -@@ -12,7 +12,11 @@ - newPRWelcomeComment: | - 💖 Thanks for opening this pull request! 💖 - -+<<<<<<< .our - We use [semantic commit messages](https://github.com/electron/electron/blob/master/docs/development/pull-requests.md#commit-message-guidelines) to streamline the release process. Before your pull request can be merged, you should **update your pull request title** to start with a semantic prefix. -+======= -+ We use [semantic commit messages](https://github.com/electron/electron/blob/master/docs/development/pull-requests.md#commit-message-guidelines) to streamline the release process. Before your pull request can be merged, you should **update your pull request title** to start with a semantic prefix, OR prefix at least one of your commit messages. -+>>>>>>> .their - - Examples of commit messages with semantic prefixes: - -added in both - our 100644 f393b1cdcef87b41bb3ed47ebae59757fed3a780 .gitignore - their 100644 665fb6fa10444592991a714828b60ca08daa4a2f .gitignore -@@ -50,5 +50,8 @@ - # npm package - /npm/dist - /npm/path.txt -+<<<<<<< .our - --.npmrc -\ No newline at end of file -+.npmrc -+======= -+>>>>>>> .their -added in both - our 100644 d00c4b1e3d3523641210ff20fda41d76c9eb546c BUILD.gn - their 100644 4a71e5550f6c7b8b74fcd15ceffdace06c8f9f52 BUILD.gn -@@ -1,5 +1,6 @@ - import("//build/config/locales.gni") - import("//tools/grit/repack.gni") -+<<<<<<< .our - import("//tools/v8_context_snapshot/v8_context_snapshot.gni") - import("build/asar.gni") - import("build/npm.gni") -@@ -7,6 +8,10 @@ - import("//build/config/win/manifest.gni") - import("electron_paks.gni") - import("//third_party/ffmpeg/ffmpeg_options.gni") -+======= -+import("build/asar.gni") -+import("build/npm.gni") -+>>>>>>> .their - - if (is_mac) { - import("//build/config/mac/rules.gni") -@@ -31,6 +36,7 @@ - - enable_desktop_capturer = true - enable_run_as_node = true -+<<<<<<< .our - enable_osr = false - } - -@@ -47,6 +53,20 @@ - ], - "scope", - [ "filenames.gypi" ]) -+======= -+ enable_osr = true -+} -+ -+filenames_gypi = exec_script( -+ "//build/gypi_to_gn.py", -+ [ -+ rebase_path("filenames.gypi"), -+ "--replace=<(SHARED_INTERMEDIATE_DIR)=$target_gen_dir", -+ ], -+ "scope", -+ [ "filenames.gypi" ] -+) -+>>>>>>> .their - - config("branding") { - defines = [ -@@ -68,6 +88,7 @@ - } - } - -+<<<<<<< .our - npm_action("atom_browserify_sandbox") { - deps = [ - ":atom_js2c_copy", -@@ -85,6 +106,59 @@ - "./lib/sandboxed_renderer/api/exports/path.js:path", - "-r", - "./lib/sandboxed_renderer/api/exports/child_process.js:child_process", -+======= -+config("native_mate_config") { -+ include_dirs = [ -+ "//third_party/native_mate", -+ ] -+ cflags_cc = [ -+ "-Wno-deprecated-declarations", -+ ] -+ cflags_objcc = cflags_cc -+} -+ -+source_set("native_mate") { -+ deps = [ -+ "//base", -+ "//net", -+ "//v8:v8_headers", -+ "build/node", -+ ] -+ public_configs = [ ":native_mate_config" ] -+ sources = [ -+ "//third_party/native_mate/native_mate/arguments.cc", -+ "//third_party/native_mate/native_mate/arguments.h", -+ "//third_party/native_mate/native_mate/compat.h", -+ "//third_party/native_mate/native_mate/constructor.h", -+ "//third_party/native_mate/native_mate/converter.cc", -+ "//third_party/native_mate/native_mate/converter.h", -+ "//third_party/native_mate/native_mate/dictionary.cc", -+ "//third_party/native_mate/native_mate/dictionary.h", -+ "//third_party/native_mate/native_mate/function_template.cc", -+ "//third_party/native_mate/native_mate/function_template.h", -+ "//third_party/native_mate/native_mate/handle.h", -+ "//third_party/native_mate/native_mate/object_template_builder.cc", -+ "//third_party/native_mate/native_mate/object_template_builder.h", -+ "//third_party/native_mate/native_mate/persistent_dictionary.cc", -+ "//third_party/native_mate/native_mate/persistent_dictionary.h", -+ "//third_party/native_mate/native_mate/scoped_persistent.h", -+ "//third_party/native_mate/native_mate/wrappable.cc", -+ "//third_party/native_mate/native_mate/wrappable.h", -+ "//third_party/native_mate/native_mate/wrappable_base.h", -+ ] -+} -+ -+npm_action("atom_browserify_sandbox") { -+ deps = [ ":atom_js2c_copy" ] -+ -+ sandbox_args = [ -+ "lib/sandboxed_renderer/init.js", -+ "-r", "./lib/sandboxed_renderer/api/exports/electron.js:electron", -+ "-r", "./lib/sandboxed_renderer/api/exports/fs.js:fs", -+ "-r", "./lib/sandboxed_renderer/api/exports/os.js:os", -+ "-r", "./lib/sandboxed_renderer/api/exports/path.js:path", -+ "-r", "./lib/sandboxed_renderer/api/exports/child_process.js:child_process", -+>>>>>>> .their - ] - - inputs = [ -@@ -95,6 +169,7 @@ - "lib/sandboxed_renderer/api/exports/path.js", - "lib/sandboxed_renderer/api/exports/child_process.js", - ] -+<<<<<<< .our - outputs = [ - "$target_gen_dir/js2c/preload_bundle.js", - ] -@@ -123,6 +198,26 @@ - "-o", - rebase_path(outputs[0]), - ] -+======= -+ outputs = [ "$target_gen_dir/js2c/preload_bundle.js" ] -+ -+ script = "browserify" -+ args = sandbox_args + [ -+ "-o", rebase_path(outputs[0]) -+ ] -+} -+ -+npm_action("atom_browserify_isolated") { -+ deps = [ ":atom_js2c_copy" ] -+ -+ inputs = [ "lib/isolated_renderer/init.js" ] -+ outputs = [ "$target_gen_dir/js2c/isolated_bundle.js" ] -+ -+ script = "browserify" -+ args = inputs + [ -+ "-o", rebase_path(outputs[0]) -+ ] -+>>>>>>> .their - } - - copy("atom_js2c_copy") { -@@ -130,16 +225,26 @@ - "lib/common/asar.js", - "lib/common/asar_init.js", - ] -+<<<<<<< .our - outputs = [ - "$target_gen_dir/js2c/{{source_file_part}}", - ] -+======= -+ outputs = [ "$target_gen_dir/js2c/{{source_file_part}}" ] -+>>>>>>> .their - } - - action("atom_js2c") { - deps = [ -+<<<<<<< .our - ":atom_browserify_isolated", - ":atom_browserify_sandbox", - ":atom_js2c_copy", -+======= -+ ":atom_js2c_copy", -+ ":atom_browserify_sandbox", -+ ":atom_browserify_isolated", -+>>>>>>> .their - ] - - js2c_sources = filenames_gypi.js2c_sources -@@ -151,6 +256,7 @@ - - inputs = js2c_sources + browserify_sources - -+<<<<<<< .our - outputs = [ - "$target_gen_dir/atom_natives.h", - ] -@@ -159,10 +265,21 @@ - args = [ rebase_path("//third_party/electron_node") ] + - rebase_path(outputs, root_build_dir) + - [ rebase_path("$target_gen_dir/js2c", root_build_dir) ] -+======= -+ outputs = [ "$target_gen_dir/atom_natives.h" ] -+ -+ script = "tools/js2c.py" -+ args = [ -+ rebase_path("//third_party/electron_node") -+ ] + rebase_path(outputs, root_build_dir) + [ -+ rebase_path("$target_gen_dir/js2c", root_build_dir) -+ ] -+>>>>>>> .their - } - - asar("js2asar") { - sources = filenames_gypi.js_sources -+<<<<<<< .our - if (enable_desktop_capturer) { - sources += [ - "lib/browser/desktop-capturer.js", -@@ -172,11 +289,15 @@ - outputs = [ - "$root_out_dir/resources/electron.asar", - ] -+======= -+ outputs = [ "$root_out_dir/resources/electron.asar" ] -+>>>>>>> .their - root = "lib" - } - - asar("app2asar") { - sources = filenames_gypi.default_app_sources -+<<<<<<< .our - outputs = [ - "$root_out_dir/resources/default_app.asar", - ] -@@ -187,10 +308,25 @@ - configs += [ "//v8:external_startup_data" ] - configs += [ "//third_party/electron_node:node_internals" ] - -+======= -+ outputs = [ "$root_out_dir/resources/default_app.asar" ] -+ root = "default_app" -+} -+ -+group("electron") { -+ deps = [ ":electron_lib" ] -+} -+ -+static_library("electron_lib") { -+ configs += [ -+ "//v8:external_startup_data", -+ ] -+>>>>>>> .their - public_configs = [ - ":branding", - ":features", - ] -+<<<<<<< .our - - deps = [ - ":atom_js2c", -@@ -198,15 +334,22 @@ - "native_mate", - "//base", - "//base:i18n", -+======= -+ deps = [ -+>>>>>>> .their - "//chrome/common:constants", - "//components/cdm/renderer", - "//components/network_session_configurator/common", - "//components/prefs", - "//components/printing/common", - "//components/security_state/content", -+<<<<<<< .our - "//components/viz/service", - "//content/public/app:both", - "//content/public/child", -+======= -+ "//content/public/browser", -+>>>>>>> .their - "//device/geolocation", - "//gin", - "//net:net_resources", -@@ -214,6 +357,7 @@ - "//ppapi/proxy", - "//ppapi/shared_impl", - "//printing", -+<<<<<<< .our - "//services/device/wake_lock/power_save_blocker", # TODO: this requires a visibility patch to chromium src - "//skia", - "//third_party/WebKit/public:blink", -@@ -228,10 +372,64 @@ - "//v8", - ] - -+======= -+ "//services/device/wake_lock/power_save_blocker", # TODO: this requires a visibility patch to chromium src -+ "//skia", -+ "//third_party/WebKit/public:blink", -+ "//third_party/boringssl", -+ "//third_party/crashpad/crashpad/client", -+ "//third_party/leveldatabase", -+ "//third_party/libyuv", -+ "//third_party/webrtc/modules/desktop_capture", -+ "//third_party/webrtc/modules/desktop_capture:primitives", -+ "//ui/events:dom_keycode_converter", -+ "//ui/views", -+ "//v8", -+ ":atom_js2c", -+ ":native_mate", -+ "brightray", -+ "build/node", -+ ] -+ if (is_mac) { -+ deps += [ -+ "//ui/accelerated_widget_mac", -+ "//base/allocator:features", -+ ] -+ } -+ if (is_linux) { -+ deps += [ -+ "//build/config/linux/gtk3", -+ "//chrome/browser/ui/libgtkui", -+ "//device/bluetooth", -+ "//third_party/breakpad:client", -+ "//ui/events/devices/x11", -+ "//ui/events/platform/x11", -+ "//ui/native_theme", -+ "//ui/views/controls/webview", -+ "//ui/wm", -+ ] -+ configs += [ ":gio_unix" ] -+ } -+ defines = [ -+ # This is defined in skia/skia_common.gypi. -+ "SK_SUPPORT_LEGACY_GETTOPDEVICE", -+ # Disable warnings for g_settings_list_schemas. -+ "GLIB_DISABLE_DEPRECATION_WARNINGS", -+ -+ # Import V8 symbols from shared library (node.dll / libnode.so) -+ "USING_V8_SHARED", -+ "USING_V8_PLATFORM_SHARED", -+ "USING_V8_BASE_SHARED", -+ -+ # Enables SkBitmap size 64 operations -+ #"SK_SUPPORT_LEGACY_SAFESIZE64", # doesn't seem to be needed to build? -+ ] -+>>>>>>> .their - include_dirs = [ - "chromium_src", - ".", - "$target_gen_dir", -+<<<<<<< .our - - # TODO(nornagon): replace usage of SchemeRegistry by an actually exported - # API of blink, then delete this include dir. -@@ -240,6 +438,21 @@ - - defines = [] - libs = [] -+======= -+ # TODO(nornagon): replace usage of SchemeRegistry by an actually exported -+ # API of blink, then delete this include dir. -+ "//third_party/WebKit/Source", -+ # NOTE(nornagon): other chromium files use the full path to include -+ # crashpad; this is just here for compatibility between GN and GYP, so that -+ # the #includes can be agnostic about where crashpad is vendored. -+ "//third_party/crashpad", -+ ] -+ if (is_linux) { -+ include_dirs += [ -+ "//third_party/breakpad", -+ ] -+ } -+>>>>>>> .their - - extra_source_filters = [] - if (!is_linux) { -@@ -249,7 +462,10 @@ - "*_x11.cc", - "*_gtk.h", - "*_gtk.cc", -+<<<<<<< .our - "*\blibrary_loaders/*", -+======= -+>>>>>>> .their - ] - } - if (!is_win) { -@@ -268,6 +484,7 @@ - ] - } - -+<<<<<<< .our - set_sources_assignment_filter( - sources_assignment_filter + extra_source_filters) - sources = filenames_gypi.lib_sources -@@ -349,6 +566,12 @@ - deps += [ "//pdf" ] - } - -+======= -+ set_sources_assignment_filter(sources_assignment_filter + extra_source_filters) -+ sources = filenames_gypi.lib_sources -+ set_sources_assignment_filter(sources_assignment_filter) -+ -+>>>>>>> .their - if (enable_run_as_node) { - sources += [ - "atom/app/node_main.cc", -@@ -371,18 +594,27 @@ - "atom/browser/osr/osr_web_contents_view_mac.mm", - ] - deps += [ -+<<<<<<< .our - "//components/viz/service", - "//ui/compositor", -+======= -+ "//ui/compositor", -+ "//components/viz/service", -+>>>>>>> .their - ] - } - - if (enable_desktop_capturer) { -+<<<<<<< .our - deps += [ "//third_party/webrtc/modules/desktop_capture" ] -+======= -+>>>>>>> .their - sources += [ - "atom/browser/api/atom_api_desktop_capturer.cc", - "atom/browser/api/atom_api_desktop_capturer.h", - ] - } -+<<<<<<< .our - } - - electron_paks("packed_resources") { -@@ -391,32 +623,69 @@ - copy_data_to_bundle = true - } else { - output_dir = root_out_dir -+======= -+ -+ if (is_mac) { -+ libs = [ -+ "Squirrel.framework", -+ "ReactiveCocoa.framework", -+ "Mantle.framework", -+ ] -+ cflags_objcc = [ -+ "-F", rebase_path("external_binaries", root_build_dir) -+ ] -+ if (true) { # !is_mas_build -+ # ReactiveCocoa which is used by Squirrel requires using __weak. -+ cflags_objcc += [ "-fobjc-weak" ] -+ } -+ } -+ if (is_linux) { -+ sources += filenames_gypi.lib_sources_linux -+ sources += filenames_gypi.lib_sources_nss -+>>>>>>> .their - } - } - - if (is_mac) { - electron_framework_name = electron_product_name + " Framework" - electron_helper_name = electron_product_name + " Helper" -+<<<<<<< .our - electron_login_helper_name = electron_product_name + " Login Helper" -+======= -+>>>>>>> .their - electron_framework_version = "A" - electron_mac_bundle_id = "com.$electron_company_abbr.$electron_project_name" - - mac_xib_bundle_data("electron_xibs") { -+<<<<<<< .our - sources = [ - "atom/common/resources/mac/MainMenu.xib", - ] -+======= -+ sources = [ "atom/common/resources/mac/MainMenu.xib" ] -+>>>>>>> .their - } - - bundle_data("electron_framework_resources") { - public_deps = [ -+<<<<<<< .our - ":packed_resources", - ] - sources = [] -+======= -+ "//content/shell:pak", -+ ":electron_locales", -+ ] -+ sources = [ -+ "$root_out_dir/content_shell.pak", -+ ] -+>>>>>>> .their - if (icu_use_data_file) { - sources += [ "$root_out_dir/icudtl.dat" ] - public_deps += [ "//third_party/icu:icudata" ] - } - if (v8_use_external_startup_data) { -+<<<<<<< .our - sources += [ "$root_out_dir/natives_blob.bin" ] - public_deps += [ "//v8" ] - if (use_v8_context_snapshot) { -@@ -425,12 +694,20 @@ - } else { - sources += [ "$root_out_dir/snapshot_blob.bin" ] - } -+======= -+ sources += [ -+ "$root_out_dir/natives_blob.bin", -+ "$root_out_dir/snapshot_blob.bin", -+ ] -+ public_deps += [ "//v8" ] -+>>>>>>> .their - } - outputs = [ - "{{bundle_resources_dir}}/{{source_file_part}}", - ] - } - -+<<<<<<< .our - if (!is_component_build) { - bundle_data("electron_framework_libraries") { - sources = [] -@@ -453,6 +730,19 @@ - } - - bundle_data("electron_crashpad_helper") { -+======= -+ bundle_data("electron_framework_libraries") { -+ public_deps = [ "build/node" ] -+ sources = [ -+ "$root_out_dir/libnode.dylib" -+ ] -+ outputs = [ -+ "{{bundle_contents_dir}}/Libraries/{{source_file_part}}" -+ ] -+ } -+ -+ bundle_data("electron_framework_helpers") { -+>>>>>>> .their - sources = [ - "$root_out_dir/crashpad_handler", - ] -@@ -470,6 +760,7 @@ - output_name = electron_framework_name - framework_version = electron_framework_version - framework_contents = [ "Resources" ] -+<<<<<<< .our - public_deps = [ - ":electron_lib", - ] -@@ -485,6 +776,25 @@ - extra_substitutions = [ "ATOM_BUNDLE_ID=$electron_mac_bundle_id.framework" ] - - include_dirs = [ "." ] -+======= -+ public_deps = [ ":electron_lib" ] -+ deps = [ -+ "//base", -+ "//base:i18n", -+ ":electron_framework_helpers", -+ ":electron_framework_libraries", -+ ":electron_framework_resources", -+ ":electron_xibs", -+ ] -+ info_plist = "atom/common/resources/mac/Info.plist" -+ extra_substitutions = [ -+ "ATOM_BUNDLE_ID=$electron_mac_bundle_id.framework", -+ ] -+ -+ include_dirs = [ -+ ".", -+ ] -+>>>>>>> .their - sources = filenames_gypi.framework_sources - - libs = [ -@@ -497,8 +807,12 @@ - "StoreKit.framework", - ] - ldflags = [ -+<<<<<<< .our - "-F", - rebase_path("external_binaries", root_build_dir), -+======= -+ "-F", rebase_path("external_binaries", root_build_dir), -+>>>>>>> .their - "-Wl,-install_name,@rpath/$output_name.framework/$output_name", - "-rpath", - "@loader_path/Libraries", -@@ -506,13 +820,18 @@ - if (is_component_build) { - ldflags += [ - "-rpath", -+<<<<<<< .our - "@executable_path/../../../../../..", -+======= -+ "@executable_path/../../../../../.." -+>>>>>>> .their - ] - } - } - - mac_app_bundle("electron_helper_app") { - output_name = electron_helper_name -+<<<<<<< .our - deps = [ - ":electron_framework+link", - ] -@@ -520,6 +839,15 @@ - include_dirs = [ "." ] - info_plist = "atom/renderer/resources/mac/Info.plist" - extra_substitutions = [ "ATOM_BUNDLE_ID=$electron_mac_bundle_id.helper" ] -+======= -+ deps = [ ":electron_framework+link" ] -+ sources = filenames_gypi.app_sources -+ include_dirs = [ "." ] -+ info_plist = "atom/renderer/resources/mac/Info.plist" -+ extra_substitutions = [ -+ "ATOM_BUNDLE_ID=$electron_mac_bundle_id.helper", -+ ] -+>>>>>>> .their - ldflags = [ - "-rpath", - "@executable_path/../../..", -@@ -530,6 +858,7 @@ - sources = [ - "$root_out_dir/$electron_framework_name.framework", - "$root_out_dir/$electron_helper_name.app", -+<<<<<<< .our - ] - if (!is_mas_build) { - sources += [ -@@ -538,6 +867,12 @@ - "external_binaries/Squirrel.framework", - ] - } -+======= -+ "external_binaries/Squirrel.framework", -+ "external_binaries/ReactiveCocoa.framework", -+ "external_binaries/Mantle.framework", -+ ] -+>>>>>>> .their - outputs = [ - "{{bundle_contents_dir}}/Frameworks/{{source_file_part}}", - ] -@@ -547,6 +882,7 @@ - ] - } - -+<<<<<<< .our - mac_app_bundle("electron_login_helper") { - output_name = electron_login_helper_name - sources = filenames_gypi.login_helper_sources -@@ -581,6 +917,44 @@ - outputs = [ - "{{bundle_resources_dir}}/{{source_file_part}}", - ] -+======= -+ bundle_data("electron_app_resources") { -+ public_deps = [ -+ ":js2asar", -+ ":app2asar", -+ ] -+ sources = [ -+ "$root_out_dir/resources/electron.asar", -+ "$root_out_dir/resources/default_app.asar", -+ ] -+ outputs = [ -+ "{{bundle_resources_dir}}/{{source_file_part}}" -+ ] -+ } -+ -+ repack_locales("electron_locales") { -+ source_patterns = [ -+ "${root_gen_dir}/content/app/strings/content_strings_", -+ ] -+ deps = [ -+ "//content/app/strings", -+ ] -+ -+ input_locales = locales -+ -+ if (is_mac) { -+ output_locales = locales_as_mac_outputs -+ } else { -+ output_locales = locales -+ } -+ -+ if (is_mac) { -+ output_dir = "$root_gen_dir/repack" -+ copy_data_to_bundle = true -+ } else { -+ output_dir = root_out_dir -+ } -+>>>>>>> .their - } - - mac_app_bundle("electron_app") { -@@ -591,16 +965,24 @@ - ":electron_app_framework_bundle_data", - ":electron_app_resources", - ] -+<<<<<<< .our - if (is_mas_build) { - deps += [ ":electron_login_helper_app" ] - } - info_plist = "atom/browser/resources/mac/Info.plist" - extra_substitutions = [ "ATOM_BUNDLE_ID=$electron_mac_bundle_id" ] -+======= -+ info_plist = "atom/browser/resources/mac/Info.plist" -+ extra_substitutions = [ -+ "ATOM_BUNDLE_ID=$electron_mac_bundle_id", -+ ] -+>>>>>>> .their - ldflags = [ - "-rpath", - "@executable_path/../Frameworks", - ] - } -+<<<<<<< .our - } else { - windows_manifest("electron_app_manifest") { - sources = [ -@@ -610,12 +992,18 @@ - ] - } - -+======= -+} -+ -+if (is_linux) { -+>>>>>>> .their - executable("electron_app") { - output_name = electron_project_name - sources = filenames_gypi.app_sources - include_dirs = [ "." ] - deps = [ - ":app2asar", -+<<<<<<< .our - ":electron_app_manifest", - ":electron_lib", - ":js2asar", -@@ -814,3 +1202,16 @@ - group("electron") { - deps = [ ":electron_app" ] - } -+======= -+ ":electron_lib", -+ ":js2asar", -+ "//build/config:exe_and_shlib_deps", -+ "//chrome:packed_resources", -+ "//content/shell:copy_shell_resources", -+ "//content/shell:pak", -+ "//third_party/WebKit/public:image_resources", -+ "//ui/strings", -+ ] -+ } -+} -+>>>>>>> .their -added in both - our 100644 b3b9d650b27274f4f98f7408319b1e6b35f63abf DEPS - their 100644 5c1f2337c5a6f3ec82c5b1daabf7e0b608b7afba DEPS -@@ -1,16 +1,27 @@ - vars = { - 'chromium_version': -+<<<<<<< .our - '66.0.3359.181', - 'libchromiumcontent_revision': - 'c85470a1c379b1c4bedb372c146521bc4be9b75d', - 'node_version': - 'ece0a06ac8147efb5b5af431c21f312f1884616e', -+======= -+ '63.0.3239.150', -+ 'libchromiumcontent_revision': -+ '92dc0accfae5cd133fa2a6758ae6b3ff4ff7e569', -+ 'node_version': -+ 'v9.7.0-33-g538a5023af', -+ 'native_mate_revision': -+ '4cd7d113915de0cc08e9a218be35bff9c7361906', -+>>>>>>> .their - - 'chromium_git': - 'https://chromium.googlesource.com', - - 'electron_git': - 'https://github.com/electron', -+<<<<<<< .our - - 'checkout_nacl': - False, -@@ -18,6 +29,8 @@ - True, - 'checkout_oculus_sdk': - False, -+======= -+>>>>>>> .their - } - - deps = { -@@ -27,15 +40,24 @@ - (Var("electron_git")) + '/libchromiumcontent.git@' + (Var("libchromiumcontent_revision")), - 'src/third_party/electron_node': - (Var("electron_git")) + '/node.git@' + (Var("node_version")), -+<<<<<<< .our -+======= -+ 'src/third_party/native_mate': -+ (Var("electron_git")) + '/native-mate.git@' + (Var("native_mate_revision")), -+>>>>>>> .their - } - - hooks = [ - { - 'action': [ -+<<<<<<< .our - 'python', - 'src/libchromiumcontent/script/apply-patches', - '--project-root=.', - '--commit' -+======= -+ 'src/libchromiumcontent/script/apply-patches' -+>>>>>>> .their - ], - 'pattern': - 'src/libchromiumcontent', -@@ -44,7 +66,10 @@ - }, - { - 'action': [ -+<<<<<<< .our - 'python', -+======= -+>>>>>>> .their - 'src/electron/script/update-external-binaries.py' - ], - 'pattern': -@@ -54,9 +79,26 @@ - }, - { - 'action': [ -+<<<<<<< .our - 'python', - '-c', - 'import os; os.chdir("src"); os.chdir("electron"); os.system("npm install")', -+======= -+ 'bash', -+ '-c', -+ # NOTE(nornagon): this ridiculous {{}} stuff is because these strings get -+ # variable-substituted twice by gclient. -+ 'echo -e "#\\n{{{{\'variables\':{{{{}}}}}}}}" > src/third_party/electron_node/config.gypi', -+ ], -+ 'pattern': 'src/third_party/electron_node', -+ 'name': 'touch_node_config_gypi' -+ }, -+ { -+ 'action': [ -+ 'bash', -+ '-c', -+ 'cd src/electron; npm install', -+>>>>>>> .their - ], - 'pattern': 'src/electron/package.json', - 'name': 'electron_npm_deps' -@@ -67,6 +109,7 @@ - 'src', - 'src/libchromiumcontent', - ] -+<<<<<<< .our - - gclient_gn_args = [ - 'checkout_libaom', -@@ -74,3 +117,5 @@ - 'checkout_oculus_sdk' - ] - gclient_gn_args_file = 'src/build/config/gclient_args.gni' -+======= -+>>>>>>> .their -added in remote - their 100644 d0281e481f6a6b2f0ffe25aeb309c737e3a8d228 appveyor-override.yml -@@ -0,0 +1,71 @@ -+build_cloud: electron-16 -+image: electron-16-vs2017-15.4.5 -+build_script: -+- ps: >- -+ echo "Build worker image $env:APPVEYOR_BUILD_WORKER_IMAGE" -+ -+ &"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -+ -+ if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) { -+ Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild -+ } else { -+ Add-Path "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64" -+ $env:path = "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64;$env:path" -+ if($env:APPVEYOR_SCHEDULED_BUILD -eq 'True') { -+ $env:RUN_RELEASE_BUILD = "1" -+ } -+ $Message = (git log --format=%B -n 1 HEAD) | Out-String -+ if ((Test-Path Env:\RUN_RELEASE_BUILD)) { -+ $env:ELECTRON_RELEASE = '1' -+ Write-Output "release build triggered from api" -+ } -+ if ((Test-Path Env:\ELECTRON_RELEASE)) { -+ Write-Output "Running release build" -+ python script\bootstrap.py --target_arch=$env:TARGET_ARCH -+ python script\build.py -c R -+ python script\create-dist.py -+ } else { -+ Write-Output "Running debug build" -+ python script\bootstrap.py --target_arch=$env:TARGET_ARCH --dev -+ python script\build.py -c D -+ } -+ if ($? -ne 'True') { -+ throw "Build failed with exit code $?" -+ } else { -+ "Build succeeded." -+ } -+ Push-AppveyorArtifact out -+ } -+test_script: -+- ps: >- -+ if (Test-Path Env:\ELECTRON_RELEASE) { -+ Write-Output "Skipping tests for release build" -+ } else { -+ Write-Output "Running tests for debug build" -+ python script\test.py --ci --rebuild_native_modules -+ if ($LASTEXITCODE -ne '0') { -+ throw "Tests failed with exit code $LASTEXITCODE" -+ } else { -+ Write-Output "Tests succeeded." -+ } -+ python script\verify-ffmpeg.py -+ if ($LASTEXITCODE -ne '0') { -+ throw "Verify ffmpeg failed with exit code $LASTEXITCODE" -+ } else { -+ "Verify ffmpeg succeeded." -+ } -+ } -+artifacts: -+- path: test-results.xml -+ name: test-results.xml -+deploy_script: -+- ps: >- -+ if (Test-Path Env:\ELECTRON_RELEASE) { -+ if (Test-Path Env:\RUN_RELEASE_BUILD) { -+ Write-Output "Uploading Electron release distribution to s3" -+ & python script\upload.py --upload_to_s3 -+ } else { -+ Write-Output "Uploading Electron release distribution to github releases" -+ & python script\upload.py -+ } -+ } -added in both - our 100644 fc77100d9acb58221c35f364c4db7866a44d347d atom/app/atom_main.cc - their 100644 d6f3e0a1cfa59ce910557e8b04f001db9f9ad8aa atom/app/atom_main.cc -@@ -71,7 +71,11 @@ - - #ifdef _DEBUG - // Don't display assert dialog boxes in CI test runs -+<<<<<<< .our - static const char* kCI = "ELECTRON_CI"; -+======= -+ static const auto kCI = "ELECTRON_CI"; -+>>>>>>> .their - bool is_ci = IsEnvSet(kCI); - if (!is_ci) { - for (int i = 0; i < arguments.argc; ++i) { -added in both - our 100644 b3b5b8f2a8f24b8928f69a286c80e8a3b8464366 atom/app/atom_main_delegate.cc - their 100644 40be88a55abf6b054aad50b4c20c270588ac69a9 atom/app/atom_main_delegate.cc -@@ -131,6 +131,11 @@ - brightray::MainDelegate::PreSandboxStartup(); - - auto* command_line = base::CommandLine::ForCurrentProcess(); -+<<<<<<< .our -+======= -+ std::string process_type = -+ command_line->GetSwitchValueASCII(::switches::kProcessType); -+>>>>>>> .their - - // Only append arguments for browser process. - if (!IsBrowserProcess(command_line)) -added in both - our 100644 089a2b63d1bae3afebea925582a3aac81ddeaa4f atom/browser/api/atom_api_app.cc - their 100644 b3c1bb1522bddb4cc429696e65d96ba592cab332 atom/browser/api/atom_api_app.cc -@@ -990,8 +990,12 @@ - const net::CompletionCallback& callback) { - auto browser_context = AtomBrowserContext::From("", false); - if (!certificate_manager_model_) { -+<<<<<<< .our - auto copy = base::DictionaryValue::From( - base::Value::ToUniquePtrValue(options.Clone())); -+======= -+ std::unique_ptr<base::DictionaryValue> copy = options.CreateDeepCopy(); -+>>>>>>> .their - CertificateManagerModel::Create( - browser_context.get(), - base::Bind(&App::OnCertificateManagerModelCreated, -@@ -1115,10 +1119,13 @@ - mate::Dictionary memory_dict = mate::Dictionary::CreateEmpty(isolate); - mate::Dictionary cpu_dict = mate::Dictionary::CreateEmpty(isolate); - -+<<<<<<< .our - pid_dict.SetHidden("simple", true); - memory_dict.SetHidden("simple", true); - cpu_dict.SetHidden("simple", true); - -+======= -+>>>>>>> .their - memory_dict.Set( - "workingSetSize", - static_cast<double>( -@@ -1224,7 +1231,10 @@ - .SetMethod("getName", base::Bind(&Browser::GetName, browser)) - .SetMethod("setName", base::Bind(&Browser::SetName, browser)) - .SetMethod("isReady", base::Bind(&Browser::is_ready, browser)) -+<<<<<<< .our - .SetMethod("whenReady", base::Bind(&Browser::WhenReady, browser)) -+======= -+>>>>>>> .their - .SetMethod("addRecentDocument", - base::Bind(&Browser::AddRecentDocument, browser)) - .SetMethod("clearRecentDocuments", -added in both - our 100644 ee0ad42c05fe33be17146b79cbe3422953516621 atom/browser/api/atom_api_app.h - their 100644 e9032073f6a731a55cbd5e84c0d21f51020249dc atom/browser/api/atom_api_app.h -@@ -15,7 +15,10 @@ - #include "atom/browser/browser.h" - #include "atom/browser/browser_observer.h" - #include "atom/common/native_mate_converters/callback.h" -+<<<<<<< .our - #include "atom/common/promise_util.h" -+======= -+>>>>>>> .their - #include "base/process/process_iterator.h" - #include "base/task/cancelable_task_tracker.h" - #include "chrome/browser/icon_manager.h" -added in both - our 100644 d0ae6f4ea78407c70e4cce6ff1181ce01e395133 atom/browser/api/atom_api_browser_window.cc - their 100644 1b0ed8d2950d6a2a24887bed802140372e9acc73 atom/browser/api/atom_api_browser_window.cc -@@ -55,7 +55,11 @@ - base::DictionaryValue web_preferences_dict; - if (mate::ConvertFromV8(isolate, web_preferences.GetHandle(), - &web_preferences_dict)) { -+<<<<<<< .our - existing_preferences->Clear(); -+======= -+ existing_preferences->dict()->Clear(); -+>>>>>>> .their - existing_preferences->Merge(web_preferences_dict); - } - } else { -added in both - our 100644 daccf443927abdf444845613b6e2916d167f96f3 atom/browser/api/atom_api_cookies.cc - their 100644 2f226d9210db6ed80f6960b08cfe1dc12b2f3180 atom/browser/api/atom_api_cookies.cc -@@ -264,6 +264,7 @@ - - void Cookies::Get(const base::DictionaryValue& filter, - const GetCallback& callback) { -+<<<<<<< .our - auto copy = base::DictionaryValue::From( - base::Value::ToUniquePtrValue(filter.Clone())); - auto* getter = browser_context_->GetRequestContext(); -@@ -271,6 +272,14 @@ - BrowserThread::IO, FROM_HERE, - base::BindOnce(GetCookiesOnIO, base::RetainedRef(getter), std::move(copy), - callback)); -+======= -+ std::unique_ptr<base::DictionaryValue> copied(filter.CreateDeepCopy()); -+ auto* getter = browser_context_->GetRequestContext(); -+ content::BrowserThread::PostTask( -+ BrowserThread::IO, FROM_HERE, -+ base::BindOnce(GetCookiesOnIO, base::RetainedRef(getter), -+ std::move(copied), callback)); -+>>>>>>> .their - } - - void Cookies::Remove(const GURL& url, -@@ -285,6 +294,7 @@ - - void Cookies::Set(const base::DictionaryValue& details, - const SetCallback& callback) { -+<<<<<<< .our - auto copy = base::DictionaryValue::From( - base::Value::ToUniquePtrValue(details.Clone())); - auto* getter = browser_context_->GetRequestContext(); -@@ -292,6 +302,14 @@ - BrowserThread::IO, FROM_HERE, - base::BindOnce(SetCookieOnIO, base::RetainedRef(getter), std::move(copy), - callback)); -+======= -+ std::unique_ptr<base::DictionaryValue> copied(details.CreateDeepCopy()); -+ auto* getter = browser_context_->GetRequestContext(); -+ content::BrowserThread::PostTask( -+ BrowserThread::IO, FROM_HERE, -+ base::BindOnce(SetCookieOnIO, base::RetainedRef(getter), -+ std::move(copied), callback)); -+>>>>>>> .their - } - - void Cookies::FlushStore(const base::Closure& callback) { -added in both - our 100644 e0ef26a9fc46818056581a69169395e741ce2efe atom/browser/api/atom_api_system_preferences.h - their 100644 bfd64e80159dc46806360f14fd609ba24ccc09cb atom/browser/api/atom_api_system_preferences.h -@@ -50,6 +50,14 @@ - #if defined(OS_WIN) - bool IsAeroGlassEnabled(); - -+<<<<<<< .our -+======= -+ typedef HRESULT(STDAPICALLTYPE* DwmGetColorizationColor)(DWORD*, BOOL*); -+ DwmGetColorizationColor dwmGetColorizationColor = -+ (DwmGetColorizationColor)GetProcAddress(LoadLibraryW(L"dwmapi.dll"), -+ "DwmGetColorizationColor"); -+ -+>>>>>>> .their - std::string GetAccentColor(); - std::string GetColor(const std::string& color, mate::Arguments* args); - -added in both - our 100644 0a24d1abf45fe7ff244386ea238b0e7b03b2df00 atom/browser/api/atom_api_system_preferences_win.cc - their 100644 b3fd74d59d9bcb53a23712f4a48206af191d45a6 atom/browser/api/atom_api_system_preferences_win.cc -@@ -2,7 +2,10 @@ - // Use of this source code is governed by the MIT license that can be - // found in the LICENSE file. - -+<<<<<<< .our - #include <dwmapi.h> -+======= -+>>>>>>> .their - #include <iomanip> - - #include "atom/browser/api/atom_api_system_preferences.h" -@@ -39,7 +42,11 @@ - DWORD color = 0; - BOOL opaque = FALSE; - -+<<<<<<< .our - if (FAILED(DwmGetColorizationColor(&color, &opaque))) { -+======= -+ if (FAILED(dwmGetColorizationColor(&color, &opaque))) { -+>>>>>>> .their - return ""; - } - -added in both - our 100644 c8db6b0bb468a2a722d8d830a9b2cb4bf2ce116b atom/browser/api/atom_api_top_level_window.cc - their 100644 f1f61c66752baf0b4bc5a6e94a639142b276e670 atom/browser/api/atom_api_top_level_window.cc -@@ -194,6 +194,7 @@ - Emit("restore"); - } - -+<<<<<<< .our - void TopLevelWindow::OnWindowWillResize(const gfx::Rect& new_bounds, - bool* prevent_default) { - if (Emit("will-resize", new_bounds)) { -@@ -201,6 +202,8 @@ - } - } - -+======= -+>>>>>>> .their - void TopLevelWindow::OnWindowResize() { - Emit("resize"); - } -@@ -578,10 +581,13 @@ - return window_->GetOpacity(); - } - -+<<<<<<< .our - void TopLevelWindow::SetShape(const std::vector<gfx::Rect>& rects) { - window_->widget()->SetShape(std::make_unique<std::vector<gfx::Rect>>(rects)); - } - -+======= -+>>>>>>> .their - void TopLevelWindow::SetRepresentedFilename(const std::string& filename) { - window_->SetRepresentedFilename(filename); - } -@@ -749,6 +755,7 @@ - args->ThrowError("AddTabbedWindow cannot be called by a window on itself."); - } - -+<<<<<<< .our - void TopLevelWindow::SetWindowButtonVisibility(bool visible, - mate::Arguments* args) { - if (!window_->SetWindowButtonVisibility(visible)) { -@@ -756,6 +763,8 @@ - } - } - -+======= -+>>>>>>> .their - void TopLevelWindow::SetAutoHideMenuBar(bool auto_hide) { - window_->SetAutoHideMenuBar(auto_hide); - } -@@ -828,7 +837,11 @@ - args->ThrowError(); - return false; - } -+<<<<<<< .our - auto* window = static_cast<NativeWindowViews*>(window_.get()); -+======= -+ auto window = static_cast<NativeWindowViews*>(window_.get()); -+>>>>>>> .their - return window->taskbar_host().SetThumbarButtons( - window_->GetAcceleratedWidget(), buttons); - #else -@@ -1011,7 +1024,10 @@ - .SetMethod("hasShadow", &TopLevelWindow::HasShadow) - .SetMethod("setOpacity", &TopLevelWindow::SetOpacity) - .SetMethod("getOpacity", &TopLevelWindow::GetOpacity) -+<<<<<<< .our - .SetMethod("setShape", &TopLevelWindow::SetShape) -+======= -+>>>>>>> .their - .SetMethod("setRepresentedFilename", - &TopLevelWindow::SetRepresentedFilename) - .SetMethod("getRepresentedFilename", -@@ -1049,8 +1065,11 @@ - .SetMethod("moveTabToNewWindow", &TopLevelWindow::MoveTabToNewWindow) - .SetMethod("toggleTabBar", &TopLevelWindow::ToggleTabBar) - .SetMethod("addTabbedWindow", &TopLevelWindow::AddTabbedWindow) -+<<<<<<< .our - .SetMethod("setWindowButtonVisibility", - &TopLevelWindow::SetWindowButtonVisibility) -+======= -+>>>>>>> .their - #endif - .SetMethod("setAutoHideMenuBar", &TopLevelWindow::SetAutoHideMenuBar) - .SetMethod("isMenuBarAutoHide", &TopLevelWindow::IsMenuBarAutoHide) -added in both - our 100644 ac4c7670a544abc25029314122ba6124a81cc81a atom/browser/api/atom_api_top_level_window.h - their 100644 5a76fd229c6b1cd1737199c5a502bb069e81dd64 atom/browser/api/atom_api_top_level_window.h -@@ -60,8 +60,11 @@ - void OnWindowUnmaximize() override; - void OnWindowMinimize() override; - void OnWindowRestore() override; -+<<<<<<< .our - void OnWindowWillResize(const gfx::Rect& new_bounds, - bool* prevent_default) override; -+======= -+>>>>>>> .their - void OnWindowResize() override; - void OnWindowMove() override; - void OnWindowMoved() override; -@@ -148,7 +151,10 @@ - bool HasShadow(); - void SetOpacity(const double opacity); - double GetOpacity(); -+<<<<<<< .our - void SetShape(const std::vector<gfx::Rect>& rects); -+======= -+>>>>>>> .their - void SetRepresentedFilename(const std::string& filename); - std::string GetRepresentedFilename(); - void SetDocumentEdited(bool edited); -@@ -176,7 +182,10 @@ - void MoveTabToNewWindow(); - void ToggleTabBar(); - void AddTabbedWindow(NativeWindow* window, mate::Arguments* args); -+<<<<<<< .our - void SetWindowButtonVisibility(bool visible, mate::Arguments* args); -+======= -+>>>>>>> .their - void SetAutoHideMenuBar(bool auto_hide); - bool IsMenuBarAutoHide(); - void SetMenuBarVisibility(bool visible); -added in both - our 100644 9f18d97d2656fbc5dc62b7bcea05a8acab63e847 atom/browser/api/atom_api_url_request.cc - their 100644 51c7969e31f44c9c08dbc5aa7ccc8b1e60fff863 atom/browser/api/atom_api_url_request.cc -@@ -125,6 +125,7 @@ - return IsFlagSet(ResponseStateFlags::kFailed); - } - -+<<<<<<< .our - mate::Dictionary URLRequest::GetUploadProgress(v8::Isolate* isolate) { - mate::Dictionary progress = mate::Dictionary::CreateEmpty(isolate); - -@@ -137,6 +138,8 @@ - return progress; - } - -+======= -+>>>>>>> .their - URLRequest::URLRequest(v8::Isolate* isolate, v8::Local<v8::Object> wrapper) { - InitWith(isolate, wrapper); - } -@@ -195,7 +198,10 @@ - .SetMethod("setChunkedUpload", &URLRequest::SetChunkedUpload) - .SetMethod("followRedirect", &URLRequest::FollowRedirect) - .SetMethod("_setLoadFlags", &URLRequest::SetLoadFlags) -+<<<<<<< .our - .SetMethod("getUploadProgress", &URLRequest::GetUploadProgress) -+======= -+>>>>>>> .their - .SetProperty("notStarted", &URLRequest::NotStarted) - .SetProperty("finished", &URLRequest::Finished) - // Response APi -added in both - our 100644 4a5a2b65160bf0590c9e890e52d0531b799b583a atom/browser/api/atom_api_url_request.h - their 100644 3b5e667d7590b9398b6d41632f0f016f1a6c27d5 atom/browser/api/atom_api_url_request.h -@@ -112,7 +112,10 @@ - void OnResponseData(scoped_refptr<const net::IOBufferWithSize> data); - void OnResponseCompleted(); - void OnError(const std::string& error, bool isRequestError); -+<<<<<<< .our - mate::Dictionary GetUploadProgress(v8::Isolate* isolate); -+======= -+>>>>>>> .their - - protected: - explicit URLRequest(v8::Isolate* isolate, v8::Local<v8::Object> wrapper); -added in both - our 100644 20a1ac2e672f08ffea528b6e094ba530ff8083d1 atom/browser/api/atom_api_web_contents.cc - their 100644 ce8fbeb848db9787e712f20264e0fa52f9b20405 atom/browser/api/atom_api_web_contents.cc -@@ -1075,12 +1075,30 @@ - details.is_same_document, details.did_replace_entry); - } - -+<<<<<<< .our -+======= -+int64_t WebContents::GetIDForContents(content::WebContents* web_contents) { -+ int64_t process_id = web_contents->GetMainFrame()->GetProcess()->GetID(); -+ int64_t routing_id = web_contents->GetMainFrame()->GetRoutingID(); -+ int64_t rv = (process_id << 32) + routing_id; -+ return rv; -+} -+ -+int64_t WebContents::GetID() const { -+ return WebContents::GetIDForContents(web_contents()); -+} -+ -+>>>>>>> .their - int WebContents::GetProcessID() const { - return web_contents()->GetMainFrame()->GetProcess()->GetID(); - } - - base::ProcessId WebContents::GetOSProcessID() const { -+<<<<<<< .our - base::ProcessHandle process_handle = -+======= -+ auto process_handle = -+>>>>>>> .their - web_contents()->GetMainFrame()->GetProcess()->GetHandle(); - return base::GetProcId(process_handle); - } -@@ -1090,7 +1108,11 @@ - } - - bool WebContents::Equal(const WebContents* web_contents) const { -+<<<<<<< .our - return ID() == web_contents->ID(); -+======= -+ return GetID() == web_contents->GetID(); -+>>>>>>> .their - } - - void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) { -@@ -1142,8 +1164,13 @@ - if (view) { - auto* web_preferences = WebContentsPreferences::From(web_contents()); - std::string color_name; -+<<<<<<< .our - if (web_preferences->GetPreference(options::kBackgroundColor, - &color_name)) { -+======= -+ if (web_preferences->dict()->GetString(options::kBackgroundColor, -+ &color_name)) { -+>>>>>>> .their - view->SetBackgroundColor(ParseHexColor(color_name)); - } else { - view->SetBackgroundColor(SK_ColorTRANSPARENT); -@@ -1391,10 +1418,13 @@ - return web_contents()->IsAudioMuted(); - } - -+<<<<<<< .our - bool WebContents::IsCurrentlyAudible() { - return web_contents()->IsCurrentlyAudible(); - } - -+======= -+>>>>>>> .their - void WebContents::Print(mate::Arguments* args) { - PrintSettings settings = {false, false, base::string16()}; - if (args->Length() >= 1 && !args->GetNext(&settings)) { -@@ -1823,7 +1853,11 @@ - zoom_controller_->SetZoomLevel(level); - } - -+<<<<<<< .our - double WebContents::GetZoomLevel() const { -+======= -+double WebContents::GetZoomLevel() { -+>>>>>>> .their - return zoom_controller_->GetZoomLevel(); - } - -@@ -1832,7 +1866,11 @@ - SetZoomLevel(level); - } - -+<<<<<<< .our - double WebContents::GetZoomFactor() const { -+======= -+double WebContents::GetZoomFactor() { -+>>>>>>> .their - auto level = GetZoomLevel(); - return content::ZoomLevelToZoomFactor(level); - } -@@ -1863,6 +1901,7 @@ - return v8::Null(isolate); - } - -+<<<<<<< .our - v8::Local<v8::Value> WebContents::GetWebPreferences( - v8::Isolate* isolate) const { - auto* web_preferences = WebContentsPreferences::From(web_contents()); -@@ -1880,6 +1919,24 @@ - } - - v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() const { -+======= -+v8::Local<v8::Value> WebContents::GetWebPreferences(v8::Isolate* isolate) { -+ auto* web_preferences = WebContentsPreferences::From(web_contents()); -+ if (!web_preferences) -+ return v8::Null(isolate); -+ return mate::ConvertToV8(isolate, *web_preferences->dict()); -+} -+ -+v8::Local<v8::Value> WebContents::GetLastWebPreferences(v8::Isolate* isolate) { -+ WebContentsPreferences* web_preferences = -+ WebContentsPreferences::FromWebContents(web_contents()); -+ if (!web_preferences) -+ return v8::Null(isolate); -+ return mate::ConvertToV8(isolate, *web_preferences->last_dict()); -+} -+ -+v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() { -+>>>>>>> .their - if (owner_window()) - return BrowserWindow::From(isolate(), owner_window()); - else -@@ -1961,6 +2018,10 @@ - prototype->SetClassName(mate::StringToV8(isolate, "WebContents")); - mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) - .MakeDestroyable() -+<<<<<<< .our -+======= -+ .SetMethod("getId", &WebContents::GetID) -+>>>>>>> .their - .SetMethod("getProcessId", &WebContents::GetProcessID) - .SetMethod("getOSProcessId", &WebContents::GetOSProcessID) - .SetMethod("equal", &WebContents::Equal) -@@ -1990,7 +2051,10 @@ - .SetMethod("setIgnoreMenuShortcuts", &WebContents::SetIgnoreMenuShortcuts) - .SetMethod("setAudioMuted", &WebContents::SetAudioMuted) - .SetMethod("isAudioMuted", &WebContents::IsAudioMuted) -+<<<<<<< .our - .SetMethod("isCurrentlyAudible", &WebContents::IsCurrentlyAudible) -+======= -+>>>>>>> .their - .SetMethod("undo", &WebContents::Undo) - .SetMethod("redo", &WebContents::Redo) - .SetMethod("cut", &WebContents::Cut) -added in both - our 100644 7939f8268aa8c3371623e0c15f3b6001d7f1efa4 atom/browser/api/atom_api_web_contents.h - their 100644 336ef1f33355e9c88879450c6b891d8e50806757 atom/browser/api/atom_api_web_contents.h -@@ -97,9 +97,18 @@ - static void BuildPrototype(v8::Isolate* isolate, - v8::Local<v8::FunctionTemplate> prototype); - -+<<<<<<< .our - // Notifies to destroy any guest web contents before destroying self. - void DestroyWebContents(bool async); - -+======= -+ static int64_t GetIDForContents(content::WebContents* web_contents); -+ -+ // Notifies to destroy any guest web contents before destroying self. -+ void DestroyWebContents(bool async); -+ -+ int64_t GetID() const; -+>>>>>>> .their - int GetProcessID() const; - base::ProcessId GetOSProcessID() const; - Type GetType() const; -@@ -139,7 +148,10 @@ - void SetIgnoreMenuShortcuts(bool ignore); - void SetAudioMuted(bool muted); - bool IsAudioMuted(); -+<<<<<<< .our - bool IsCurrentlyAudible(); -+======= -+>>>>>>> .their - void Print(mate::Arguments* args); - std::vector<printing::PrinterBasicInfo> GetPrinterList(); - void SetEmbedder(const WebContents* embedder); -@@ -213,9 +225,15 @@ - - // Methods for zoom handling. - void SetZoomLevel(double level); -+<<<<<<< .our - double GetZoomLevel() const; - void SetZoomFactor(double factor); - double GetZoomFactor() const; -+======= -+ double GetZoomLevel(); -+ void SetZoomFactor(double factor); -+ double GetZoomFactor(); -+>>>>>>> .their - - // Callback triggered on permission response. - void OnEnterFullscreenModeForTab(content::WebContents* source, -@@ -234,11 +252,19 @@ - v8::Local<v8::Value> GetPreloadPath(v8::Isolate* isolate) const; - - // Returns the web preferences of current WebContents. -+<<<<<<< .our - v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate) const; - v8::Local<v8::Value> GetLastWebPreferences(v8::Isolate* isolate) const; - - // Returns the owner window. - v8::Local<v8::Value> GetOwnerBrowserWindow() const; -+======= -+ v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate); -+ v8::Local<v8::Value> GetLastWebPreferences(v8::Isolate* isolate); -+ -+ // Returns the owner window. -+ v8::Local<v8::Value> GetOwnerBrowserWindow(); -+>>>>>>> .their - - // Grants the child process the capability to access URLs with the origin of - // the specified URL. -added in both - our 100644 7bcb7ab9370a8b3fe245c9569c93dbbdac0a0697 atom/browser/api/frame_subscriber.cc - their 100644 4b1234d5677e15b9c77d1e8a80e2be159b7d75e7 atom/browser/api/frame_subscriber.cc -@@ -83,7 +83,11 @@ - : frame; - - size_t rgb_row_size = bitmap.width() * bitmap.bytesPerPixel(); -+<<<<<<< .our - auto* source = static_cast<const char*>(bitmap.getPixels()); -+======= -+ auto source = static_cast<const char*>(bitmap.getPixels()); -+>>>>>>> .their - - v8::MaybeLocal<v8::Object> buffer = - node::Buffer::Copy(isolate_, source, rgb_row_size * bitmap.height()); -added in both - our 100644 d3e82855417cb59c0449f1c1b685970ffaea2af6 atom/browser/api/frame_subscriber.h - their 100644 3de976f3051139f7ebd3a63da7455faf9d69ef76 atom/browser/api/frame_subscriber.h -@@ -29,7 +29,11 @@ - content::WebContents* web_contents, - const FrameCaptureCallback& callback, - bool only_dirty); -+<<<<<<< .our - ~FrameSubscriber() override; -+======= -+ ~FrameSubscriber(); -+>>>>>>> .their - - private: - gfx::Rect GetDamageRect(); -added in both - our 100644 57c4ee582405e6d501ec23940ccb10689ecd64a1 atom/browser/atom_browser_client.cc - their 100644 06fad9e28f6888009e2be08369f8e154d4eeca0b atom/browser/atom_browser_client.cc -@@ -31,6 +31,10 @@ - #include "base/strings/string_number_conversions.h" - #include "base/strings/string_util.h" - #include "chrome/browser/printing/printing_message_filter.h" -+<<<<<<< .our -+======= -+#include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h" -+>>>>>>> .their - #include "chrome/browser/speech/tts_message_filter.h" - #include "content/public/browser/browser_ppapi_host.h" - #include "content/public/browser/client_certificate_delegate.h" -@@ -60,10 +64,13 @@ - #include "net/ssl/client_cert_store.h" - #endif - -+<<<<<<< .our - #if defined(ENABLE_PEPPER_FLASH) - #include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h" - #endif // defined(ENABLE_PEPPER_FLASH) - -+======= -+>>>>>>> .their - using content::BrowserThread; - - namespace atom { -@@ -251,11 +258,19 @@ - return; - - // Do we have an affinity site to manage ? -+<<<<<<< .our - auto* web_contents = content::WebContents::FromRenderFrameHost(rfh); - auto* web_preferences = WebContentsPreferences::From(web_contents); - std::string affinity; - if (web_preferences && - web_preferences->GetPreference("affinity", &affinity) && -+======= -+ std::string affinity; -+ auto* web_contents = content::WebContents::FromRenderFrameHost(rfh); -+ auto* web_preferences = WebContentsPreferences::From(web_contents); -+ if (web_preferences && -+ web_preferences->dict()->GetString("affinity", &affinity) && -+>>>>>>> .their - !affinity.empty()) { - affinity = base::ToLowerASCII(affinity); - auto iter = site_per_affinities.find(affinity); -@@ -343,14 +358,26 @@ - web_preferences->AppendCommandLineSwitches(command_line); - SessionPreferences::AppendExtraCommandLineSwitches( - web_contents->GetBrowserContext(), command_line); -+<<<<<<< .our -+======= -+ -+ auto context_id = atom::api::WebContents::GetIDForContents(web_contents); -+ command_line->AppendSwitchASCII(switches::kContextId, -+ base::IntToString(context_id)); -+>>>>>>> .their - } - } - - void AtomBrowserClient::DidCreatePpapiPlugin(content::BrowserPpapiHost* host) { -+<<<<<<< .our - #if defined(ENABLE_PEPPER_FLASH) - host->GetPpapiHost()->AddHostFactoryFilter( - base::WrapUnique(new ChromeBrowserPepperHostFactory(host))); - #endif -+======= -+ host->GetPpapiHost()->AddHostFactoryFilter( -+ base::WrapUnique(new chrome::ChromeBrowserPepperHostFactory(host))); -+>>>>>>> .their - } - - void AtomBrowserClient::GetGeolocationRequestContext( -added in both - our 100644 e036cbc8103f19a034ce386940462f8a23ea6807 atom/browser/atom_browser_context.cc - their 100644 ffef00da50a6da587dded419bebbf7400c9aa13e atom/browser/atom_browser_context.cc -@@ -10,7 +10,10 @@ - #include "atom/browser/atom_permission_manager.h" - #include "atom/browser/browser.h" - #include "atom/browser/request_context_delegate.h" -+<<<<<<< .our - #include "atom/browser/special_storage_policy.h" -+======= -+>>>>>>> .their - #include "atom/browser/web_view_manager.h" - #include "atom/common/atom_version.h" - #include "atom/common/chrome_version.h" -@@ -43,8 +46,12 @@ - bool in_memory, - const base::DictionaryValue& options) - : brightray::BrowserContext(partition, in_memory), -+<<<<<<< .our - url_request_context_getter_(nullptr), - storage_policy_(new SpecialStoragePolicy) { -+======= -+ url_request_context_getter_(nullptr) { -+>>>>>>> .their - // Construct user agent string. - Browser* browser = Browser::Get(); - std::string name = RemoveWhitespace(browser->GetName()); -@@ -100,10 +107,13 @@ - return permission_manager_.get(); - } - -+<<<<<<< .our - storage::SpecialStoragePolicy* AtomBrowserContext::GetSpecialStoragePolicy() { - return storage_policy_.get(); - } - -+======= -+>>>>>>> .their - void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) { - pref_registry->RegisterFilePathPref(prefs::kSelectFileLastDirectory, - base::FilePath()); -added in both - our 100644 9e6a841ceb8d11069a1a094bf7dbbd3a788918b3 atom/browser/atom_browser_context.h - their 100644 581ecc185f1227c3cd020b6f61d7f58dfd667419 atom/browser/atom_browser_context.h -@@ -8,6 +8,7 @@ - #include <string> - #include <vector> - -+<<<<<<< .our - #include "base/memory/scoped_refptr.h" - #include "brightray/browser/browser_context.h" - -@@ -15,13 +16,20 @@ - class SpecialStoragePolicy; - } - -+======= -+#include "brightray/browser/browser_context.h" -+ -+>>>>>>> .their - namespace atom { - - class AtomBlobReader; - class AtomDownloadManagerDelegate; - class AtomPermissionManager; - class RequestContextDelegate; -+<<<<<<< .our - class SpecialStoragePolicy; -+======= -+>>>>>>> .their - class WebViewManager; - - class AtomBrowserContext : public brightray::BrowserContext { -@@ -41,7 +49,10 @@ - content::DownloadManagerDelegate* GetDownloadManagerDelegate() override; - content::BrowserPluginGuestManager* GetGuestManager() override; - content::PermissionManager* GetPermissionManager() override; -+<<<<<<< .our - storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override; -+======= -+>>>>>>> .their - - // brightray::BrowserContext: - void RegisterPrefs(PrefRegistrySimple* pref_registry) override; -@@ -65,7 +76,10 @@ - std::unique_ptr<AtomDownloadManagerDelegate> download_manager_delegate_; - std::unique_ptr<WebViewManager> guest_manager_; - std::unique_ptr<AtomPermissionManager> permission_manager_; -+<<<<<<< .our - scoped_refptr<storage::SpecialStoragePolicy> storage_policy_; -+======= -+>>>>>>> .their - std::unique_ptr<AtomBlobReader> blob_reader_; - std::unique_ptr<RequestContextDelegate> request_context_delegate_; - std::string user_agent_; -added in both - our 100644 25fc326ebac3f2a5beb9199194067dae12c8229b atom/browser/atom_javascript_dialog_manager.cc - their 100644 c0c7be6302796cf774923757b466084816d897fe atom/browser/atom_javascript_dialog_manager.cc -@@ -62,7 +62,11 @@ - std::string checkbox; - if (origin_counts_[origin] > 1 && web_preferences && - web_preferences->IsEnabled("safeDialogs") && -+<<<<<<< .our - !web_preferences->GetPreference("safeDialogsMessage", &checkbox)) { -+======= -+ !web_preferences->dict()->GetString("safeDialogsMessage", &checkbox)) { -+>>>>>>> .their - checkbox = "Prevent this app from creating additional dialogs"; - } - -added in both - our 100644 ce35de64d60c6767ac52596c1b32e7bde5ceefa0 atom/browser/browser.cc - their 100644 0df8876bb620f5df7a1d0fd6ff3329c36ba5bd1b atom/browser/browser.cc -@@ -155,13 +155,17 @@ - base::CreateDirectoryAndGetError(user_data, nullptr); - - is_ready_ = true; -+<<<<<<< .our - if (ready_promise_) { - ready_promise_->Resolve(); - } -+======= -+>>>>>>> .their - for (BrowserObserver& observer : observers_) - observer.OnFinishLaunching(launch_info); - } - -+<<<<<<< .our - util::Promise* Browser::WhenReady(v8::Isolate* isolate) { - if (!ready_promise_) { - ready_promise_ = new util::Promise(isolate); -@@ -172,6 +176,8 @@ - return ready_promise_; - } - -+======= -+>>>>>>> .their - void Browser::OnAccessibilitySupportChanged() { - for (BrowserObserver& observer : observers_) - observer.OnAccessibilitySupportChanged(); -added in both - our 100644 aed7d25c37da59c0dd5e09940a064c329353a0b2 atom/browser/browser.h - their 100644 d63ac7ccac55f3e13032bb0c5b16f9f2c5acc47e atom/browser/browser.h -@@ -10,7 +10,10 @@ - - #include "atom/browser/browser_observer.h" - #include "atom/browser/window_list_observer.h" -+<<<<<<< .our - #include "atom/common/promise_util.h" -+======= -+>>>>>>> .their - #include "base/compiler_specific.h" - #include "base/macros.h" - #include "base/observer_list.h" -@@ -191,10 +194,13 @@ - base::string16 description; - base::FilePath icon_path; - int icon_index; -+<<<<<<< .our - - UserTask(); - UserTask(const UserTask&); - ~UserTask(); -+======= -+>>>>>>> .their - }; - - // Add a custom task to jump list. -@@ -245,7 +251,10 @@ - bool is_shutting_down() const { return is_shutdown_; } - bool is_quiting() const { return is_quiting_; } - bool is_ready() const { return is_ready_; } -+<<<<<<< .our - util::Promise* WhenReady(v8::Isolate* isolate); -+======= -+>>>>>>> .their - - protected: - // Returns the version of application bundle or executable file. -@@ -281,8 +290,11 @@ - - int badge_count_ = 0; - -+<<<<<<< .our - util::Promise* ready_promise_ = nullptr; - -+======= -+>>>>>>> .their - #if defined(OS_MACOSX) - base::DictionaryValue about_panel_options_; - #endif -added in both - our 100644 27e347eccebf006336d5d110c81717ecc45af9c3 atom/browser/browser_mac.mm - their 100644 19b27416a16dfedbe960ee42d6e6a98ca197a6cb atom/browser/browser_mac.mm -@@ -336,9 +336,16 @@ - for (base::DictionaryValue::Iterator iter(options); !iter.IsAtEnd(); - iter.Advance()) { - std::string key = iter.key(); -+<<<<<<< .our - if (!key.empty() && iter.value().is_string()) { - key[0] = base::ToUpperASCII(key[0]); - about_panel_options_.SetString(key, iter.value().GetString()); -+======= -+ std::string value; -+ if (!key.empty() && iter.value().GetAsString(&value)) { -+ key[0] = base::ToUpperASCII(key[0]); -+ about_panel_options_.SetString(key, value); -+>>>>>>> .their - } - } - } -added in both - our 100644 fc3b9f330a4958b0b1e30d41c2bebe091b135856 atom/browser/browser_win.cc - their 100644 d109129afbb40471006560d895d94aa7e9a0e288 atom/browser/browser_win.cc -@@ -84,10 +84,13 @@ - - } // namespace - -+<<<<<<< .our - Browser::UserTask::UserTask() = default; - Browser::UserTask::UserTask(const UserTask&) = default; - Browser::UserTask::~UserTask() = default; - -+======= -+>>>>>>> .their - void Browser::Focus() { - // On Windows we just focus on the first window found for this process. - DWORD pid = GetCurrentProcessId(); -added in both - our 100644 4ff2bcfcabfd34d8563f9ed213c03655a99dd9c6 atom/browser/native_window.cc - their 100644 4048e2a32b251859efccb22d8fc03d8a6d22d672 atom/browser/native_window.cc -@@ -355,10 +355,13 @@ - return true; - } - -+<<<<<<< .our - bool NativeWindow::SetWindowButtonVisibility(bool visible) { - return false; - } - -+======= -+>>>>>>> .their - double NativeWindow::GetAspectRatio() { - return aspect_ratio_; - } -@@ -458,12 +461,15 @@ - observer.OnWindowRestore(); - } - -+<<<<<<< .our - void NativeWindow::NotifyWindowWillResize(const gfx::Rect& new_bounds, - bool* prevent_default) { - for (NativeWindowObserver& observer : observers_) - observer.OnWindowWillResize(new_bounds, prevent_default); - } - -+======= -+>>>>>>> .their - void NativeWindow::NotifyWindowResize() { - for (NativeWindowObserver& observer : observers_) - observer.OnWindowResize(); -added in both - our 100644 35b67e2dd230692c415a32aae5f0a5e99ab74ac0 atom/browser/native_window.h - their 100644 759d7cb202101710855c3fabada43c976c8543df atom/browser/native_window.h -@@ -187,9 +187,12 @@ - virtual void ToggleTabBar(); - virtual bool AddTabbedWindow(NativeWindow* window); - -+<<<<<<< .our - // Returns false if unsupported. - virtual bool SetWindowButtonVisibility(bool visible); - -+======= -+>>>>>>> .their - // Toggle the menu bar. - virtual void SetAutoHideMenuBar(bool auto_hide); - virtual bool IsMenuBarAutoHide(); -@@ -236,8 +239,11 @@ - void NotifyWindowMinimize(); - void NotifyWindowRestore(); - void NotifyWindowMove(); -+<<<<<<< .our - void NotifyWindowWillResize(const gfx::Rect& new_bounds, - bool* prevent_default); -+======= -+>>>>>>> .their - void NotifyWindowResize(); - void NotifyWindowMoved(); - void NotifyWindowScrollTouchBegin(); -added in both - our 100644 44a78198f44cdba9875e3fb27c8e2c87eaa6f33b atom/browser/native_window_mac.h - their 100644 54891c5b35af7a88c842e95b9b72a2f2be363681 atom/browser/native_window_mac.h -@@ -119,8 +119,11 @@ - void ToggleTabBar() override; - bool AddTabbedWindow(NativeWindow* window) override; - -+<<<<<<< .our - bool SetWindowButtonVisibility(bool visible) override; - -+======= -+>>>>>>> .their - void SetVibrancy(const std::string& type) override; - void SetTouchBar( - const std::vector<mate::PersistentDictionary>& items) override; -@@ -195,10 +198,13 @@ - // The "titleBarStyle" option. - TitleBarStyle title_bar_style_ = NORMAL; - -+<<<<<<< .our - // The visibility mode of window button controls when explicitly set through - // setWindowButtonVisibility(). - base::Optional<bool> window_button_visibility_; - -+======= -+>>>>>>> .their - // Simple (pre-Lion) Fullscreen Settings - bool always_simple_fullscreen_ = false; - bool is_simple_fullscreen_ = false; -added in both - our 100644 004263ec127709067e903ffbf31003b8844226b4 atom/browser/native_window_mac.mm - their 100644 2d8149668e5988c2f26c39678a57a9780ca150c6 atom/browser/native_window_mac.mm -@@ -884,9 +884,14 @@ - // Resize the window to accomodate the _entire_ screen size - fullscreenFrame.size.height -= - [[[NSApplication sharedApplication] mainMenu] menuBarHeight]; -+<<<<<<< .our - } else if (!window_button_visibility_.has_value()) { - // Lets keep previous behaviour - hide window controls in titled - // fullscreen mode when not specified otherwise. -+======= -+ } else { -+ // No need to hide the title, but we should still hide the window buttons -+>>>>>>> .their - [[window standardWindowButton:NSWindowZoomButton] setHidden:YES]; - [[window standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES]; - [[window standardWindowButton:NSWindowCloseButton] setHidden:YES]; -@@ -905,6 +910,7 @@ - if (!fullscreen_window_title()) { - // Restore the titlebar - SetStyleMask(true, NSTitledWindowMask); -+<<<<<<< .our - } - - // Restore window controls visibility state -@@ -916,6 +922,15 @@ - [[window standardWindowButton:NSWindowCloseButton] - setHidden:window_button_hidden]; - -+======= -+ } else { -+ // Show the window buttons -+ [[window standardWindowButton:NSWindowZoomButton] setHidden:NO]; -+ [[window standardWindowButton:NSWindowMiniaturizeButton] setHidden:NO]; -+ [[window standardWindowButton:NSWindowCloseButton] setHidden:NO]; -+ } -+ -+>>>>>>> .their - [window setFrame:original_frame_ display:YES animate:YES]; - - [NSApp setPresentationOptions:simple_fullscreen_options_]; -@@ -1153,6 +1168,7 @@ - return true; - } - -+<<<<<<< .our - bool NativeWindowMac::SetWindowButtonVisibility(bool visible) { - if (title_bar_style_ == CUSTOM_BUTTONS_ON_HOVER) { - return false; -@@ -1166,6 +1182,8 @@ - return true; - } - -+======= -+>>>>>>> .their - void NativeWindowMac::SetVibrancy(const std::string& type) { - if (@available(macOS 10.10, *)) { - NSView* vibrant_view = [window_ vibrantView]; -added in both - our 100644 c2a86ea6b65cd6091fa7e8018bed0b11c7390f23 atom/browser/native_window_observer.h - their 100644 33e9eb643254c9066bfafbae993d2f98c624a5f3 atom/browser/native_window_observer.h -@@ -16,10 +16,13 @@ - #include <windows.h> - #endif - -+<<<<<<< .our - namespace gfx { - class Rect; - } - -+======= -+>>>>>>> .their - namespace atom { - - class NativeWindowObserver { -@@ -67,8 +70,11 @@ - virtual void OnWindowUnmaximize() {} - virtual void OnWindowMinimize() {} - virtual void OnWindowRestore() {} -+<<<<<<< .our - virtual void OnWindowWillResize(const gfx::Rect& new_bounds, - bool* prevent_default) {} -+======= -+>>>>>>> .their - virtual void OnWindowResize() {} - virtual void OnWindowMove() {} - virtual void OnWindowMoved() {} -added in both - our 100644 0e61d18b915924eb3d3d14e40d1cbbd199631bed atom/browser/native_window_views_win.cc - their 100644 c9802b2e0a83680a2df01e18cd2674e4d114f2af atom/browser/native_window_views_win.cc -@@ -164,7 +164,11 @@ - - const DWORD obj_id = static_cast<DWORD>(l_param); - -+<<<<<<< .our - if (obj_id != static_cast<DWORD>(OBJID_CLIENT)) { -+======= -+ if (obj_id != OBJID_CLIENT) { -+>>>>>>> .their - return false; - } - -@@ -174,7 +178,11 @@ - - checked_for_a11y_support_ = true; - -+<<<<<<< .our - auto* const axState = content::BrowserAccessibilityState::GetInstance(); -+======= -+ const auto axState = content::BrowserAccessibilityState::GetInstance(); -+>>>>>>> .their - if (axState && !axState->IsAccessibleBrowser()) { - axState->OnScreenReaderDetected(); - Browser::Get()->OnAccessibilitySupportChanged(); -@@ -187,6 +195,7 @@ - if (HIWORD(w_param) == THBN_CLICKED) - return taskbar_host_.HandleThumbarButtonEvent(LOWORD(w_param)); - return false; -+<<<<<<< .our - case WM_SIZING: { - bool prevent_default = false; - NotifyWindowWillResize(gfx::Rect(*reinterpret_cast<RECT*>(l_param)), -@@ -197,6 +206,8 @@ - } - return false; - } -+======= -+>>>>>>> .their - case WM_SIZE: { - // Handle window state change. - HandleSizeEvent(w_param, l_param); -@@ -208,8 +219,12 @@ - } - case WM_MOVING: { - if (!movable_) -+<<<<<<< .our - ::GetWindowRect(GetAcceleratedWidget(), - reinterpret_cast<RECT*>(l_param)); -+======= -+ ::GetWindowRect(GetAcceleratedWidget(), (LPRECT)l_param); -+>>>>>>> .their - return false; - } - case WM_MOVE: { -@@ -289,8 +304,11 @@ - NotifyWindowRestore(); - } - break; -+<<<<<<< .our - default: - break; -+======= -+>>>>>>> .their - } - } - break; -@@ -363,7 +381,11 @@ - // the cursor since they are in a state where they would otherwise ignore all - // mouse input. - if (w_param == WM_MOUSEMOVE) { -+<<<<<<< .our - for (auto* window : forwarding_windows_) { -+======= -+ for (auto window : forwarding_windows_) { -+>>>>>>> .their - // At first I considered enumerating windows to check whether the cursor - // was directly above the window, but since nothing bad seems to happen - // if we post the message even if some other window occludes it I have -added in both - our 100644 e71ea74317b69f31a5aac8e723902748972fed8f atom/browser/net/atom_network_delegate.cc - their 100644 ca0a3ddeba5fe980a792a27e16ab3f22214abd4d atom/browser/net/atom_network_delegate.cc -@@ -128,7 +128,11 @@ - std::string key; - std::string value; - while (headers->EnumerateHeaderLines(&iter, &key, &value)) { -+<<<<<<< .our - if (dict->FindKey(key)) { -+======= -+ if (dict->HasKey(key)) { -+>>>>>>> .their - base::ListValue* values = nullptr; - if (dict->GetList(key, &values)) - values->AppendString(value); -@@ -189,10 +193,16 @@ - headers->Clear(); - for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); - it.Advance()) { -+<<<<<<< .our - if (it.value().is_string()) { - std::string value = it.value().GetString(); - headers->SetHeader(it.key(), value); - } -+======= -+ std::string value; -+ if (it.value().GetAsString(&value)) -+ headers->SetHeader(it.key(), value); -+>>>>>>> .their - } - } - } -@@ -542,8 +552,12 @@ - uint64_t id, - T out, - const base::DictionaryValue& response) { -+<<<<<<< .our - auto copy = base::DictionaryValue::From( - base::Value::ToUniquePtrValue(response.Clone())); -+======= -+ std::unique_ptr<base::DictionaryValue> copy = response.CreateDeepCopy(); -+>>>>>>> .their - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::BindOnce(&AtomNetworkDelegate::OnListenerResultInIO<T>, -added in both - our 100644 5ffbfd65a48b4459b2ebca66a5c2259f18ed80a8 atom/browser/net/atom_url_request.cc - their 100644 94d7f4a3b1a77426b6e797999abdb7a631812684 atom/browser/net/atom_url_request.cc -@@ -501,6 +501,7 @@ - delegate_->OnError(error, isRequestError); - } - -+<<<<<<< .our - void AtomURLRequest::GetUploadProgress(mate::Dictionary* progress) const { - net::UploadProgress upload_progress; - if (request_) { -@@ -513,4 +514,6 @@ - progress->Set("total", upload_progress.size()); - } - -+======= -+>>>>>>> .their - } // namespace atom -added in both - our 100644 fde7b161385fb431b2d807012a00679a4bdb507a atom/browser/net/atom_url_request.h - their 100644 2b03ad7bc37ce6cfec1ff79ce183d37adf90749b atom/browser/net/atom_url_request.h -@@ -43,7 +43,10 @@ - void PassLoginInformation(const base::string16& username, - const base::string16& password) const; - void SetLoadFlags(int flags) const; -+<<<<<<< .our - void GetUploadProgress(mate::Dictionary* progress) const; -+======= -+>>>>>>> .their - - protected: - // Overrides of net::URLRequest::Delegate -added in both - our 100644 59e3ab881c2355c2ed29b806de59ef372c170b62 atom/browser/net/js_asker.cc - their 100644 daf978082f102937d142dcddbdd860c92c709dbe atom/browser/net/js_asker.cc -@@ -62,8 +62,13 @@ - if (dict->GetInteger("error", error)) - return true; - } else if (value->is_int()) { -+<<<<<<< .our - *error = value->GetInt(); - return true; -+======= -+ if (value->GetAsInteger(error)) -+ return true; -+>>>>>>> .their - } - return false; - } -added in both - our 100644 1c15fd39b9d479b441b0931564f9e2c3f9de37c7 atom/browser/net/url_request_async_asar_job.cc - their 100644 06959032411d27e69ec441577b7a1987a2117080 atom/browser/net/url_request_async_asar_job.cc -@@ -7,7 +7,10 @@ - #include <string> - - #include "atom/common/atom_constants.h" -+<<<<<<< .our - #include "base/strings/utf_string_conversions.h" -+======= -+>>>>>>> .their - #include "base/task_scheduler/post_task.h" - - namespace atom { -@@ -18,6 +21,7 @@ - : JsAsker<asar::URLRequestAsarJob>(request, network_delegate) {} - - void URLRequestAsyncAsarJob::StartAsync(std::unique_ptr<base::Value> options) { -+<<<<<<< .our - std::string file_path; - if (options->is_dict()) { - auto* path_value = -@@ -26,6 +30,14 @@ - file_path = path_value->GetString(); - } else if (options->is_string()) { - file_path = options->GetString(); -+======= -+ base::FilePath::StringType file_path; -+ if (options->is_dict()) { -+ static_cast<base::DictionaryValue*>(options.get()) -+ ->GetString("path", &file_path); -+ } else if (options->is_string()) { -+ options->GetAsString(&file_path); -+>>>>>>> .their - } - - if (file_path.empty()) { -@@ -36,11 +48,15 @@ - base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::USER_VISIBLE, - base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}), -+<<<<<<< .our - #if defined(OS_WIN) - base::FilePath(base::UTF8ToWide(file_path))); - #else - base::FilePath(file_path)); - #endif -+======= -+ base::FilePath(file_path)); -+>>>>>>> .their - asar::URLRequestAsarJob::Start(); - } - } -added in both - our 100644 31381ff118665f10a53e13fbe0044046738ca230 atom/browser/net/url_request_string_job.cc - their 100644 453dd0bb6615880d75f73294d22e67ec9975b7c3 atom/browser/net/url_request_string_job.cc -@@ -25,7 +25,11 @@ - dict->GetString("charset", &charset_); - dict->GetString("data", &data_); - } else if (options->is_string()) { -+<<<<<<< .our - data_ = options->GetString(); -+======= -+ options->GetAsString(&data_); -+>>>>>>> .their - } - net::URLRequestSimpleJob::Start(); - } -added in both - our 100644 ae60f3c21ca91f7065da3eb0926ee62a27cb5e97 atom/browser/render_process_preferences.cc - their 100644 1d11181776616d20bbd3c349559423b76d08aa7e atom/browser/render_process_preferences.cc -@@ -21,8 +21,12 @@ - - int RenderProcessPreferences::AddEntry(const base::DictionaryValue& entry) { - int id = ++next_id_; -+<<<<<<< .our - entries_[id] = - base::DictionaryValue::From(base::Value::ToUniquePtrValue(entry.Clone())); -+======= -+ entries_[id] = entry.CreateDeepCopy(); -+>>>>>>> .their - cache_needs_update_ = true; - return id; - } -added in both - our 100644 9094f0f7335edf833d51f688851e6a105de60433 atom/browser/resources/mac/Info.plist - their 100644 70a794e41b94870bf45efa8f692d25f8c43998cd atom/browser/resources/mac/Info.plist -@@ -17,9 +17,15 @@ - <key>CFBundleIconFile</key> - <string>electron.icns</string> - <key>CFBundleVersion</key> -+<<<<<<< .our - <string>4.0.0</string> - <key>CFBundleShortVersionString</key> - <string>4.0.0</string> -+======= -+ <string>3.0.0</string> -+ <key>CFBundleShortVersionString</key> -+ <string>3.0.0</string> -+>>>>>>> .their - <key>LSApplicationCategoryType</key> - <string>public.app-category.developer-tools</string> - <key>LSMinimumSystemVersion</key> -added in both - our 100644 c0bd831e8bddf10180f75cd40694831e2e98622d atom/browser/resources/win/atom.rc - their 100644 9d70adbd54c5d2b90a2d03384534816cb23ec725 atom/browser/resources/win/atom.rc -@@ -1,6 +1,10 @@ - // Microsoft Visual C++ generated resource script. - // -+<<<<<<< .our - #include "ui\\resources\\grit\\ui_unscaled_resources.h" -+======= -+#include "grit\\ui_unscaled_resources.h" -+>>>>>>> .their - #include "resource.h" - #include <winresrc.h> - #ifdef IDC_STATIC -@@ -56,8 +60,13 @@ - // - - VS_VERSION_INFO VERSIONINFO -+<<<<<<< .our - FILEVERSION 4,0,0,20180821 - PRODUCTVERSION 4,0,0,20180821 -+======= -+ FILEVERSION 3,0,0,7 -+ PRODUCTVERSION 3,0,0,7 -+>>>>>>> .their - FILEFLAGSMASK 0x3fL - #ifdef _DEBUG - FILEFLAGS 0x1L -@@ -74,12 +83,20 @@ - BEGIN - VALUE "CompanyName", "GitHub, Inc." - VALUE "FileDescription", "Electron" -+<<<<<<< .our - VALUE "FileVersion", "4.0.0" -+======= -+ VALUE "FileVersion", "3.0.0" -+>>>>>>> .their - VALUE "InternalName", "electron.exe" - VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." - VALUE "OriginalFilename", "electron.exe" - VALUE "ProductName", "Electron" -+<<<<<<< .our - VALUE "ProductVersion", "4.0.0" -+======= -+ VALUE "ProductVersion", "3.0.0" -+>>>>>>> .their - VALUE "SquirrelAwareVersion", "1" - END - END -added in both - our 100644 f3dc0e0cc6ae044daf9cc499061db98f387d7dea atom/browser/ui/certificate_trust_win.cc - their 100644 6179b08607041c38996d7faef8f7f456e42e4ac4 atom/browser/ui/certificate_trust_win.cc -@@ -20,8 +20,13 @@ - // This requires prompting the user to confirm they trust the certificate. - BOOL AddToTrustedRootStore(const PCCERT_CONTEXT cert_context, - const scoped_refptr<net::X509Certificate>& cert) { -+<<<<<<< .our - auto* root_cert_store = CertOpenStore( - CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"Root"); -+======= -+ auto root_cert_store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, -+ CERT_SYSTEM_STORE_CURRENT_USER, L"Root"); -+>>>>>>> .their - - if (root_cert_store == NULL) { - return false; -@@ -32,7 +37,11 @@ - - if (result) { - // force Chromium to reload it's database for this certificate -+<<<<<<< .our - auto* cert_db = net::CertDatabase::GetInstance(); -+======= -+ auto cert_db = net::CertDatabase::GetInstance(); -+>>>>>>> .their - cert_db->NotifyObserversCertDBChanged(); - } - -added in both - our 100644 aaaf933e106080002d198ad6c15e637043609618 atom/browser/ui/cocoa/atom_ns_window.mm - their 100644 56ed5dc2319ccc62ad26919460a416a8c1ccc047 atom/browser/ui/cocoa/atom_ns_window.mm -@@ -173,12 +173,20 @@ - buttonFrame.origin.x += NSWidth( - [[self standardWindowButton:NSWindowMiniaturizeButton] frame]); - buttonFrame.origin.x += windowButtonsInterButtonSpacing_; -+<<<<<<< .our - FALLTHROUGH; -+======= -+ // fallthrough -+>>>>>>> .their - case NSWindowMiniaturizeButton: - buttonFrame.origin.x += - NSWidth([[self standardWindowButton:NSWindowCloseButton] frame]); - buttonFrame.origin.x += windowButtonsInterButtonSpacing_; -+<<<<<<< .our - FALLTHROUGH; -+======= -+ // fallthrough -+>>>>>>> .their - default: - break; - } -added in both - our 100644 c58da546dc8dab14b6f32e284727342bc8096d0c atom/browser/ui/cocoa/atom_ns_window_delegate.mm - their 100644 78bfe1fcd7b523290c190bdbe9b04ae250a6af1b atom/browser/ui/cocoa/atom_ns_window_delegate.mm -@@ -112,6 +112,7 @@ - extraHeightPlusFrame); - } - -+<<<<<<< .our - { - bool prevent_default = false; - gfx::Rect new_bounds(gfx::Point(sender.frame.origin), gfx::Size(newSize)); -@@ -121,6 +122,8 @@ - } - } - -+======= -+>>>>>>> .their - return newSize; - } - -added in both - our 100644 becc1806610ae54c005b3e8aef17a9ef19d730bf atom/browser/ui/file_dialog.h - their 100644 efa50062bb8284149a893c9bff174ed1cdb10ced atom/browser/ui/file_dialog.h -@@ -66,7 +66,10 @@ - bool security_scoped_bookmarks = false; - - DialogSettings(); -+<<<<<<< .our - DialogSettings(const DialogSettings&); -+======= -+>>>>>>> .their - ~DialogSettings(); - }; - -added in both - our 100644 dab125ec881bc75ff608dbbfddff972169049e54 atom/browser/ui/file_dialog_win.cc - their 100644 2d708086bfdf28bd31dd735360e36ed6222a6a16 atom/browser/ui/file_dialog_win.cc -@@ -6,10 +6,16 @@ - - #include <windows.h> // windows.h must be included first - -+<<<<<<< .our - #include <atlbase.h> // atlbase.h for CComPtr - - #include <shlobj.h> - #include <shobjidl.h> -+======= -+#include <atlbase.h> -+#include <commdlg.h> -+#include <shlobj.h> -+>>>>>>> .their - - #include "atom/browser/native_window_views.h" - #include "atom/browser/unresponsive_suppressor.h" -@@ -21,11 +27,19 @@ - #include "base/threading/thread.h" - #include "base/threading/thread_task_runner_handle.h" - #include "base/win/registry.h" -+<<<<<<< .our -+======= -+#include "third_party/wtl/include/atlapp.h" -+#include "third_party/wtl/include/atldlgs.h" -+>>>>>>> .their - - namespace file_dialog { - - DialogSettings::DialogSettings() = default; -+<<<<<<< .our - DialogSettings::DialogSettings(const DialogSettings&) = default; -+======= -+>>>>>>> .their - DialogSettings::~DialogSettings() = default; - - namespace { -@@ -64,6 +78,90 @@ - } - } - -+<<<<<<< .our -+======= -+// Generic class to delegate common open/save dialog's behaviours, users need to -+// call interface methods via GetPtr(). -+template <typename T> -+class FileDialog { -+ public: -+ FileDialog(const DialogSettings& settings, int options) { -+ std::wstring file_part; -+ if (!IsDirectory(settings.default_path)) -+ file_part = settings.default_path.BaseName().value(); -+ -+ std::vector<std::wstring> buffer; -+ std::vector<COMDLG_FILTERSPEC> filterspec; -+ ConvertFilters(settings.filters, &buffer, &filterspec); -+ -+ dialog_.reset(new T(file_part.c_str(), options, NULL, filterspec.data(), -+ filterspec.size())); -+ -+ if (!settings.title.empty()) -+ GetPtr()->SetTitle(base::UTF8ToUTF16(settings.title).c_str()); -+ -+ if (!settings.button_label.empty()) -+ GetPtr()->SetOkButtonLabel( -+ base::UTF8ToUTF16(settings.button_label).c_str()); -+ -+ // By default, *.* will be added to the file name if file type is "*.*". In -+ // Electron, we disable it to make a better experience. -+ // -+ // From MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ -+ // bb775970(v=vs.85).aspx -+ // -+ // If SetDefaultExtension is not called, the dialog will not update -+ // automatically when user choose a new file type in the file dialog. -+ // -+ // We set file extension to the first none-wildcard extension to make -+ // sure the dialog will update file extension automatically. -+ for (size_t i = 0; i < filterspec.size(); ++i) { -+ if (std::wstring(filterspec[i].pszSpec) != L"*.*") { -+ // SetFileTypeIndex is regarded as one-based index. -+ GetPtr()->SetFileTypeIndex(i + 1); -+ GetPtr()->SetDefaultExtension(filterspec[i].pszSpec); -+ break; -+ } -+ } -+ -+ if (settings.default_path.IsAbsolute()) { -+ SetDefaultFolder(settings.default_path); -+ } -+ } -+ -+ bool Show(atom::NativeWindow* parent_window) { -+ atom::UnresponsiveSuppressor suppressor; -+ HWND window = parent_window -+ ? static_cast<atom::NativeWindowViews*>(parent_window) -+ ->GetAcceleratedWidget() -+ : NULL; -+ return dialog_->DoModal(window) == IDOK; -+ } -+ -+ T* GetDialog() { return dialog_.get(); } -+ -+ IFileDialog* GetPtr() const { return dialog_->GetPtr(); } -+ -+ private: -+ // Set up the initial directory for the dialog. -+ void SetDefaultFolder(const base::FilePath file_path) { -+ std::wstring directory = IsDirectory(file_path) -+ ? file_path.value() -+ : file_path.DirName().value(); -+ -+ ATL::CComPtr<IShellItem> folder_item; -+ HRESULT hr = SHCreateItemFromParsingName(directory.c_str(), NULL, -+ IID_PPV_ARGS(&folder_item)); -+ if (SUCCEEDED(hr)) -+ GetPtr()->SetFolder(folder_item); -+ } -+ -+ std::unique_ptr<T> dialog_; -+ -+ DISALLOW_COPY_AND_ASSIGN(FileDialog); -+}; -+ -+>>>>>>> .their - struct RunState { - base::Thread* dialog_thread; - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner; -@@ -103,6 +201,7 @@ - - } // namespace - -+<<<<<<< .our - static HRESULT GetFileNameFromShellItem(IShellItem* pShellItem, - SIGDN type, - LPWSTR lpstr, -@@ -207,6 +306,11 @@ - return false; - - DWORD options = FOS_FORCEFILESYSTEM | FOS_FILEMUSTEXIST; -+======= -+bool ShowOpenDialog(const DialogSettings& settings, -+ std::vector<base::FilePath>* paths) { -+ int options = FOS_FORCEFILESYSTEM | FOS_FILEMUSTEXIST; -+>>>>>>> .their - if (settings.properties & FILE_DIALOG_OPEN_DIRECTORY) - options |= FOS_PICKFOLDERS; - if (settings.properties & FILE_DIALOG_MULTI_SELECTIONS) -@@ -215,6 +319,7 @@ - options |= FOS_FORCESHOWHIDDEN; - if (settings.properties & FILE_DIALOG_PROMPT_TO_CREATE) - options |= FOS_CREATEPROMPT; -+<<<<<<< .our - file_open_dialog->SetOptions(options); - - ApplySettings(file_open_dialog, settings); -@@ -224,6 +329,16 @@ - - ATL::CComPtr<IShellItemArray> items; - hr = file_open_dialog->GetResults(&items); -+======= -+ -+ FileDialog<CShellFileOpenDialog> open_dialog(settings, options); -+ if (!open_dialog.Show(settings.parent_window)) -+ return false; -+ -+ ATL::CComPtr<IShellItemArray> items; -+ HRESULT hr = -+ static_cast<IFileOpenDialog*>(open_dialog.GetPtr())->GetResults(&items); -+>>>>>>> .their - if (FAILED(hr)) - return false; - -@@ -240,8 +355,13 @@ - return false; - - wchar_t file_name[MAX_PATH]; -+<<<<<<< .our - hr = GetFileNameFromShellItem(item, SIGDN_FILESYSPATH, file_name, MAX_PATH); - -+======= -+ hr = CShellFileOpenDialog::GetFileNameFromShellItem(item, SIGDN_FILESYSPATH, -+ file_name, MAX_PATH); -+>>>>>>> .their - if (FAILED(hr)) - return false; - -@@ -265,6 +385,7 @@ - } - - bool ShowSaveDialog(const DialogSettings& settings, base::FilePath* path) { -+<<<<<<< .our - ATL::CComPtr<IFileSaveDialog> file_save_dialog; - HRESULT hr = file_save_dialog.CoCreateInstance(CLSID_FileSaveDialog); - if (FAILED(hr)) -@@ -291,6 +412,19 @@ - *path = base::FilePath(result_path); - CoTaskMemFree(result_path); - -+======= -+ FileDialog<CShellFileSaveDialog> save_dialog( -+ settings, FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT); -+ if (!save_dialog.Show(settings.parent_window)) -+ return false; -+ -+ wchar_t buffer[MAX_PATH]; -+ HRESULT hr = save_dialog.GetDialog()->GetFilePath(buffer, MAX_PATH); -+ if (FAILED(hr)) -+ return false; -+ -+ *path = base::FilePath(buffer); -+>>>>>>> .their - return true; - } - -added in both - our 100644 b0e73f550e1d3a91f15e8d2d0604518027f75298 atom/browser/ui/message_box_win.cc - their 100644 e5a0e61379d0b7f294253e3bf1daa005dccfbfbd atom/browser/ui/message_box_win.cc -@@ -128,8 +128,11 @@ - case MESSAGE_BOX_TYPE_ERROR: - config.pszMainIcon = TD_ERROR_ICON; - break; -+<<<<<<< .our - case MESSAGE_BOX_TYPE_NONE: - break; -+======= -+>>>>>>> .their - } - } - -added in both - our 100644 e838d3cc217b5ffdb77226beff0d7217539f23f9 atom/browser/ui/views/menu_bar.cc - their 100644 535af8f2803187d737e1f5e42507d95b9b7272c2 atom/browser/ui/views/menu_bar.cc -@@ -29,8 +29,13 @@ - : background_color_(kDefaultColor), window_(window) { - RefreshColorCache(); - UpdateViewColors(); -+<<<<<<< .our - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); -+======= -+ SetLayoutManager(std::make_unique<views::BoxLayout>( -+ views::BoxLayout::kHorizontal)); -+>>>>>>> .their - window_->GetFocusManager()->AddFocusChangeListener(this); - } - -@@ -178,7 +183,11 @@ - } - #elif defined(OS_WIN) - for (auto* child : GetChildrenInZOrder()) { -+<<<<<<< .our - auto* button = static_cast<SubmenuButton*>(child); -+======= -+ auto button = static_cast<SubmenuButton*>(child); -+>>>>>>> .their - button->SetUnderlineColor(color_utils::GetSysSkColor(COLOR_MENUTEXT)); - } - #endif -added in both - our 100644 8f2139cb90fab876a1db1b17cac016997a3904ba atom/browser/ui/views/win_frame_view.cc - their 100644 91fdb8a966809633d934f97b46861aa4ef4c8120 atom/browser/ui/views/win_frame_view.cc -@@ -10,7 +10,15 @@ - - namespace atom { - -+<<<<<<< .our - const char WinFrameView::kViewClassName[] = "WinFrameView"; -+======= -+namespace { -+ -+const char kViewClassName[] = "WinFrameView"; -+ -+} // namespace -+>>>>>>> .their - - WinFrameView::WinFrameView() {} - -added in both - our 100644 a6ffd7f363304913bb124908f138258bb804e56f atom/browser/ui/views/win_frame_view.h - their 100644 b2c1ef3a15de9a222233a27193ed811a8add09f6 atom/browser/ui/views/win_frame_view.h -@@ -11,9 +11,14 @@ - - class WinFrameView : public FramelessView { - public: -+<<<<<<< .our - static const char kViewClassName[]; - WinFrameView(); - ~WinFrameView() override; -+======= -+ WinFrameView(); -+ virtual ~WinFrameView(); -+>>>>>>> .their - - // views::NonClientFrameView: - gfx::Rect GetWindowBoundsForClientBounds( -added in both - our 100644 39197cdccc994ee96aad07d8f5db01258fcb66a4 atom/browser/ui/webui/pdf_viewer_handler.cc - their 100644 4b63c3dc7112a85f594061bb262def495da69582 atom/browser/ui/webui/pdf_viewer_handler.cc -@@ -112,8 +112,12 @@ - PopulateStreamInfo(stream_info.get(), stream_, original_url_); - ResolveJavascriptCallback(*callback_id, *stream_info); - } else { -+<<<<<<< .our - initialize_callback_id_ = - base::Value::ToUniquePtrValue(callback_id.Clone()); -+======= -+ initialize_callback_id_ = callback_id->CreateDeepCopy(); -+>>>>>>> .their - } - - auto zoom_controller = -added in both - our 100644 4a76126214e7ae0063fa379c64aaca6be9f17d20 atom/browser/ui/win/jump_list.cc - their 100644 6af235e756c227c0b1d7fed0446e08ee10352800 atom/browser/ui/win/jump_list.cc -@@ -144,6 +144,7 @@ - - namespace atom { - -+<<<<<<< .our - JumpListItem::JumpListItem() = default; - JumpListItem::JumpListItem(const JumpListItem&) = default; - JumpListItem::~JumpListItem() = default; -@@ -151,12 +152,17 @@ - JumpListCategory::JumpListCategory(const JumpListCategory&) = default; - JumpListCategory::~JumpListCategory() = default; - -+======= -+>>>>>>> .their - JumpList::JumpList(const base::string16& app_id) : app_id_(app_id) { - destinations_.CoCreateInstance(CLSID_DestinationList); - } - -+<<<<<<< .our - JumpList::~JumpList() = default; - -+======= -+>>>>>>> .their - bool JumpList::Begin(int* min_items, std::vector<JumpListItem>* removed_items) { - DCHECK(destinations_); - if (!destinations_) -@@ -275,9 +281,15 @@ - result = JumpListResult::GENERIC_ERROR; - } - } else { -+<<<<<<< .our - HRESULT hr = destinations_->AppendCategory(category.name.c_str(), items); - if (FAILED(hr)) { - if (hr == static_cast<HRESULT>(0x80040F03)) { -+======= -+ auto hr = destinations_->AppendCategory(category.name.c_str(), items); -+ if (FAILED(hr)) { -+ if (hr == 0x80040F03) { -+>>>>>>> .their - LOG(ERROR) << "Failed to append custom category " - << "'" << category.name << "' " - << "to Jump List due to missing file type registration."; -added in both - our 100644 59d9a21a6c31f4d8fa5ebc0261630f3383138e84 atom/browser/ui/win/jump_list.h - their 100644 fc4ab085fc0db76b0d392abd5402adf35abe6ba1 atom/browser/ui/win/jump_list.h -@@ -51,10 +51,13 @@ - base::string16 description; - base::FilePath icon_path; - int icon_index = 0; -+<<<<<<< .our - - JumpListItem(); - JumpListItem(const JumpListItem&); - ~JumpListItem(); -+======= -+>>>>>>> .their - }; - - struct JumpListCategory { -@@ -74,10 +77,13 @@ - Type type = Type::TASKS; - base::string16 name; - std::vector<JumpListItem> items; -+<<<<<<< .our - - JumpListCategory(); - JumpListCategory(const JumpListCategory&); - ~JumpListCategory(); -+======= -+>>>>>>> .their - }; - - // Creates or removes a custom Jump List for an app. -@@ -88,7 +94,10 @@ - // custom Jump List should be created/removed, it's usually obtained by - // calling GetCurrentProcessExplicitAppUserModelID(). - explicit JumpList(const base::string16& app_id); -+<<<<<<< .our - ~JumpList(); -+======= -+>>>>>>> .their - - // Starts a new transaction, must be called before appending any categories, - // aborting or committing. After the method returns |min_items| will indicate -added in both - our 100644 bd4c17d2fcee53c7c106b0912252848cd6de0dc7 atom/browser/ui/win/notify_icon.h - their 100644 aed548ecb6188ccdfd71b93684a613ee2fe21d1a atom/browser/ui/win/notify_icon.h -@@ -32,7 +32,11 @@ - public: - // Constructor which provides this icon's unique ID and messaging window. - NotifyIcon(NotifyIconHost* host, UINT id, HWND window, UINT message); -+<<<<<<< .our - ~NotifyIcon() override; -+======= -+ virtual ~NotifyIcon(); -+>>>>>>> .their - - // Handles a click event from the user - if |left_button_click| is true and - // there is a registered observer, passes the click event to the observer, -added in both - our 100644 c4b92a24aefb3afa3ff2929eea59940d439e8709 atom/browser/ui/win/taskbar_host.cc - their 100644 e023fdc8c836899b7a8b9a80d4bc57edb365f3cc atom/browser/ui/win/taskbar_host.cc -@@ -50,11 +50,14 @@ - - } // namespace - -+<<<<<<< .our - TaskbarHost::ThumbarButton::ThumbarButton() = default; - TaskbarHost::ThumbarButton::ThumbarButton(const TaskbarHost::ThumbarButton&) = - default; - TaskbarHost::ThumbarButton::~ThumbarButton() = default; - -+======= -+>>>>>>> .their - TaskbarHost::TaskbarHost() {} - - TaskbarHost::~TaskbarHost() {} -added in both - our 100644 2182d377a7736f5e135d2f518c2a0a838cd0d1a0 atom/browser/ui/win/taskbar_host.h - their 100644 31199cf22837b604beca1fe92627b53cf6f71e8f atom/browser/ui/win/taskbar_host.h -@@ -26,10 +26,13 @@ - gfx::Image icon; - std::vector<std::string> flags; - base::Closure clicked_callback; -+<<<<<<< .our - - ThumbarButton(); - ThumbarButton(const ThumbarButton&); - ~ThumbarButton(); -+======= -+>>>>>>> .their - }; - - TaskbarHost(); -added in both - our 100644 c21c93383155091a7481cdd4e741cefad90a4a55 atom/browser/web_contents_preferences.cc - their 100644 f2385b974dc7362c37cd7dcd1506bb048e5db5d7 atom/browser/web_contents_preferences.cc -@@ -15,7 +15,10 @@ - #include "base/command_line.h" - #include "base/memory/ptr_util.h" - #include "base/strings/string_number_conversions.h" -+<<<<<<< .our - #include "base/strings/utf_string_conversions.h" -+======= -+>>>>>>> .their - #include "cc/base/switches.h" - #include "content/public/browser/render_frame_host.h" - #include "content/public/browser/render_process_host.h" -@@ -30,6 +33,7 @@ - - DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::WebContentsPreferences); - -+<<<<<<< .our - namespace { - - bool GetAsString(const base::Value* val, -@@ -75,6 +79,8 @@ - - } // namespace - -+======= -+>>>>>>> .their - namespace atom { - - // static -@@ -91,7 +97,11 @@ - copied.Delete("isGuest"); - copied.Delete("session"); - -+<<<<<<< .our - mate::ConvertFromV8(isolate, copied.GetHandle(), &preference_); -+======= -+ mate::ConvertFromV8(isolate, copied.GetHandle(), &dict_); -+>>>>>>> .their - web_contents->SetUserData(UserDataKey(), base::WrapUnique(this)); - - instances_.push_back(this); -@@ -99,6 +109,10 @@ - // Set WebPreferences defaults onto the JS object - SetDefaultBoolIfUndefined(options::kPlugins, false); - SetDefaultBoolIfUndefined(options::kExperimentalFeatures, false); -+<<<<<<< .our -+======= -+ SetDefaultBoolIfUndefined(options::kExperimentalCanvasFeatures, false); -+>>>>>>> .their - bool node = SetDefaultBoolIfUndefined(options::kNodeIntegration, true); - SetDefaultBoolIfUndefined(options::kNodeIntegrationInWorker, false); - SetDefaultBoolIfUndefined(options::kWebviewTag, node); -@@ -124,7 +138,11 @@ - #endif - SetDefaultBoolIfUndefined(options::kOffscreen, false); - -+<<<<<<< .our - last_preference_ = preference_.Clone(); -+======= -+ last_dict_ = std::move(*dict_.CreateDeepCopy()); -+>>>>>>> .their - } - - WebContentsPreferences::~WebContentsPreferences() { -@@ -135,6 +153,7 @@ - bool WebContentsPreferences::SetDefaultBoolIfUndefined( - const base::StringPiece& key, - bool val) { -+<<<<<<< .our - auto* current_value = - preference_.FindKeyOfType(key, base::Value::Type::BOOLEAN); - if (current_value) { -@@ -167,20 +186,47 @@ - bool WebContentsPreferences::GetPreference(const base::StringPiece& name, - std::string* value) const { - return GetAsString(&preference_, name, value); -+======= -+ bool existing; -+ if (!dict_.GetBoolean(key, &existing)) { -+ dict_.SetBoolean(key, val); -+ return val; -+ } -+ return existing; -+} -+ -+bool WebContentsPreferences::IsEnabled(const base::StringPiece& name, -+ bool default_value) { -+ bool bool_value = default_value; -+ dict_.GetBoolean(name, &bool_value); -+ return bool_value; -+} -+ -+void WebContentsPreferences::Merge(const base::DictionaryValue& extend) { -+ dict_.MergeDictionary(&extend); -+>>>>>>> .their - } - - bool WebContentsPreferences::GetPreloadPath( - base::FilePath::StringType* path) const { - DCHECK(path); - base::FilePath::StringType preload; -+<<<<<<< .our - if (GetAsString(&preference_, options::kPreloadScript, &preload)) { -+======= -+ if (dict_.GetString(options::kPreloadScript, &preload)) { -+>>>>>>> .their - if (base::FilePath(preload).IsAbsolute()) { - *path = std::move(preload); - return true; - } else { - LOG(ERROR) << "preload script must have absolute path."; - } -+<<<<<<< .our - } else if (GetAsString(&preference_, options::kPreloadURL, &preload)) { -+======= -+ } else if (dict_.GetString(options::kPreloadURL, &preload)) { -+>>>>>>> .their - // Translate to file path if there is "preload-url" option. - base::FilePath preload_path; - if (net::FileURLToFilePath(GURL(preload), &preload_path)) { -@@ -214,6 +260,7 @@ - - void WebContentsPreferences::AppendCommandLineSwitches( - base::CommandLine* command_line) { -+<<<<<<< .our - // Check if plugins are enabled. - if (IsEnabled(options::kPlugins)) - command_line->AppendSwitch(switches::kEnablePlugins); -@@ -230,17 +277,45 @@ - - // Whether to enable node integration in Worker. - if (IsEnabled(options::kNodeIntegrationInWorker)) -+======= -+ bool b; -+ // Check if plugins are enabled. -+ if (dict_.GetBoolean(options::kPlugins, &b) && b) -+ command_line->AppendSwitch(switches::kEnablePlugins); -+ -+ // Experimental flags. -+ if (dict_.GetBoolean(options::kExperimentalFeatures, &b) && b) -+ command_line->AppendSwitch( -+ ::switches::kEnableExperimentalWebPlatformFeatures); -+ if (dict_.GetBoolean(options::kExperimentalCanvasFeatures, &b) && b) -+ command_line->AppendSwitch(::switches::kEnableExperimentalCanvasFeatures); -+ -+ // Check if we have node integration specified. -+ bool node_integration = true; -+ dict_.GetBoolean(options::kNodeIntegration, &node_integration); -+ command_line->AppendSwitchASCII(switches::kNodeIntegration, -+ node_integration ? "true" : "false"); -+ -+ // Whether to enable node integration in Worker. -+ if (dict_.GetBoolean(options::kNodeIntegrationInWorker, &b) && b) -+>>>>>>> .their - command_line->AppendSwitch(switches::kNodeIntegrationInWorker); - - // Check if webview tag creation is enabled, default to nodeIntegration value. - // TODO(kevinsawicki): Default to false in 2.0 -+<<<<<<< .our - bool webview_tag = IsEnabled(options::kWebviewTag, enable_node_integration); -+======= -+ bool webview_tag = node_integration; -+ dict_.GetBoolean(options::kWebviewTag, &webview_tag); -+>>>>>>> .their - command_line->AppendSwitchASCII(switches::kWebviewTag, - webview_tag ? "true" : "false"); - - // If the `sandbox` option was passed to the BrowserWindow's webPreferences, - // pass `--enable-sandbox` to the renderer so it won't have any node.js - // integration. -+<<<<<<< .our - if (IsEnabled(options::kSandbox)) - command_line->AppendSwitch(switches::kEnableSandbox); - else if (!command_line->HasSwitch(switches::kEnableSandbox)) -@@ -248,6 +323,13 @@ - - // Check if nativeWindowOpen is enabled. - if (IsEnabled(options::kNativeWindowOpen)) -+======= -+ if (dict_.GetBoolean(options::kSandbox, &b) && b) -+ command_line->AppendSwitch(switches::kEnableSandbox); -+ else if (!command_line->HasSwitch(switches::kEnableSandbox)) -+ command_line->AppendSwitch(::switches::kNoSandbox); -+ if (dict_.GetBoolean(options::kNativeWindowOpen, &b) && b) -+>>>>>>> .their - command_line->AppendSwitch(switches::kNativeWindowOpen); - - // The preload script. -@@ -256,43 +338,70 @@ - command_line->AppendSwitchNative(switches::kPreloadScript, preload); - - // Custom args for renderer process -+<<<<<<< .our - auto* customArgs = - preference_.FindKeyOfType(options::kCustomArgs, base::Value::Type::LIST); - if (customArgs) { - for (const auto& customArg : customArgs->GetList()) { -+======= -+ base::Value* customArgs; -+ if (dict_.Get(options::kCustomArgs, &customArgs) && customArgs->is_list()) { -+ for (const base::Value& customArg : customArgs->GetList()) { -+>>>>>>> .their - if (customArg.is_string()) - command_line->AppendArg(customArg.GetString()); - } - } - - // Run Electron APIs and preload script in isolated world -+<<<<<<< .our - if (IsEnabled(options::kContextIsolation)) -+======= -+ if (dict_.GetBoolean(options::kContextIsolation, &b) && b) -+>>>>>>> .their - command_line->AppendSwitch(switches::kContextIsolation); - - // --background-color. - std::string s; -+<<<<<<< .our - if (GetAsString(&preference_, options::kBackgroundColor, &s)) -+======= -+ if (dict_.GetString(options::kBackgroundColor, &s)) -+>>>>>>> .their - command_line->AppendSwitchASCII(switches::kBackgroundColor, s); - - // --guest-instance-id, which is used to identify guest WebContents. - int guest_instance_id = 0; -+<<<<<<< .our - if (GetAsInteger(&preference_, options::kGuestInstanceID, &guest_instance_id)) -+======= -+ if (dict_.GetInteger(options::kGuestInstanceID, &guest_instance_id)) -+>>>>>>> .their - command_line->AppendSwitchASCII(switches::kGuestInstanceID, - base::IntToString(guest_instance_id)); - - // Pass the opener's window id. - int opener_id; -+<<<<<<< .our - if (GetAsInteger(&preference_, options::kOpenerID, &opener_id)) -+======= -+ if (dict_.GetInteger(options::kOpenerID, &opener_id)) -+>>>>>>> .their - command_line->AppendSwitchASCII(switches::kOpenerID, - base::IntToString(opener_id)); - - #if defined(OS_MACOSX) - // Enable scroll bounce. -+<<<<<<< .our - if (IsEnabled(options::kScrollBounce)) -+======= -+ if (dict_.GetBoolean(options::kScrollBounce, &b) && b) -+>>>>>>> .their - command_line->AppendSwitch(switches::kScrollBounce); - #endif - - // Custom command line switches. -+<<<<<<< .our - auto* args = - preference_.FindKeyOfType("commandLineSwitches", base::Value::Type::LIST); - if (args) { -@@ -302,15 +411,31 @@ - if (!arg_val.empty()) - command_line->AppendSwitch(arg_val); - } -+======= -+ const base::ListValue* args; -+ if (dict_.GetList("commandLineSwitches", &args)) { -+ for (size_t i = 0; i < args->GetSize(); ++i) { -+ std::string arg; -+ if (args->GetString(i, &arg) && !arg.empty()) -+ command_line->AppendSwitch(arg); -+>>>>>>> .their - } - } - - // Enable blink features. -+<<<<<<< .our - if (GetAsString(&preference_, options::kEnableBlinkFeatures, &s)) - command_line->AppendSwitchASCII(::switches::kEnableBlinkFeatures, s); - - // Disable blink features. - if (GetAsString(&preference_, options::kDisableBlinkFeatures, &s)) -+======= -+ if (dict_.GetString(options::kEnableBlinkFeatures, &s)) -+ command_line->AppendSwitchASCII(::switches::kEnableBlinkFeatures, s); -+ -+ // Disable blink features. -+ if (dict_.GetString(options::kDisableBlinkFeatures, &s)) -+>>>>>>> .their - command_line->AppendSwitchASCII(::switches::kDisableBlinkFeatures, s); - - if (guest_instance_id) { -@@ -337,11 +462,16 @@ - // We are appending args to a webContents so let's save the current state - // of our preferences object so that during the lifetime of the WebContents - // we can fetch the options used to initally configure the WebContents -+<<<<<<< .our - last_preference_ = preference_.Clone(); -+======= -+ last_dict_ = std::move(*dict_.CreateDeepCopy()); -+>>>>>>> .their - } - - void WebContentsPreferences::OverrideWebkitPrefs( - content::WebPreferences* prefs) { -+<<<<<<< .our - prefs->javascript_enabled = IsEnabled("javascript", true /* default_value */); - prefs->images_enabled = IsEnabled("images", true /* default_value */); - prefs->text_areas_are_resizable = -@@ -392,4 +522,66 @@ - prefs->default_encoding = encoding; - } - -+======= -+ bool b; -+ if (dict_.GetBoolean("javascript", &b)) -+ prefs->javascript_enabled = b; -+ if (dict_.GetBoolean("images", &b)) -+ prefs->images_enabled = b; -+ if (dict_.GetBoolean("textAreasAreResizable", &b)) -+ prefs->text_areas_are_resizable = b; -+ if (dict_.GetBoolean("webgl", &b)) { -+ prefs->webgl1_enabled = b; -+ prefs->webgl2_enabled = b; -+ } -+ if (dict_.GetBoolean(options::kWebSecurity, &b)) { -+ prefs->web_security_enabled = b; -+ prefs->allow_running_insecure_content = !b; -+ } -+ if (dict_.GetBoolean(options::kAllowRunningInsecureContent, &b)) -+ prefs->allow_running_insecure_content = b; -+ if (dict_.GetBoolean("navigateOnDragDrop", &b)) -+ prefs->navigate_on_drag_drop = b; -+ const base::DictionaryValue* fonts = nullptr; -+ if (dict_.GetDictionary("defaultFontFamily", &fonts)) { -+ base::string16 font; -+ if (fonts->GetString("standard", &font)) -+ prefs->standard_font_family_map[content::kCommonScript] = font; -+ if (fonts->GetString("serif", &font)) -+ prefs->serif_font_family_map[content::kCommonScript] = font; -+ if (fonts->GetString("sansSerif", &font)) -+ prefs->sans_serif_font_family_map[content::kCommonScript] = font; -+ if (fonts->GetString("monospace", &font)) -+ prefs->fixed_font_family_map[content::kCommonScript] = font; -+ if (fonts->GetString("cursive", &font)) -+ prefs->cursive_font_family_map[content::kCommonScript] = font; -+ if (fonts->GetString("fantasy", &font)) -+ prefs->fantasy_font_family_map[content::kCommonScript] = font; -+ } -+ int size; -+ if (GetInteger("defaultFontSize", &size)) -+ prefs->default_font_size = size; -+ if (GetInteger("defaultMonospaceFontSize", &size)) -+ prefs->default_fixed_font_size = size; -+ if (GetInteger("minimumFontSize", &size)) -+ prefs->minimum_font_size = size; -+ std::string encoding; -+ if (dict_.GetString("defaultEncoding", &encoding)) -+ prefs->default_encoding = encoding; -+} -+ -+bool WebContentsPreferences::GetInteger(const base::StringPiece& attribute_name, -+ int* val) { -+ // if it is already an integer, no conversion needed -+ if (dict_.GetInteger(attribute_name, val)) -+ return true; -+ -+ std::string str; -+ if (dict_.GetString(attribute_name, &str)) -+ return base::StringToInt(str, val); -+ -+ return false; -+} -+ -+>>>>>>> .their - } // namespace atom -added in both - our 100644 d835347afcd259f473f95271a2c19e42afcc6f2b atom/browser/web_contents_preferences.h - their 100644 c1a24eff3418bedaeaf131c0e39a0e3bb229129a atom/browser/web_contents_preferences.h -@@ -37,8 +37,12 @@ - ~WebContentsPreferences() override; - - // A simple way to know whether a Boolean property is enabled. -+<<<<<<< .our - bool IsEnabled(const base::StringPiece& name, - bool default_value = false) const; -+======= -+ bool IsEnabled(const base::StringPiece& name, bool default_value = false); -+>>>>>>> .their - - // $.extend(|web_preferences|, |new_web_preferences|). - void Merge(const base::DictionaryValue& new_web_preferences); -@@ -49,18 +53,27 @@ - // Modify the WebPreferences according to preferences. - void OverrideWebkitPrefs(content::WebPreferences* prefs); - -+<<<<<<< .our - // Clear the current WebPreferences. - void Clear(); - - // Return true if the particular preference value exists. - bool GetPreference(const base::StringPiece& name, std::string* value) const; - -+======= -+>>>>>>> .their - // Returns the preload script path. - bool GetPreloadPath(base::FilePath::StringType* path) const; - - // Returns the web preferences. -+<<<<<<< .our - base::Value* preference() { return &preference_; } - base::Value* last_preference() { return &last_preference_; } -+======= -+ base::DictionaryValue* dict() { return &dict_; } -+ const base::DictionaryValue* dict() const { return &dict_; } -+ base::DictionaryValue* last_dict() { return &last_dict_; } -+>>>>>>> .their - - private: - friend class content::WebContentsUserData<WebContentsPreferences>; -@@ -72,12 +85,23 @@ - // Set preference value to given bool if user did not provide value - bool SetDefaultBoolIfUndefined(const base::StringPiece& key, bool val); - -+<<<<<<< .our -+======= -+ // Get preferences value as integer possibly coercing it from a string -+ bool GetInteger(const base::StringPiece& attribute_name, int* val); -+ -+>>>>>>> .their - static std::vector<WebContentsPreferences*> instances_; - - content::WebContents* web_contents_; - -+<<<<<<< .our - base::Value preference_ = base::Value(base::Value::Type::DICTIONARY); - base::Value last_preference_ = base::Value(base::Value::Type::DICTIONARY); -+======= -+ base::DictionaryValue dict_; -+ base::DictionaryValue last_dict_; -+>>>>>>> .their - - DISALLOW_COPY_AND_ASSIGN(WebContentsPreferences); - }; -added in both - our 100644 74c8573d13f15bcaa189abdc40fa0cd8e48f89be atom/browser/web_dialog_helper.cc - their 100644 f39f77a643522bba10cc2f764b0d5daf02f35d42 atom/browser/web_dialog_helper.cc -@@ -220,7 +220,10 @@ - switch (params.mode) { - case content::FileChooserParams::OpenMultiple: - flags |= file_dialog::FILE_DIALOG_MULTI_SELECTIONS; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case content::FileChooserParams::Open: - flags |= file_dialog::FILE_DIALOG_OPEN_FILE; - flags |= file_dialog::FILE_DIALOG_TREAT_PACKAGE_APP_AS_DIRECTORY; -added in both - our 100644 09edfdaac9107386241505d2d5763b1b24aa73a4 atom/common/api/atom_api_native_image.cc - their 100644 7b274b38cae7e44b0737912e93a7015c64a60895 atom/common/api/atom_api_native_image.cc -@@ -245,14 +245,23 @@ - - // First try loading the icon with specified size. - if (!hicon_path_.empty()) { -+<<<<<<< .our - hicons_[size] = ReadICOFromPath(size, hicon_path_); -+======= -+ hicons_[size] = std::move(ReadICOFromPath(size, hicon_path_)); -+>>>>>>> .their - return hicons_[size].get(); - } - - // Then convert the image to ICO. - if (image_.IsEmpty()) - return NULL; -+<<<<<<< .our - hicons_[size] = IconUtil::CreateHICONFromSkBitmap(image_.AsBitmap()); -+======= -+ hicons_[size] = -+ std::move(IconUtil::CreateHICONFromSkBitmap(image_.AsBitmap())); -+>>>>>>> .their - return hicons_[size].get(); - } - #endif -added in both - our 100644 3dba3d63673ca8eb02044bd1335a3095f0194971 atom/common/api/atom_bindings.cc - their 100644 ee02ed3f6a28bcc15407465ae0cc34f71664d9dc atom/common/api/atom_bindings.cc -@@ -14,7 +14,10 @@ - #include "atom/common/native_mate_converters/string16_converter.h" - #include "atom/common/node_includes.h" - #include "base/logging.h" -+<<<<<<< .our - #include "base/process/process_info.h" -+======= -+>>>>>>> .their - #include "base/process/process_metrics_iocounters.h" - #include "base/sys_info.h" - #include "native_mate/dictionary.h" -@@ -56,10 +59,16 @@ - dict.SetMethod("log", &Log); - dict.SetMethod("getHeapStatistics", &GetHeapStatistics); - dict.SetMethod("getProcessMemoryInfo", &GetProcessMemoryInfo); -+<<<<<<< .our - dict.SetMethod("getCreationTime", &GetCreationTime); - dict.SetMethod("getSystemMemoryInfo", &GetSystemMemoryInfo); - dict.SetMethod("getCPUUsage", base::Bind(&AtomBindings::GetCPUUsage, - base::Unretained(metrics_.get()))); -+======= -+ dict.SetMethod("getSystemMemoryInfo", &GetSystemMemoryInfo); -+ dict.SetMethod("getCPUUsage", base::Bind(&AtomBindings::GetCPUUsage, -+ base::Unretained(this))); -+>>>>>>> .their - dict.SetMethod("getIOCounters", &GetIOCounters); - #if defined(OS_POSIX) - dict.SetMethod("setFdLimit", &base::SetFdLimit); -@@ -135,7 +144,10 @@ - isolate->GetHeapStatistics(&v8_heap_stats); - - mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); -+<<<<<<< .our - dict.SetHidden("simple", true); -+======= -+>>>>>>> .their - dict.Set("totalHeapSize", - static_cast<double>(v8_heap_stats.total_heap_size() >> 10)); - dict.Set( -@@ -164,7 +176,10 @@ - auto metrics = base::ProcessMetrics::CreateCurrentProcessMetrics(); - - mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); -+<<<<<<< .our - dict.SetHidden("simple", true); -+======= -+>>>>>>> .their - dict.Set("workingSetSize", - static_cast<double>(metrics->GetWorkingSetSize() >> 10)); - dict.Set("peakWorkingSetSize", -@@ -180,6 +195,7 @@ - } - - // static -+<<<<<<< .our - v8::Local<v8::Value> AtomBindings::GetCreationTime(v8::Isolate* isolate) { - auto timeValue = base::CurrentProcessInfo::CreationTime(); - if (timeValue.is_null()) { -@@ -190,6 +206,8 @@ - } - - // static -+======= -+>>>>>>> .their - v8::Local<v8::Value> AtomBindings::GetSystemMemoryInfo(v8::Isolate* isolate, - mate::Arguments* args) { - base::SystemMemoryInfoKB mem_info; -@@ -199,7 +217,10 @@ - } - - mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); -+<<<<<<< .our - dict.SetHidden("simple", true); -+======= -+>>>>>>> .their - dict.Set("total", mem_info.total); - - // See Chromium's "base/process/process_metrics.h" for an explanation. -@@ -220,6 +241,7 @@ - return dict.GetHandle(); - } - -+<<<<<<< .our - // static - v8::Local<v8::Value> AtomBindings::GetCPUUsage(base::ProcessMetrics* metrics, - v8::Isolate* isolate) { -@@ -228,11 +250,22 @@ - int processor_count = base::SysInfo::NumberOfProcessors(); - dict.Set("percentCPUUsage", - metrics->GetPlatformIndependentCPUUsage() / processor_count); -+======= -+v8::Local<v8::Value> AtomBindings::GetCPUUsage(v8::Isolate* isolate) { -+ mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); -+ int processor_count = base::SysInfo::NumberOfProcessors(); -+ dict.Set("percentCPUUsage", -+ metrics_->GetPlatformIndependentCPUUsage() / processor_count); -+>>>>>>> .their - - // NB: This will throw NOTIMPLEMENTED() on Windows - // For backwards compatibility, we'll return 0 - #if !defined(OS_WIN) -+<<<<<<< .our - dict.Set("idleWakeupsPerSecond", metrics->GetIdleWakeupsPerSecond()); -+======= -+ dict.Set("idleWakeupsPerSecond", metrics_->GetIdleWakeupsPerSecond()); -+>>>>>>> .their - #else - dict.Set("idleWakeupsPerSecond", 0); - #endif -@@ -245,7 +278,10 @@ - auto metrics = base::ProcessMetrics::CreateCurrentProcessMetrics(); - base::IoCounters io_counters; - mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); -+<<<<<<< .our - dict.SetHidden("simple", true); -+======= -+>>>>>>> .their - - if (metrics->GetIOCounters(&io_counters)) { - dict.Set("readOperationCount", io_counters.ReadOperationCount); -added in both - our 100644 ba8385c979b15286fd7647582e7d0aee93e1974e atom/common/api/atom_bindings.h - their 100644 46a5f36bdcea9adb76c091b17bbed47a0ba8a2ea atom/common/api/atom_bindings.h -@@ -37,11 +37,17 @@ - static void Hang(); - static v8::Local<v8::Value> GetHeapStatistics(v8::Isolate* isolate); - static v8::Local<v8::Value> GetProcessMemoryInfo(v8::Isolate* isolate); -+<<<<<<< .our - static v8::Local<v8::Value> GetCreationTime(v8::Isolate* isolate); - static v8::Local<v8::Value> GetSystemMemoryInfo(v8::Isolate* isolate, - mate::Arguments* args); - static v8::Local<v8::Value> GetCPUUsage(base::ProcessMetrics* metrics, - v8::Isolate* isolate); -+======= -+ static v8::Local<v8::Value> GetSystemMemoryInfo(v8::Isolate* isolate, -+ mate::Arguments* args); -+ v8::Local<v8::Value> GetCPUUsage(v8::Isolate* isolate); -+>>>>>>> .their - static v8::Local<v8::Value> GetIOCounters(v8::Isolate* isolate); - - private: -added in both - our 100644 9b37f94a4dc462c0cc84e0182654ff2571952df9 atom/common/asar/archive.cc - their 100644 769efec0a2b0d402428ab10ced26feeb5c6157c5 atom/common/asar/archive.cc -@@ -221,13 +221,21 @@ - if (!GetNodeFromPath(path.AsUTF8Unsafe(), header_.get(), &node)) - return false; - -+<<<<<<< .our - if (node->FindKey("link")) { -+======= -+ if (node->HasKey("link")) { -+>>>>>>> .their - stats->is_file = false; - stats->is_link = true; - return true; - } - -+<<<<<<< .our - if (node->FindKey("files")) { -+======= -+ if (node->HasKey("files")) { -+>>>>>>> .their - stats->is_file = false; - stats->is_directory = true; - return true; -added in both - our 100644 65e7d19911559a40b1b258319df5fe0fa180354f atom/common/atom_version.h - their 100644 3321475153fda689b992c1b53600094ebd23c879 atom/common/atom_version.h -@@ -5,10 +5,17 @@ - #ifndef ATOM_COMMON_ATOM_VERSION_H_ - #define ATOM_COMMON_ATOM_VERSION_H_ - -+<<<<<<< .our - #define ATOM_MAJOR_VERSION 4 - #define ATOM_MINOR_VERSION 0 - #define ATOM_PATCH_VERSION 0 - #define ATOM_PRE_RELEASE_VERSION -nightly.20180821 -+======= -+#define ATOM_MAJOR_VERSION 3 -+#define ATOM_MINOR_VERSION 0 -+#define ATOM_PATCH_VERSION 0 -+#define ATOM_PRE_RELEASE_VERSION -beta.7 -+>>>>>>> .their - - #ifndef ATOM_STRINGIFY - #define ATOM_STRINGIFY(n) ATOM_STRINGIFY_HELPER(n) -added in both - our 100644 89a2a5966d6caf3c13643065ef084e98b69efcaf atom/common/crash_reporter/crash_reporter_win.h - their 100644 f7f1c6b28455a52daf0860028df1054788ddde54 atom/common/crash_reporter/crash_reporter_win.h -@@ -11,7 +11,11 @@ - - #include "atom/common/crash_reporter/crash_reporter.h" - #include "base/compiler_specific.h" -+<<<<<<< .our - #include "breakpad/src/client/windows/handler/exception_handler.h" -+======= -+#include "vendor/breakpad/src/client/windows/handler/exception_handler.h" -+>>>>>>> .their - - namespace base { - template <typename T> -@@ -40,7 +44,11 @@ - friend struct base::DefaultSingletonTraits<CrashReporterWin>; - - CrashReporterWin(); -+<<<<<<< .our - ~CrashReporterWin() override; -+======= -+ virtual ~CrashReporterWin(); -+>>>>>>> .their - - static bool FilterCallback(void* context, - EXCEPTION_POINTERS* exinfo, -@@ -65,9 +73,13 @@ - google_breakpad::CustomClientInfo custom_info_; - - bool skip_system_crash_handler_ = false; -+<<<<<<< .our - #ifdef _WIN64 - bool code_range_registered_ = false; - #endif -+======= -+ bool code_range_registered_ = false; -+>>>>>>> .their - std::unique_ptr<google_breakpad::ExceptionHandler> breakpad_; - - DISALLOW_COPY_AND_ASSIGN(CrashReporterWin); -added in both - our 100644 8b0e3de5cecdda5c97237ebd5d6e0bbbd99a280b atom/common/crash_reporter/linux/crash_dump_handler.cc - their 100644 ccc8d0d538e3a23a85f7dc3dd2d2650f6cb88bcd atom/common/crash_reporter/linux/crash_dump_handler.cc -@@ -15,7 +15,11 @@ - #include "base/posix/eintr_wrapper.h" - #include "breakpad/src/client/linux/minidump_writer/directory_reader.h" - #include "breakpad/src/common/linux/linux_libc_support.h" -+<<<<<<< .our - #include "breakpad/src/common/memory_allocator.h" -+======= -+#include "breakpad/src/common/memory.h" -+>>>>>>> .their - - #include "third_party/lss/linux_syscall_support.h" - -added in both - our 100644 d13111f495be844df10deebacd572560021bbb4e atom/common/crash_reporter/win/crash_service.cc - their 100644 a1a6ab6d7908389bdc0a400cf751fde809408115 atom/common/crash_reporter/win/crash_service.cc -@@ -17,9 +17,15 @@ - #include "base/strings/string_util.h" - #include "base/time/time.h" - #include "base/win/windows_version.h" -+<<<<<<< .our - #include "breakpad/src/client/windows/crash_generation/client_info.h" - #include "breakpad/src/client/windows/crash_generation/crash_generation_server.h" - #include "breakpad/src/client/windows/sender/crash_report_sender.h" -+======= -+#include "vendor/breakpad/src/client/windows/crash_generation/client_info.h" -+#include "vendor/breakpad/src/client/windows/crash_generation/crash_generation_server.h" -+#include "vendor/breakpad/src/client/windows/sender/crash_report_sender.h" -+>>>>>>> .their - - namespace breakpad { - -@@ -132,7 +138,11 @@ - wcx.lpfnWndProc = CrashSvcWndProc; - wcx.hInstance = instance; - wcx.lpszClassName = class_name.c_str(); -+<<<<<<< .our - ::RegisterClassExW(&wcx); -+======= -+ ATOM atom = ::RegisterClassExW(&wcx); -+>>>>>>> .their - DWORD style = visible ? WS_POPUPWINDOW | WS_VISIBLE : WS_OVERLAPPED; - - // The window size is zero but being a popup window still shows in the -@@ -487,6 +497,10 @@ - // Build the SDDL string for the label. - std::wstring sddl = L"S:(ML;;NW;;;S-1-16-4096)"; - -+<<<<<<< .our -+======= -+ DWORD error = ERROR_SUCCESS; -+>>>>>>> .their - PSECURITY_DESCRIPTOR sec_desc = NULL; - - PACL sacl = NULL; -added in both - our 100644 d0a12cb6d91b9688c1bed496e64d6bbaccaf244a atom/common/keyboard_util.cc - their 100644 b8caa1f1b00d652a67ecd103e5ce3a78b70c01f4 atom/common/keyboard_util.cc -@@ -88,108 +88,171 @@ - - case ')': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case '0': - return ui::VKEY_0; - case '!': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case '1': - return ui::VKEY_1; - case '@': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case '2': - return ui::VKEY_2; - case '#': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case '3': - return ui::VKEY_3; - case '$': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case '4': - return ui::VKEY_4; - case '%': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case '5': - return ui::VKEY_5; - case '^': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case '6': - return ui::VKEY_6; - case '&': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case '7': - return ui::VKEY_7; - case '*': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case '8': - return ui::VKEY_8; - case '(': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case '9': - return ui::VKEY_9; - - case ':': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case ';': - return ui::VKEY_OEM_1; - case '+': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case '=': - return ui::VKEY_OEM_PLUS; - case '<': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case ',': - return ui::VKEY_OEM_COMMA; - case '_': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case '-': - return ui::VKEY_OEM_MINUS; - case '>': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case '.': - return ui::VKEY_OEM_PERIOD; - case '?': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case '/': - return ui::VKEY_OEM_2; - case '~': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case '`': - return ui::VKEY_OEM_3; - case '{': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case '[': - return ui::VKEY_OEM_4; - case '|': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case '\\': - return ui::VKEY_OEM_5; - case '}': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case ']': - return ui::VKEY_OEM_6; - case '"': - *shifted = true; -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case '\'': - return ui::VKEY_OEM_7; - -added in both - our 100644 2684aa7dda07ac79e47823c3cf9bf00d3f5cf3f5 atom/common/native_mate_converters/content_converter.cc - their 100644 46364e21266a93c7c496d87acbf6cc4ff4965194 atom/common/native_mate_converters/content_converter.cc -@@ -43,12 +43,18 @@ - case content::MenuItem::CHECKABLE_OPTION: - case content::MenuItem::GROUP: - v8_item.Set("checked", item.checked); -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - case content::MenuItem::OPTION: - case content::MenuItem::SUBMENU: - v8_item.Set("label", item.label); - v8_item.Set("enabled", item.enabled); -+<<<<<<< .our - FALLTHROUGH; -+======= -+>>>>>>> .their - default: - v8_item.Set("type", item.type); - } -added in both - our 100644 db54210e7c095da593c6f5b9f4ed1eafb91b945d atom/common/native_mate_converters/net_converter.cc - their 100644 d3890bbff79276627528e7ced7eb69ffcf367f43 atom/common/native_mate_converters/net_converter.cc -@@ -160,7 +160,11 @@ - std::string value; - while (headers->EnumerateHeaderLines(&iter, &key, &value)) { - key = base::ToLowerASCII(key); -+<<<<<<< .our - if (response_headers.FindKey(key)) { -+======= -+ if (response_headers.HasKey(key)) { -+>>>>>>> .their - base::ListValue* values = nullptr; - if (response_headers.GetList(key, &values)) - values->AppendString(value); -@@ -239,9 +243,14 @@ - if (reader->AsBytesReader()) { - const net::UploadBytesElementReader* bytes_reader = - reader->AsBytesReader(); -+<<<<<<< .our - auto bytes = std::make_unique<base::Value>( - std::vector<char>(bytes_reader->bytes(), - bytes_reader->bytes() + bytes_reader->length())); -+======= -+ std::unique_ptr<base::Value> bytes(base::Value::CreateWithCopiedBuffer( -+ bytes_reader->bytes(), bytes_reader->length())); -+>>>>>>> .their - upload_data_dict->Set("bytes", std::move(bytes)); - } else if (reader->AsFileReader()) { - const net::UploadFileElementReader* file_reader = reader->AsFileReader(); -added in both - our 100644 61a6563a617030684081e4934044865fdc3c6540 atom/common/native_mate_converters/network_converter.cc - their 100644 1f98a5b8ebd548f54a8113f186c5344618dcd027 atom/common/native_mate_converters/network_converter.cc -@@ -6,7 +6,10 @@ - - #include <string> - #include <utility> -+<<<<<<< .our - #include <vector> -+======= -+>>>>>>> .their - - #include "atom/common/native_mate_converters/value_converter.h" - #include "native_mate/dictionary.h" -@@ -26,8 +29,13 @@ - auto post_data_dict = std::make_unique<base::DictionaryValue>(); - auto type = element.type(); - if (type == network::DataElement::TYPE_BYTES) { -+<<<<<<< .our - auto bytes = std::make_unique<base::Value>(std::vector<char>( - element.bytes(), element.bytes() + (element.length()))); -+======= -+ auto bytes = base::Value::CreateWithCopiedBuffer( -+ element.bytes(), static_cast<size_t>(element.length())); -+>>>>>>> .their - post_data_dict->SetString("type", "rawData"); - post_data_dict->Set("bytes", std::move(bytes)); - } else if (type == network::DataElement::TYPE_FILE) { -added in both - our 100644 3fa070771d6843e9428e560c746965b095961e2a atom/common/native_mate_converters/v8_value_converter.cc - their 100644 fbc410bdcb7111bf2ee86dbe07538957de486b68 atom/common/native_mate_converters/v8_value_converter.cc -@@ -8,7 +8,10 @@ - #include <memory> - #include <string> - #include <utility> -+<<<<<<< .our - #include <vector> -+======= -+>>>>>>> .their - - #include "base/logging.h" - #include "base/values.h" -@@ -163,22 +166,42 @@ - return v8::Null(isolate); - - case base::Value::Type::BOOLEAN: { -+<<<<<<< .our - bool val = value->GetBool(); -+======= -+ bool val = false; -+ value->GetAsBoolean(&val); -+>>>>>>> .their - return v8::Boolean::New(isolate, val); - } - - case base::Value::Type::INTEGER: { -+<<<<<<< .our - int val = value->GetInt(); -+======= -+ int val = 0; -+ value->GetAsInteger(&val); -+>>>>>>> .their - return v8::Integer::New(isolate, val); - } - - case base::Value::Type::DOUBLE: { -+<<<<<<< .our - double val = value->GetDouble(); -+======= -+ double val = 0.0; -+ value->GetAsDouble(&val); -+>>>>>>> .their - return v8::Number::New(isolate, val); - } - - case base::Value::Type::STRING: { -+<<<<<<< .our - std::string val = value->GetString(); -+======= -+ std::string val; -+ value->GetAsString(&val); -+>>>>>>> .their - return v8::String::NewFromUtf8(isolate, val.c_str(), - v8::String::kNormalString, val.length()); - } -@@ -342,8 +365,13 @@ - if (val->IsRegExp()) { - if (!reg_exp_allowed_) - // JSON.stringify converts to an object. -+<<<<<<< .our - return FromV8Object(val->ToObject(context).ToLocalChecked(), state, - isolate); -+======= -+ return FromV8Object(val->ToObject(context).ToLocalChecked(), -+ state, isolate); -+>>>>>>> .their - return new base::Value( - *v8::String::Utf8Value(val->ToString(context).ToLocalChecked())); - } -@@ -356,8 +384,13 @@ - if (!function_allowed_) - // JSON.stringify refuses to convert function(){}. - return nullptr; -+<<<<<<< .our - return FromV8Object(val->ToObject(context).ToLocalChecked(), state, - isolate); -+======= -+ return FromV8Object(val->ToObject(context).ToLocalChecked(), -+ state, isolate); -+>>>>>>> .their - } - - if (node::Buffer::HasInstance(val)) { -@@ -365,8 +398,13 @@ - } - - if (val->IsObject()) { -+<<<<<<< .our - return FromV8Object(val->ToObject(context).ToLocalChecked(), state, - isolate); -+======= -+ return FromV8Object(val->ToObject(context).ToLocalChecked(), -+ state, isolate); -+>>>>>>> .their - } - - LOG(ERROR) << "Unexpected v8 value type encountered."; -@@ -415,9 +453,15 @@ - base::Value* V8ValueConverter::FromNodeBuffer(v8::Local<v8::Value> value, - FromV8ValueState* state, - v8::Isolate* isolate) const { -+<<<<<<< .our - return new base::Value(std::vector<char>( - node::Buffer::Data(value), - node::Buffer::Data(value) + node::Buffer::Length(value))); -+======= -+ return base::Value::CreateWithCopiedBuffer(node::Buffer::Data(value), -+ node::Buffer::Length(value)) -+ .release(); -+>>>>>>> .their - } - - base::Value* V8ValueConverter::FromV8Object(v8::Local<v8::Object> val, -added in both - our 100644 a71cc70f83d2526596a75d8daf036f905ca099be atom/common/native_mate_converters/value_converter.cc - their 100644 0412a0118f2b5f6e2801f02e6089f9d12214d311 atom/common/native_mate_converters/value_converter.cc -@@ -30,6 +30,7 @@ - return converter.ToV8Value(&val, isolate->GetCurrentContext()); - } - -+<<<<<<< .our - bool Converter<base::Value>::FromV8(v8::Isolate* isolate, - v8::Local<v8::Value> val, - base::Value* out) { -@@ -50,6 +51,8 @@ - return converter.ToV8Value(&val, isolate->GetCurrentContext()); - } - -+======= -+>>>>>>> .their - bool Converter<base::ListValue>::FromV8(v8::Isolate* isolate, - v8::Local<v8::Value> val, - base::ListValue* out) { -added in both - our 100644 b2ea5def0aa9646791c635c15e0ed504dc0af465 atom/common/native_mate_converters/value_converter.h - their 100644 a53b2724b0883ab343f6262f7e506deb39e5b34d atom/common/native_mate_converters/value_converter.h -@@ -10,7 +10,10 @@ - namespace base { - class DictionaryValue; - class ListValue; -+<<<<<<< .our - class Value; -+======= -+>>>>>>> .their - } // namespace base - - namespace mate { -@@ -25,6 +28,7 @@ - }; - - template <> -+<<<<<<< .our - struct Converter<base::Value> { - static bool FromV8(v8::Isolate* isolate, - v8::Local<v8::Value> val, -@@ -34,6 +38,8 @@ - }; - - template <> -+======= -+>>>>>>> .their - struct Converter<base::ListValue> { - static bool FromV8(v8::Isolate* isolate, - v8::Local<v8::Value> val, -added in both - our 100644 e6aded2e661af919c2d89c2f9bd46b4921d4aec4 atom/common/node_bindings.cc - their 100644 a26747cf03c85a7ada7e84a2bda860791a4d73e2 atom/common/node_bindings.cc -@@ -15,6 +15,10 @@ - #include "base/base_paths.h" - #include "base/command_line.h" - #include "base/environment.h" -+<<<<<<< .our -+======= -+#include "base/files/file_path.h" -+>>>>>>> .their - #include "base/path_service.h" - #include "base/run_loop.h" - #include "base/strings/utf_string_conversions.h" -@@ -194,10 +198,13 @@ - return g_is_initialized; - } - -+<<<<<<< .our - base::FilePath::StringType NodeBindings::GetHelperResourcesPath() { - return GetResourcesPath(false).value(); - } - -+======= -+>>>>>>> .their - void NodeBindings::Initialize() { - // Open node's error reporting system for browser process. - node::g_standalone_mode = browser_env_ == BROWSER; -added in both - our 100644 5e5ec8e5300ba2c1917e3e9d7e2e8ea1ee341e3b atom/common/node_bindings.h - their 100644 7c8cad46cc6927de6746ea65b7db536245baad20 atom/common/node_bindings.h -@@ -5,7 +5,10 @@ - #ifndef ATOM_COMMON_NODE_BINDINGS_H_ - #define ATOM_COMMON_NODE_BINDINGS_H_ - -+<<<<<<< .our - #include "base/files/file_path.h" -+======= -+>>>>>>> .their - #include "base/macros.h" - #include "base/memory/weak_ptr.h" - #include "base/single_thread_task_runner.h" -@@ -34,7 +37,10 @@ - static NodeBindings* Create(BrowserEnvironment browser_env); - static void RegisterBuiltinModules(); - static bool IsInitialized(); -+<<<<<<< .our - static base::FilePath::StringType GetHelperResourcesPath(); -+======= -+>>>>>>> .their - - virtual ~NodeBindings(); - -added in both - our 100644 e41fb585f57114de00376f52e0d97277e6eca94b atom/common/node_bindings_win.cc - their 100644 4a5ff5c51406d0b051f6d790b111a3477da561bf atom/common/node_bindings_win.cc -@@ -8,6 +8,13 @@ - - #include "base/logging.h" - -+<<<<<<< .our -+======= -+extern "C" { -+#include "vendor/node/deps/uv/src/win/internal.h" -+} -+ -+>>>>>>> .their - namespace atom { - - NodeBindingsWin::NodeBindingsWin(BrowserEnvironment browser_env) -added in both - our 100644 77fe5f43b54c8d53bfc5a4a29c9c0a6f62bea423 atom/common/node_bindings_win.h - their 100644 793586d88da8a40c86a322bef383f118404d2480 atom/common/node_bindings_win.h -@@ -13,7 +13,11 @@ - class NodeBindingsWin : public NodeBindings { - public: - explicit NodeBindingsWin(BrowserEnvironment browser_env); -+<<<<<<< .our - ~NodeBindingsWin() override; -+======= -+ virtual ~NodeBindingsWin(); -+>>>>>>> .their - - private: - void PollEvents() override; -added in both - our 100644 fa1a7499a8b082fe9007f04041b46e58502b3ad9 atom/common/node_includes.h - their 100644 edd4812e01c29f9307a21b59db876106ae8fc8ec atom/common/node_includes.h -@@ -9,9 +9,13 @@ - - // Include common headers for using node APIs. - -+<<<<<<< .our - #ifdef NODE_SHARED_MODE - #define BUILDING_NODE_EXTENSION - #endif -+======= -+#define BUILDING_NODE_EXTENSION -+>>>>>>> .their - - // The following define makes sure that we do not include the macros - // again. But we still need the tracing functions, so declaring them. -added in both - our 100644 8b1836f80c583e4db68971ff1b00ca4f86356b45 atom/common/options_switches.cc - their 100644 db82468f292dce07471d626e8536aea55de8cb2e atom/common/options_switches.cc -@@ -118,6 +118,10 @@ - - // Web runtime features. - const char kExperimentalFeatures[] = "experimentalFeatures"; -+<<<<<<< .our -+======= -+const char kExperimentalCanvasFeatures[] = "experimentalCanvasFeatures"; -+>>>>>>> .their - - // Opener window's ID. - const char kOpenerID[] = "openerId"; -@@ -188,9 +192,19 @@ - // The application path - const char kAppPath[] = "app-path"; - -+<<<<<<< .our - // The command line switch versions of the options. - const char kBackgroundColor[] = "background-color"; - const char kPreloadScript[] = "preload"; -+======= -+// The context ID for this process -+const char kContextId[] = "context-id"; -+ -+// The command line switch versions of the options. -+const char kBackgroundColor[] = "background-color"; -+const char kPreloadScript[] = "preload"; -+const char kPreloadURL[] = "preload-url"; -+>>>>>>> .their - const char kPreloadScripts[] = "preload-scripts"; - const char kNodeIntegration[] = "node-integration"; - const char kContextIsolation[] = "context-isolation"; -added in both - our 100644 5f6d7e9d38120668ed06922ced2f8d6a6e27a52b atom/common/options_switches.h - their 100644 2469c7b5841f861c99e47d59fa18649264b259aa atom/common/options_switches.h -@@ -61,6 +61,10 @@ - extern const char kContextIsolation[]; - extern const char kGuestInstanceID[]; - extern const char kExperimentalFeatures[]; -+<<<<<<< .our -+======= -+extern const char kExperimentalCanvasFeatures[]; -+>>>>>>> .their - extern const char kOpenerID[]; - extern const char kScrollBounce[]; - extern const char kEnableBlinkFeatures[]; -@@ -92,9 +96,17 @@ - extern const char kSecureSchemes[]; - extern const char kAppUserModelId[]; - extern const char kAppPath[]; -+<<<<<<< .our - - extern const char kBackgroundColor[]; - extern const char kPreloadScript[]; -+======= -+extern const char kContextId[]; -+ -+extern const char kBackgroundColor[]; -+extern const char kPreloadScript[]; -+extern const char kPreloadURL[]; -+>>>>>>> .their - extern const char kPreloadScripts[]; - extern const char kNodeIntegration[]; - extern const char kContextIsolation[]; -added in both - our 100644 34576be95f2552aaa985dacb3f36406dfc29d54c atom/common/platform_util_win.cc - their 100644 193e2ece0042367113ee23512b5b3ee6d4785fca atom/common/platform_util_win.cc -@@ -31,12 +31,32 @@ - - namespace { - -+<<<<<<< .our -+======= -+// Old ShellExecute crashes the process when the command for a given scheme -+// is empty. This function tells if it is. -+bool ValidateShellCommandForScheme(const std::string& scheme) { -+ base::win::RegKey key; -+ base::string16 registry_path = -+ base::ASCIIToUTF16(scheme) + L"\\shell\\open\\command"; -+ key.Open(HKEY_CLASSES_ROOT, registry_path.c_str(), KEY_READ); -+ if (!key.Valid()) -+ return false; -+ DWORD size = 0; -+ key.ReadValue(NULL, NULL, &size, NULL); -+ if (size <= 2) -+ return false; -+ return true; -+} -+ -+>>>>>>> .their - // Required COM implementation of IFileOperationProgressSink so we can - // precheck files before deletion to make sure they can be move to the - // Recycle Bin. - class DeleteFileProgressSink : public IFileOperationProgressSink { - public: - DeleteFileProgressSink(); -+<<<<<<< .our - virtual ~DeleteFileProgressSink() = default; - - private: -@@ -75,17 +95,55 @@ - HRESULT, - IShellItem*) override; - HRESULT STDMETHODCALLTYPE PreNewItem(DWORD, IShellItem*, LPCWSTR) override; -+======= -+ -+ private: -+ ULONG STDMETHODCALLTYPE AddRef(void); -+ ULONG STDMETHODCALLTYPE Release(void); -+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID* ppvObj); -+ HRESULT STDMETHODCALLTYPE StartOperations(void); -+ HRESULT STDMETHODCALLTYPE FinishOperations(HRESULT); -+ HRESULT STDMETHODCALLTYPE PreRenameItem(DWORD, IShellItem*, LPCWSTR); -+ HRESULT STDMETHODCALLTYPE -+ PostRenameItem(DWORD, IShellItem*, LPCWSTR, HRESULT, IShellItem*); -+ HRESULT STDMETHODCALLTYPE PreMoveItem(DWORD, -+ IShellItem*, -+ IShellItem*, -+ LPCWSTR); -+ HRESULT STDMETHODCALLTYPE -+ PostMoveItem(DWORD, IShellItem*, IShellItem*, LPCWSTR, HRESULT, IShellItem*); -+ HRESULT STDMETHODCALLTYPE PreCopyItem(DWORD, -+ IShellItem*, -+ IShellItem*, -+ LPCWSTR); -+ HRESULT STDMETHODCALLTYPE -+ PostCopyItem(DWORD, IShellItem*, IShellItem*, LPCWSTR, HRESULT, IShellItem*); -+ HRESULT STDMETHODCALLTYPE PreDeleteItem(DWORD, IShellItem*); -+ HRESULT STDMETHODCALLTYPE PostDeleteItem(DWORD, -+ IShellItem*, -+ HRESULT, -+ IShellItem*); -+ HRESULT STDMETHODCALLTYPE PreNewItem(DWORD, IShellItem*, LPCWSTR); -+>>>>>>> .their - HRESULT STDMETHODCALLTYPE PostNewItem(DWORD, - IShellItem*, - LPCWSTR, - LPCWSTR, - DWORD, - HRESULT, -+<<<<<<< .our - IShellItem*) override; - HRESULT STDMETHODCALLTYPE UpdateProgress(UINT, UINT) override; - HRESULT STDMETHODCALLTYPE ResetTimer(void) override; - HRESULT STDMETHODCALLTYPE PauseTimer(void) override; - HRESULT STDMETHODCALLTYPE ResumeTimer(void) override; -+======= -+ IShellItem*); -+ HRESULT STDMETHODCALLTYPE UpdateProgress(UINT, UINT); -+ HRESULT STDMETHODCALLTYPE ResetTimer(void); -+ HRESULT STDMETHODCALLTYPE PauseTimer(void); -+ HRESULT STDMETHODCALLTYPE ResumeTimer(void); -+>>>>>>> .their - - ULONG m_cRef; - }; -@@ -240,6 +298,36 @@ - if (dir.empty()) - return false; - -+<<<<<<< .our -+======= -+ typedef HRESULT(WINAPI * SHOpenFolderAndSelectItemsFuncPtr)( -+ PCIDLIST_ABSOLUTE pidl_Folder, UINT cidl, PCUITEMID_CHILD_ARRAY pidls, -+ DWORD flags); -+ -+ static SHOpenFolderAndSelectItemsFuncPtr open_folder_and_select_itemsPtr = -+ NULL; -+ static bool initialize_open_folder_proc = true; -+ if (initialize_open_folder_proc) { -+ initialize_open_folder_proc = false; -+ // The SHOpenFolderAndSelectItems API is exposed by shell32 version 6 -+ // and does not exist in Win2K. We attempt to retrieve this function export -+ // from shell32 and if it does not exist, we just invoke ShellExecute to -+ // open the folder thus losing the functionality to select the item in -+ // the process. -+ HMODULE shell32_base = GetModuleHandle(L"shell32.dll"); -+ if (!shell32_base) { -+ NOTREACHED() << " " << __FUNCTION__ << "(): Can't open shell32.dll"; -+ return false; -+ } -+ open_folder_and_select_itemsPtr = -+ reinterpret_cast<SHOpenFolderAndSelectItemsFuncPtr>( -+ GetProcAddress(shell32_base, "SHOpenFolderAndSelectItems")); -+ } -+ if (!open_folder_and_select_itemsPtr) { -+ return ui::win::OpenFolderViaShell(dir); -+ } -+ -+>>>>>>> .their - Microsoft::WRL::ComPtr<IShellFolder> desktop; - HRESULT hr = SHGetDesktopFolder(desktop.GetAddressOf()); - if (FAILED(hr)) -@@ -263,8 +351,13 @@ - - const ITEMIDLIST* highlight[] = {file_item}; - -+<<<<<<< .our - hr = SHOpenFolderAndSelectItems(dir_item, arraysize(highlight), highlight, - NULL); -+======= -+ hr = (*open_folder_and_select_itemsPtr)(dir_item, arraysize(highlight), -+ highlight, NULL); -+>>>>>>> .their - if (!FAILED(hr)) - return true; - -@@ -275,8 +368,14 @@ - return ui::win::OpenFolderViaShell(dir); - } else { - LPTSTR message = NULL; -+<<<<<<< .our - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - 0, hr, 0, reinterpret_cast<LPTSTR>(&message), 0, NULL); -+======= -+ DWORD message_length = FormatMessage( -+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 0, hr, 0, -+ reinterpret_cast<LPTSTR>(&message), 0, NULL); -+>>>>>>> .their - LOG(WARNING) << " " << __FUNCTION__ << "(): Can't open full_path = \"" - << full_path.value() << "\"" - << " hr = " << hr << " " << reinterpret_cast<LPTSTR>(&message); -added in both - our 100644 6e29fe45a69f44856d7fca449ec1be4eaf6970a2 atom/renderer/atom_sandboxed_renderer_client.cc - their 100644 ce214162033ca353a34ced83f0facf5b1dd1eca4 atom/renderer/atom_sandboxed_renderer_client.cc -@@ -16,7 +16,10 @@ - #include "base/command_line.h" - #include "base/files/file_path.h" - #include "base/path_service.h" -+<<<<<<< .our - #include "base/process/process_handle.h" -+======= -+>>>>>>> .their - #include "chrome/renderer/printing/print_web_view_helper.h" - #include "content/public/renderer/render_frame.h" - #include "native_mate/dictionary.h" -@@ -90,11 +93,32 @@ - return path.value(); - } - -+<<<<<<< .our - v8::Local<v8::Value> CreatePreloadScript(v8::Isolate* isolate, - v8::Local<v8::String> preloadSrc) { - auto script = v8::Script::Compile(preloadSrc); - auto func = script->Run(); - return func; -+======= -+void InitializeBindings(v8::Local<v8::Object> binding, -+ v8::Local<v8::Context> context) { -+ auto* isolate = context->GetIsolate(); -+ mate::Dictionary b(isolate, binding); -+ b.SetMethod("get", GetBinding); -+ b.SetMethod("crash", AtomBindings::Crash); -+ b.SetMethod("hang", AtomBindings::Hang); -+ b.SetMethod("getArgv", GetArgv); -+ b.SetMethod("getExecPath", GetExecPath); -+ b.SetMethod("getHeapStatistics", &AtomBindings::GetHeapStatistics); -+ b.SetMethod("getProcessMemoryInfo", &AtomBindings::GetProcessMemoryInfo); -+ b.SetMethod("getSystemMemoryInfo", &AtomBindings::GetSystemMemoryInfo); -+ -+ // Pass in CLI flags needed to setup the renderer -+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); -+ if (command_line->HasSwitch(switches::kGuestInstanceID)) -+ b.Set(options::kGuestInstanceID, -+ command_line->GetSwitchValueASCII(switches::kGuestInstanceID)); -+>>>>>>> .their - } - - class AtomSandboxedRenderFrameObserver : public AtomRenderFrameObserver { -@@ -132,11 +156,15 @@ - AtomSandboxedRendererClient::AtomSandboxedRendererClient() { - // Explicitly register electron's builtin modules. - NodeBindings::RegisterBuiltinModules(); -+<<<<<<< .our - metrics_ = base::ProcessMetrics::CreateCurrentProcessMetrics(); -+======= -+>>>>>>> .their - } - - AtomSandboxedRendererClient::~AtomSandboxedRendererClient() {} - -+<<<<<<< .our - void AtomSandboxedRendererClient::InitializeBindings( - v8::Local<v8::Object> binding, - v8::Local<v8::Context> context) { -@@ -164,6 +192,8 @@ - command_line->GetSwitchValueASCII(switches::kGuestInstanceID)); - } - -+======= -+>>>>>>> .their - void AtomSandboxedRendererClient::RenderFrameCreated( - content::RenderFrame* render_frame) { - new AtomSandboxedRenderFrameObserver(render_frame, this); -added in both - our 100644 4afef42dfd43d9e177d93a3c49b115c34f7e2e6a atom/renderer/atom_sandboxed_renderer_client.h - their 100644 1ebf4429794f47996c8f92f66b1c5b0295365b06 atom/renderer/atom_sandboxed_renderer_client.h -@@ -8,7 +8,10 @@ - #include <vector> - - #include "atom/renderer/renderer_client_base.h" -+<<<<<<< .our - #include "base/process/process_metrics.h" -+======= -+>>>>>>> .their - - namespace atom { - -@@ -17,8 +20,11 @@ - AtomSandboxedRendererClient(); - ~AtomSandboxedRendererClient() override; - -+<<<<<<< .our - void InitializeBindings(v8::Local<v8::Object> binding, - v8::Local<v8::Context> context); -+======= -+>>>>>>> .their - void InvokeIpcCallback(v8::Handle<v8::Context> context, - const std::string& callback_name, - std::vector<v8::Handle<v8::Value>> args); -@@ -33,8 +39,11 @@ - void RenderViewCreated(content::RenderView*) override; - - private: -+<<<<<<< .our - std::unique_ptr<base::ProcessMetrics> metrics_; - -+======= -+>>>>>>> .their - DISALLOW_COPY_AND_ASSIGN(AtomSandboxedRendererClient); - }; - -added in both - our 100644 3c591201532e4510010f5bc895da3c16780d08d9 atom/renderer/preferences_manager.cc - their 100644 2c6540cd5f40b7244e70a55f9c146571ec91e4a1 atom/renderer/preferences_manager.cc -@@ -26,9 +26,13 @@ - - void PreferencesManager::OnUpdatePreferences( - const base::ListValue& preferences) { -+<<<<<<< .our - auto copy = - base::ListValue::From(base::Value::ToUniquePtrValue(preferences.Clone())); - preferences_.swap(copy); -+======= -+ preferences_ = preferences.CreateDeepCopy(); -+>>>>>>> .their - } - - } // namespace atom -added in both - our 100644 69490420ef5b8f87e7cb8fd97ebd5ec4509fa1ae atom/renderer/renderer_client_base.cc - their 100644 a73dd265f9367dd35308568588b42597c6650189 atom/renderer/renderer_client_base.cc -@@ -20,6 +20,10 @@ - #include "base/strings/string_split.h" - #include "base/strings/stringprintf.h" - #include "chrome/renderer/media/chrome_key_systems.h" -+<<<<<<< .our -+======= -+#include "chrome/renderer/pepper/pepper_helper.h" -+>>>>>>> .their - #include "chrome/renderer/printing/print_web_view_helper.h" - #include "chrome/renderer/tts_dispatcher.h" - #include "content/public/common/content_constants.h" -@@ -46,10 +50,13 @@ - #include "atom/common/atom_constants.h" - #endif // defined(ENABLE_PDF_VIEWER) - -+<<<<<<< .our - #if defined(ENABLE_PEPPER_FLASH) - #include "chrome/renderer/pepper/pepper_helper.h" - #endif // defined(ENABLE_PEPPER_FLASH) - -+======= -+>>>>>>> .their - // This is defined in later versions of Chromium, remove this if you see - // compiler complaining duplicate defines. - #if defined(OS_WIN) || defined(OS_FUCHSIA) -@@ -95,7 +102,11 @@ - void RendererClientBase::DidCreateScriptContext( - v8::Handle<v8::Context> context, - content::RenderFrame* render_frame) { -+<<<<<<< .our - // global.setHidden("contextId", `${processId}-${++next_context_id_}`) -+======= -+ // global.setHidden("contextId", `${processId}-${++nextContextId}`) -+>>>>>>> .their - std::string context_id = base::StringPrintf( - "%" CrPRIdPid "-%d", base::GetCurrentProcId(), ++next_context_id_); - v8::Isolate* isolate = context->GetIsolate(); -@@ -164,9 +175,13 @@ - #if defined(TOOLKIT_VIEWS) - new AutofillAgent(render_frame); - #endif -+<<<<<<< .our - #if defined(ENABLE_PEPPER_FLASH) - new PepperHelper(render_frame); - #endif -+======= -+ new PepperHelper(render_frame); -+>>>>>>> .their - new ContentSettingsObserver(render_frame); - new printing::PrintWebViewHelper(render_frame); - -added in both - our 100644 166c01b8686498ecb9cb1929e872309441eeaf36 brightray/BUILD.gn - their 100644 c2185726abdf17d7c24010a0b076b7e33496f2ad brightray/BUILD.gn -@@ -1,14 +1,48 @@ - import("//build/config/ui.gni") - -+<<<<<<< .our - filenames_gypi = exec_script("//build/gypi_to_gn.py", - [ rebase_path("filenames.gypi") ], - "scope", - [ "filenames.gypi" ]) -+======= -+filenames_gypi = exec_script( -+ "//build/gypi_to_gn.py", -+ [ rebase_path("filenames.gypi") ], -+ "scope", -+ [ "filenames.gypi" ] -+) -+ -+ -+if (is_linux) { -+ # TODO: Experiment with using //tools/generate_library_loader for generating -+ # the libnotify loader. -+ copy("libnotify_headers") { -+ sources = [ -+ "/usr/include/libnotify/notify.h", -+ "/usr/include/libnotify/notification.h", -+ "/usr/include/libnotify/notify-enum-types.h", -+ "/usr/include/libnotify/notify-features.h", -+ ] -+ outputs = [ "$target_gen_dir/libnotify-copy/libnotify/{{source_file_part}}" ] -+ } -+ config("libnotify_config") { -+ include_dirs = [ "$target_gen_dir/libnotify-copy" ] -+ } -+ group("libnotify") { -+ deps = [ ":libnotify_headers" ] -+ public_configs = [ ":libnotify_config" ] -+ } -+} -+>>>>>>> .their - - static_library("brightray") { - deps = [ - "//base", -+<<<<<<< .our - "//base:base_static", -+======= -+>>>>>>> .their - "//components/network_session_configurator/common", - "//components/prefs", - "//content/public/browser", -@@ -18,6 +52,7 @@ - "//ui/views", - ] - -+<<<<<<< .our - include_dirs = [ ".." ] - - defines = [ -@@ -27,6 +62,21 @@ - - if (is_linux) { - deps += [ "//build/config/linux/gtk" ] -+======= -+ include_dirs = [ -+ "..", -+ ] -+ -+ defines = [ -+ "DISABLE_NACL=1", -+ ] -+ -+ if (is_linux) { -+ deps += [ -+ "//build/config/linux/gtk3", -+ ":libnotify", -+ ] -+>>>>>>> .their - } - - extra_source_filters = [] -@@ -38,8 +88,12 @@ - ] - } - -+<<<<<<< .our - set_sources_assignment_filter( - sources_assignment_filter + extra_source_filters) -+======= -+ set_sources_assignment_filter(sources_assignment_filter + extra_source_filters) -+>>>>>>> .their - sources = filenames_gypi.brightray_sources - set_sources_assignment_filter(sources_assignment_filter) - } -added in both - our 100644 8a945dc0219293d90e30162e4691a4d871071f4f brightray/brightray.gypi - their 100644 33d42bc8069ce4031cbb4375e37194c923b9de89 brightray/brightray.gypi -@@ -155,7 +155,14 @@ - 'WEBRTC_MAC', - ], - }], # OS=="mac" -+<<<<<<< .our - ['OS=="win"', { -+======= -+ ['OS=="win"', { -+ 'include_dirs': [ -+ '<(libchromiumcontent_src_dir)/third_party/wtl/include', -+ ], -+>>>>>>> .their - 'defines': [ - '_WIN32_WINNT=0x0602', - 'WINVER=0x0602', -@@ -205,7 +212,10 @@ - 'SKIA_DLL', - 'USING_V8_SHARED', - 'WEBKIT_DLL', -+<<<<<<< .our - 'V8_ENABLE_CHECKS', -+======= -+>>>>>>> .their - ], - 'msvs_settings': { - 'VCCLCompilerTool': { -added in both - our 100644 1eff7344e9aef78bb88720c38c0f75fb92e6bc09 brightray/browser/browser_context.cc - their 100644 708a97bddd1e883f1192e0e431957b72e40e7f22 brightray/browser/browser_context.cc -@@ -11,6 +11,10 @@ - #include "brightray/browser/brightray_paths.h" - #include "brightray/browser/browser_client.h" - #include "brightray/browser/inspectable_web_contents_impl.h" -+<<<<<<< .our -+======= -+#include "brightray/browser/special_storage_policy.h" -+>>>>>>> .their - #include "brightray/browser/zoom_level_delegate.h" - #include "brightray/common/application_info.h" - #include "components/prefs/json_pref_store.h" -@@ -54,6 +58,10 @@ - - BrowserContext::BrowserContext(const std::string& partition, bool in_memory) - : in_memory_(in_memory), -+<<<<<<< .our -+======= -+ storage_policy_(new SpecialStoragePolicy), -+>>>>>>> .their - weak_factory_(this) { - if (!PathService::Get(DIR_USER_DATA, &path_)) { - PathService::Get(DIR_APP_DATA, &path_); -@@ -158,6 +166,13 @@ - return nullptr; - } - -+<<<<<<< .our -+======= -+storage::SpecialStoragePolicy* BrowserContext::GetSpecialStoragePolicy() { -+ return storage_policy_.get(); -+} -+ -+>>>>>>> .their - content::PushMessagingService* BrowserContext::GetPushMessagingService() { - return nullptr; - } -added in both - our 100644 1fb1c59b8043dbb711a364fca3c357c11993bedc brightray/browser/browser_context.h - their 100644 d36ec3bbdff9ad50a080ab849e879c211e2a9213 brightray/browser/browser_context.h -@@ -17,6 +17,13 @@ - class PrefRegistrySimple; - class PrefService; - -+<<<<<<< .our -+======= -+namespace storage { -+class SpecialStoragePolicy; -+} -+ -+>>>>>>> .their - namespace brightray { - - class BrowserContext; -@@ -48,6 +55,10 @@ - content::ResourceContext* GetResourceContext() override; - content::DownloadManagerDelegate* GetDownloadManagerDelegate() override; - content::BrowserPluginGuestManager* GetGuestManager() override; -+<<<<<<< .our -+======= -+ storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override; -+>>>>>>> .their - content::PushMessagingService* GetPushMessagingService() override; - content::SSLHostStateDelegate* GetSSLHostStateDelegate() override; - content::BackgroundFetchDelegate* GetBackgroundFetchDelegate() override; -@@ -116,6 +127,10 @@ - base::FilePath path_; - bool in_memory_; - -+<<<<<<< .our -+======= -+ scoped_refptr<storage::SpecialStoragePolicy> storage_policy_; -+>>>>>>> .their - std::unique_ptr<PrefService> prefs_; - std::unique_ptr<MediaDeviceIDSalt> media_device_id_salt_; - // Self-destructing class responsible for creating URLRequestContextGetter -added in both - our 100644 80e6615be13d8dd8fd244c1b2c90b3630e893578 brightray/browser/mac/cocoa_notification.h - their 100644 066528ee490b8821bd797c49805cd34bbcdf0bc0 brightray/browser/mac/cocoa_notification.h -@@ -31,7 +31,10 @@ - void NotificationActivated(); - void NotificationActivated(NSUserNotificationAction* action) - API_AVAILABLE(macosx(10.10)); -+<<<<<<< .our - void NotificationDismissed(); -+======= -+>>>>>>> .their - - NSUserNotification* notification() const { return notification_; } - -added in both - our 100644 57f53931e972adac9cbadf643c737b21d6b9b712 brightray/browser/mac/cocoa_notification.mm - their 100644 6b576497d41a9b747b702d5502583637d96606df brightray/browser/mac/cocoa_notification.mm -@@ -156,6 +156,7 @@ - this->LogAction("button clicked"); - } - -+<<<<<<< .our - void CocoaNotification::NotificationDismissed() { - if (delegate()) - delegate()->NotificationClosed(); -@@ -163,6 +164,8 @@ - this->LogAction("dismissed"); - } - -+======= -+>>>>>>> .their - void CocoaNotification::LogAction(const char* action) { - if (getenv("ELECTRON_DEBUG_NOTIFICATIONS")) { - NSString* identifier = [notification_ valueForKey:@"identifier"]; -added in both - our 100644 ddf0cbfa888d3f3be47db890c842900ce52d2411 brightray/browser/mac/notification_center_delegate.mm - their 100644 7ae24b8979b441e7583583ade5aa2708cfb1b994 brightray/browser/mac/notification_center_delegate.mm -@@ -65,6 +65,7 @@ - return YES; - } - -+<<<<<<< .our - #if !defined(MAS_BUILD) - // This undocumented method notifies us if a user closes "Alert" notifications - // https://chromium.googlesource.com/chromium/src/+/lkgr/chrome/browser/notifications/notification_platform_bridge_mac.mm -@@ -89,4 +90,6 @@ - } - #endif - -+======= -+>>>>>>> .their - @end -added in remote - their 100644 e662441dedbfe3c5cf08e8dcce3413153c1fcf82 brightray/browser/special_storage_policy.cc -@@ -0,0 +1,41 @@ -+// Copyright 2014 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "brightray/browser/special_storage_policy.h" -+ -+namespace brightray { -+ -+SpecialStoragePolicy::SpecialStoragePolicy() {} -+ -+SpecialStoragePolicy::~SpecialStoragePolicy() {} -+ -+bool SpecialStoragePolicy::IsStorageProtected(const GURL& origin) { -+ return true; -+} -+ -+bool SpecialStoragePolicy::IsStorageUnlimited(const GURL& origin) { -+ return true; -+} -+ -+bool SpecialStoragePolicy::IsStorageDurable(const GURL& origin) { -+ return true; -+} -+ -+bool SpecialStoragePolicy::HasIsolatedStorage(const GURL& origin) { -+ return false; -+} -+ -+bool SpecialStoragePolicy::IsStorageSessionOnly(const GURL& origin) { -+ return false; -+} -+ -+bool SpecialStoragePolicy::HasSessionOnlyOrigins() { -+ return false; -+} -+ -+bool SpecialStoragePolicy::ShouldDeleteCookieOnExit(const GURL& origin) { -+ return false; -+} -+ -+} // namespace brightray -added in remote - their 100644 2d02cdd293438d4f10863c4cf6a7932dc20a3666 brightray/browser/special_storage_policy.h -@@ -0,0 +1,31 @@ -+// Copyright 2014 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef BRIGHTRAY_BROWSER_SPECIAL_STORAGE_POLICY_H_ -+#define BRIGHTRAY_BROWSER_SPECIAL_STORAGE_POLICY_H_ -+ -+#include "storage/browser/quota/special_storage_policy.h" -+ -+namespace brightray { -+ -+class SpecialStoragePolicy : public storage::SpecialStoragePolicy { -+ public: -+ SpecialStoragePolicy(); -+ -+ // storage::SpecialStoragePolicy implementation. -+ bool IsStorageProtected(const GURL& origin) override; -+ bool IsStorageUnlimited(const GURL& origin) override; -+ bool IsStorageDurable(const GURL& origin) override; -+ bool HasIsolatedStorage(const GURL& origin) override; -+ bool IsStorageSessionOnly(const GURL& origin) override; -+ bool HasSessionOnlyOrigins() override; -+ bool ShouldDeleteCookieOnExit(const GURL& origin) override; -+ -+ protected: -+ ~SpecialStoragePolicy() override; -+}; -+ -+} // namespace brightray -+ -+#endif // BRIGHTRAY_BROWSER_SPECIAL_STORAGE_POLICY_H_ -added in both - our 100644 f954489704cf1147b13937bc3a228898f45cb38d brightray/browser/win/notification_presenter_win.h - their 100644 2a1a779bfa3d53e693b50d3b7f669a6afd92efaa brightray/browser/win/notification_presenter_win.h -@@ -35,7 +35,11 @@ - class NotificationPresenterWin : public NotificationPresenter { - public: - NotificationPresenterWin(); -+<<<<<<< .our - ~NotificationPresenterWin() override; -+======= -+ ~NotificationPresenterWin(); -+>>>>>>> .their - - bool Init(); - -added in both - our 100644 cbfea8360b983a139736c01e93f0fda5b104f900 brightray/browser/win/notification_presenter_win7.cc - their 100644 9a1ede3642afae305a6f5b1f388d04646f6b765b brightray/browser/win/notification_presenter_win7.cc -@@ -13,8 +13,13 @@ - - Win32Notification* NotificationPresenterWin7::GetNotificationObjectByRef( - const DesktopNotificationController::Notification& ref) { -+<<<<<<< .our - for (auto* n : this->notifications()) { - auto* w32n = static_cast<Win32Notification*>(n); -+======= -+ for (auto n : this->notifications()) { -+ auto w32n = static_cast<Win32Notification*>(n); -+>>>>>>> .their - if (w32n->GetRef() == ref) - return w32n; - } -@@ -24,8 +29,13 @@ - - Win32Notification* NotificationPresenterWin7::GetNotificationObjectByTag( - const std::string& tag) { -+<<<<<<< .our - for (auto* n : this->notifications()) { - auto* w32n = static_cast<Win32Notification*>(n); -+======= -+ for (auto n : this->notifications()) { -+ auto w32n = static_cast<Win32Notification*>(n); -+>>>>>>> .their - if (w32n->GetTag() == tag) - return w32n; - } -@@ -35,14 +45,22 @@ - - void NotificationPresenterWin7::OnNotificationClicked( - Notification& notification) { -+<<<<<<< .our - auto* n = GetNotificationObjectByRef(notification); -+======= -+ auto n = GetNotificationObjectByRef(notification); -+>>>>>>> .their - if (n) - n->NotificationClicked(); - } - - void NotificationPresenterWin7::OnNotificationDismissed( - Notification& notification) { -+<<<<<<< .our - auto* n = GetNotificationObjectByRef(notification); -+======= -+ auto n = GetNotificationObjectByRef(notification); -+>>>>>>> .their - if (n) - n->NotificationDismissed(); - } -added in both - our 100644 f07d43105fc1b99b7421e38b7d937a280738a6b6 brightray/browser/win/win32_desktop_notifications/common.h - their 100644 967ad247481f224e0c4f305337d6127ffd9cfa19 brightray/browser/win/win32_desktop_notifications/common.h -@@ -36,7 +36,11 @@ - GetProcAddress(GetModuleHandle(TEXT("shcore")), "GetDpiForMonitor")); - - if (GetDpiForMonitor) { -+<<<<<<< .our - auto* monitor = MonitorFromPoint({}, MONITOR_DEFAULTTOPRIMARY); -+======= -+ auto monitor = MonitorFromPoint({}, MONITOR_DEFAULTTOPRIMARY); -+>>>>>>> .their - if (GetDpiForMonitor(monitor, 0, &dpi_x, &dpi_y) == S_OK) - return; - } -added in both - our 100644 71395a49d82f7be8a3ffd66e4795af968973a274 brightray/browser/win/win32_desktop_notifications/desktop_notification_controller.cc - their 100644 0840d9e6364dc743458588dd21464f32ea946adf brightray/browser/win/win32_desktop_notifications/desktop_notification_controller.cc -@@ -1,9 +1,14 @@ -+<<<<<<< .our - #ifndef NOMINMAX - #define NOMINMAX - #endif - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN - #endif -+======= -+#define NOMINMAX -+#define WIN32_LEAN_AND_MEAN -+>>>>>>> .their - #include "brightray/browser/win/win32_desktop_notifications/desktop_notification_controller.h" - #include <windowsx.h> - #include <algorithm> -@@ -39,9 +44,12 @@ - return ret; - } - -+<<<<<<< .our - const TCHAR DesktopNotificationController::class_name_[] = - TEXT("DesktopNotificationController"); - -+======= -+>>>>>>> .their - HINSTANCE DesktopNotificationController::RegisterWndClasses() { - // We keep a static `module` variable which serves a dual purpose: - // 1. Stores the HINSTANCE where the window classes are registered, -@@ -90,7 +98,11 @@ - LPARAM lparam) { - switch (message) { - case WM_CREATE: { -+<<<<<<< .our - auto*& cs = reinterpret_cast<const CREATESTRUCT*&>(lparam); -+======= -+ auto& cs = reinterpret_cast<const CREATESTRUCT*&>(lparam); -+>>>>>>> .their - SetWindowLongPtr(hwnd, 0, (LONG_PTR)cs->lpCreateParams); - } break; - -@@ -101,7 +113,11 @@ - return 0; - - case WM_DISPLAYCHANGE: { -+<<<<<<< .our - auto* inst = Get(hwnd); -+======= -+ auto inst = Get(hwnd); -+>>>>>>> .their - inst->ClearAssets(); - inst->AnimateAll(); - } break; -@@ -189,13 +205,21 @@ - POINT origin = {work_area.right, - work_area.bottom - metrics.Y(toast_margin_)}; - -+<<<<<<< .our - auto* hdwp = BeginDeferWindowPos(static_cast<int>(instances_.size())); -+======= -+ auto hdwp = BeginDeferWindowPos(static_cast<int>(instances_.size())); -+>>>>>>> .their - - for (auto&& inst : instances_) { - if (!inst.hwnd) - continue; - -+<<<<<<< .our - auto* notification = Toast::Get(inst.hwnd); -+======= -+ auto notification = Toast::Get(inst.hwnd); -+>>>>>>> .their - hdwp = notification->Animate(hdwp, origin); - if (!hdwp) - break; -@@ -252,7 +276,11 @@ - int target_pos = 0; - for (auto&& inst : instances_) { - if (inst.hwnd) { -+<<<<<<< .our - auto* toast = Toast::Get(inst.hwnd); -+======= -+ auto toast = Toast::Get(inst.hwnd); -+>>>>>>> .their - - if (toast->IsHighlighted()) - target_pos = toast->GetVerticalPosition(); -@@ -295,9 +323,15 @@ - } - - // Dismiss active toast -+<<<<<<< .our - auto* hwnd = GetToast(notification.data_.get()); - if (hwnd) { - auto* toast = Toast::Get(hwnd); -+======= -+ auto hwnd = GetToast(notification.data_.get()); -+ if (hwnd) { -+ auto toast = Toast::Get(hwnd); -+>>>>>>> .their - toast->Dismiss(); - } - } -@@ -310,8 +344,13 @@ - } - - void DesktopNotificationController::CreateToast(NotificationLink&& data) { -+<<<<<<< .our - auto* hinstance = RegisterWndClasses(); - auto* hwnd = Toast::Create(hinstance, data); -+======= -+ auto hinstance = RegisterWndClasses(); -+ auto hwnd = Toast::Create(hinstance, data); -+>>>>>>> .their - if (hwnd) { - int toast_pos = 0; - if (!instances_.empty()) { -@@ -319,7 +358,11 @@ - _ASSERT(item.hwnd); - - ScreenMetrics scr; -+<<<<<<< .our - auto* toast = Toast::Get(item.hwnd); -+======= -+ auto toast = Toast::Get(item.hwnd); -+>>>>>>> .their - toast_pos = toast->GetVerticalPosition() + toast->GetHeight() + - scr.Y(toast_margin_); - } -@@ -333,7 +376,11 @@ - NULL, hinstance, this); - } - -+<<<<<<< .our - auto* toast = Toast::Get(hwnd); -+======= -+ auto toast = Toast::Get(hwnd); -+>>>>>>> .their - toast->PopUp(toast_pos); - } - } -@@ -363,18 +410,24 @@ - } - } - -+<<<<<<< .our - DesktopNotificationController::Notification::Notification() = default; - DesktopNotificationController::Notification::Notification( - const DesktopNotificationController::Notification&) = default; - -+======= -+>>>>>>> .their - DesktopNotificationController::Notification::Notification( - const shared_ptr<NotificationData>& data) - : data_(data) { - _ASSERT(data != nullptr); - } - -+<<<<<<< .our - DesktopNotificationController::Notification::~Notification() = default; - -+======= -+>>>>>>> .their - bool DesktopNotificationController::Notification::operator==( - const Notification& other) const { - return data_ == other.data_; -@@ -405,9 +458,15 @@ - data_->body_text = move(body_text); - data_->image = CopyBitmap(image); - -+<<<<<<< .our - auto* hwnd = data_->controller->GetToast(data_.get()); - if (hwnd) { - auto* toast = Toast::Get(hwnd); -+======= -+ auto hwnd = data_->controller->GetToast(data_.get()); -+ if (hwnd) { -+ auto toast = Toast::Get(hwnd); -+>>>>>>> .their - toast->ResetContents(); - } - -@@ -422,7 +481,11 @@ - } - - DesktopNotificationController::NotificationLink::~NotificationLink() { -+<<<<<<< .our - auto* p = get(); -+======= -+ auto p = get(); -+>>>>>>> .their - if (p) - p->controller = nullptr; - } -added in both - our 100644 d6d8fd35a2958b39dc0f6a76b4ee110b2951c832 brightray/browser/win/win32_desktop_notifications/desktop_notification_controller.h - their 100644 ad62fa727b453510e07917ee718e830e8ac84d2d brightray/browser/win/win32_desktop_notifications/desktop_notification_controller.h -@@ -76,7 +76,12 @@ - void DestroyToast(ToastInstance& inst); - - private: -+<<<<<<< .our - static const TCHAR class_name_[]; -+======= -+ static constexpr const TCHAR class_name_[] = -+ TEXT("DesktopNotificationController"); -+>>>>>>> .their - - HWND hwnd_controller_ = NULL; - HFONT caption_font_ = NULL, body_font_ = NULL; -@@ -87,10 +92,15 @@ - - class DesktopNotificationController::Notification { - public: -+<<<<<<< .our - Notification(); - explicit Notification(const std::shared_ptr<NotificationData>& data); - Notification(const Notification&); - ~Notification(); -+======= -+ Notification() = default; -+ explicit Notification(const std::shared_ptr<NotificationData>& data); -+>>>>>>> .their - - bool operator==(const Notification& other) const; - -added in both - our 100644 061eb977a8dc58f07aff1370467f88b10aec8003 brightray/browser/win/win32_desktop_notifications/toast.cc - their 100644 9a1e7cb099e83e4b6af7c5bcdde3f5c83d09e454 brightray/browser/win/win32_desktop_notifications/toast.cc -@@ -1,11 +1,18 @@ -+<<<<<<< .our - #ifndef NOMINMAX - #define NOMINMAX - #endif -+======= -+#define NOMINMAX -+>>>>>>> .their - #include "brightray/browser/win/win32_desktop_notifications/toast.h" - #include <uxtheme.h> - #include <windowsx.h> - #include <algorithm> -+<<<<<<< .our - #include "base/logging.h" -+======= -+>>>>>>> .their - #include "brightray/browser/win/win32_desktop_notifications/common.h" - - #pragma comment(lib, "msimg32.lib") -@@ -86,7 +93,11 @@ - if (GetDIBits(hdc_screen, bitmap, 0, 0, 0, - reinterpret_cast<BITMAPINFO*>(&bmi), DIB_RGB_COLORS) && - bmi.biSizeImage > 0 && (bmi.biSizeImage % 4) == 0) { -+<<<<<<< .our - auto* buf = reinterpret_cast<BYTE*>( -+======= -+ auto buf = reinterpret_cast<BYTE*>( -+>>>>>>> .their - _aligned_malloc(bmi.biSizeImage, sizeof(DWORD))); - - if (buf) { -@@ -120,12 +131,20 @@ - bmi.biCompression = BI_RGB; - - void* color_bits; -+<<<<<<< .our - auto* color_bitmap = -+======= -+ auto color_bitmap = -+>>>>>>> .their - CreateDIBSection(NULL, reinterpret_cast<BITMAPINFO*>(&bmi), - DIB_RGB_COLORS, &color_bits, NULL, 0); - - void* alpha_bits; -+<<<<<<< .our - auto* alpha_bitmap = -+======= -+ auto alpha_bitmap = -+>>>>>>> .their - CreateDIBSection(NULL, reinterpret_cast<BITMAPINFO*>(&bmi), - DIB_RGB_COLORS, &alpha_bits, NULL, 0); - -@@ -151,9 +170,15 @@ - GdiFlush(); - - // apply the alpha channel -+<<<<<<< .our - auto* dest = reinterpret_cast<BYTE*>(color_bits); - auto* src = reinterpret_cast<const BYTE*>(alpha_bits); - auto* end = src + (width * height * 4); -+======= -+ auto dest = reinterpret_cast<BYTE*>(color_bits); -+ auto src = reinterpret_cast<const BYTE*>(alpha_bits); -+ auto end = src + (width * height * 4); -+>>>>>>> .their - while (src != end) { - dest[3] = src[0]; - dest += 4; -@@ -184,9 +209,12 @@ - return result_bitmap; - } - -+<<<<<<< .our - const TCHAR DesktopNotificationController::Toast::class_name_[] = - TEXT("DesktopNotificationToast"); - -+======= -+>>>>>>> .their - DesktopNotificationController::Toast::Toast(HWND hwnd, - shared_ptr<NotificationData>* data) - : hwnd_(hwnd), data_(*data) { -@@ -220,10 +248,17 @@ - LPARAM lparam) { - switch (message) { - case WM_CREATE: { -+<<<<<<< .our - auto*& cs = reinterpret_cast<const CREATESTRUCT*&>(lparam); - auto* data = - static_cast<shared_ptr<NotificationData>*>(cs->lpCreateParams); - auto* inst = new Toast(hwnd, data); -+======= -+ auto& cs = reinterpret_cast<const CREATESTRUCT*&>(lparam); -+ auto data = -+ static_cast<shared_ptr<NotificationData>*>(cs->lpCreateParams); -+ auto inst = new Toast(hwnd, data); -+>>>>>>> .their - SetWindowLongPtr(hwnd, 0, (LONG_PTR)inst); - } break; - -@@ -242,7 +277,11 @@ - return 0; - - case WM_LBUTTONDOWN: { -+<<<<<<< .our - auto* inst = Get(hwnd); -+======= -+ auto inst = Get(hwnd); -+>>>>>>> .their - - inst->Dismiss(); - -@@ -255,7 +294,11 @@ - return 0; - - case WM_MOUSEMOVE: { -+<<<<<<< .our - auto* inst = Get(hwnd); -+======= -+ auto inst = Get(hwnd); -+>>>>>>> .their - if (!inst->is_highlighted_) { - inst->is_highlighted_ = true; - -@@ -275,7 +318,11 @@ - return 0; - - case WM_MOUSELEAVE: { -+<<<<<<< .our - auto* inst = Get(hwnd); -+======= -+ auto inst = Get(hwnd); -+>>>>>>> .their - inst->is_highlighted_ = false; - inst->is_close_hot_ = false; - inst->UpdateContents(); -@@ -289,7 +336,11 @@ - return 0; - - case WM_WINDOWPOSCHANGED: { -+<<<<<<< .our - auto*& wp = reinterpret_cast<WINDOWPOS*&>(lparam); -+======= -+ auto& wp = reinterpret_cast<WINDOWPOS*&>(lparam); -+>>>>>>> .their - if (wp->flags & SWP_HIDEWINDOW) { - if (!IsWindowVisible(hwnd)) - Get(hwnd)->is_highlighted_ = false; -@@ -363,7 +414,11 @@ - - // Draw background - { -+<<<<<<< .our - auto* brush = CreateSolidBrush(back_color); -+======= -+ auto brush = CreateSolidBrush(back_color); -+>>>>>>> .their - - RECT rc = {0, 0, toast_size_.cx, toast_size_.cy}; - FillRect(hdc_, &rc, brush); -@@ -374,8 +429,13 @@ - SetBkMode(hdc_, TRANSPARENT); - - const auto close = L'\x2715'; -+<<<<<<< .our - auto* caption_font = data_->controller->GetCaptionFont(); - auto* body_font = data_->controller->GetBodyFont(); -+======= -+ auto caption_font = data_->controller->GetCaptionFont(); -+ auto body_font = data_->controller->GetBodyFont(); -+>>>>>>> .their - - TEXTMETRIC tm_cap; - SelectFont(hdc_, caption_font); -@@ -526,7 +586,11 @@ - if (new_size.cx != this->toast_size_.cx || - new_size.cy != this->toast_size_.cy) { - HDC hdc_screen = GetDC(NULL); -+<<<<<<< .our - auto* new_bitmap = -+======= -+ auto new_bitmap = -+>>>>>>> .their - CreateCompatibleBitmap(hdc_screen, new_size.cx, new_size.cy); - ReleaseDC(NULL, hdc_screen); - -@@ -567,7 +631,11 @@ - auto b1 = UpdateLayeredWindowIndirect(hwnd_, &ulw); - ulw.prcDirty = &dirty2; - auto b2 = UpdateLayeredWindowIndirect(hwnd_, &ulw); -+<<<<<<< .our - DCHECK(b1 && b2); -+======= -+ _ASSERT(b1 && b2); -+>>>>>>> .their - } - - return; -@@ -739,21 +807,33 @@ - // ULWI fails, which can happen when one of the dimensions is zero (e.g. - // at the beginning of ease-in). - -+<<<<<<< .our - UpdateLayeredWindowIndirect(hwnd_, &ulw); -+======= -+ auto ulw_result = UpdateLayeredWindowIndirect(hwnd_, &ulw); -+>>>>>>> .their - hdwp = DeferWindowPos(hdwp, hwnd_, HWND_TOPMOST, pt.x, pt.y, size.cx, size.cy, - dwpFlags); - return hdwp; - } - - void DesktopNotificationController::Toast::StartEaseIn() { -+<<<<<<< .our - DCHECK(!ease_in_active_); -+======= -+ _ASSERT(!ease_in_active_); -+>>>>>>> .their - ease_in_start_ = GetTickCount(); - ease_in_active_ = true; - data_->controller->StartAnimation(); - } - - void DesktopNotificationController::Toast::StartEaseOut() { -+<<<<<<< .our - DCHECK(!ease_out_active_); -+======= -+ _ASSERT(!ease_out_active_); -+>>>>>>> .their - ease_out_start_ = GetTickCount(); - ease_out_active_ = true; - data_->controller->StartAnimation(); -added in both - our 100644 5a0e91b5e5ca02a51d4938c853c8b14903a403b4 brightray/browser/win/win32_desktop_notifications/toast.h - their 100644 967697ac8ccaf5a72825446137b845ed64b44acd brightray/browser/win/win32_desktop_notifications/toast.h -@@ -64,7 +64,11 @@ - float AnimateStackCollapse(); - - private: -+<<<<<<< .our - static const TCHAR class_name_[]; -+======= -+ static constexpr const TCHAR class_name_[] = TEXT("DesktopNotificationToast"); -+>>>>>>> .their - - const HWND hwnd_; - HDC hdc_; -added in both - our 100644 adeb55656b5130e4cc09b7a5d82b78cc50a3b873 brightray/browser/win/win32_notification.cc - their 100644 d459438ea952de679d2197dec90656a87f8e2351 brightray/browser/win/win32_notification.cc -@@ -1,6 +1,10 @@ -+<<<<<<< .our - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN - #endif -+======= -+#define WIN32_LEAN_AND_MEAN -+>>>>>>> .their - - #include "brightray/browser/win/win32_notification.h" - -@@ -13,7 +17,11 @@ - namespace brightray { - - void Win32Notification::Show(const NotificationOptions& options) { -+<<<<<<< .our - auto* presenter = static_cast<NotificationPresenterWin7*>(this->presenter()); -+======= -+ auto presenter = static_cast<NotificationPresenterWin7*>(this->presenter()); -+>>>>>>> .their - if (!presenter) - return; - -added in both - our 100644 a87ca051ff4ca81b0e4d6130ca3c7a2106204bdd brightray/browser/win/windows_toast_notification.cc - their 100644 72adba548493129d094fc044ae76ddf616dc10a3 brightray/browser/win/windows_toast_notification.cc -@@ -80,7 +80,11 @@ - } - - void WindowsToastNotification::Show(const NotificationOptions& options) { -+<<<<<<< .our - auto* presenter_win = static_cast<NotificationPresenterWin*>(presenter()); -+======= -+ auto presenter_win = static_cast<NotificationPresenterWin*>(presenter()); -+>>>>>>> .their - std::wstring icon_path = - presenter_win->SaveIconToFilesystem(options.icon, options.icon_url); - -added in both - our 100644 6e368fb38dcb9e2fbf6d6108e39c5cfb25a5b7a5 brightray/browser/win/windows_toast_notification.h - their 100644 62c8b844c753ae5a35c676cdca1adcab8018f65b brightray/browser/win/windows_toast_notification.h -@@ -47,7 +47,11 @@ - - WindowsToastNotification(NotificationDelegate* delegate, - NotificationPresenter* presenter); -+<<<<<<< .our - ~WindowsToastNotification() override; -+======= -+ ~WindowsToastNotification(); -+>>>>>>> .their - - protected: - // Notification: -@@ -108,7 +112,11 @@ - DesktopToastFailedEventHandler> { - public: - explicit ToastEventHandler(Notification* notification); -+<<<<<<< .our - ~ToastEventHandler() override; -+======= -+ ~ToastEventHandler(); -+>>>>>>> .their - - IFACEMETHODIMP Invoke( - ABI::Windows::UI::Notifications::IToastNotification* sender, -added in both - our 100644 407866f006d51ac528efaba97cb3750687229900 brightray/common/application_info.h - their 100644 a4918cc7c3d5b3f73a5e50b2adeccbb4e527c127 brightray/common/application_info.h -@@ -2,7 +2,10 @@ - #define BRIGHTRAY_COMMON_APPLICATION_INFO_H_ - - #if defined(OS_WIN) -+<<<<<<< .our - #include "base/strings/string16.h" -+======= -+>>>>>>> .their - #include "brightray/browser/win/scoped_hstring.h" - #endif - -added in both - our 100644 a0256372bbdbbc1d77cb84885faab42a27f55c9f brightray/common/application_info_win.cc - their 100644 49a3720f01e97316b58791c9c6e8333c8d0d8314 brightray/common/application_info_win.cc -@@ -22,14 +22,22 @@ - const wchar_t kAppUserModelIDFormat[] = L"electron.app.$1"; - - std::string GetApplicationName() { -+<<<<<<< .our - auto* module = GetModuleHandle(nullptr); -+======= -+ auto module = GetModuleHandle(nullptr); -+>>>>>>> .their - std::unique_ptr<FileVersionInfo> info( - FileVersionInfo::CreateFileVersionInfoForModule(module)); - return base::UTF16ToUTF8(info->product_name()); - } - - std::string GetApplicationVersion() { -+<<<<<<< .our - auto* module = GetModuleHandle(nullptr); -+======= -+ auto module = GetModuleHandle(nullptr); -+>>>>>>> .their - std::unique_ptr<FileVersionInfo> info( - FileVersionInfo::CreateFileVersionInfoForModule(module)); - return base::UTF16ToUTF8(info->product_version()); -added in both - our 100644 c25cb5f0c02e6b29139cb44f01d8aab69b713381 brightray/common/main_delegate.cc - their 100644 5f94601be9163415329b6fa5bf372ecb8445bb79 brightray/common/main_delegate.cc -@@ -48,6 +48,7 @@ - if (initialized) - ui::ResourceBundle::CleanupSharedInstance(); - -+<<<<<<< .our - // Load other resource files. - base::FilePath pak_dir; - #if defined(OS_MACOSX) -@@ -70,6 +71,21 @@ - ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); - bundle.ReloadLocaleResources(locale); - -+======= -+ ui::ResourceBundle::InitSharedInstanceWithLocale( -+ locale, nullptr, ui::ResourceBundle::DO_NOT_LOAD_COMMON_RESOURCES); -+ -+ ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); -+ bundle.ReloadLocaleResources(locale); -+ -+ // Load other resource files. -+ base::FilePath pak_dir; -+#if defined(OS_MACOSX) -+ pak_dir = base::mac::FrameworkBundlePath().Append("Resources"); -+#else -+ PathService::Get(base::DIR_MODULE, &pak_dir); -+#endif -+>>>>>>> .their - bundle.AddDataPackFromPath( - pak_dir.Append(FILE_PATH_LITERAL("content_shell.pak")), - ui::GetSupportedScaleFactors()[0]); -@@ -90,7 +106,10 @@ - bundle.AddDataPackFromPath( - pak_dir.Append(FILE_PATH_LITERAL("views_resources_200_percent.pak")), - ui::SCALE_FACTOR_200P); -+<<<<<<< .our - #endif -+======= -+>>>>>>> .their - } - - MainDelegate::MainDelegate() {} -added in both - our 100644 b9e2d96175f8ee2d407db9c49b2e2b74756327de brightray/filenames.gypi - their 100644 03b1106f978cbe08c75016f22335c3e6e21fc39f brightray/filenames.gypi -@@ -79,6 +79,11 @@ - 'browser/win/win32_notification.h', - 'browser/win/windows_toast_notification.cc', - 'browser/win/windows_toast_notification.h', -+<<<<<<< .our -+======= -+ 'browser/special_storage_policy.cc', -+ 'browser/special_storage_policy.h', -+>>>>>>> .their - 'browser/url_request_context_getter.cc', - 'browser/url_request_context_getter.h', - 'browser/views/inspectable_web_contents_view_views.h', -added in both - our 100644 110a1d892892d3e27618574c45ae9c12757eb280 build/asar.gni - their 100644 d9298e82d42b072c6b0c0173f913561c80eafd32 build/asar.gni -@@ -1,5 +1,6 @@ - import("npm.gni") - -+<<<<<<< .our - # Run an action with a given working directory. Behaves identically to the - # action() target type, with the exception that it changes directory before - # running the script. -@@ -30,11 +31,14 @@ - } - } - -+======= -+>>>>>>> .their - template("asar") { - assert(defined(invoker.sources), - "Need sources in $target_name listing the JS files.") - assert(defined(invoker.outputs), - "Need asar name (as 1-element array, e.g. \$root_out_dir/foo.asar)") -+<<<<<<< .our - assert(defined(invoker.root), "Need asar root directory") - asar_root = invoker.root - -@@ -46,5 +50,27 @@ - script = "//electron/tools/js2asar.py" - cwd = rebase_path(get_path_info(".", "abspath")) - args = rebase_path(outputs, cwd) + [ asar_root ] + rebase_path(sources, ".") -+======= -+ assert(defined(invoker.root), -+ "Need asar root directory") -+ asar_root = invoker.root -+ copy_target_name = target_name + "_inputs" -+ copy(copy_target_name) { -+ sources = invoker.sources -+ outputs = [ -+ "$target_gen_dir/$target_name/{{source_target_relative}}" -+ ] -+ } -+ npm_action(target_name) { -+ forward_variables_from(invoker, ["deps", "public_deps"]) -+ deps = [":$copy_target_name"] -+ sources = invoker.sources -+ script = "asar" -+ outputs = invoker.outputs -+ args = [ -+ "pack", -+ rebase_path("$target_gen_dir/$target_name/$asar_root") -+ ] + rebase_path(outputs) -+>>>>>>> .their - } - } -added in remote - their 100644 59a181b1ac668b563384e6d3f40b3693845532b3 build/node/BUILD.gn -@@ -0,0 +1,113 @@ -+action("configure_node") { -+ script = "//third_party/electron_node/configure" -+ args = [ -+ "--enable-static", -+ "--release-urlbase=https://atom.io/download/electron", -+ "--shared", -+ "--shared-openssl", -+ "--shared-openssl-includes=" + rebase_path("//third_party/boringssl/src/include"), -+ "--shared-openssl-libname=boringssl", -+ "--shared-openssl-libpath=" + rebase_path(root_out_dir), -+ "--without-npm", -+ "--without-bundled-v8", -+ "--without-dtrace", -+ "--without-etw", -+ "--without-perfctr", -+ "--without-v8-platform", -+ "--without-intl", -+ "--prefix=", -+ "--config-out-dir=" + rebase_path(target_gen_dir), -+ "--no-run-gyp", -+ ] -+ outputs = [ -+ "$target_gen_dir/config.gypi", -+ ] -+} -+ -+action("gyp_node") { -+ script = "//tools/gyp/gyp_main.py" -+ deps = [ ":configure_node" ] -+ inputs = [ -+ "//third_party/electron_node/common.gypi", -+ "//third_party/electron_node/node.gyp", -+ "//third_party/electron_node/node.gypi", -+ "$target_gen_dir/config.gypi", -+ "node_override.gypi", -+ ] -+ outputs = [ -+ "$target_out_dir/Release/build.ninja", -+ ] -+ -+ # TODO(jeremy): should shlib_suffix be set inside node.gypi? -+ if (is_mac) { -+ shlib_suffix = "dylib" -+ } else if (is_linux) { -+ shlib_suffix = "so" -+ } -+ args = [ -+ "-I", rebase_path("$target_gen_dir/config.gypi", root_build_dir), -+ "-I", rebase_path("node_override.gypi", root_build_dir), -+ "-I", rebase_path("//third_party/electron_node/common.gypi", root_build_dir), -+ "-D", "component=shared_library", -+ "-D", "target_arch=$target_cpu", -+ "-D", "host_arch=$host_cpu", -+ "-D", "config_gypi=" + rebase_path("$target_gen_dir/config.gypi"), -+ "-Goutput_dir=./$target_out_dir", # bizarrely, gyp generates from the build root instead of from cwd -+ "-fninja", -+ rebase_path("//third_party/electron_node/node.gyp", root_build_dir), -+ ] -+} -+ -+action("build_node") { -+ deps = [ -+ "//third_party/boringssl", -+ "//third_party/icu", -+ "//v8", -+ "//v8:v8_libbase", -+ "//v8:v8_libplatform", -+ ":gyp_node", -+ ] -+ script = "//electron/build/run-ninja.py" -+ args = [ -+ "-C", rebase_path(target_out_dir, root_build_dir) + "/Release", -+ "node_lib" -+ ] -+ if (is_mac) { -+ outputs = [ "$target_out_dir/Release/libnode.dylib" ] -+ } -+ if (is_linux) { -+ outputs = [ "$target_out_dir/Release/lib/libnode.so" ] -+ } -+} -+ -+node_libs = get_target_outputs(":build_node") -+ -+copy("copy_node") { -+ deps = [ ":build_node" ] -+ sources = node_libs -+ outputs = [ "$root_out_dir/{{source_file_part}}" ] -+} -+ -+config("node_config") { -+ include_dirs = [ -+ "//third_party/electron_node/src", -+ "//third_party/electron_node/deps/uv/include", -+ "//third_party/electron_node/deps/cares/include", -+ ] -+ libs = node_libs -+ cflags_cc = [ -+ "-Wno-deprecated-declarations", -+ ] -+ defines = [ -+ # We need to access internal implementations of Node. -+ "NODE_WANT_INTERNALS=1", -+ "NODE_SHARED_MODE", -+ "HAVE_OPENSSL=1", -+ "HAVE_INSPECTOR=1", -+ ] -+} -+ -+group("node") { -+ public_configs = [ ":node_config" ] -+ public_deps = [ ":copy_node" ] -+} -added in remote - their 100644 01ff4ff249786f56c7162ab4d0272711e61395a9 build/node/node_override.gypi -@@ -0,0 +1,41 @@ -+{ -+ 'variables': { -+ # Node disables the inspector unless icu is enabled. But node doesn't know -+ # that we're building v8 with icu, so force it on. -+ 'v8_enable_inspector': 1, -+ -+ # By default, node will build a dylib called something like -+ # libnode.$node_module_version.dylib, which is inconvenient for our -+ # purposes (since it makes the library's name unpredictable). This forces -+ # it to drop the module_version from the filename and just produce -+ # `libnode.dylib`. -+ 'shlib_suffix': 'dylib', -+ }, -+ 'target_defaults': { -+ 'target_conditions': [ -+ ['_target_name=="node_lib"', { -+ 'include_dirs': [ -+ '../../../v8', -+ '../../../v8/include', -+ '../../../third_party/icu/source/common', -+ '../../../third_party/icu/source/i18n', -+ ], -+ 'libraries': [ -+ '../../../../../../libv8.dylib', -+ '../../../../../../libv8_libbase.dylib', -+ '../../../../../../libv8_libplatform.dylib', -+ '../../../../../../libicuuc.dylib', -+ ], -+ 'defines': [ -+ # These will no longer be necessary once -+ # https://github.com/google/boringssl/commit/a02ed04d527e1b57b4efaa0b4f9bdbc1ed5975b2 -+ # is in the past for Electron -+ 'EVP_CIPH_CCM_MODE=0', -+ 'EVP_CIPH_WRAP_MODE=0', -+ 'EVP_CIPHER_CTX_FLAG_WRAP_ALLOW=0', -+ 'EVP_CIPHER_CTX_set_flags(...)', -+ ], -+ }], -+ ], -+ }, -+} -added in remote - their 100644 802b17d51df17893196e59446fcbf6fb495310e4 build/node/toolchain.gypi -@@ -0,0 +1,35 @@ -+{ -+ 'variables': { -+ 'llvm_dir': '<(chromium_src_dir)/third_party/llvm-build/Release+Asserts', -+ }, -+ 'conditions': [ -+ ['clang==1', { -+ 'make_global_settings': [ -+ ['CC', '<(llvm_dir)/bin/clang'], -+ ['CXX', '<(llvm_dir)/bin/clang++'], -+ ['CC.host', '$(CC)'], -+ ['CXX.host', '$(CXX)'], -+ ], -+ 'target_defaults': { -+ 'target_conditions': [ -+ ['OS=="linux" and _toolset=="target"', { -+ 'cflags_cc': [ -+ '-std=gnu++14', -+ '-nostdinc++', -+ '-isystem<(chromium_src_dir)/buildtools/third_party/libc++/trunk/include', -+ '-isystem<(chromium_src_dir)/buildtools/third_party/libc++abi/trunk/include', -+ ], -+ 'ldflags': [ -+ '-nostdlib++', -+ ], -+ }], -+ ['OS=="linux" and _toolset=="host"', { -+ 'cflags_cc': [ -+ '-std=gnu++14', -+ ], -+ }], -+ ], -+ }, -+ }], # clang==1 -+ ], -+} -added in both - our 100644 1a8b6dddefd1d868bb9d2453655223742b227976 chromium_src/chrome/browser/extensions/global_shortcut_listener_win.h - their 100644 83e9fdff283fb9e582ed7cd65365ec88cd925530 chromium_src/chrome/browser/extensions/global_shortcut_listener_win.h -@@ -21,17 +21,30 @@ - class GlobalShortcutListenerWin : public GlobalShortcutListener { - public: - GlobalShortcutListenerWin(); -+<<<<<<< .our - ~GlobalShortcutListenerWin() override; -+======= -+ virtual ~GlobalShortcutListenerWin(); -+>>>>>>> .their - - private: - // The implementation of our Window Proc, called by SingletonHwndObserver. - void OnWndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); - - // GlobalShortcutListener implementation. -+<<<<<<< .our - void StartListening() override; - void StopListening() override; - bool RegisterAcceleratorImpl(const ui::Accelerator& accelerator) override; - void UnregisterAcceleratorImpl(const ui::Accelerator& accelerator) override; -+======= -+ virtual void StartListening() override; -+ virtual void StopListening() override; -+ virtual bool RegisterAcceleratorImpl( -+ const ui::Accelerator& accelerator) override; -+ virtual void UnregisterAcceleratorImpl( -+ const ui::Accelerator& accelerator) override; -+>>>>>>> .their - - // Whether this object is listening for global shortcuts. - bool is_listening_; -added in remote - their 100644 28229a178e6ca1103e5b0fdffc9718a5bd8d79b8 chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc -@@ -0,0 +1,94 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h" -+ -+#include "build/build_config.h" -+#include "chrome/browser/renderer_host/pepper/pepper_broker_message_filter.h" -+#include "chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h" -+#include "chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h" -+#include "chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h" -+#include "chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h" -+#include "content/public/browser/browser_ppapi_host.h" -+#include "ppapi/host/message_filter_host.h" -+#include "ppapi/host/ppapi_host.h" -+#include "ppapi/host/resource_host.h" -+#include "ppapi/proxy/ppapi_messages.h" -+#include "ppapi/shared_impl/ppapi_permissions.h" -+ -+using ppapi::host::MessageFilterHost; -+using ppapi::host::ResourceHost; -+using ppapi::host::ResourceMessageFilter; -+ -+namespace chrome { -+ -+ChromeBrowserPepperHostFactory::ChromeBrowserPepperHostFactory( -+ content::BrowserPpapiHost* host) -+ : host_(host) {} -+ -+ChromeBrowserPepperHostFactory::~ChromeBrowserPepperHostFactory() {} -+ -+std::unique_ptr<ResourceHost> -+ChromeBrowserPepperHostFactory::CreateResourceHost( -+ ppapi::host::PpapiHost* host, -+ PP_Resource resource, -+ PP_Instance instance, -+ const IPC::Message& message) { -+ DCHECK(host == host_->GetPpapiHost()); -+ -+ // Make sure the plugin is giving us a valid instance for this resource. -+ if (!host_->IsValidInstance(instance)) -+ return std::unique_ptr<ResourceHost>(); -+ -+ // Private interfaces. -+ if (host_->GetPpapiHost()->permissions().HasPermission( -+ ppapi::PERMISSION_PRIVATE)) { -+ switch (message.type()) { -+ case PpapiHostMsg_Broker_Create::ID: { -+ scoped_refptr<ResourceMessageFilter> broker_filter( -+ new PepperBrokerMessageFilter(instance, host_)); -+ return std::unique_ptr<ResourceHost>(new MessageFilterHost( -+ host_->GetPpapiHost(), instance, resource, broker_filter)); -+ } -+ } -+ } -+ -+ // Flash interfaces. -+ if (host_->GetPpapiHost()->permissions().HasPermission( -+ ppapi::PERMISSION_FLASH)) { -+ switch (message.type()) { -+ case PpapiHostMsg_Flash_Create::ID: -+ return std::unique_ptr<ResourceHost>( -+ new PepperFlashBrowserHost(host_, instance, resource)); -+ case PpapiHostMsg_FlashClipboard_Create::ID: { -+ scoped_refptr<ResourceMessageFilter> clipboard_filter( -+ new PepperFlashClipboardMessageFilter); -+ return std::unique_ptr<ResourceHost>(new MessageFilterHost( -+ host_->GetPpapiHost(), instance, resource, clipboard_filter)); -+ } -+ case PpapiHostMsg_FlashDRM_Create::ID: -+ return std::unique_ptr<ResourceHost>( -+ new chrome::PepperFlashDRMHost(host_, instance, resource)); -+ } -+ } -+ -+ // Permissions for the following interfaces will be checked at the -+ // time of the corresponding instance's methods calls (because -+ // permission check can be performed only on the UI -+ // thread). Currently these interfaces are available only for -+ // whitelisted apps which may not have access to the other private -+ // interfaces. -+ if (message.type() == PpapiHostMsg_IsolatedFileSystem_Create::ID) { -+ PepperIsolatedFileSystemMessageFilter* isolated_fs_filter = -+ PepperIsolatedFileSystemMessageFilter::Create(instance, host_); -+ if (!isolated_fs_filter) -+ return std::unique_ptr<ResourceHost>(); -+ return std::unique_ptr<ResourceHost>( -+ new MessageFilterHost(host, instance, resource, isolated_fs_filter)); -+ } -+ -+ return std::unique_ptr<ResourceHost>(); -+} -+ -+} // namespace chrome -added in remote - their 100644 84385140ceca7e4eb2e16b2a0802714fd0aa392b chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h -@@ -0,0 +1,38 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_CHROME_BROWSER_PEPPER_HOST_FACTORY_H_ -+#define CHROME_BROWSER_RENDERER_HOST_PEPPER_CHROME_BROWSER_PEPPER_HOST_FACTORY_H_ -+ -+#include "base/macros.h" -+#include "ppapi/host/host_factory.h" -+ -+namespace content { -+class BrowserPpapiHost; -+} // namespace content -+ -+namespace chrome { -+ -+class ChromeBrowserPepperHostFactory : public ppapi::host::HostFactory { -+ public: -+ // Non-owning pointer to the filter must outlive this class. -+ explicit ChromeBrowserPepperHostFactory(content::BrowserPpapiHost* host); -+ ~ChromeBrowserPepperHostFactory() override; -+ -+ std::unique_ptr<ppapi::host::ResourceHost> CreateResourceHost( -+ ppapi::host::PpapiHost* host, -+ PP_Resource resource, -+ PP_Instance instance, -+ const IPC::Message& message) override; -+ -+ private: -+ // Non-owning pointer. -+ content::BrowserPpapiHost* host_; -+ -+ DISALLOW_COPY_AND_ASSIGN(ChromeBrowserPepperHostFactory); -+}; -+ -+} // namespace chrome -+ -+#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_CHROME_BROWSER_PEPPER_HOST_FACTORY_H_ -added in remote - their 100644 cc10ee85780caa46817802f861e38f9ce9af9d61 chromium_src/chrome/browser/renderer_host/pepper/monitor_finder_mac.h -@@ -0,0 +1,52 @@ -+// Copyright 2014 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_MONITOR_FINDER_MAC_H_ -+#define CHROME_BROWSER_RENDERER_HOST_PEPPER_MONITOR_FINDER_MAC_H_ -+ -+#include <ApplicationServices/ApplicationServices.h> -+#include <stdint.h> -+ -+#include "base/macros.h" -+#include "base/memory/ref_counted.h" -+#include "base/synchronization/lock.h" -+ -+namespace chrome { -+ -+// MonitorFinder maps a RenderFrameHost to the display ID on which the widget -+// is painting. This class operates on the IO thread while the RenderFrameHost -+// is on the UI thread, so the value returned by GetMonitor() may be 0 until -+// the information can be retrieved asynchronously. -+class MonitorFinder : public base::RefCountedThreadSafe<MonitorFinder> { -+ public: -+ MonitorFinder(int process_id, int render_frame_id); -+ -+ // Gets the native display ID for the <process_id, render_frame_id> tuple. -+ int64_t GetMonitor(); -+ -+ // Checks if the given |monitor_id| represents a built-in display. -+ static bool IsMonitorBuiltIn(int64_t monitor_id); -+ -+ private: -+ friend class base::RefCountedThreadSafe<MonitorFinder>; -+ ~MonitorFinder(); -+ -+ // Method run on the UI thread to get the display information. -+ void FetchMonitorFromWidget(); -+ -+ const int process_id_; -+ const int render_frame_id_; -+ -+ base::Lock mutex_; // Protects the two members below. -+ // Whether one request to FetchMonitorFromWidget() has been made already. -+ bool request_sent_; -+ // The native display ID for the RenderFrameHost. -+ CGDirectDisplayID display_id_; -+ -+ DISALLOW_COPY_AND_ASSIGN(MonitorFinder); -+}; -+ -+} // namespace chrome -+ -+#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_MONITOR_FINDER_H_ -added in remote - their 100644 e6e0a62fa67edabae605c17ae87a38df083f70cc chromium_src/chrome/browser/renderer_host/pepper/monitor_finder_mac.mm -@@ -0,0 +1,61 @@ -+// Copyright 2014 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "chrome/browser/renderer_host/pepper/monitor_finder_mac.h" -+ -+#import <Cocoa/Cocoa.h> -+ -+#include "content/public/browser/browser_thread.h" -+#include "content/public/browser/render_frame_host.h" -+ -+namespace chrome { -+ -+MonitorFinder::MonitorFinder(int process_id, int render_frame_id) -+ : process_id_(process_id), -+ render_frame_id_(render_frame_id), -+ request_sent_(false), -+ display_id_(kCGNullDirectDisplay) {} -+ -+MonitorFinder::~MonitorFinder() {} -+ -+int64_t MonitorFinder::GetMonitor() { -+ { -+ // The plugin may call this method several times, so avoid spamming the UI -+ // thread with requests by only allowing one outstanding request at a time. -+ base::AutoLock lock(mutex_); -+ if (request_sent_) -+ return display_id_; -+ request_sent_ = true; -+ } -+ -+ content::BrowserThread::PostTask( -+ content::BrowserThread::UI, FROM_HERE, -+ base::Bind(&MonitorFinder::FetchMonitorFromWidget, this)); -+ return display_id_; -+} -+ -+// static -+bool MonitorFinder::IsMonitorBuiltIn(int64_t display_id) { -+ return CGDisplayIsBuiltin(display_id); -+} -+ -+void MonitorFinder::FetchMonitorFromWidget() { -+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); -+ content::RenderFrameHost* rfh = -+ content::RenderFrameHost::FromID(process_id_, render_frame_id_); -+ if (!rfh) -+ return; -+ -+ gfx::NativeView native_view = rfh->GetNativeView(); -+ NSWindow* window = [native_view window]; -+ NSScreen* screen = [window screen]; -+ CGDirectDisplayID display_id = -+ [[[screen deviceDescription] objectForKey:@"NSScreenNumber"] intValue]; -+ -+ base::AutoLock lock(mutex_); -+ request_sent_ = false; -+ display_id_ = display_id; -+} -+ -+} // namespace chrome -added in remote - their 100644 d40ad53dd17d24a24f00b5c669d6e113760a1c0a chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.cc -@@ -0,0 +1,53 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "chrome/browser/renderer_host/pepper/pepper_broker_message_filter.h" -+ -+#include <string> -+ -+#include "content/public/browser/browser_ppapi_host.h" -+#include "content/public/browser/browser_thread.h" -+#include "content/public/browser/render_process_host.h" -+#include "ipc/ipc_message_macros.h" -+#include "ppapi/c/pp_errors.h" -+#include "ppapi/host/dispatch_host_message.h" -+#include "ppapi/proxy/ppapi_messages.h" -+#include "url/gurl.h" -+ -+using content::BrowserPpapiHost; -+using content::BrowserThread; -+ -+namespace chrome { -+ -+PepperBrokerMessageFilter::PepperBrokerMessageFilter(PP_Instance instance, -+ BrowserPpapiHost* host) -+ : document_url_(host->GetDocumentURLForInstance(instance)) { -+ int unused; -+ host->GetRenderFrameIDsForInstance(instance, &render_process_id_, &unused); -+} -+ -+PepperBrokerMessageFilter::~PepperBrokerMessageFilter() {} -+ -+scoped_refptr<base::TaskRunner> -+PepperBrokerMessageFilter::OverrideTaskRunnerForMessage( -+ const IPC::Message& message) { -+ return BrowserThread::GetTaskRunnerForThread(BrowserThread::UI); -+} -+ -+int32_t PepperBrokerMessageFilter::OnResourceMessageReceived( -+ const IPC::Message& msg, -+ ppapi::host::HostMessageContext* context) { -+ PPAPI_BEGIN_MESSAGE_MAP(PepperBrokerMessageFilter, msg) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Broker_IsAllowed, -+ OnIsAllowed) -+ PPAPI_END_MESSAGE_MAP() -+ return PP_ERROR_FAILED; -+} -+ -+int32_t PepperBrokerMessageFilter::OnIsAllowed( -+ ppapi::host::HostMessageContext* context) { -+ return PP_OK; -+} -+ -+} // namespace chrome -added in remote - their 100644 2aad5593b26a1eab56841e56fc56acf1d5cba28b chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.h -@@ -0,0 +1,51 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_BROKER_MESSAGE_FILTER_H_ -+#define CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_BROKER_MESSAGE_FILTER_H_ -+ -+#include "base/compiler_specific.h" -+#include "ppapi/c/pp_instance.h" -+#include "ppapi/host/resource_message_filter.h" -+#include "url/gurl.h" -+ -+namespace content { -+class BrowserPpapiHost; -+} -+ -+namespace ppapi { -+namespace host { -+struct HostMessageContext; -+} -+} // namespace ppapi -+ -+namespace chrome { -+ -+// This filter handles messages for the PepperBrokerHost on the UI thread. -+class PepperBrokerMessageFilter : public ppapi::host::ResourceMessageFilter { -+ public: -+ PepperBrokerMessageFilter(PP_Instance instance, -+ content::BrowserPpapiHost* host); -+ -+ private: -+ ~PepperBrokerMessageFilter() override; -+ -+ // ppapi::host::ResourceMessageFilter overrides. -+ scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage( -+ const IPC::Message& message) override; -+ int32_t OnResourceMessageReceived( -+ const IPC::Message& msg, -+ ppapi::host::HostMessageContext* context) override; -+ -+ int32_t OnIsAllowed(ppapi::host::HostMessageContext* context); -+ -+ int render_process_id_; -+ GURL document_url_; -+ -+ DISALLOW_COPY_AND_ASSIGN(PepperBrokerMessageFilter); -+}; -+ -+} // namespace chrome -+ -+#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_BROKER_MESSAGE_FILTER_H_ -added in remote - their 100644 901da1ad6e221b55196a1b25a1549fa272b4fdf7 chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc -@@ -0,0 +1,111 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h" -+ -+#include "base/time/time.h" -+#include "content/public/browser/browser_context.h" -+#include "content/public/browser/browser_ppapi_host.h" -+#include "content/public/browser/browser_thread.h" -+#include "content/public/browser/render_process_host.h" -+#include "ipc/ipc_message_macros.h" -+#include "ppapi/c/pp_errors.h" -+#include "ppapi/c/private/ppb_flash.h" -+#include "ppapi/host/dispatch_host_message.h" -+#include "ppapi/proxy/ppapi_messages.h" -+#include "ppapi/proxy/resource_message_params.h" -+#include "ppapi/shared_impl/time_conversion.h" -+#include "url/gurl.h" -+ -+#if defined(OS_WIN) -+#include <windows.h> -+#elif defined(OS_MACOSX) -+#include <CoreServices/CoreServices.h> -+#endif -+ -+using content::BrowserPpapiHost; -+using content::BrowserThread; -+ -+namespace chrome { -+ -+PepperFlashBrowserHost::PepperFlashBrowserHost(BrowserPpapiHost* host, -+ PP_Instance instance, -+ PP_Resource resource) -+ : ResourceHost(host->GetPpapiHost(), instance, resource), -+ host_(host), -+ weak_factory_(this) { -+ int unused; -+ host->GetRenderFrameIDsForInstance(instance, &render_process_id_, &unused); -+} -+ -+PepperFlashBrowserHost::~PepperFlashBrowserHost() {} -+ -+int32_t PepperFlashBrowserHost::OnResourceMessageReceived( -+ const IPC::Message& msg, -+ ppapi::host::HostMessageContext* context) { -+ PPAPI_BEGIN_MESSAGE_MAP(PepperFlashBrowserHost, msg) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Flash_UpdateActivity, -+ OnUpdateActivity) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_GetLocalTimeZoneOffset, -+ OnGetLocalTimeZoneOffset) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( -+ PpapiHostMsg_Flash_GetLocalDataRestrictions, OnGetLocalDataRestrictions) -+ PPAPI_END_MESSAGE_MAP() -+ return PP_ERROR_FAILED; -+} -+ -+int32_t PepperFlashBrowserHost::OnUpdateActivity( -+ ppapi::host::HostMessageContext* host_context) { -+#if defined(OS_WIN) -+ // Reading then writing back the same value to the screensaver timeout system -+ // setting resets the countdown which prevents the screensaver from turning -+ // on "for a while". As long as the plugin pings us with this message faster -+ // than the screensaver timeout, it won't go on. -+ int value = 0; -+ if (SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT, 0, &value, 0)) -+ SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, value, NULL, 0); -+#elif defined(OS_MACOSX) -+// UpdateSystemActivity(OverallAct); -+#else -+// TODO(brettw) implement this for other platforms. -+#endif -+ return PP_OK; -+} -+ -+int32_t PepperFlashBrowserHost::OnGetLocalTimeZoneOffset( -+ ppapi::host::HostMessageContext* host_context, -+ const base::Time& t) { -+ // The reason for this processing being in the browser process is that on -+ // Linux, the localtime calls require filesystem access prohibited by the -+ // sandbox. -+ host_context->reply_msg = PpapiPluginMsg_Flash_GetLocalTimeZoneOffsetReply( -+ ppapi::PPGetLocalTimeZoneOffset(t)); -+ return PP_OK; -+} -+ -+int32_t PepperFlashBrowserHost::OnGetLocalDataRestrictions( -+ ppapi::host::HostMessageContext* context) { -+ // Getting the Flash LSO settings requires using the CookieSettings which -+ // belong to the profile which lives on the UI thread. We lazily initialize -+ // |cookie_settings_| by grabbing the reference from the UI thread and then -+ // call |GetLocalDataRestrictions| with it. -+ GURL document_url = host_->GetDocumentURLForInstance(pp_instance()); -+ GURL plugin_url = host_->GetPluginURLForInstance(pp_instance()); -+ GetLocalDataRestrictions(context->MakeReplyMessageContext(), document_url, -+ plugin_url); -+ return PP_OK_COMPLETIONPENDING; -+} -+ -+void PepperFlashBrowserHost::GetLocalDataRestrictions( -+ ppapi::host::ReplyMessageContext reply_context, -+ const GURL& document_url, -+ const GURL& plugin_url) { -+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); -+ -+ PP_FlashLSORestrictions restrictions = PP_FLASHLSORESTRICTIONS_NONE; -+ SendReply(reply_context, PpapiPluginMsg_Flash_GetLocalDataRestrictionsReply( -+ static_cast<int32_t>(restrictions))); -+} -+ -+} // namespace chrome -added in remote - their 100644 65e0d02c001c6086d78d09154a515d031293227d chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h -@@ -0,0 +1,59 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_BROWSER_HOST_H_ -+#define CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_BROWSER_HOST_H_ -+ -+#include "base/memory/ref_counted.h" -+#include "base/memory/weak_ptr.h" -+#include "ppapi/host/host_message_context.h" -+#include "ppapi/host/resource_host.h" -+ -+namespace base { -+class Time; -+} -+ -+namespace content { -+class BrowserPpapiHost; -+class ResourceContext; -+} // namespace content -+ -+class GURL; -+ -+namespace chrome { -+ -+class PepperFlashBrowserHost : public ppapi::host::ResourceHost { -+ public: -+ PepperFlashBrowserHost(content::BrowserPpapiHost* host, -+ PP_Instance instance, -+ PP_Resource resource); -+ ~PepperFlashBrowserHost() override; -+ -+ // ppapi::host::ResourceHost override. -+ int32_t OnResourceMessageReceived( -+ const IPC::Message& msg, -+ ppapi::host::HostMessageContext* context) override; -+ -+ private: -+ int32_t OnUpdateActivity(ppapi::host::HostMessageContext* host_context); -+ int32_t OnGetLocalTimeZoneOffset( -+ ppapi::host::HostMessageContext* host_context, -+ const base::Time& t); -+ int32_t OnGetLocalDataRestrictions(ppapi::host::HostMessageContext* context); -+ -+ void GetLocalDataRestrictions(ppapi::host::ReplyMessageContext reply_context, -+ const GURL& document_url, -+ const GURL& plugin_url); -+ -+ content::BrowserPpapiHost* host_; -+ int render_process_id_; -+ // For fetching the Flash LSO settings. -+ base::WeakPtrFactory<PepperFlashBrowserHost> weak_factory_; -+ -+ DISALLOW_COPY_AND_ASSIGN(PepperFlashBrowserHost); -+}; -+ -+} // namespace chrome -+ -+#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_BROWSER_HOST_H_ -added in remote - their 100644 c62d2d98621d6f8cc651501111af81f7a5ade2c0 chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc -@@ -0,0 +1,372 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h" -+ -+#include <stddef.h> -+ -+#include "base/pickle.h" -+#include "base/strings/utf_string_conversions.h" -+#include "content/public/browser/browser_thread.h" -+#include "ipc/ipc_message.h" -+#include "ipc/ipc_message_macros.h" -+#include "ppapi/c/pp_errors.h" -+#include "ppapi/c/private/ppb_flash_clipboard.h" -+#include "ppapi/host/dispatch_host_message.h" -+#include "ppapi/host/host_message_context.h" -+#include "ppapi/host/ppapi_host.h" -+#include "ppapi/proxy/ppapi_messages.h" -+#include "ppapi/proxy/resource_message_params.h" -+#include "ui/base/clipboard/scoped_clipboard_writer.h" -+ -+using content::BrowserThread; -+ -+namespace chrome { -+ -+namespace { -+ -+const size_t kMaxClipboardWriteSize = 1000000; -+ -+ui::ClipboardType ConvertClipboardType(uint32_t type) { -+ switch (type) { -+ case PP_FLASH_CLIPBOARD_TYPE_STANDARD: -+ return ui::CLIPBOARD_TYPE_COPY_PASTE; -+ case PP_FLASH_CLIPBOARD_TYPE_SELECTION: -+ return ui::CLIPBOARD_TYPE_SELECTION; -+ } -+ NOTREACHED(); -+ return ui::CLIPBOARD_TYPE_COPY_PASTE; -+} -+ -+// Functions to pack/unpack custom data from a pickle. See the header file for -+// more detail on custom formats in Pepper. -+// TODO(raymes): Currently pepper custom formats are stored in their own -+// native format type. However we should be able to store them in the same way -+// as "Web Custom" formats are. This would allow clipboard data to be shared -+// between pepper applications and web applications. However currently web apps -+// assume all data that is placed on the clipboard is UTF16 and pepper allows -+// arbitrary data so this change would require some reworking of the chrome -+// clipboard interface for custom data. -+bool JumpToFormatInPickle(const base::string16& format, -+ base::PickleIterator* iter) { -+ uint32_t size = 0; -+ if (!iter->ReadUInt32(&size)) -+ return false; -+ for (uint32_t i = 0; i < size; ++i) { -+ base::string16 stored_format; -+ if (!iter->ReadString16(&stored_format)) -+ return false; -+ if (stored_format == format) -+ return true; -+ int skip_length; -+ if (!iter->ReadLength(&skip_length)) -+ return false; -+ if (!iter->SkipBytes(skip_length)) -+ return false; -+ } -+ return false; -+} -+ -+bool IsFormatAvailableInPickle(const base::string16& format, -+ const base::Pickle& pickle) { -+ base::PickleIterator iter(pickle); -+ return JumpToFormatInPickle(format, &iter); -+} -+ -+std::string ReadDataFromPickle(const base::string16& format, -+ const base::Pickle& pickle) { -+ std::string result; -+ base::PickleIterator iter(pickle); -+ if (!JumpToFormatInPickle(format, &iter) || !iter.ReadString(&result)) -+ return std::string(); -+ return result; -+} -+ -+void WriteDataToPickle(const std::map<base::string16, std::string>& data, -+ base::Pickle* pickle) { -+ pickle->WriteUInt32(data.size()); -+ for (std::map<base::string16, std::string>::const_iterator it = data.begin(); -+ it != data.end(); ++it) { -+ pickle->WriteString16(it->first); -+ pickle->WriteString(it->second); -+ } -+} -+ -+} // namespace -+ -+PepperFlashClipboardMessageFilter::PepperFlashClipboardMessageFilter() {} -+ -+PepperFlashClipboardMessageFilter::~PepperFlashClipboardMessageFilter() {} -+ -+scoped_refptr<base::TaskRunner> -+PepperFlashClipboardMessageFilter::OverrideTaskRunnerForMessage( -+ const IPC::Message& msg) { -+ // Clipboard writes should always occur on the UI thread due to the -+ // restrictions of various platform APIs. In general, the clipboard is not -+ // thread-safe, so all clipboard calls should be serviced from the UI thread. -+ if (msg.type() == PpapiHostMsg_FlashClipboard_WriteData::ID) -+ return BrowserThread::GetTaskRunnerForThread(BrowserThread::UI); -+ -+// Windows needs clipboard reads to be serviced from the IO thread because -+// these are sync IPCs which can result in deadlocks with plugins if serviced -+// from the UI thread. Note that Windows clipboard calls ARE thread-safe so it -+// is ok for reads and writes to be serviced from different threads. -+#if !defined(OS_WIN) -+ return BrowserThread::GetTaskRunnerForThread(BrowserThread::UI); -+#else -+ return BrowserThread::GetTaskRunnerForThread(BrowserThread::IO); -+#endif -+} -+ -+int32_t PepperFlashClipboardMessageFilter::OnResourceMessageReceived( -+ const IPC::Message& msg, -+ ppapi::host::HostMessageContext* context) { -+ PPAPI_BEGIN_MESSAGE_MAP(PepperFlashClipboardMessageFilter, msg) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL( -+ PpapiHostMsg_FlashClipboard_RegisterCustomFormat, -+ OnMsgRegisterCustomFormat) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL( -+ PpapiHostMsg_FlashClipboard_IsFormatAvailable, OnMsgIsFormatAvailable) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_ReadData, -+ OnMsgReadData) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_WriteData, -+ OnMsgWriteData) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL( -+ PpapiHostMsg_FlashClipboard_GetSequenceNumber, OnMsgGetSequenceNumber) -+ PPAPI_END_MESSAGE_MAP() -+ return PP_ERROR_FAILED; -+} -+ -+int32_t PepperFlashClipboardMessageFilter::OnMsgRegisterCustomFormat( -+ ppapi::host::HostMessageContext* host_context, -+ const std::string& format_name) { -+ uint32_t format = custom_formats_.RegisterFormat(format_name); -+ if (format == PP_FLASH_CLIPBOARD_FORMAT_INVALID) -+ return PP_ERROR_FAILED; -+ host_context->reply_msg = -+ PpapiPluginMsg_FlashClipboard_RegisterCustomFormatReply(format); -+ return PP_OK; -+} -+ -+int32_t PepperFlashClipboardMessageFilter::OnMsgIsFormatAvailable( -+ ppapi::host::HostMessageContext* host_context, -+ uint32_t clipboard_type, -+ uint32_t format) { -+ if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) { -+ NOTIMPLEMENTED(); -+ return PP_ERROR_FAILED; -+ } -+ -+ ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); -+ ui::ClipboardType type = ConvertClipboardType(clipboard_type); -+ bool available = false; -+ switch (format) { -+ case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: { -+ bool plain = clipboard->IsFormatAvailable( -+ ui::Clipboard::GetPlainTextFormatType(), type); -+ bool plainw = clipboard->IsFormatAvailable( -+ ui::Clipboard::GetPlainTextWFormatType(), type); -+ available = plain || plainw; -+ break; -+ } -+ case PP_FLASH_CLIPBOARD_FORMAT_HTML: -+ available = clipboard->IsFormatAvailable( -+ ui::Clipboard::GetHtmlFormatType(), type); -+ break; -+ case PP_FLASH_CLIPBOARD_FORMAT_RTF: -+ available = -+ clipboard->IsFormatAvailable(ui::Clipboard::GetRtfFormatType(), type); -+ break; -+ case PP_FLASH_CLIPBOARD_FORMAT_INVALID: -+ break; -+ default: -+ if (custom_formats_.IsFormatRegistered(format)) { -+ std::string format_name = custom_formats_.GetFormatName(format); -+ std::string clipboard_data; -+ clipboard->ReadData(ui::Clipboard::GetPepperCustomDataFormatType(), -+ &clipboard_data); -+ base::Pickle pickle(clipboard_data.data(), clipboard_data.size()); -+ available = -+ IsFormatAvailableInPickle(base::UTF8ToUTF16(format_name), pickle); -+ } -+ break; -+ } -+ -+ return available ? PP_OK : PP_ERROR_FAILED; -+} -+ -+int32_t PepperFlashClipboardMessageFilter::OnMsgReadData( -+ ppapi::host::HostMessageContext* host_context, -+ uint32_t clipboard_type, -+ uint32_t format) { -+ if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) { -+ NOTIMPLEMENTED(); -+ return PP_ERROR_FAILED; -+ } -+ -+ ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); -+ ui::ClipboardType type = ConvertClipboardType(clipboard_type); -+ std::string clipboard_string; -+ int32_t result = PP_ERROR_FAILED; -+ switch (format) { -+ case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: { -+ if (clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(), -+ type)) { -+ base::string16 text; -+ clipboard->ReadText(type, &text); -+ if (!text.empty()) { -+ result = PP_OK; -+ clipboard_string = base::UTF16ToUTF8(text); -+ break; -+ } -+ } -+ // If the PlainTextW format isn't available or is empty, take the -+ // ASCII text format. -+ if (clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(), -+ type)) { -+ result = PP_OK; -+ clipboard->ReadAsciiText(type, &clipboard_string); -+ } -+ break; -+ } -+ case PP_FLASH_CLIPBOARD_FORMAT_HTML: { -+ if (!clipboard->IsFormatAvailable(ui::Clipboard::GetHtmlFormatType(), -+ type)) { -+ break; -+ } -+ -+ base::string16 html; -+ std::string url; -+ uint32_t fragment_start; -+ uint32_t fragment_end; -+ clipboard->ReadHTML(type, &html, &url, &fragment_start, &fragment_end); -+ result = PP_OK; -+ clipboard_string = base::UTF16ToUTF8( -+ html.substr(fragment_start, fragment_end - fragment_start)); -+ break; -+ } -+ case PP_FLASH_CLIPBOARD_FORMAT_RTF: { -+ if (!clipboard->IsFormatAvailable(ui::Clipboard::GetRtfFormatType(), -+ type)) { -+ break; -+ } -+ result = PP_OK; -+ clipboard->ReadRTF(type, &clipboard_string); -+ break; -+ } -+ case PP_FLASH_CLIPBOARD_FORMAT_INVALID: -+ break; -+ default: { -+ if (custom_formats_.IsFormatRegistered(format)) { -+ base::string16 format_name = -+ base::UTF8ToUTF16(custom_formats_.GetFormatName(format)); -+ std::string clipboard_data; -+ clipboard->ReadData(ui::Clipboard::GetPepperCustomDataFormatType(), -+ &clipboard_data); -+ base::Pickle pickle(clipboard_data.data(), clipboard_data.size()); -+ if (IsFormatAvailableInPickle(format_name, pickle)) { -+ result = PP_OK; -+ clipboard_string = ReadDataFromPickle(format_name, pickle); -+ } -+ } -+ break; -+ } -+ } -+ -+ if (result == PP_OK) { -+ host_context->reply_msg = -+ PpapiPluginMsg_FlashClipboard_ReadDataReply(clipboard_string); -+ } -+ return result; -+} -+ -+int32_t PepperFlashClipboardMessageFilter::OnMsgWriteData( -+ ppapi::host::HostMessageContext* host_context, -+ uint32_t clipboard_type, -+ const std::vector<uint32_t>& formats, -+ const std::vector<std::string>& data) { -+ if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) { -+ NOTIMPLEMENTED(); -+ return PP_ERROR_FAILED; -+ } -+ if (formats.size() != data.size()) -+ return PP_ERROR_FAILED; -+ -+ ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); -+ ui::ClipboardType type = ConvertClipboardType(clipboard_type); -+ // If no formats are passed in clear the clipboard. -+ if (formats.size() == 0) { -+ clipboard->Clear(type); -+ return PP_OK; -+ } -+ -+ ui::ScopedClipboardWriter scw(type); -+ std::map<base::string16, std::string> custom_data_map; -+ int32_t res = PP_OK; -+ for (uint32_t i = 0; i < formats.size(); ++i) { -+ if (data[i].length() > kMaxClipboardWriteSize) { -+ res = PP_ERROR_NOSPACE; -+ break; -+ } -+ -+ switch (formats[i]) { -+ case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: -+ scw.WriteText(base::UTF8ToUTF16(data[i])); -+ break; -+ case PP_FLASH_CLIPBOARD_FORMAT_HTML: -+ scw.WriteHTML(base::UTF8ToUTF16(data[i]), std::string()); -+ break; -+ case PP_FLASH_CLIPBOARD_FORMAT_RTF: -+ scw.WriteRTF(data[i]); -+ break; -+ case PP_FLASH_CLIPBOARD_FORMAT_INVALID: -+ res = PP_ERROR_BADARGUMENT; -+ break; -+ default: -+ if (custom_formats_.IsFormatRegistered(formats[i])) { -+ std::string format_name = custom_formats_.GetFormatName(formats[i]); -+ custom_data_map[base::UTF8ToUTF16(format_name)] = data[i]; -+ } else { -+ // Invalid format. -+ res = PP_ERROR_BADARGUMENT; -+ break; -+ } -+ } -+ -+ if (res != PP_OK) -+ break; -+ } -+ -+ if (custom_data_map.size() > 0) { -+ base::Pickle pickle; -+ WriteDataToPickle(custom_data_map, &pickle); -+ scw.WritePickledData(pickle, -+ ui::Clipboard::GetPepperCustomDataFormatType()); -+ } -+ -+ if (res != PP_OK) { -+ // Need to clear the objects so nothing is written. -+ scw.Reset(); -+ } -+ -+ return res; -+} -+ -+int32_t PepperFlashClipboardMessageFilter::OnMsgGetSequenceNumber( -+ ppapi::host::HostMessageContext* host_context, -+ uint32_t clipboard_type) { -+ if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) { -+ NOTIMPLEMENTED(); -+ return PP_ERROR_FAILED; -+ } -+ -+ ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); -+ ui::ClipboardType type = ConvertClipboardType(clipboard_type); -+ int64_t sequence_number = clipboard->GetSequenceNumber(type); -+ host_context->reply_msg = -+ PpapiPluginMsg_FlashClipboard_GetSequenceNumberReply(sequence_number); -+ return PP_OK; -+} -+ -+} // namespace chrome -added in remote - their 100644 b282d54df28cbb43b5a1b49c6272b504565cde2b chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h -@@ -0,0 +1,76 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_CLIPBOARD_MESSAGE_FILTER_H_ -+#define CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_CLIPBOARD_MESSAGE_FILTER_H_ -+ -+#include <string> -+#include <vector> -+ -+#include "ppapi/host/resource_message_filter.h" -+#include "ppapi/shared_impl/flash_clipboard_format_registry.h" -+ -+namespace ppapi { -+namespace host { -+struct HostMessageContext; -+} -+} // namespace ppapi -+ -+namespace ui { -+class ScopedClipboardWriter; -+} -+ -+namespace chrome { -+ -+// Resource message filter for accessing the clipboard in Pepper. Pepper -+// supports reading/writing custom formats from the clipboard. Currently, all -+// custom formats that are read/written from the clipboard through pepper are -+// stored in a single real clipboard format (in the same way the "web custom" -+// clipboard formats are). This is done so that we don't have to have use real -+// clipboard types for each custom clipboard format which may be a limited -+// resource on a particular platform. -+class PepperFlashClipboardMessageFilter -+ : public ppapi::host::ResourceMessageFilter { -+ public: -+ PepperFlashClipboardMessageFilter(); -+ -+ protected: -+ // ppapi::host::ResourceMessageFilter overrides. -+ scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage( -+ const IPC::Message& msg) override; -+ int32_t OnResourceMessageReceived( -+ const IPC::Message& msg, -+ ppapi::host::HostMessageContext* context) override; -+ -+ private: -+ ~PepperFlashClipboardMessageFilter() override; -+ -+ int32_t OnMsgRegisterCustomFormat( -+ ppapi::host::HostMessageContext* host_context, -+ const std::string& format_name); -+ int32_t OnMsgIsFormatAvailable(ppapi::host::HostMessageContext* host_context, -+ uint32_t clipboard_type, -+ uint32_t format); -+ int32_t OnMsgReadData(ppapi::host::HostMessageContext* host_context, -+ uint32_t clipoard_type, -+ uint32_t format); -+ int32_t OnMsgWriteData(ppapi::host::HostMessageContext* host_context, -+ uint32_t clipboard_type, -+ const std::vector<uint32_t>& formats, -+ const std::vector<std::string>& data); -+ int32_t OnMsgGetSequenceNumber(ppapi::host::HostMessageContext* host_context, -+ uint32_t clipboard_type); -+ -+ int32_t WriteClipboardDataItem(uint32_t format, -+ const std::string& data, -+ ui::ScopedClipboardWriter* scw); -+ -+ ppapi::FlashClipboardFormatRegistry custom_formats_; -+ -+ DISALLOW_COPY_AND_ASSIGN(PepperFlashClipboardMessageFilter); -+}; -+ -+} // namespace chrome -+ -+#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_CLIPBOARD_MESSAGE_FILTER_H_ -added in remote - their 100644 06b0b583a6441819cb6486e99a3aa77c4ed906db chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.cc -@@ -0,0 +1,216 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h" -+ -+#include <cmath> -+ -+#if defined(OS_WIN) -+#include <Windows.h> -+#endif -+ -+#include "base/bind.h" -+#include "base/compiler_specific.h" -+#include "base/logging.h" -+#include "base/memory/ref_counted.h" -+#include "base/strings/string_number_conversions.h" -+#include "build/build_config.h" -+#include "content/public/browser/browser_ppapi_host.h" -+#include "content/public/browser/browser_thread.h" -+#include "content/public/browser/child_process_security_policy.h" -+#include "content/public/browser/render_frame_host.h" -+#include "content/public/common/pepper_plugin_info.h" -+#include "net/base/network_interfaces.h" -+#include "ppapi/c/pp_errors.h" -+#include "ppapi/host/dispatch_host_message.h" -+#include "ppapi/host/host_message_context.h" -+#include "ppapi/host/ppapi_host.h" -+#include "ppapi/proxy/ppapi_messages.h" -+ -+#if defined(USE_AURA) -+#include "ui/aura/window.h" -+#include "ui/aura/window_tree_host.h" -+#endif -+ -+#if defined(OS_MACOSX) -+#include "chrome/browser/renderer_host/pepper/monitor_finder_mac.h" -+#endif -+ -+using content::BrowserPpapiHost; -+ -+namespace chrome { -+ -+namespace { -+ -+const char kVoucherFilename[] = "plugin.vch"; -+ -+#if defined(OS_WIN) -+bool GetSystemVolumeSerialNumber(std::string* number) { -+ // Find the system root path (e.g: C:\). -+ wchar_t system_path[MAX_PATH + 1]; -+ if (!GetSystemDirectoryW(system_path, MAX_PATH)) -+ return false; -+ -+ wchar_t* first_slash = wcspbrk(system_path, L"\\/"); -+ if (first_slash != NULL) -+ *(first_slash + 1) = 0; -+ -+ DWORD number_local = 0; -+ if (!GetVolumeInformationW(system_path, NULL, 0, &number_local, NULL, NULL, -+ NULL, 0)) -+ return false; -+ -+ *number = base::IntToString(std::abs(static_cast<int>(number_local))); -+ return true; -+} -+#endif -+ -+} // namespace -+ -+#if defined(OS_WIN) -+// Helper class to get the UI thread which monitor is showing the -+// window associated with the instance's render view. Since we get -+// called by the IO thread and we cannot block, the first answer is -+// of GetMonitor() may be NULL, but eventually it will contain the -+// right monitor. -+class MonitorFinder : public base::RefCountedThreadSafe<MonitorFinder> { -+ public: -+ MonitorFinder(int process_id, int render_frame_id) -+ : process_id_(process_id), -+ render_frame_id_(render_frame_id), -+ monitor_(NULL), -+ request_sent_(0) {} -+ -+ int64_t GetMonitor() { -+ // We use |request_sent_| as an atomic boolean so that we -+ // never have more than one task posted at a given time. We -+ // do this because we don't know how often our client is going -+ // to call and we can't cache the |monitor_| value. -+ if (InterlockedCompareExchange(&request_sent_, 1, 0) == 0) { -+ content::BrowserThread::PostTask( -+ content::BrowserThread::UI, FROM_HERE, -+ base::Bind(&MonitorFinder::FetchMonitorFromWidget, this)); -+ } -+ return reinterpret_cast<int64_t>(monitor_); -+ } -+ -+ private: -+ friend class base::RefCountedThreadSafe<MonitorFinder>; -+ ~MonitorFinder() {} -+ -+ void FetchMonitorFromWidget() { -+ InterlockedExchange(&request_sent_, 0); -+ content::RenderFrameHost* rfh = -+ content::RenderFrameHost::FromID(process_id_, render_frame_id_); -+ if (!rfh) -+ return; -+ gfx::NativeView native_view = rfh->GetNativeView(); -+#if defined(USE_AURA) -+ aura::WindowTreeHost* host = native_view->GetHost(); -+ if (!host) -+ return; -+ HWND window = host->GetAcceleratedWidget(); -+#else -+ HWND window = native_view; -+#endif -+ HMONITOR monitor = ::MonitorFromWindow(window, MONITOR_DEFAULTTONULL); -+ InterlockedExchangePointer(reinterpret_cast<void* volatile*>(&monitor_), -+ monitor); -+ } -+ -+ const int process_id_; -+ const int render_frame_id_; -+ volatile HMONITOR monitor_; -+ volatile long request_sent_; -+}; -+#elif !defined(OS_MACOSX) -+// TODO(cpu): Support Linux someday. -+class MonitorFinder : public base::RefCountedThreadSafe<MonitorFinder> { -+ public: -+ MonitorFinder(int, int) {} -+ int64_t GetMonitor() { return 0; } -+ -+ private: -+ friend class base::RefCountedThreadSafe<MonitorFinder>; -+ ~MonitorFinder() {} -+}; -+#endif -+ -+PepperFlashDRMHost::PepperFlashDRMHost(BrowserPpapiHost* host, -+ PP_Instance instance, -+ PP_Resource resource) -+ : ppapi::host::ResourceHost(host->GetPpapiHost(), instance, resource), -+ weak_factory_(this) { -+ // Grant permissions to read the flash voucher file. -+ int render_process_id; -+ int render_frame_id; -+ bool success = host->GetRenderFrameIDsForInstance( -+ instance, &render_process_id, &render_frame_id); -+ base::FilePath plugin_dir = host->GetPluginPath().DirName(); -+ DCHECK(!plugin_dir.empty() && success); -+ base::FilePath voucher_file = plugin_dir.AppendASCII(kVoucherFilename); -+ content::ChildProcessSecurityPolicy::GetInstance()->GrantReadFile( -+ render_process_id, voucher_file); -+ -+ monitor_finder_ = new MonitorFinder(render_process_id, render_frame_id); -+ monitor_finder_->GetMonitor(); -+} -+ -+PepperFlashDRMHost::~PepperFlashDRMHost() {} -+ -+int32_t PepperFlashDRMHost::OnResourceMessageReceived( -+ const IPC::Message& msg, -+ ppapi::host::HostMessageContext* context) { -+ PPAPI_BEGIN_MESSAGE_MAP(PepperFlashDRMHost, msg) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FlashDRM_GetDeviceID, -+ OnHostMsgGetDeviceID) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FlashDRM_GetHmonitor, -+ OnHostMsgGetHmonitor) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FlashDRM_MonitorIsExternal, -+ OnHostMsgMonitorIsExternal) -+ PPAPI_END_MESSAGE_MAP() -+ return PP_ERROR_FAILED; -+} -+ -+int32_t PepperFlashDRMHost::OnHostMsgGetDeviceID( -+ ppapi::host::HostMessageContext* context) { -+ static std::string id; -+#if defined(OS_WIN) -+ if (id.empty() && !GetSystemVolumeSerialNumber(&id)) -+ id = net::GetHostName(); -+#else -+ if (id.empty()) -+ id = net::GetHostName(); -+#endif -+ context->reply_msg = PpapiPluginMsg_FlashDRM_GetDeviceIDReply(id); -+ return PP_OK; -+} -+ -+int32_t PepperFlashDRMHost::OnHostMsgGetHmonitor( -+ ppapi::host::HostMessageContext* context) { -+ int64_t monitor_id = monitor_finder_->GetMonitor(); -+ if (monitor_id) { -+ context->reply_msg = PpapiPluginMsg_FlashDRM_GetHmonitorReply(monitor_id); -+ return PP_OK; -+ } -+ return PP_ERROR_FAILED; -+} -+ -+int32_t PepperFlashDRMHost::OnHostMsgMonitorIsExternal( -+ ppapi::host::HostMessageContext* context) { -+ int64_t monitor_id = monitor_finder_->GetMonitor(); -+ if (!monitor_id) -+ return PP_ERROR_FAILED; -+ -+ PP_Bool is_external = PP_FALSE; -+#if defined(OS_MACOSX) -+ if (!MonitorFinder::IsMonitorBuiltIn(monitor_id)) -+ is_external = PP_TRUE; -+#endif -+ context->reply_msg = -+ PpapiPluginMsg_FlashDRM_MonitorIsExternalReply(is_external); -+ return PP_OK; -+} -+ -+} // namespace chrome -added in remote - their 100644 91bba9631e68f08728d5d926528fc80ce4f9cb00 chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h -@@ -0,0 +1,55 @@ -+// Copyright (c) 2013 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_DRM_HOST_H_ -+#define CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_DRM_HOST_H_ -+ -+#include <stdint.h> -+ -+#include <string> -+ -+#include "base/macros.h" -+#include "base/memory/weak_ptr.h" -+#include "ppapi/host/host_message_context.h" -+#include "ppapi/host/resource_host.h" -+ -+namespace content { -+class BrowserPpapiHost; -+} -+ -+namespace IPC { -+class Message; -+} -+ -+namespace chrome { -+class MonitorFinder; -+ -+class PepperFlashDRMHost : public ppapi::host::ResourceHost { -+ public: -+ PepperFlashDRMHost(content::BrowserPpapiHost* host, -+ PP_Instance instance, -+ PP_Resource resource); -+ ~PepperFlashDRMHost() override; -+ -+ // ResourceHost override. -+ int32_t OnResourceMessageReceived( -+ const IPC::Message& msg, -+ ppapi::host::HostMessageContext* context) override; -+ -+ private: -+ // IPC message handler. -+ int32_t OnHostMsgGetDeviceID(ppapi::host::HostMessageContext* context); -+ int32_t OnHostMsgGetHmonitor(ppapi::host::HostMessageContext* context); -+ int32_t OnHostMsgMonitorIsExternal(ppapi::host::HostMessageContext* context); -+ -+ scoped_refptr<MonitorFinder> monitor_finder_; -+ -+ base::WeakPtrFactory<PepperFlashDRMHost> weak_factory_; -+ -+ DISALLOW_COPY_AND_ASSIGN(PepperFlashDRMHost); -+}; -+ -+} // namespace chrome -+ -+#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_DRM_HOST_H_ -added in remote - their 100644 be771653066bf4689f9857e6a218dd3c79d9696e chromium_src/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc -@@ -0,0 +1,106 @@ -+// Copyright 2013 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h" -+ -+#include "content/public/browser/browser_ppapi_host.h" -+#include "content/public/browser/browser_thread.h" -+#include "content/public/browser/child_process_security_policy.h" -+#include "content/public/browser/render_view_host.h" -+#include "ppapi/c/pp_errors.h" -+#include "ppapi/host/dispatch_host_message.h" -+#include "ppapi/host/host_message_context.h" -+#include "ppapi/host/ppapi_host.h" -+#include "ppapi/proxy/ppapi_messages.h" -+#include "ppapi/shared_impl/file_system_util.h" -+#include "storage/browser/fileapi/isolated_context.h" -+ -+namespace chrome { -+ -+// static -+PepperIsolatedFileSystemMessageFilter* -+PepperIsolatedFileSystemMessageFilter::Create(PP_Instance instance, -+ content::BrowserPpapiHost* host) { -+ int render_process_id; -+ int unused_render_frame_id; -+ if (!host->GetRenderFrameIDsForInstance(instance, &render_process_id, -+ &unused_render_frame_id)) { -+ return NULL; -+ } -+ return new PepperIsolatedFileSystemMessageFilter( -+ render_process_id, host->GetProfileDataDirectory(), -+ host->GetDocumentURLForInstance(instance), host->GetPpapiHost()); -+} -+ -+PepperIsolatedFileSystemMessageFilter::PepperIsolatedFileSystemMessageFilter( -+ int render_process_id, -+ const base::FilePath& profile_directory, -+ const GURL& document_url, -+ ppapi::host::PpapiHost* ppapi_host) -+ : render_process_id_(render_process_id), -+ profile_directory_(profile_directory), -+ document_url_(document_url), -+ ppapi_host_(ppapi_host) {} -+ -+PepperIsolatedFileSystemMessageFilter:: -+ ~PepperIsolatedFileSystemMessageFilter() {} -+ -+scoped_refptr<base::TaskRunner> -+PepperIsolatedFileSystemMessageFilter::OverrideTaskRunnerForMessage( -+ const IPC::Message& msg) { -+ // In order to reach ExtensionSystem, we need to get ProfileManager first. -+ // ProfileManager lives in UI thread, so we need to do this in UI thread. -+ return content::BrowserThread::GetTaskRunnerForThread( -+ content::BrowserThread::UI); -+} -+ -+int32_t PepperIsolatedFileSystemMessageFilter::OnResourceMessageReceived( -+ const IPC::Message& msg, -+ ppapi::host::HostMessageContext* context) { -+ PPAPI_BEGIN_MESSAGE_MAP(PepperIsolatedFileSystemMessageFilter, msg) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL( -+ PpapiHostMsg_IsolatedFileSystem_BrowserOpen, OnOpenFileSystem) -+ PPAPI_END_MESSAGE_MAP() -+ return PP_ERROR_FAILED; -+} -+ -+int32_t PepperIsolatedFileSystemMessageFilter::OnOpenFileSystem( -+ ppapi::host::HostMessageContext* context, -+ PP_IsolatedFileSystemType_Private type) { -+ switch (type) { -+ case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_INVALID: -+ case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_CRX: -+ break; -+ case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_PLUGINPRIVATE: -+ return OpenPluginPrivateFileSystem(context); -+ } -+ NOTREACHED(); -+ context->reply_msg = -+ PpapiPluginMsg_IsolatedFileSystem_BrowserOpenReply(std::string()); -+ return PP_ERROR_FAILED; -+} -+ -+int32_t PepperIsolatedFileSystemMessageFilter::OpenPluginPrivateFileSystem( -+ ppapi::host::HostMessageContext* context) { -+ DCHECK(ppapi_host_); -+ // Only plugins with private permission can open the filesystem. -+ if (!ppapi_host_->permissions().HasPermission(ppapi::PERMISSION_PRIVATE)) -+ return PP_ERROR_NOACCESS; -+ -+ const std::string& root_name = ppapi::IsolatedFileSystemTypeToRootName( -+ PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_PLUGINPRIVATE); -+ const std::string& fsid = -+ storage::IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath( -+ storage::kFileSystemTypePluginPrivate, root_name, base::FilePath()); -+ -+ // Grant full access of isolated filesystem to renderer process. -+ content::ChildProcessSecurityPolicy* policy = -+ content::ChildProcessSecurityPolicy::GetInstance(); -+ policy->GrantCreateReadWriteFileSystem(render_process_id_, fsid); -+ -+ context->reply_msg = PpapiPluginMsg_IsolatedFileSystem_BrowserOpenReply(fsid); -+ return PP_OK; -+} -+ -+} // namespace chrome -added in remote - their 100644 6a24feadd150e0c5ecd1fa44c7e412262ecae55d chromium_src/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h -@@ -0,0 +1,76 @@ -+// Copyright 2013 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_ISOLATED_FILE_SYSTEM_MESSAGE_FILTER_H_ -+#define CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_ISOLATED_FILE_SYSTEM_MESSAGE_FILTER_H_ -+ -+#include <set> -+#include <string> -+ -+#include "base/files/file_path.h" -+#include "ppapi/c/pp_instance.h" -+#include "ppapi/c/pp_resource.h" -+#include "ppapi/c/private/ppb_isolated_file_system_private.h" -+#include "ppapi/host/resource_host.h" -+#include "ppapi/host/resource_message_filter.h" -+#include "url/gurl.h" -+ -+class Profile; -+ -+namespace content { -+class BrowserPpapiHost; -+} -+ -+namespace ppapi { -+namespace host { -+struct HostMessageContext; -+} // namespace host -+} // namespace ppapi -+ -+namespace chrome { -+ -+class PepperIsolatedFileSystemMessageFilter -+ : public ppapi::host::ResourceMessageFilter { -+ public: -+ static PepperIsolatedFileSystemMessageFilter* Create( -+ PP_Instance instance, -+ content::BrowserPpapiHost* host); -+ -+ // ppapi::host::ResourceMessageFilter implementation. -+ scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage( -+ const IPC::Message& msg) override; -+ int32_t OnResourceMessageReceived( -+ const IPC::Message& msg, -+ ppapi::host::HostMessageContext* context) override; -+ -+ private: -+ PepperIsolatedFileSystemMessageFilter(int render_process_id, -+ const base::FilePath& profile_directory, -+ const GURL& document_url, -+ ppapi::host::PpapiHost* ppapi_host_); -+ -+ ~PepperIsolatedFileSystemMessageFilter() override; -+ -+ // Returns filesystem id of isolated filesystem if valid, or empty string -+ // otherwise. This must run on the UI thread because ProfileManager only -+ // allows access on that thread. -+ -+ int32_t OnOpenFileSystem(ppapi::host::HostMessageContext* context, -+ PP_IsolatedFileSystemType_Private type); -+ int32_t OpenPluginPrivateFileSystem(ppapi::host::HostMessageContext* context); -+ -+ const int render_process_id_; -+ // Keep a copy from original thread. -+ const base::FilePath profile_directory_; -+ const GURL document_url_; -+ -+ // Not owned by this object. -+ ppapi::host::PpapiHost* ppapi_host_; -+ -+ DISALLOW_COPY_AND_ASSIGN(PepperIsolatedFileSystemMessageFilter); -+}; -+ -+} // namespace chrome -+ -+#endif // CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_ISOLATED_FILE_SYSTEM_MESSAGE_FILTER_H_ -added in both - our 100644 850bd7ad3630604fa35bdb67397eb789e059973a chromium_src/chrome/browser/ui/views/color_chooser_dialog.h - their 100644 b23061a386dc0dc235f5924fc559aa3b7d355a56 chromium_src/chrome/browser/ui/views/color_chooser_dialog.h -@@ -23,6 +23,7 @@ - ColorChooserDialog(views::ColorChooserListener* listener, - SkColor initial_color, - gfx::NativeWindow owning_window); -+<<<<<<< .our - - // BaseShellDialog: - bool IsRunning(gfx::NativeWindow owning_window) const override; -@@ -32,6 +33,15 @@ - ~ColorChooserDialog() override; - friend class base::RefCountedThreadSafe<ColorChooserDialog>; - -+======= -+ virtual ~ColorChooserDialog(); -+ -+ // BaseShellDialog: -+ virtual bool IsRunning(gfx::NativeWindow owning_window) const override; -+ virtual void ListenerDestroyed() override; -+ -+ private: -+>>>>>>> .their - struct ExecuteOpenParams { - ExecuteOpenParams(SkColor color, RunState run_state, HWND owner); - SkColor color; -added in both - our 100644 0f8ebfa6366f90e435dc0e854b20cef92fc2964f chromium_src/chrome/browser/ui/views/color_chooser_win.cc - their 100644 fc330dd63f1810bc9486428a32f351ec0cdfb3eb chromium_src/chrome/browser/ui/views/color_chooser_win.cc -@@ -22,6 +22,7 @@ - SkColor initial_color); - - ColorChooserWin(content::WebContents* web_contents, SkColor initial_color); -+<<<<<<< .our - ~ColorChooserWin() override; - - // content::ColorChooser overrides: -@@ -31,6 +32,17 @@ - // views::ColorChooserListener overrides: - void OnColorChosen(SkColor color) override; - void OnColorChooserDialogClosed() override; -+======= -+ ~ColorChooserWin(); -+ -+ // content::ColorChooser overrides: -+ virtual void End() override; -+ virtual void SetSelectedColor(SkColor color) override {} -+ -+ // views::ColorChooserListener overrides: -+ virtual void OnColorChosen(SkColor color); -+ virtual void OnColorChooserDialogClosed(); -+>>>>>>> .their - - private: - static ColorChooserWin* current_color_chooser_; -added in remote - their 100644 437d87f8ff5e89c13990e1fba87e7e51de7d962f chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc -@@ -0,0 +1,99 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h" -+ -+#include "base/logging.h" -+#include "chrome/renderer/pepper/pepper_flash_font_file_host.h" -+#include "chrome/renderer/pepper/pepper_flash_fullscreen_host.h" -+#include "chrome/renderer/pepper/pepper_flash_menu_host.h" -+#include "chrome/renderer/pepper/pepper_flash_renderer_host.h" -+#include "content/public/renderer/renderer_ppapi_host.h" -+#include "ppapi/host/ppapi_host.h" -+#include "ppapi/host/resource_host.h" -+#include "ppapi/proxy/ppapi_message_utils.h" -+#include "ppapi/proxy/ppapi_messages.h" -+#include "ppapi/shared_impl/ppapi_permissions.h" -+ -+#if defined(ENABLE_PDF_VIEWER) -+#include "components/pdf/renderer/pepper_pdf_host.h" -+#endif // defined(ENABLE_PDF_VIEWER) -+ -+using ppapi::host::ResourceHost; -+ -+ChromeRendererPepperHostFactory::ChromeRendererPepperHostFactory( -+ content::RendererPpapiHost* host) -+ : host_(host) {} -+ -+ChromeRendererPepperHostFactory::~ChromeRendererPepperHostFactory() {} -+ -+std::unique_ptr<ResourceHost> -+ChromeRendererPepperHostFactory::CreateResourceHost( -+ ppapi::host::PpapiHost* host, -+ PP_Resource resource, -+ PP_Instance instance, -+ const IPC::Message& message) { -+ DCHECK_EQ(host_->GetPpapiHost(), host); -+ -+ // Make sure the plugin is giving us a valid instance for this resource. -+ if (!host_->IsValidInstance(instance)) -+ return std::unique_ptr<ResourceHost>(); -+ -+ if (host_->GetPpapiHost()->permissions().HasPermission( -+ ppapi::PERMISSION_FLASH)) { -+ switch (message.type()) { -+ case PpapiHostMsg_Flash_Create::ID: { -+ return std::unique_ptr<ResourceHost>( -+ new PepperFlashRendererHost(host_, instance, resource)); -+ } -+ case PpapiHostMsg_FlashFullscreen_Create::ID: { -+ return std::unique_ptr<ResourceHost>( -+ new PepperFlashFullscreenHost(host_, instance, resource)); -+ } -+ case PpapiHostMsg_FlashMenu_Create::ID: { -+ ppapi::proxy::SerializedFlashMenu serialized_menu; -+ if (ppapi::UnpackMessage<PpapiHostMsg_FlashMenu_Create>( -+ message, &serialized_menu)) { -+ return std::unique_ptr<ResourceHost>(new PepperFlashMenuHost( -+ host_, instance, resource, serialized_menu)); -+ } -+ break; -+ } -+ } -+ } -+ -+ // TODO(raymes): PDF also needs access to the FlashFontFileHost currently. -+ // We should either rename PPB_FlashFont_File to PPB_FontFile_Private or get -+ // rid of its use in PDF if possible. -+ if (host_->GetPpapiHost()->permissions().HasPermission( -+ ppapi::PERMISSION_FLASH) || -+ host_->GetPpapiHost()->permissions().HasPermission( -+ ppapi::PERMISSION_PRIVATE)) { -+ switch (message.type()) { -+ case PpapiHostMsg_FlashFontFile_Create::ID: { -+ ppapi::proxy::SerializedFontDescription description; -+ PP_PrivateFontCharset charset; -+ if (ppapi::UnpackMessage<PpapiHostMsg_FlashFontFile_Create>( -+ message, &description, &charset)) { -+ return std::unique_ptr<ResourceHost>(new PepperFlashFontFileHost( -+ host_, instance, resource, description, charset)); -+ } -+ break; -+ } -+ } -+ } -+ -+#if defined(ENABLE_PDF_VIEWER) -+ if (host_->GetPpapiHost()->permissions().HasPermission( -+ ppapi::PERMISSION_PRIVATE)) { -+ switch (message.type()) { -+ case PpapiHostMsg_PDF_Create::ID: { -+ return std::make_unique<pdf::PepperPDFHost>(host_, instance, resource); -+ } -+ } -+ } -+#endif // defined(ENABLE_PDF_VIEWER) -+ -+ return std::unique_ptr<ResourceHost>(); -+} -added in remote - their 100644 c52c73b56f048fc522f4879597e870285ec7009d chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h -@@ -0,0 +1,34 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef CHROME_RENDERER_PEPPER_CHROME_RENDERER_PEPPER_HOST_FACTORY_H_ -+#define CHROME_RENDERER_PEPPER_CHROME_RENDERER_PEPPER_HOST_FACTORY_H_ -+ -+#include "base/macros.h" -+#include "ppapi/host/host_factory.h" -+ -+namespace content { -+class RendererPpapiHost; -+} -+ -+class ChromeRendererPepperHostFactory : public ppapi::host::HostFactory { -+ public: -+ explicit ChromeRendererPepperHostFactory(content::RendererPpapiHost* host); -+ ~ChromeRendererPepperHostFactory() override; -+ -+ // HostFactory. -+ std::unique_ptr<ppapi::host::ResourceHost> CreateResourceHost( -+ ppapi::host::PpapiHost* host, -+ PP_Resource resource, -+ PP_Instance instance, -+ const IPC::Message& message) override; -+ -+ private: -+ // Not owned by this object. -+ content::RendererPpapiHost* host_; -+ -+ DISALLOW_COPY_AND_ASSIGN(ChromeRendererPepperHostFactory); -+}; -+ -+#endif // CHROME_RENDERER_PEPPER_CHROME_RENDERER_PEPPER_HOST_FACTORY_H_ -added in remote - their 100644 efdc9316b82976b2e07cb3c8aec06141304f390c chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.cc -@@ -0,0 +1,105 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "chrome/renderer/pepper/pepper_flash_font_file_host.h" -+ -+#include "base/sys_byteorder.h" -+#include "build/build_config.h" -+#include "content/public/renderer/renderer_ppapi_host.h" -+#include "ppapi/c/pp_errors.h" -+#include "ppapi/host/dispatch_host_message.h" -+#include "ppapi/host/host_message_context.h" -+#include "ppapi/host/ppapi_host.h" -+#include "ppapi/proxy/ppapi_messages.h" -+#include "ppapi/proxy/serialized_structs.h" -+ -+#if defined(OS_LINUX) || defined(OS_OPENBSD) -+#include "content/public/child/child_process_sandbox_support_linux.h" -+#include "content/public/common/common_sandbox_support_linux.h" -+#elif defined(OS_WIN) -+#include "third_party/skia/include/ports/SkFontMgr.h" -+#endif -+ -+PepperFlashFontFileHost::PepperFlashFontFileHost( -+ content::RendererPpapiHost* host, -+ PP_Instance instance, -+ PP_Resource resource, -+ const ppapi::proxy::SerializedFontDescription& description, -+ PP_PrivateFontCharset charset) -+ : ResourceHost(host->GetPpapiHost(), instance, resource) { -+#if defined(OS_LINUX) || defined(OS_OPENBSD) -+ fd_.reset(content::MatchFontWithFallback( -+ description.face.c_str(), -+ description.weight >= PP_BROWSERFONT_TRUSTED_WEIGHT_BOLD, -+ description.italic, charset, PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT)); -+#elif defined(OS_WIN) // defined(OS_LINUX) || defined(OS_OPENBSD) -+ int weight = description.weight; -+ if (weight == FW_DONTCARE) -+ weight = SkFontStyle::kNormal_Weight; -+ SkFontStyle style(weight, SkFontStyle::kNormal_Width, -+ description.italic ? SkFontStyle::kItalic_Slant -+ : SkFontStyle::kUpright_Slant); -+ sk_sp<SkFontMgr> font_mgr(SkFontMgr::RefDefault()); -+ typeface_ = sk_sp<SkTypeface>( -+ font_mgr->matchFamilyStyle(description.face.c_str(), style)); -+#endif // defined(OS_WIN) -+} -+ -+PepperFlashFontFileHost::~PepperFlashFontFileHost() {} -+ -+int32_t PepperFlashFontFileHost::OnResourceMessageReceived( -+ const IPC::Message& msg, -+ ppapi::host::HostMessageContext* context) { -+ PPAPI_BEGIN_MESSAGE_MAP(PepperFlashFontFileHost, msg) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashFontFile_GetFontTable, -+ OnGetFontTable) -+ PPAPI_END_MESSAGE_MAP() -+ return PP_ERROR_FAILED; -+} -+bool PepperFlashFontFileHost::GetFontData(uint32_t table, -+ void* buffer, -+ size_t* length) { -+ bool result = false; -+#if defined(OS_LINUX) || defined(OS_OPENBSD) -+ int fd = fd_.get(); -+ if (fd != -1) -+ result = content::GetFontTable(fd, table, 0 /* offset */, -+ reinterpret_cast<uint8_t*>(buffer), length); -+#elif defined(OS_WIN) -+ if (typeface_) { -+ table = base::ByteSwap(table); -+ if (buffer == NULL) { -+ *length = typeface_->getTableSize(table); -+ if (*length > 0) -+ result = true; -+ } else { -+ size_t new_length = typeface_->getTableData(table, 0, *length, buffer); -+ if (new_length == *length) -+ result = true; -+ } -+ } -+#endif -+ return result; -+} -+ -+int32_t PepperFlashFontFileHost::OnGetFontTable( -+ ppapi::host::HostMessageContext* context, -+ uint32_t table) { -+ std::string contents; -+ int32_t result = PP_ERROR_FAILED; -+ size_t length = 0; -+ if (GetFontData(table, NULL, &length)) { -+ contents.resize(length); -+ uint8_t* contents_ptr = -+ reinterpret_cast<uint8_t*>(const_cast<char*>(contents.c_str())); -+ if (GetFontData(table, contents_ptr, &length)) { -+ result = PP_OK; -+ } else { -+ contents.clear(); -+ } -+ } -+ -+ context->reply_msg = PpapiPluginMsg_FlashFontFile_GetFontTableReply(contents); -+ return result; -+} -added in remote - their 100644 15eb73837b50dbb85d607a84bc3b3a71cf789ac5 chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.h -@@ -0,0 +1,56 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef CHROME_RENDERER_PEPPER_PEPPER_FLASH_FONT_FILE_HOST_H_ -+#define CHROME_RENDERER_PEPPER_PEPPER_FLASH_FONT_FILE_HOST_H_ -+ -+#include "ppapi/c/private/pp_private_font_charset.h" -+#include "ppapi/host/resource_host.h" -+ -+#if defined(OS_LINUX) || defined(OS_OPENBSD) -+#include "base/files/scoped_file.h" -+#elif defined(OS_WIN) -+#include "third_party/skia/include/core/SkRefCnt.h" -+#include "third_party/skia/include/core/SkTypeface.h" -+#endif -+ -+namespace content { -+class RendererPpapiHost; -+} -+ -+namespace ppapi { -+namespace proxy { -+struct SerializedFontDescription; -+} -+} // namespace ppapi -+ -+class PepperFlashFontFileHost : public ppapi::host::ResourceHost { -+ public: -+ PepperFlashFontFileHost( -+ content::RendererPpapiHost* host, -+ PP_Instance instance, -+ PP_Resource resource, -+ const ppapi::proxy::SerializedFontDescription& description, -+ PP_PrivateFontCharset charset); -+ ~PepperFlashFontFileHost() override; -+ -+ int32_t OnResourceMessageReceived( -+ const IPC::Message& msg, -+ ppapi::host::HostMessageContext* context) override; -+ -+ private: -+ int32_t OnGetFontTable(ppapi::host::HostMessageContext* context, -+ uint32_t table); -+ bool GetFontData(uint32_t table, void* buffer, size_t* length); -+ -+#if defined(OS_LINUX) || defined(OS_OPENBSD) -+ base::ScopedFD fd_; -+#elif defined(OS_WIN) -+ sk_sp<SkTypeface> typeface_; -+#endif -+ -+ DISALLOW_COPY_AND_ASSIGN(PepperFlashFontFileHost); -+}; -+ -+#endif // CHROME_RENDERER_PEPPER_PEPPER_FLASH_FONT_FILE_HOST_H_ -added in remote - their 100644 f4367ef73ce882cec4392da24413800620237c25 chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.cc -@@ -0,0 +1,42 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "chrome/renderer/pepper/pepper_flash_fullscreen_host.h" -+ -+#include "content/public/renderer/pepper_plugin_instance.h" -+#include "content/public/renderer/renderer_ppapi_host.h" -+#include "ppapi/c/pp_errors.h" -+#include "ppapi/host/dispatch_host_message.h" -+#include "ppapi/host/host_message_context.h" -+#include "ppapi/host/ppapi_host.h" -+#include "ppapi/proxy/ppapi_messages.h" -+ -+PepperFlashFullscreenHost::PepperFlashFullscreenHost( -+ content::RendererPpapiHost* host, -+ PP_Instance instance, -+ PP_Resource resource) -+ : ResourceHost(host->GetPpapiHost(), instance, resource), -+ renderer_ppapi_host_(host) {} -+ -+PepperFlashFullscreenHost::~PepperFlashFullscreenHost() {} -+ -+int32_t PepperFlashFullscreenHost::OnResourceMessageReceived( -+ const IPC::Message& msg, -+ ppapi::host::HostMessageContext* context) { -+ PPAPI_BEGIN_MESSAGE_MAP(PepperFlashFullscreenHost, msg) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL( -+ PpapiHostMsg_FlashFullscreen_SetFullscreen, OnSetFullscreen) -+ PPAPI_END_MESSAGE_MAP() -+ return PP_ERROR_FAILED; -+} -+ -+int32_t PepperFlashFullscreenHost::OnSetFullscreen( -+ ppapi::host::HostMessageContext* context, -+ bool fullscreen) { -+ content::PepperPluginInstance* plugin_instance = -+ renderer_ppapi_host_->GetPluginInstance(pp_instance()); -+ if (plugin_instance && plugin_instance->FlashSetFullscreen(fullscreen, true)) -+ return PP_OK; -+ return PP_ERROR_FAILED; -+} -added in remote - their 100644 86d0af73aee54451905485e2afa0e4cd08d0037e chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.h -@@ -0,0 +1,35 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef CHROME_RENDERER_PEPPER_PEPPER_FLASH_FULLSCREEN_HOST_H_ -+#define CHROME_RENDERER_PEPPER_PEPPER_FLASH_FULLSCREEN_HOST_H_ -+ -+#include "ppapi/host/resource_host.h" -+ -+namespace content { -+class RendererPpapiHost; -+} -+ -+class PepperFlashFullscreenHost : public ppapi::host::ResourceHost { -+ public: -+ PepperFlashFullscreenHost(content::RendererPpapiHost* host, -+ PP_Instance instance, -+ PP_Resource resource); -+ ~PepperFlashFullscreenHost() override; -+ -+ int32_t OnResourceMessageReceived( -+ const IPC::Message& msg, -+ ppapi::host::HostMessageContext* context) override; -+ -+ private: -+ int32_t OnSetFullscreen(ppapi::host::HostMessageContext* context, -+ bool fullscreen); -+ -+ // Non-owning pointer. -+ content::RendererPpapiHost* renderer_ppapi_host_; -+ -+ DISALLOW_COPY_AND_ASSIGN(PepperFlashFullscreenHost); -+}; -+ -+#endif // CHROME_RENDERER_PEPPER_PEPPER_FLASH_FULLSCREEN_HOST_H_ -added in remote - their 100644 45a79349a1c5e6f0b2767cbb1f5e678358f714b8 chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.cc -@@ -0,0 +1,201 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "chrome/renderer/pepper/pepper_flash_menu_host.h" -+ -+#include "base/strings/utf_string_conversions.h" -+#include "content/public/common/context_menu_params.h" -+#include "content/public/renderer/render_frame.h" -+#include "content/public/renderer/renderer_ppapi_host.h" -+#include "ipc/ipc_message.h" -+#include "ppapi/c/private/ppb_flash_menu.h" -+#include "ppapi/host/dispatch_host_message.h" -+#include "ppapi/host/ppapi_host.h" -+#include "ppapi/proxy/ppapi_messages.h" -+#include "ppapi/proxy/serialized_flash_menu.h" -+#include "ui/gfx/geometry/point.h" -+ -+namespace { -+ -+// Maximum depth of submenus allowed (e.g., 1 indicates that submenus are -+// allowed, but not sub-submenus). -+const size_t kMaxMenuDepth = 2; -+ -+// Maximum number of entries in any single menu (including separators). -+const size_t kMaxMenuEntries = 50; -+ -+// Maximum total number of entries in the |menu_id_map| (see below). -+// (Limit to 500 real entries; reserve the 0 action as an invalid entry.) -+const size_t kMaxMenuIdMapEntries = 501; -+ -+// Converts menu data from one form to another. -+// - |depth| is the current nested depth (call it starting with 0). -+// - |menu_id_map| is such that |menu_id_map[output_item.action] == -+// input_item.id| (where |action| is what a |MenuItem| has, |id| is what a -+// |PP_Flash_MenuItem| has). -+bool ConvertMenuData(const PP_Flash_Menu* in_menu, -+ size_t depth, -+ std::vector<content::MenuItem>* out_menu, -+ std::vector<int32_t>* menu_id_map) { -+ if (depth > kMaxMenuDepth || !in_menu) -+ return false; -+ -+ // Clear the output, just in case. -+ out_menu->clear(); -+ -+ if (!in_menu->count) -+ return true; // Nothing else to do. -+ -+ if (!in_menu->items || in_menu->count > kMaxMenuEntries) -+ return false; -+ for (uint32_t i = 0; i < in_menu->count; i++) { -+ content::MenuItem item; -+ -+ PP_Flash_MenuItem_Type type = in_menu->items[i].type; -+ switch (type) { -+ case PP_FLASH_MENUITEM_TYPE_NORMAL: -+ item.type = content::MenuItem::OPTION; -+ break; -+ case PP_FLASH_MENUITEM_TYPE_CHECKBOX: -+ item.type = content::MenuItem::CHECKABLE_OPTION; -+ break; -+ case PP_FLASH_MENUITEM_TYPE_SEPARATOR: -+ item.type = content::MenuItem::SEPARATOR; -+ break; -+ case PP_FLASH_MENUITEM_TYPE_SUBMENU: -+ item.type = content::MenuItem::SUBMENU; -+ break; -+ default: -+ return false; -+ } -+ if (in_menu->items[i].name) -+ item.label = base::UTF8ToUTF16(in_menu->items[i].name); -+ if (menu_id_map->size() >= kMaxMenuIdMapEntries) -+ return false; -+ item.action = static_cast<unsigned>(menu_id_map->size()); -+ // This sets |(*menu_id_map)[item.action] = in_menu->items[i].id|. -+ menu_id_map->push_back(in_menu->items[i].id); -+ item.enabled = PP_ToBool(in_menu->items[i].enabled); -+ item.checked = PP_ToBool(in_menu->items[i].checked); -+ if (type == PP_FLASH_MENUITEM_TYPE_SUBMENU) { -+ if (!ConvertMenuData(in_menu->items[i].submenu, depth + 1, &item.submenu, -+ menu_id_map)) -+ return false; -+ } -+ -+ out_menu->push_back(item); -+ } -+ -+ return true; -+} -+ -+} // namespace -+ -+PepperFlashMenuHost::PepperFlashMenuHost( -+ content::RendererPpapiHost* host, -+ PP_Instance instance, -+ PP_Resource resource, -+ const ppapi::proxy::SerializedFlashMenu& serial_menu) -+ : ppapi::host::ResourceHost(host->GetPpapiHost(), instance, resource), -+ renderer_ppapi_host_(host), -+ showing_context_menu_(false), -+ context_menu_request_id_(0), -+ has_saved_context_menu_action_(false), -+ saved_context_menu_action_(0) { -+ menu_id_map_.push_back(0); // Reserve |menu_id_map_[0]|. -+ if (!ConvertMenuData(serial_menu.pp_menu(), 0, &menu_data_, &menu_id_map_)) { -+ menu_data_.clear(); -+ menu_id_map_.clear(); -+ } -+} -+ -+PepperFlashMenuHost::~PepperFlashMenuHost() { -+ if (showing_context_menu_) { -+ content::RenderFrame* render_frame = -+ renderer_ppapi_host_->GetRenderFrameForInstance(pp_instance()); -+ if (render_frame) -+ render_frame->CancelContextMenu(context_menu_request_id_); -+ } -+} -+ -+int32_t PepperFlashMenuHost::OnResourceMessageReceived( -+ const IPC::Message& msg, -+ ppapi::host::HostMessageContext* context) { -+ PPAPI_BEGIN_MESSAGE_MAP(PepperFlashMenuHost, msg) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashMenu_Show, -+ OnHostMsgShow) -+ PPAPI_END_MESSAGE_MAP() -+ return PP_ERROR_FAILED; -+} -+ -+int32_t PepperFlashMenuHost::OnHostMsgShow( -+ ppapi::host::HostMessageContext* context, -+ const PP_Point& location) { -+ // Note that all early returns must do a SendMenuReply. The sync result for -+ // this message isn't used, so to forward the error to the plugin, we need to -+ // additionally call SendMenuReply explicitly. -+ if (menu_data_.empty()) { -+ SendMenuReply(PP_ERROR_FAILED, -1); -+ return PP_ERROR_FAILED; -+ } -+ if (showing_context_menu_) { -+ SendMenuReply(PP_ERROR_INPROGRESS, -1); -+ return PP_ERROR_INPROGRESS; -+ } -+ -+ content::RenderFrame* render_frame = -+ renderer_ppapi_host_->GetRenderFrameForInstance(pp_instance()); -+ -+ content::ContextMenuParams params; -+ params.x = location.x; -+ params.y = location.y; -+ params.custom_context.is_pepper_menu = true; -+ params.custom_context.render_widget_id = -+ renderer_ppapi_host_->GetRoutingIDForWidget(pp_instance()); -+ params.custom_items = menu_data_; -+ -+ // Transform the position to be in render frame's coordinates. -+ gfx::Point render_frame_pt = renderer_ppapi_host_->PluginPointToRenderFrame( -+ pp_instance(), gfx::Point(location.x, location.y)); -+ params.x = render_frame_pt.x(); -+ params.y = render_frame_pt.y(); -+ -+ showing_context_menu_ = true; -+ context_menu_request_id_ = render_frame->ShowContextMenu(this, params); -+ -+ // Note: the show message is sync so this OK is for the sync reply which we -+ // don't actually use (see the comment in the resource file for this). The -+ // async message containing the context menu action will be sent in the -+ // future. -+ return PP_OK; -+} -+ -+void PepperFlashMenuHost::OnMenuAction(int request_id, unsigned action) { -+ // Just save the action. -+ DCHECK(!has_saved_context_menu_action_); -+ has_saved_context_menu_action_ = true; -+ saved_context_menu_action_ = action; -+} -+ -+void PepperFlashMenuHost::OnMenuClosed(int request_id) { -+ if (has_saved_context_menu_action_ && -+ saved_context_menu_action_ < menu_id_map_.size()) { -+ SendMenuReply(PP_OK, menu_id_map_[saved_context_menu_action_]); -+ has_saved_context_menu_action_ = false; -+ saved_context_menu_action_ = 0; -+ } else { -+ SendMenuReply(PP_ERROR_USERCANCEL, -1); -+ } -+ -+ showing_context_menu_ = false; -+ context_menu_request_id_ = 0; -+} -+ -+void PepperFlashMenuHost::SendMenuReply(int32_t result, int action) { -+ ppapi::host::ReplyMessageContext reply_context( -+ ppapi::proxy::ResourceMessageReplyParams(pp_resource(), 0), NULL, -+ MSG_ROUTING_NONE); -+ reply_context.params.set_result(result); -+ host()->SendReply(reply_context, PpapiPluginMsg_FlashMenu_ShowReply(action)); -+} -added in remote - their 100644 a2b4f9cb40098aa65bd8c15759dbbfbcc4fa6674 chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.h -@@ -0,0 +1,69 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef CHROME_RENDERER_PEPPER_PEPPER_FLASH_MENU_HOST_H_ -+#define CHROME_RENDERER_PEPPER_PEPPER_FLASH_MENU_HOST_H_ -+ -+#include <vector> -+ -+#include "base/compiler_specific.h" -+#include "content/public/renderer/context_menu_client.h" -+#include "ppapi/c/pp_point.h" -+#include "ppapi/host/host_message_context.h" -+#include "ppapi/host/resource_host.h" -+ -+namespace content { -+class RendererPpapiHost; -+struct MenuItem; -+} // namespace content -+ -+namespace ppapi { -+namespace proxy { -+class SerializedFlashMenu; -+} -+} // namespace ppapi -+ -+class PepperFlashMenuHost : public ppapi::host::ResourceHost, -+ public content::ContextMenuClient { -+ public: -+ PepperFlashMenuHost(content::RendererPpapiHost* host, -+ PP_Instance instance, -+ PP_Resource resource, -+ const ppapi::proxy::SerializedFlashMenu& serial_menu); -+ ~PepperFlashMenuHost() override; -+ -+ int32_t OnResourceMessageReceived( -+ const IPC::Message& msg, -+ ppapi::host::HostMessageContext* context) override; -+ -+ private: -+ int32_t OnHostMsgShow(ppapi::host::HostMessageContext* context, -+ const PP_Point& location); -+ -+ // ContextMenuClient implementation. -+ void OnMenuAction(int request_id, unsigned action) override; -+ void OnMenuClosed(int request_id) override; -+ -+ void SendMenuReply(int32_t result, int action); -+ -+ content::RendererPpapiHost* renderer_ppapi_host_; -+ -+ bool showing_context_menu_; -+ int context_menu_request_id_; -+ -+ std::vector<content::MenuItem> menu_data_; -+ -+ // We send |MenuItem|s, which have an |unsigned| "action" field instead of -+ // an |int32_t| ID. (CONTENT also limits the range of valid values for -+ // actions.) This maps actions to IDs. -+ std::vector<int32_t> menu_id_map_; -+ -+ // Used to send a single context menu "completion" upon menu close. -+ bool has_saved_context_menu_action_; -+ unsigned saved_context_menu_action_; -+ -+ DISALLOW_COPY_AND_ASSIGN(PepperFlashMenuHost); -+}; -+ -+#endif // CHROME_RENDERER_PEPPER_PEPPER_FLASH_MENU_HOST_H_ -added in remote - their 100644 50015122ccc7e2da02d0e9b2c7014e085c3ffec4 chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.cc -@@ -0,0 +1,370 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "chrome/renderer/pepper/pepper_flash_renderer_host.h" -+ -+#include <map> -+#include <vector> -+ -+#include "base/lazy_instance.h" -+#include "base/macros.h" -+#include "base/metrics/histogram_macros.h" -+#include "base/strings/string_util.h" -+#include "content/public/renderer/pepper_plugin_instance.h" -+#include "content/public/renderer/render_thread.h" -+#include "content/public/renderer/renderer_ppapi_host.h" -+#include "ipc/ipc_message_macros.h" -+#include "net/http/http_util.h" -+#include "ppapi/c/pp_errors.h" -+#include "ppapi/c/trusted/ppb_browser_font_trusted.h" -+#include "ppapi/host/dispatch_host_message.h" -+#include "ppapi/proxy/host_dispatcher.h" -+#include "ppapi/proxy/ppapi_messages.h" -+#include "ppapi/proxy/resource_message_params.h" -+#include "ppapi/proxy/serialized_structs.h" -+#include "ppapi/thunk/enter.h" -+#include "ppapi/thunk/ppb_image_data_api.h" -+#include "skia/ext/platform_canvas.h" -+#include "third_party/skia/include/core/SkCanvas.h" -+#include "third_party/skia/include/core/SkFontStyle.h" -+#include "third_party/skia/include/core/SkMatrix.h" -+#include "third_party/skia/include/core/SkPaint.h" -+#include "third_party/skia/include/core/SkPoint.h" -+#include "third_party/skia/include/core/SkTypeface.h" -+#include "ui/gfx/geometry/rect.h" -+#include "url/gurl.h" -+ -+using ppapi::thunk::EnterResourceNoLock; -+using ppapi::thunk::PPB_ImageData_API; -+ -+namespace { -+ -+// Some non-simple HTTP request headers that Flash may set. -+// (Please see http://www.w3.org/TR/cors/#simple-header for the definition of -+// simple headers.) -+// -+// The list and the enum defined below are used to collect data about request -+// headers used in PPB_Flash.Navigate() calls, in order to understand the impact -+// of rejecting PPB_Flash.Navigate() requests with non-simple headers. -+// -+// TODO(yzshen): We should be able to remove the histogram recording code once -+// we get the answer. -+const char* const kRejectedHttpRequestHeaders[] = { -+ "authorization", // -+ "cache-control", // -+ "content-encoding", // -+ "content-md5", // -+ "content-type", // If the media type is not one of those covered by the -+ // simple header definition. -+ "expires", // -+ "from", // -+ "if-match", // -+ "if-none-match", // -+ "if-range", // -+ "if-unmodified-since", // -+ "pragma", // -+ "referer" // -+}; -+ -+// Please note that new entries should be added right above -+// FLASH_NAVIGATE_USAGE_ENUM_COUNT, and existing entries shouldn't be re-ordered -+// or removed, since this ordering is used in a histogram. -+enum FlashNavigateUsage { -+ // This section must be in the same order as kRejectedHttpRequestHeaders. -+ REJECT_AUTHORIZATION = 0, -+ REJECT_CACHE_CONTROL, -+ REJECT_CONTENT_ENCODING, -+ REJECT_CONTENT_MD5, -+ REJECT_CONTENT_TYPE, -+ REJECT_EXPIRES, -+ REJECT_FROM, -+ REJECT_IF_MATCH, -+ REJECT_IF_NONE_MATCH, -+ REJECT_IF_RANGE, -+ REJECT_IF_UNMODIFIED_SINCE, -+ REJECT_PRAGMA, -+ REJECT_REFERER, -+ -+ // The navigate request is rejected because of headers not listed above -+ // (e.g., custom headers). -+ REJECT_OTHER_HEADERS, -+ -+ // Total number of rejected navigate requests. -+ TOTAL_REJECTED_NAVIGATE_REQUESTS, -+ -+ // Total number of navigate requests. -+ TOTAL_NAVIGATE_REQUESTS, -+ FLASH_NAVIGATE_USAGE_ENUM_COUNT -+}; -+ -+static base::LazyInstance<std::map<std::string, FlashNavigateUsage>>:: -+ DestructorAtExit g_rejected_headers = LAZY_INSTANCE_INITIALIZER; -+ -+bool IsSimpleHeader(const std::string& lower_case_header_name, -+ const std::string& header_value) { -+ if (lower_case_header_name == "accept" || -+ lower_case_header_name == "accept-language" || -+ lower_case_header_name == "content-language") { -+ return true; -+ } -+ -+ if (lower_case_header_name == "content-type") { -+ std::string lower_case_mime_type; -+ std::string lower_case_charset; -+ bool had_charset = false; -+ net::HttpUtil::ParseContentType(header_value, &lower_case_mime_type, -+ &lower_case_charset, &had_charset, NULL); -+ return lower_case_mime_type == "application/x-www-form-urlencoded" || -+ lower_case_mime_type == "multipart/form-data" || -+ lower_case_mime_type == "text/plain"; -+ } -+ -+ return false; -+} -+ -+void RecordFlashNavigateUsage(FlashNavigateUsage usage) { -+ DCHECK_NE(FLASH_NAVIGATE_USAGE_ENUM_COUNT, usage); -+ UMA_HISTOGRAM_ENUMERATION("Plugin.FlashNavigateUsage", usage, -+ FLASH_NAVIGATE_USAGE_ENUM_COUNT); -+} -+ -+} // namespace -+ -+PepperFlashRendererHost::PepperFlashRendererHost( -+ content::RendererPpapiHost* host, -+ PP_Instance instance, -+ PP_Resource resource) -+ : ResourceHost(host->GetPpapiHost(), instance, resource), -+ host_(host), -+ weak_factory_(this) {} -+ -+PepperFlashRendererHost::~PepperFlashRendererHost() { -+ // This object may be destroyed in the middle of a sync message. If that is -+ // the case, make sure we respond to all the pending navigate calls. -+ std::vector<ppapi::host::ReplyMessageContext>::reverse_iterator it; -+ for (it = navigate_replies_.rbegin(); it != navigate_replies_.rend(); ++it) -+ SendReply(*it, IPC::Message()); -+} -+ -+int32_t PepperFlashRendererHost::OnResourceMessageReceived( -+ const IPC::Message& msg, -+ ppapi::host::HostMessageContext* context) { -+ PPAPI_BEGIN_MESSAGE_MAP(PepperFlashRendererHost, msg) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_GetProxyForURL, -+ OnGetProxyForURL) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_SetInstanceAlwaysOnTop, -+ OnSetInstanceAlwaysOnTop) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_DrawGlyphs, -+ OnDrawGlyphs) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_Navigate, OnNavigate) -+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_IsRectTopmost, -+ OnIsRectTopmost) -+ PPAPI_END_MESSAGE_MAP() -+ return PP_ERROR_FAILED; -+} -+ -+int32_t PepperFlashRendererHost::OnGetProxyForURL( -+ ppapi::host::HostMessageContext* host_context, -+ const std::string& url) { -+ GURL gurl(url); -+ if (!gurl.is_valid()) -+ return PP_ERROR_FAILED; -+ std::string proxy; -+ bool result = content::RenderThread::Get()->ResolveProxy(gurl, &proxy); -+ if (!result) -+ return PP_ERROR_FAILED; -+ host_context->reply_msg = PpapiPluginMsg_Flash_GetProxyForURLReply(proxy); -+ return PP_OK; -+} -+ -+int32_t PepperFlashRendererHost::OnSetInstanceAlwaysOnTop( -+ ppapi::host::HostMessageContext* host_context, -+ bool on_top) { -+ content::PepperPluginInstance* plugin_instance = -+ host_->GetPluginInstance(pp_instance()); -+ if (plugin_instance) -+ plugin_instance->SetAlwaysOnTop(on_top); -+ // Since no reply is sent for this message, it doesn't make sense to return an -+ // error. -+ return PP_OK; -+} -+ -+int32_t PepperFlashRendererHost::OnDrawGlyphs( -+ ppapi::host::HostMessageContext* host_context, -+ ppapi::proxy::PPBFlash_DrawGlyphs_Params params) { -+ return PP_ERROR_FAILED; -+ // if (params.glyph_indices.size() != params.glyph_advances.size() || -+ // params.glyph_indices.empty()) -+ // return PP_ERROR_FAILED; -+ // -+ // // Set up the typeface. -+ // int weight = (params.font_desc.weight + 1) * 100; -+ // SkFontStyle::Slant slant = SkFontStyle::kUpright_Slant; -+ // if (params.font_desc.italic) -+ // slant = SkFontStyle::kItalic_Slant; -+ // SkFontStyle style(weight, SkFontStyle::kNormal_Width, slant); -+ // sk_sp<SkTypeface> typeface( -+ // SkTypeface::MakeFromName(params.font_desc.face.c_str(), style)); -+ // if (!typeface) -+ // return PP_ERROR_FAILED; -+ // -+ // EnterResourceNoLock<PPB_ImageData_API> enter( -+ // params.image_data.host_resource(), true); -+ // if (enter.failed()) -+ // return PP_ERROR_FAILED; -+ // -+ // // Set up the canvas. -+ // PPB_ImageData_API* image = static_cast<PPB_ImageData_API*>(enter.object()); -+ // SkCanvas* canvas = image->GetCanvas(); -+ // bool needs_unmapping = false; -+ // if (!canvas) { -+ // needs_unmapping = true; -+ // image->Map(); -+ // canvas = image->GetCanvas(); -+ // if (!canvas) -+ // return PP_ERROR_FAILED; // Failure mapping. -+ // } -+ // -+ // SkAutoCanvasRestore acr(canvas, true); -+ // -+ // // Clip is applied in pixels before the transform. -+ // SkRect clip_rect = { -+ // SkIntToScalar(params.clip.point.x), SkIntToScalar(params.clip.point.y), -+ // SkIntToScalar(params.clip.point.x + params.clip.size.width), -+ // SkIntToScalar(params.clip.point.y + params.clip.size.height)}; -+ // canvas->clipRect(clip_rect); -+ // -+ // // Convert & set the matrix. -+ // SkMatrix matrix; -+ // matrix.set(SkMatrix::kMScaleX, SkFloatToScalar(params.transformation[0][0])); -+ // matrix.set(SkMatrix::kMSkewX, SkFloatToScalar(params.transformation[0][1])); -+ // matrix.set(SkMatrix::kMTransX, SkFloatToScalar(params.transformation[0][2])); -+ // matrix.set(SkMatrix::kMSkewY, SkFloatToScalar(params.transformation[1][0])); -+ // matrix.set(SkMatrix::kMScaleY, SkFloatToScalar(params.transformation[1][1])); -+ // matrix.set(SkMatrix::kMTransY, SkFloatToScalar(params.transformation[1][2])); -+ // matrix.set(SkMatrix::kMPersp0, SkFloatToScalar(params.transformation[2][0])); -+ // matrix.set(SkMatrix::kMPersp1, SkFloatToScalar(params.transformation[2][1])); -+ // matrix.set(SkMatrix::kMPersp2, SkFloatToScalar(params.transformation[2][2])); -+ // canvas->concat(matrix); -+ // -+ // SkPaint paint; -+ // paint.setColor(params.color); -+ // paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); -+ // paint.setAntiAlias(true); -+ // paint.setHinting(SkPaint::kFull_Hinting); -+ // paint.setTextSize(SkIntToScalar(params.font_desc.size)); -+ // paint.setTypeface(std::move(typeface)); -+ // if (params.allow_subpixel_aa) { -+ // paint.setSubpixelText(true); -+ // paint.setLCDRenderText(true); -+ // } -+ // -+ // SkScalar x = SkIntToScalar(params.position.x); -+ // SkScalar y = SkIntToScalar(params.position.y); -+ // -+ // // Build up the skia advances. -+ // size_t glyph_count = params.glyph_indices.size(); -+ // if (glyph_count) { -+ // std::vector<SkPoint> storage; -+ // storage.resize(glyph_count); -+ // SkPoint* sk_positions = &storage[0]; -+ // for (uint32_t i = 0; i < glyph_count; i++) { -+ // sk_positions[i].set(x, y); -+ // x += SkFloatToScalar(params.glyph_advances[i].x); -+ // y += SkFloatToScalar(params.glyph_advances[i].y); -+ // } -+ // -+ // canvas->drawPosText(¶ms.glyph_indices[0], glyph_count * 2, sk_positions, -+ // paint); -+ // } -+ // -+ // if (needs_unmapping) -+ // image->Unmap(); -+ // -+ // return PP_OK; -+} -+ -+// CAUTION: This code is subtle because Navigate is a sync call which may -+// cause re-entrancy or cause the instance to be destroyed. If the instance -+// is destroyed we need to ensure that we respond to all outstanding sync -+// messages so that the plugin process does not remain blocked. -+int32_t PepperFlashRendererHost::OnNavigate( -+ ppapi::host::HostMessageContext* host_context, -+ const ppapi::URLRequestInfoData& data, -+ const std::string& target, -+ bool from_user_action) { -+ // If our PepperPluginInstance is already destroyed, just return a failure. -+ content::PepperPluginInstance* plugin_instance = -+ host_->GetPluginInstance(pp_instance()); -+ if (!plugin_instance) -+ return PP_ERROR_FAILED; -+ -+ std::map<std::string, FlashNavigateUsage>& rejected_headers = -+ g_rejected_headers.Get(); -+ if (rejected_headers.empty()) { -+ for (size_t i = 0; i < arraysize(kRejectedHttpRequestHeaders); ++i) -+ rejected_headers[kRejectedHttpRequestHeaders[i]] = -+ static_cast<FlashNavigateUsage>(i); -+ } -+ -+ net::HttpUtil::HeadersIterator header_iter(data.headers.begin(), -+ data.headers.end(), "\n\r"); -+ bool rejected = false; -+ while (header_iter.GetNext()) { -+ std::string lower_case_header_name = base::ToLowerASCII(header_iter.name()); -+ if (!IsSimpleHeader(lower_case_header_name, header_iter.values())) { -+ rejected = true; -+ -+ std::map<std::string, FlashNavigateUsage>::const_iterator iter = -+ rejected_headers.find(lower_case_header_name); -+ FlashNavigateUsage usage = -+ iter != rejected_headers.end() ? iter->second : REJECT_OTHER_HEADERS; -+ RecordFlashNavigateUsage(usage); -+ } -+ } -+ -+ RecordFlashNavigateUsage(TOTAL_NAVIGATE_REQUESTS); -+ if (rejected) { -+ RecordFlashNavigateUsage(TOTAL_REJECTED_NAVIGATE_REQUESTS); -+ return PP_ERROR_NOACCESS; -+ } -+ -+ // Navigate may call into Javascript (e.g. with a "javascript:" URL), -+ // or do things like navigate away from the page, either one of which will -+ // need to re-enter into the plugin. It is safe, because it is essentially -+ // equivalent to NPN_GetURL, where Flash would expect re-entrancy. -+ ppapi::proxy::HostDispatcher* host_dispatcher = -+ ppapi::proxy::HostDispatcher::GetForInstance(pp_instance()); -+ host_dispatcher->set_allow_plugin_reentrancy(); -+ -+ // Grab a weak pointer to ourselves on the stack so we can check if we are -+ // still alive. -+ base::WeakPtr<PepperFlashRendererHost> weak_ptr = weak_factory_.GetWeakPtr(); -+ // Keep track of reply contexts in case we are destroyed during a Navigate -+ // call. Even if we are destroyed, we still need to send these replies to -+ // unblock the plugin process. -+ navigate_replies_.push_back(host_context->MakeReplyMessageContext()); -+ plugin_instance->Navigate(data, target.c_str(), from_user_action); -+ // This object might have been destroyed by this point. If it is destroyed -+ // the reply will be sent in the destructor. Otherwise send the reply here. -+ if (weak_ptr.get()) { -+ SendReply(navigate_replies_.back(), IPC::Message()); -+ navigate_replies_.pop_back(); -+ } -+ -+ // Return PP_OK_COMPLETIONPENDING so that no reply is automatically sent. -+ return PP_OK_COMPLETIONPENDING; -+} -+ -+int32_t PepperFlashRendererHost::OnIsRectTopmost( -+ ppapi::host::HostMessageContext* host_context, -+ const PP_Rect& rect) { -+ content::PepperPluginInstance* plugin_instance = -+ host_->GetPluginInstance(pp_instance()); -+ if (plugin_instance && -+ plugin_instance->IsRectTopmost(gfx::Rect( -+ rect.point.x, rect.point.y, rect.size.width, rect.size.height))) -+ return PP_OK; -+ return PP_ERROR_FAILED; -+} -added in remote - their 100644 b080f1d9fbf0db2e6adaf67dd783b05eeb9d06a0 chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.h -@@ -0,0 +1,68 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef CHROME_RENDERER_PEPPER_PEPPER_FLASH_RENDERER_HOST_H_ -+#define CHROME_RENDERER_PEPPER_PEPPER_FLASH_RENDERER_HOST_H_ -+ -+#include <string> -+#include <vector> -+ -+#include "base/memory/weak_ptr.h" -+#include "ppapi/host/host_message_context.h" -+#include "ppapi/host/resource_host.h" -+ -+struct PP_Rect; -+ -+namespace ppapi { -+struct URLRequestInfoData; -+} -+ -+namespace ppapi { -+namespace proxy { -+struct PPBFlash_DrawGlyphs_Params; -+} -+} // namespace ppapi -+ -+namespace content { -+class RendererPpapiHost; -+} -+ -+class PepperFlashRendererHost : public ppapi::host::ResourceHost { -+ public: -+ PepperFlashRendererHost(content::RendererPpapiHost* host, -+ PP_Instance instance, -+ PP_Resource resource); -+ ~PepperFlashRendererHost() override; -+ -+ // ppapi::host::ResourceHost override. -+ int32_t OnResourceMessageReceived( -+ const IPC::Message& msg, -+ ppapi::host::HostMessageContext* context) override; -+ -+ private: -+ int32_t OnGetProxyForURL(ppapi::host::HostMessageContext* host_context, -+ const std::string& url); -+ int32_t OnSetInstanceAlwaysOnTop( -+ ppapi::host::HostMessageContext* host_context, -+ bool on_top); -+ int32_t OnDrawGlyphs(ppapi::host::HostMessageContext* host_context, -+ ppapi::proxy::PPBFlash_DrawGlyphs_Params params); -+ int32_t OnNavigate(ppapi::host::HostMessageContext* host_context, -+ const ppapi::URLRequestInfoData& data, -+ const std::string& target, -+ bool from_user_action); -+ int32_t OnIsRectTopmost(ppapi::host::HostMessageContext* host_context, -+ const PP_Rect& rect); -+ -+ // A stack of ReplyMessageContexts to track Navigate() calls which have not -+ // yet been replied to. -+ std::vector<ppapi::host::ReplyMessageContext> navigate_replies_; -+ -+ content::RendererPpapiHost* host_; -+ base::WeakPtrFactory<PepperFlashRendererHost> weak_factory_; -+ -+ DISALLOW_COPY_AND_ASSIGN(PepperFlashRendererHost); -+}; -+ -+#endif // CHROME_RENDERER_PEPPER_PEPPER_FLASH_RENDERER_HOST_H_ -added in remote - their 100644 eef18560f9e577a77f8dc4eba64bf5907f77a0e2 chromium_src/chrome/renderer/pepper/pepper_helper.cc -@@ -0,0 +1,30 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "chrome/renderer/pepper/pepper_helper.h" -+ -+#include "chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h" -+#include "chrome/renderer/pepper/pepper_shared_memory_message_filter.h" -+#include "content/public/renderer/renderer_ppapi_host.h" -+#include "ppapi/host/ppapi_host.h" -+ -+PepperHelper::PepperHelper(content::RenderFrame* render_frame) -+ : RenderFrameObserver(render_frame) {} -+ -+PepperHelper::~PepperHelper() {} -+ -+void PepperHelper::DidCreatePepperPlugin(content::RendererPpapiHost* host) { -+ // TODO(brettw) figure out how to hook up the host factory. It needs some -+ // kind of filter-like system to allow dynamic additions. -+ host->GetPpapiHost()->AddHostFactoryFilter( -+ std::unique_ptr<ppapi::host::HostFactory>( -+ new ChromeRendererPepperHostFactory(host))); -+ host->GetPpapiHost()->AddInstanceMessageFilter( -+ std::unique_ptr<ppapi::host::InstanceMessageFilter>( -+ new PepperSharedMemoryMessageFilter(host))); -+} -+ -+void PepperHelper::OnDestruct() { -+ delete this; -+} -added in remote - their 100644 6157d2c794868d5d2b5f39ddd6f38cbce72a0a9f chromium_src/chrome/renderer/pepper/pepper_helper.h -@@ -0,0 +1,26 @@ -+// Copyright (c) 2012 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef CHROME_RENDERER_PEPPER_PEPPER_HELPER_H_ -+#define CHROME_RENDERER_PEPPER_PEPPER_HELPER_H_ -+ -+#include "base/compiler_specific.h" -+#include "content/public/renderer/render_frame_observer.h" -+ -+// This class listens for Pepper creation events from the RenderFrame and -+// attaches the parts required for Chrome-specific plugin support. -+class PepperHelper : public content::RenderFrameObserver { -+ public: -+ explicit PepperHelper(content::RenderFrame* render_frame); -+ ~PepperHelper() override; -+ -+ // RenderFrameObserver. -+ void DidCreatePepperPlugin(content::RendererPpapiHost* host) override; -+ void OnDestruct() override; -+ -+ private: -+ DISALLOW_COPY_AND_ASSIGN(PepperHelper); -+}; -+ -+#endif // CHROME_RENDERER_PEPPER_PEPPER_HELPER_H_ -added in remote - their 100644 fb72c2da786b3cbcef7ce149f560821592df1747 chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.cc -@@ -0,0 +1,63 @@ -+// Copyright (c) 2013 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "chrome/renderer/pepper/pepper_shared_memory_message_filter.h" -+ -+#include <memory> -+ -+#include "base/memory/shared_memory.h" -+#include "base/process/process_handle.h" -+#include "content/public/common/content_client.h" -+#include "content/public/renderer/pepper_plugin_instance.h" -+#include "content/public/renderer/render_thread.h" -+#include "content/public/renderer/renderer_ppapi_host.h" -+#include "ppapi/host/ppapi_host.h" -+#include "ppapi/proxy/ppapi_messages.h" -+#include "ppapi/shared_impl/var_tracker.h" -+ -+PepperSharedMemoryMessageFilter::PepperSharedMemoryMessageFilter( -+ content::RendererPpapiHost* host) -+ : InstanceMessageFilter(host->GetPpapiHost()), host_(host) {} -+ -+PepperSharedMemoryMessageFilter::~PepperSharedMemoryMessageFilter() {} -+ -+bool PepperSharedMemoryMessageFilter::OnInstanceMessageReceived( -+ const IPC::Message& msg) { -+ bool handled = true; -+ IPC_BEGIN_MESSAGE_MAP(PepperSharedMemoryMessageFilter, msg) -+ IPC_MESSAGE_HANDLER(PpapiHostMsg_SharedMemory_CreateSharedMemory, -+ OnHostMsgCreateSharedMemory) -+ IPC_MESSAGE_UNHANDLED(handled = false) -+ IPC_END_MESSAGE_MAP() -+ return handled; -+} -+ -+bool PepperSharedMemoryMessageFilter::Send(IPC::Message* msg) { -+ return host_->GetPpapiHost()->Send(msg); -+} -+ -+void PepperSharedMemoryMessageFilter::OnHostMsgCreateSharedMemory( -+ PP_Instance instance, -+ uint32_t size, -+ int* host_handle_id, -+ ppapi::proxy::SerializedHandle* plugin_handle) { -+ plugin_handle->set_null_shmem(); -+ *host_handle_id = -1; -+ std::unique_ptr<base::SharedMemory> shm( -+ content::RenderThread::Get()->HostAllocateSharedMemoryBuffer(size)); -+ if (!shm.get()) -+ return; -+ -+ base::SharedMemoryHandle host_shm_handle = shm->handle().Duplicate(); -+ *host_handle_id = -+ content::PepperPluginInstance::Get(instance) -+ ->GetVarTracker() -+ ->TrackSharedMemoryHandle(instance, host_shm_handle, size); -+ -+ // We set auto_close to false since we need our file descriptor to -+ // actually be duplicated on linux. The shared memory destructor will -+ // close the original handle for us. -+ plugin_handle->set_shmem( -+ host_->ShareSharedMemoryHandleWithRemote(host_shm_handle), size); -+} -added in remote - their 100644 d1e2dc1719e501561941cafeab4fd95ef0779314 chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.h -@@ -0,0 +1,46 @@ -+// Copyright (c) 2013 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef CHROME_RENDERER_PEPPER_PEPPER_SHARED_MEMORY_MESSAGE_FILTER_H_ -+#define CHROME_RENDERER_PEPPER_PEPPER_SHARED_MEMORY_MESSAGE_FILTER_H_ -+ -+#include "ppapi/c/pp_instance.h" -+#include "ppapi/host/instance_message_filter.h" -+ -+namespace content { -+class RendererPpapiHost; -+} -+ -+namespace ppapi { -+namespace proxy { -+class SerializedHandle; -+} -+} // namespace ppapi -+ -+// Implements the backend for shared memory messages from a plugin process. -+class PepperSharedMemoryMessageFilter -+ : public ppapi::host::InstanceMessageFilter { -+ public: -+ explicit PepperSharedMemoryMessageFilter(content::RendererPpapiHost* host); -+ ~PepperSharedMemoryMessageFilter() override; -+ -+ // InstanceMessageFilter: -+ bool OnInstanceMessageReceived(const IPC::Message& msg) override; -+ -+ bool Send(IPC::Message* msg); -+ -+ private: -+ // Message handlers. -+ void OnHostMsgCreateSharedMemory( -+ PP_Instance instance, -+ uint32_t size, -+ int* host_shm_handle_id, -+ ppapi::proxy::SerializedHandle* plugin_shm_handle); -+ -+ content::RendererPpapiHost* host_; -+ -+ DISALLOW_COPY_AND_ASSIGN(PepperSharedMemoryMessageFilter); -+}; -+ -+#endif // CHROME_RENDERER_PEPPER_PEPPER_SHARED_MEMORY_MESSAGE_FILTER_H_ -added in both - our 100644 8744574f10aa0235234f87cd1b614572d9ba98e9 chromium_src/chrome/utility/printing_handler_win.h - their 100644 d058e7e505569126827ba24b3a42051ba386630c chromium_src/chrome/utility/printing_handler_win.h -@@ -13,7 +13,11 @@ - - namespace printing { - -+<<<<<<< .our - struct PdfRenderSettings; -+======= -+class PdfRenderSettings; -+>>>>>>> .their - struct PwgRasterSettings; - struct PageRange; - -added in both - our 100644 1b9da74e503ab4afa8d2c530cd45332f0868a463 default_app/default_app.js - their 100644 e6ba9eea2cb5938fe71ab7c18a47921d3959061e default_app/default_app.js -@@ -18,17 +18,24 @@ - webPreferences: { - nodeIntegrationInWorker: true - }, -+<<<<<<< .our - useContentSize: true, - show: false -+======= -+ useContentSize: true -+>>>>>>> .their - } - if (process.platform === 'linux') { - options.icon = path.join(__dirname, 'icon.png') - } - - mainWindow = new BrowserWindow(options) -+<<<<<<< .our - - mainWindow.on('ready-to-show', () => mainWindow.show()) - -+======= -+>>>>>>> .their - mainWindow.loadURL(appUrl) - mainWindow.focus() - }) -added in both - our 100644 fd4525f128b5f7718e03998a9d83ae79ff163078 default_app/index.html - their 100644 c8564cb57a11cbfea4bea37db09df4cd82dee4fb default_app/index.html -@@ -2,13 +2,174 @@ - - <head> - <title>Electron -+<<<<<<< .our - - - -+======= -+ -+>>>>>>> .their - - - -
-+<<<<<<< .our -+======= -+ -+>>>>>>> .their -
    -
  • -
  • -@@ -84,7 +245,13 @@ -
- - -+<<<<<<< .our - -+======= -+ -+>>>>>>> .their - - - -\ No newline at end of file -added in both - our 100644 0e93f684875ca8c4fd8c771c93dce9110de57c15 default_app/main.js - their 100644 7fdfc7c3fa3607f1cb664bf50a9b536abe5c40d5 default_app/main.js -@@ -320,7 +320,11 @@ - const file = option.file - const protocol = url.parse(file).protocol - const extension = path.extname(file) -+<<<<<<< .our - if (protocol === 'http:' || protocol === 'https:' || protocol === 'file:' || protocol === 'chrome:') { -+======= -+ if (protocol === 'http:' || protocol === 'https:' || protocol === 'file:') { -+>>>>>>> .their - loadApplicationByUrl(file) - } else if (extension === '.html' || extension === '.htm') { - loadApplicationByUrl('file://' + path.resolve(file)) -added in both - our 100644 977aad7ab9d4171d2ab86b599eee1e39b4b82041 default_app/renderer.js - their 100644 92e5530ada1aa971e28b276164e1a8885bce9f45 default_app/renderer.js -@@ -1,5 +1,8 @@ - const {remote, shell} = require('electron') -+<<<<<<< .our - const fs = require('fs') -+======= -+>>>>>>> .their - const path = require('path') - const URL = require('url') - const electronPath = path.relative(process.cwd(), remote.process.execPath) -@@ -21,6 +24,7 @@ - document.querySelector('.node-version').innerText = `Node v${process.versions.node}` - document.querySelector('.v8-version').innerText = `v8 v${process.versions.v8}` - document.querySelector('.command-example').innerText = `${electronPath} path-to-app` -+<<<<<<< .our - - function getOcticonSvg (name) { - const octiconPath = path.resolve(__dirname, 'node_modules', 'octicons', 'build', 'svg', `${name}.svg`) -@@ -50,3 +54,5 @@ - for (const element of document.querySelectorAll('.octicon')) { - loadSVG(element) - } -+======= -+>>>>>>> .their -added in both - our 100644 14dc557e237404cbbd5bcebabb0e65486dc36926 docs/api/app.md - their 100644 740da22d82ee5662e5bb994fa8e1c2eadb907a5e docs/api/app.md -@@ -881,7 +881,11 @@ - - Imports the certificate in pkcs12 format into the platform certificate store. - `callback` is called with the `result` of import operation, a value of `0` -+<<<<<<< .our - indicates success while any other value indicates failure according to Chromium [net_error_list](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h). -+======= -+indicates success while any other value indicates failure according to chromium [net_error_list](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h). -+>>>>>>> .their - - ### `app.disableHardwareAcceleration()` - -@@ -1033,7 +1037,11 @@ - stopAccessingSecurityScopedResource() - ``` - -+<<<<<<< .our - Start accessing a security scoped resource. With this method Electron applications that are packaged for the Mac App Store may reach outside their sandbox to access files chosen by the user. See [Apple's documentation](https://developer.apple.com/library/content/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW16) for a description of how this system works. -+======= -+Start accessing a security scoped resource. With this method electron applications that are packaged for the Mac App Store may reach outside their sandbox to access files chosen by the user. See [Apple's documentation](https://developer.apple.com/library/content/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW16) for a description of how this system works. -+>>>>>>> .their - - ### `app.commandLine.appendSwitch(switch[, value])` - -added in both - our 100644 7f840f07102aae0f0308742e66692345a84cb84b docs/api/auto-updater.md - their 100644 bb181347a0ae9c4f78c48f4932c569db9f2627b5 docs/api/auto-updater.md -@@ -84,9 +84,12 @@ - - On Windows only `releaseName` is available. - -+<<<<<<< .our - **Note:** It is not strictly necessary to handle this event. A successfully - downloaded update will still be applied the next time the application starts. - -+======= -+>>>>>>> .their - ### Event: 'before-quit-for-update' - - This event is emitted after a user calls `quitAndInstall()`. -@@ -125,9 +128,15 @@ - windows first, and automatically call `app.quit()` after all windows have been - closed. - -+<<<<<<< .our - **Note:** It is not strictly necessary to call this function to apply an update, - as a successfully downloaded update will always be applied the next time the - application starts. -+======= -+**Note:** If the application is quit without calling this API after the -+`update-downloaded` event has been emitted, the application will still be -+replaced by the updated one on the next run. -+>>>>>>> .their - - [squirrel-mac]: https://github.com/Squirrel/Squirrel.Mac - [server-support]: https://github.com/Squirrel/Squirrel.Mac#server-support -added in both - our 100644 dff61dd336f047cf2f6f06228b2df2b98ff2304d docs/api/browser-window.md - their 100644 16657f6d55f05711ade1b726966b1889ca96403b docs/api/browser-window.md -@@ -305,6 +305,11 @@ - * `plugins` Boolean (optional) - Whether plugins should be enabled. Default is `false`. - * `experimentalFeatures` Boolean (optional) - Enables Chromium's experimental features. - Default is `false`. -+<<<<<<< .our -+======= -+ * `experimentalCanvasFeatures` Boolean (optional) - Enables Chromium's experimental -+ canvas features. Default is `false`. -+>>>>>>> .their - * `scrollBounce` Boolean (optional) - Enables scroll bounce (rubber banding) effect on - macOS. Default is `false`. - * `enableBlinkFeatures` String (optional) - A list of feature strings separated by `,`, like -@@ -490,6 +495,7 @@ - - Emitted when the window is restored from a minimized state. - -+<<<<<<< .our - #### Event: 'will-resize' _macOS_ _Windows_ - - Returns: -@@ -504,6 +510,11 @@ - #### Event: 'resize' - - Emitted after the window has been resized. -+======= -+#### Event: 'resize' -+ -+Emitted when the window is being resized. -+>>>>>>> .their - - #### Event: 'move' - -@@ -1273,6 +1284,7 @@ - - Returns `Number` - between 0.0 (fully transparent) and 1.0 (fully opaque) - -+<<<<<<< .our - #### `win.setShape(rects)` _Windows_ _Linux_ _Experimental_ - - * `rects` [Rectangle[]](structures/rectangle.md) - Sets a shape on the window. -@@ -1284,6 +1296,8 @@ - the region will not be received by that window, but will fall through to - whatever is behind the window. - -+======= -+>>>>>>> .their - #### `win.setThumbarButtons(buttons)` _Windows_ - - * `buttons` [ThumbarButton[]](structures/thumbar-button.md) -@@ -1364,6 +1378,7 @@ - - Changes window icon. - -+<<<<<<< .our - #### `win.setWindowButtonVisibility(visible)` _macOS_ - - * `visible` Boolean -@@ -1372,6 +1387,8 @@ - - This cannot be called when `titleBarStyle` is set to `customButtonsOnHover`. - -+======= -+>>>>>>> .their - #### `win.setAutoHideMenuBar(hide)` - - * `hide` Boolean -added in both - our 100644 b2b28f5adb7de78a0d945e0ed1ee196d6aa45fd1 docs/api/chrome-command-line-switches.md - their 100644 132eddfdeb74b007958793ca62a033ecbf8d486d docs/api/chrome-command-line-switches.md -@@ -60,8 +60,12 @@ - Use a specified proxy server, which overrides the system setting. This switch - only affects requests with HTTP protocol, including HTTPS and WebSocket - requests. It is also noteworthy that not all proxy servers support HTTPS and -+<<<<<<< .our - WebSocket requests. The proxy URL does not support username and password - authentication [per Chromium issue](https://bugs.chromium.org/p/chromium/issues/detail?id=615947). -+======= -+WebSocket requests. -+>>>>>>> .their - - ## --proxy-bypass-list=`hosts` - -added in both - our 100644 586c17e37ac1afaf7aaac3b213434ab4ecbb1ca2 docs/api/client-request.md - their 100644 5cd9562b654a2e8d4483d25254bb2ae72ec5b7bc docs/api/client-request.md -@@ -215,6 +215,7 @@ - #### `request.followRedirect()` - - Continues any deferred redirection request when the redirection mode is `manual`. -+<<<<<<< .our - - #### `request.getUploadProgress()` - -@@ -229,3 +230,5 @@ - - You can use this method in conjunction with `POST` requests to get the progress - of a file upload or other data transfer. -+======= -+>>>>>>> .their -added in both - our 100644 80d266ab56382901e7745067488d3d316c172294 docs/api/crash-reporter.md - their 100644 d8f9f060241760ac723f7202d11edf2b93c04272 docs/api/crash-reporter.md -@@ -42,7 +42,11 @@ - ### `crashReporter.start(options)` - - * `options` Object -+<<<<<<< .our - * `companyName` String -+======= -+ * `companyName` String (optional) -+>>>>>>> .their - * `submitURL` String - URL that crash reports will be sent to as POST. - * `productName` String (optional) - Defaults to `app.getName()`. - * `uploadToServer` Boolean (optional) - Whether crash reports should be sent to the server -added in both - our 100644 11101ae3ec01954b61266051ee74078ebfe8b299 docs/api/dialog.md - their 100644 a69cba8b969eeb8c7f06b9d246981d9291dae0ed docs/api/dialog.md -@@ -141,7 +141,11 @@ - * `cancelId` Integer (optional) - The index of the button to be used to cancel the dialog, via - the `Esc` key. By default this is assigned to the first button with "cancel" or "no" as the - label. If no such labeled buttons exist and this option is not set, `0` will be used as the -+<<<<<<< .our - return value or callback response. -+======= -+ return value or callback response. This option is ignored on Windows. -+>>>>>>> .their - * `noLink` Boolean (optional) - On Windows Electron will try to figure out which one of - the `buttons` are common buttons (like "Cancel" or "Yes"), and show the - others as command links in the dialog. This can make the dialog appear in -added in both - our 100644 ae04a286821de314680b67c9a666e6d2a0f42db0 docs/api/menu-item.md - their 100644 f687e43dbc9f5fa925a06ceeaa67bf503fff5c37 docs/api/menu-item.md -@@ -47,9 +47,12 @@ - The `label` and `accelerator` values are optional when using a `role` and will - default to appropriate values for each platform. - -+<<<<<<< .our - Every menu item must have either a `role`, `label`, or in the case of a separator - a `type`. - -+======= -+>>>>>>> .their - The `role` property can have following values: - - * `undo` -@@ -62,11 +65,19 @@ - * `delete` - * `minimize` - Minimize current window. - * `close` - Close current window. -+<<<<<<< .our - * `quit` - Quit the application. - * `reload` - Reload the current window. - * `forceReload` - Reload the current window ignoring the cache. - * `toggleDevTools` - Toggle developer tools in the current window. - * `toggleFullScreen` - Toggle full screen mode on the current window. -+======= -+* `quit`- Quit the application. -+* `reload` - Reload the current window. -+* `forceReload` - Reload the current window ignoring the cache. -+* `toggleDevTools` - Toggle developer tools in the current window. -+* `toggleFullScreen`- Toggle full screen mode on the current window. -+>>>>>>> .their - * `resetZoom` - Reset the focused page's zoom level to the original size. - * `zoomIn` - Zoom in the focused page by 10%. - * `zoomOut` - Zoom out the focused page by 10%. -added in both - our 100644 e1d6e9958de7f2b95129c9c7e69f0941e466e3e8 docs/api/menu.md - their 100644 339a9ef7986b545829195d5e5600a678849f3782 docs/api/menu.md -@@ -61,7 +61,11 @@ - - #### `menu.popup(options)` - -+<<<<<<< .our - * `options` Object (optional) -+======= -+* `options` Object -+>>>>>>> .their - * `window` [BrowserWindow](browser-window.md) (optional) - Default is the focused window. - * `x` Number (optional) - Default is the current mouse cursor position. - Must be declared if `y` is declared. -added in both - our 100644 1f6b20d2f25c31b48fbb2bfedc6a064ae283424f docs/api/process.md - their 100644 e6b34290b92c071ee8e7d4f9aa45ce04fb916ec9 docs/api/process.md -@@ -16,6 +16,7 @@ - - `getHeapStatistics()` - - `getProcessMemoryInfo()` - - `getSystemMemoryInfo()` -+<<<<<<< .our - - `getCPUUsage()` - - `getIOCounters()` - - `argv` -@@ -29,6 +30,12 @@ - - `type` - - `version` - - `versions` -+======= -+- `argv` -+- `execPath` -+- `env` -+- `platform` -+>>>>>>> .their - - ## Events - -@@ -77,11 +84,14 @@ - - A `String` representing the path to the resources directory. - -+<<<<<<< .our - ### `process.sandboxed` - - A `Boolean`. When the renderer process is sandboxed, this property is `true`, - otherwise it is `undefined`. - -+======= -+>>>>>>> .their - ### `process.throwDeprecation` - - A `Boolean` that controls whether or not deprecation warnings will be thrown as -@@ -125,6 +135,7 @@ - - Causes the main thread of the current process crash. - -+<<<<<<< .our - ### `process.getCreationTime()` - - Returns `Number | null` - The number of milliseconds since epoch, or `null` if the information is unavailable -@@ -132,6 +143,8 @@ - Indicates the creation time of the application. - The time is represented as number of milliseconds since epoch. It returns null if it is unable to get the process creation time. - -+======= -+>>>>>>> .their - ### `process.getCPUUsage()` - - Returns [`CPUUsage`](structures/cpu-usage.md) -added in both - our 100644 8a9d242fce0e5b35af4d2a45dfe30153d73a0532 docs/api/sandbox-option.md - their 100644 4923f93bbe6d47c86e9c2c5a273c4c469d3a1fa7 docs/api/sandbox-option.md -@@ -2,7 +2,11 @@ - - > Create a browser window with a renderer that can run inside Chromium OS sandbox. With this - option enabled, the renderer must communicate via IPC to the main process in order to access node APIs. -+<<<<<<< .our - However, in order to enable the Chromium OS sandbox, Electron must be run with the `--enable-sandbox` -+======= -+However, in order to enable the Chromium OS sandbox, electron must be run with the `--enable-sandbox` -+>>>>>>> .their - command line argument. - - One of the key security features of Chromium is that all blink rendering/JavaScript -@@ -14,14 +18,22 @@ - [Here's](https://www.chromium.org/developers/design-documents/sandbox) more - information about the sandbox. - -+<<<<<<< .our - Since a major feature in Electron is the ability to run Node.js in the - renderer process (making it easier to develop desktop applications using web - technologies), the sandbox is disabled by electron. This is because - most Node.js APIs require system access. `require()` for example, is not -+======= -+Since a major feature in electron is the ability to run node.js in the -+renderer process (making it easier to develop desktop applications using web -+technologies), the sandbox is disabled by electron. This is because -+most node.js APIs require system access. `require()` for example, is not -+>>>>>>> .their - possible without file system permissions, which are not available in a sandboxed - environment. - - Usually this is not a problem for desktop applications since the code is always -+<<<<<<< .our - trusted, but it makes Electron less secure than Chromium for displaying - untrusted web content. For applications that require more security, the - `sandbox` flag will force Electron to spawn a classic Chromium renderer that is -@@ -34,6 +46,20 @@ - Another difference is that sandboxed renderers don't modify any of the default - JavaScript APIs. Consequently, some APIs such as `window.open` will work as they - do in Chromium (i.e. they do not return a [`BrowserWindowProxy`](browser-window-proxy.md)). -+======= -+trusted, but it makes electron less secure than chromium for displaying -+untrusted web content. For applications that require more security, the -+`sandbox` flag will force electron to spawn a classic chromium renderer that is -+compatible with the sandbox. -+ -+A sandboxed renderer doesn't have a node.js environment running and doesn't -+expose node.js JavaScript APIs to client code. The only exception is the preload script, -+which has access to a subset of the electron renderer API. -+ -+Another difference is that sandboxed renderers don't modify any of the default -+JavaScript APIs. Consequently, some APIs such as `window.open` will work as they -+do in chromium (i.e. they do not return a [`BrowserWindowProxy`](browser-window-proxy.md)). -+>>>>>>> .their - - ## Example - -@@ -51,9 +77,15 @@ - }) - ``` - -+<<<<<<< .our - In the above code the [`BrowserWindow`](browser-window.md) that was created has Node.js disabled and can communicate - only via IPC. The use of this option stops Electron from creating a Node.js runtime in the renderer. Also, - within this new window `window.open` follows the native behaviour (by default Electron creates a [`BrowserWindow`](browser-window.md) -+======= -+In the above code the [`BrowserWindow`](browser-window.md) that was created has node.js disabled and can communicate -+only via IPC. The use of this option stops electron from creating a node.js runtime in the renderer. Also, -+within this new window `window.open` follows the native behaviour (by default electron creates a [`BrowserWindow`](browser-window.md) -+>>>>>>> .their - and returns a proxy to this via `window.open`). - - It is important to note that this option alone won't enable the OS-enforced sandbox. To enable this feature, the -@@ -75,19 +107,32 @@ - - Note that it is not enough to call - `app.commandLine.appendSwitch('--enable-sandbox')`, as electron/node startup -+<<<<<<< .our - code runs after it is possible to make changes to Chromium sandbox settings. The - switch must be passed to Electron on the command-line: -+======= -+code runs after it is possible to make changes to chromium sandbox settings. The -+switch must be passed to electron on the command-line: -+>>>>>>> .their - - ```sh - electron --enable-sandbox app.js - ``` - - It is not possible to have the OS sandbox active only for some renderers, if -+<<<<<<< .our - `--enable-sandbox` is enabled, normal Electron windows cannot be created. - - If you need to mix sandboxed and non-sandboxed renderers in one application, - omit the `--enable-sandbox` argument. Without this argument, windows - created with `sandbox: true` will still have Node.js disabled and communicate -+======= -+`--enable-sandbox` is enabled, normal electron windows cannot be created. -+ -+If you need to mix sandboxed and non-sandboxed renderers in one application, -+omit the `--enable-sandbox` argument. Without this argument, windows -+created with `sandbox: true` will still have node.js disabled and communicate -+>>>>>>> .their - only via IPC, which by itself is already a gain from security POV. - - ## Preload -@@ -112,7 +157,11 @@ - - ```js - // This file is loaded whenever a javascript context is created. It runs in a -+<<<<<<< .our - // private scope that can access a subset of Electron renderer APIs. We must be -+======= -+// private scope that can access a subset of electron renderer APIs. We must be -+>>>>>>> .their - // careful to not leak any objects into the global scope! - const fs = require('fs') - const {ipcRenderer} = require('electron') -@@ -136,7 +185,11 @@ - - Important things to notice in the preload script: - -+<<<<<<< .our - - Even though the sandboxed renderer doesn't have Node.js running, it still has -+======= -+- Even though the sandboxed renderer doesn't have node.js running, it still has -+>>>>>>> .their - access to a limited node-like environment: `Buffer`, `process`, `setImmediate` - and `require` are available. - - The preload script can indirectly access all APIs from the main process through the -@@ -146,7 +199,11 @@ - - The preload script must be contained in a single script, but it is possible to have - complex preload code composed with multiple modules by using a tool like - browserify, as explained below. In fact, browserify is already used by -+<<<<<<< .our - Electron to provide a node-like environment to the preload script. -+======= -+ electron to provide a node-like environment to the preload script. -+>>>>>>> .their - - To create a browserify bundle and use it as a preload script, something like - the following should be used: -@@ -178,7 +235,11 @@ - - `timers` - - `url` - -+<<<<<<< .our - More may be added as needed to expose more Electron APIs in the sandbox, but any -+======= -+More may be added as needed to expose more electron APIs in the sandbox, but any -+>>>>>>> .their - module in the main process can already be used through - `electron.remote.require`. - -@@ -186,7 +247,11 @@ - - Please use the `sandbox` option with care, as it is still an experimental - feature. We are still not aware of the security implications of exposing some -+<<<<<<< .our - Electron renderer APIs to the preload script, but here are some things to -+======= -+electron renderer APIs to the preload script, but here are some things to -+>>>>>>> .their - consider before rendering untrusted content: - - - A preload script can accidentally leak privileged APIs to untrusted code. -@@ -194,9 +259,15 @@ - APIs, effectively granting full access to the system through the `remote` - module. - -+<<<<<<< .our - Since rendering untrusted content in Electron is still uncharted territory, - the APIs exposed to the sandbox preload script should be considered more - unstable than the rest of Electron APIs, and may have breaking changes to fix -+======= -+Since rendering untrusted content in electron is still uncharted territory, -+the APIs exposed to the sandbox preload script should be considered more -+unstable than the rest of electron APIs, and may have breaking changes to fix -+>>>>>>> .their - security issues. - - One planned enhancement that should greatly increase security is to block IPC -added in both - our 100644 2eb5574bffe05def2ec3646b200038db15df2e9b docs/api/structures/certificate-principal.md - their 100644 12c46382aaf3d098b8845176eda99e9dddd82d83 docs/api/structures/certificate-principal.md -@@ -1,8 +1,17 @@ - # CertificatePrincipal Object - -+<<<<<<< .our - * `commonName` String - Common Name. - * `organizations` String[] - Organization names. - * `organizationUnits` String[] - Organization Unit names. - * `locality` String - Locality. - * `state` String - State or province. - * `country` String - Country or region. -+======= -+* `commonName` String - Common Name -+* `organizations` String[] - Organization names -+* `organizationUnits` String[] - Organization Unit names -+* `locality` String - Locality -+* `state` String - State or province -+* `country` String - Country or region -+>>>>>>> .their -added in both - our 100644 b0e5b8d15165b23035303bafe049c1824a759439 docs/api/structures/gpu-feature-status.md - their 100644 f7bf3933d6c4c620c8f4d40fbda8a4c7c6b311ee docs/api/structures/gpu-feature-status.md -@@ -1,5 +1,6 @@ - # GPUFeatureStatus Object - -+<<<<<<< .our - * `2d_canvas` String - Canvas. - * `flash_3d` String - Flash. - * `flash_stage3d` String - Flash Stage3D. -@@ -13,6 +14,21 @@ - * `vpx_decode` String - VPx Video Decode. - * `webgl` String - WebGL. - * `webgl2` String - WebGL2. -+======= -+* `2d_canvas` String - Canvas -+* `flash_3d` String - Flash -+* `flash_stage3d` String - Flash Stage3D -+* `flash_stage3d_baseline` String - Flash Stage3D Baseline profile -+* `gpu_compositing` String - Compositing -+* `multiple_raster_threads` String - Multiple Raster Threads -+* `native_gpu_memory_buffers` String - Native GpuMemoryBuffers -+* `rasterization` String - Rasterization -+* `video_decode` String - Video Decode -+* `video_encode` String - Video Encode -+* `vpx_decode` String - VPx Video Decode -+* `webgl` String - WebGL -+* `webgl2` String - WebGL2 -+>>>>>>> .their - - Possible values: - -added in both - our 100644 470dd3a3f7d70f059c0a42736c20213b19372014 docs/api/structures/mime-typed-buffer.md - their 100644 08e5cd47a4a9a5f5ec7784c14b26c82502e20155 docs/api/structures/mime-typed-buffer.md -@@ -1,4 +1,9 @@ - # MimeTypedBuffer Object - -+<<<<<<< .our - * `mimeType` String - The mimeType of the Buffer that you are sending. - * `data` Buffer - The actual Buffer content. -+======= -+* `mimeType` String - The mimeType of the Buffer that you are sending -+* `data` Buffer - The actual Buffer content -+>>>>>>> .their -added in both - our 100644 9f7a000967d09895fe3f43b9792578d6219a43b5 docs/api/structures/rectangle.md - their 100644 1a1228bc0b7c8d0d0f0ae3cea09048960f9df197 docs/api/structures/rectangle.md -@@ -1,6 +1,13 @@ - # Rectangle Object - -+<<<<<<< .our - * `x` Number - The x coordinate of the origin of the rectangle (must be an integer). - * `y` Number - The y coordinate of the origin of the rectangle (must be an integer). - * `width` Number - The width of the rectangle (must be an integer). - * `height` Number - The height of the rectangle (must be an integer). -+======= -+* `x` Number - The x coordinate of the origin of the rectangle (must be an integer) -+* `y` Number - The y coordinate of the origin of the rectangle (must be an integer) -+* `width` Number - The width of the rectangle (must be an integer) -+* `height` Number - The height of the rectangle (must be an integer) -+>>>>>>> .their -added in both - our 100644 538579684242b9de3921d944b9d2fb64cf957a13 docs/api/structures/scrubber-item.md - their 100644 584593b6fde7e089fa296fc891eca05588c108cb docs/api/structures/scrubber-item.md -@@ -1,4 +1,9 @@ - # ScrubberItem Object - -+<<<<<<< .our - * `label` String (optional) - The text to appear in this item. - * `icon` NativeImage (optional) - The image to appear in this item. -+======= -+* `label` String (optional) - The text to appear in this item -+* `icon` NativeImage (optional) - The image to appear in this item -+>>>>>>> .their -added in both - our 100644 47dfaa24027550db196340bc4f63906b6cf43ee2 docs/api/structures/segmented-control-segment.md - their 100644 06a8fd201a190e7787ed7f7c9c55fe31c8f1f37a docs/api/structures/segmented-control-segment.md -@@ -1,5 +1,11 @@ - # SegmentedControlSegment Object - -+<<<<<<< .our - * `label` String (optional) - The text to appear in this segment. - * `icon` NativeImage (optional) - The image to appear in this segment. - * `enabled` Boolean (optional) - Whether this segment is selectable. Default: true. -+======= -+* `label` String (optional) - The text to appear in this segment -+* `icon` NativeImage (optional) - The image to appear in this segment -+* `enabled` Boolean (optional) - Whether this segment is selectable. Default: true -+>>>>>>> .their -added in both - our 100644 ec1fa27e5e7de32e18f4a8ca0ec1969d21054fd4 docs/api/structures/stream-protocol-response.md - their 100644 64847075a05e796a32e46c57eec865ae46740eed docs/api/structures/stream-protocol-response.md -@@ -1,5 +1,11 @@ - # StreamProtocolResponse Object - -+<<<<<<< .our - * `statusCode` Number - The HTTP response code. - * `headers` Object - An object containing the response headers. - * `data` ReadableStream - A Node.js readable stream representing the response body. -+======= -+* `statusCode` Number - The HTTP response code -+* `headers` Object - An object containing the response headers -+* `data` ReadableStream - A Node.js readable stream representing the response body -+>>>>>>> .their -added in both - our 100644 8990fe2e97ab62eafdd3f7a4eb8ee782415124c5 docs/api/web-contents.md - their 100644 520b3cce7bc7c42cecd80ac88d01669c0d5bba5b docs/api/web-contents.md -@@ -832,10 +832,13 @@ - - Returns `Boolean` - Whether this page has been muted. - -+<<<<<<< .our - #### `contents.isCurrentlyAudible()` - - Returns `Boolean` - Whether audio is currently playing. - -+======= -+>>>>>>> .their - #### `contents.setZoomFactor(factor)` - - * `factor` Number - Zoom factor. -@@ -1451,7 +1454,11 @@ - - #### `contents.getProcessId()` - -+<<<<<<< .our - Returns `Integer` - The Chromium internal `pid` of the associated renderer. Can -+======= -+Returns `Integer` - The chromium internal `pid` of the associated renderer. Can -+>>>>>>> .their - be compared to the `frameProcessId` passed by frame specific navigation events - (e.g. `did-frame-navigate`) - -added in both - our 100644 989060ef3e50c5d93db1a914997f1d190edf3cf5 docs/api/web-frame.md - their 100644 5a191da39b6534e78914d01f6486bae9a84ceaff docs/api/web-frame.md -@@ -4,7 +4,11 @@ - - Process: [Renderer](../glossary.md#renderer-process) - -+<<<<<<< .our - `webFrame` export of the Electron module is an instance of the `WebFrame` -+======= -+`webFrame` export of the electron module is an instance of the `WebFrame` -+>>>>>>> .their - class representing the top frame of the current `BrowserWindow`. Sub-frames can - be retrieved by certain properties and methods (e.g. `webFrame.firstChild`). - -@@ -232,8 +236,13 @@ - current renderer process. Routing IDs can be retrieved from `WebFrame` - instances (`webFrame.routingId`) and are also passed by frame - specific `WebContents` navigation events (e.g. `did-frame-navigate`) -+<<<<<<< .our - - Returns `WebFrame` - that has the supplied `routingId`, `null` if not found. -+======= -+ -+Returns `WebFrame` - that has the supplied `routingId`, `null` if not found. -+>>>>>>> .their - - ## Properties - -added in both - our 100644 0904db05accd92a661a6b02275c2166b7a8af2af docs/api/web-request.md - their 100644 2d039923d6f14f3231c7177b8c1b4242b3e4126c docs/api/web-request.md -@@ -9,9 +9,14 @@ - - The methods of `WebRequest` accept an optional `filter` and a `listener`. The - `listener` will be called with `listener(details)` when the API's event has -+<<<<<<< .our - happened. The `details` object describes the request. - - ⚠️ Only the last attached `listener` will be used. Passing `null` as `listener` will unsubscribe from the event. -+======= -+happened. The `details` object describes the request. Passing `null` -+as `listener` will unsubscribe from the event. -+>>>>>>> .their - - The `filter` object has a `urls` property which is an Array of URL - patterns that will be used to filter out the requests that do not match the URL -added in both - our 100644 8dc16b4a4e92ad132c7722ac400e2be851723f9b docs/api/webview-tag.md - their 100644 fd48cf064f93e57a8e4475e8718fa00ac5a32b30 docs/api/webview-tag.md -@@ -407,10 +407,13 @@ - - Returns `Boolean` - Whether guest page has been muted. - -+<<<<<<< .our - #### `.isCurrentlyAudible()` - - Returns `Boolean` - Whether audio is currently playing. - -+======= -+>>>>>>> .their - ### `.undo()` - - Executes editing command `undo` in page. -added in both - our 100644 cbbdaf4c3d1998ccce8e5438eea1a7c9b00f2e37 docs/development/build-instructions-gn.md - their 100644 cdddc4dc8e54b8ce21c4bba333edd128eab5636f docs/development/build-instructions-gn.md -@@ -3,6 +3,7 @@ - Follow the guidelines below for building Electron with the experimental GN - build. - -+<<<<<<< .our - > **NOTE**: The GN build system is in _experimental_ status. - - ## Platform prerequisites -@@ -61,6 +62,34 @@ - --name "src/electron" \ - --unmanaged \ - https://github.com/electron/electron -+======= -+> **NOTE**: The GN build system is in _experimental_ status, and currently only -+> works on macOS and Linux, in debug mode, as a component build. -+ -+## Prerequisites -+ -+See the [macOS](build-instructions-osx.md#prerequisites) or -+[Linux](build-instructions-linux.md#prerequisites) build instructions for the -+requirements for your platform. In addition, you'll need to install -+[`depot_tools`][depot-tools], the toolset used for fetching Chromium and its -+dependencies. -+ -+[depot-tools]: http://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up -+ -+## Getting the Code -+ -+```sh -+$ mkdir electron-gn && cd electron-gn -+$ cat > .gclient <<-GCLIENT -+solutions = [ -+ { -+ "url": "https://github.com/electron/electron", -+ "managed": False, -+ "name": "src/electron", -+ }, -+] -+GCLIENT -+>>>>>>> .their - $ gclient sync --with_branch_heads --with_tags - # This will take a while, go get a coffee. - ``` -@@ -70,6 +99,7 @@ - ```sh - $ cd src - $ export CHROMIUM_BUILDTOOLS_PATH=`pwd`/buildtools -+<<<<<<< .our - # this next line is needed only if building with sccache - $ export GN_EXTRA_ARGS="${GN_EXTRA_ARGS} cc_wrapper=\"${PWD}/electron/external_binaries/sccache\"" - $ gn gen out/Default --args="import(\"//electron/build/args/debug.gn\") $GN_EXTRA_ARGS" -@@ -99,6 +129,16 @@ - ``` - - **To build, run `ninja` with the `electron:electron_app` target:** -+======= -+$ gn gen out/Default --args='root_extra_deps=["//electron"] is_electron_build=true is_component_build=true use_jumbo_build=true v8_promise_internal_field_count=1 v8_typed_array_max_size_in_heap=0' -+``` -+ -+This will generate all the ninja files needed for the build. You shouldn't have -+to run `gn gen` again—if you want to change the build arguments you can run `gn -+args out/Default` to bring up an editor. -+ -+To build, run `ninja` with the `electron:electron_app` target: -+>>>>>>> .their - - ```sh - $ ninja -C out/Default electron:electron_app -@@ -110,8 +150,12 @@ - so it will take a while. - - To speed up subsequent builds, you can use [sccache][sccache]. Add the GN arg -+<<<<<<< .our - `cc_wrapper = "sccache"` by running `gn args out/Default` to bring up an - editor and adding a line to the end of the file. -+======= -+`cc_wrapper="sccache"` by running `gn args out/Default` to bring up an editor. -+>>>>>>> .their - - [sccache]: https://github.com/mozilla/sccache - -@@ -119,12 +163,16 @@ - - ```sh - $ ./out/Default/Electron.app/Contents/MacOS/Electron -+<<<<<<< .our - # or, on Windows - $ ./out/Default/electron.exe -+======= -+>>>>>>> .their - # or, on Linux - $ ./out/Default/electron - ``` - -+<<<<<<< .our - ### Cross-compiling - - To compile for a platform that isn't the same as the one you're building on, -@@ -157,17 +205,30 @@ - $ ninja -C out/Default third_party/electron_node:headers - # Install the test modules with the generated headers - $ (cd electron/spec && npm i --nodedir=../../out/Default/gen/node_headers) -+======= -+## Tests -+ -+To run the tests, you'll first need to build the test modules against the -+same version of node.js that was built as part of the build process. -+ -+```sh -+$ (cd electron/spec && npm i --nodedir=../../third_party/electron_node) -+>>>>>>> .their - ``` - - Then, run Electron with `electron/spec` as the argument: - - ```sh -+<<<<<<< .our - # on Mac: - $ ./out/Default/Electron.app/Contents/MacOS/Electron electron/spec - # on Windows: - $ ./out/Default/electron.exe electron/spec - # on Linux: - $ ./out/Default/electron electron/spec -+======= -+$ ./out/Default/Electron.app/Contents/MacOS/Electron electron/spec -+>>>>>>> .their - ``` - - If you're debugging something, it can be helpful to pass some extra flags to -added in both - our 100644 3276b494aec5d1a49626b8c24d725ec665cf2c62 docs/development/build-instructions-linux.md - their 100644 6f7660669bf071628d6d3d9458640a61e5bcda0e docs/development/build-instructions-linux.md -@@ -12,7 +12,11 @@ - For a quick test, run the following script: - - ```sh -+<<<<<<< .our - $ npm run check-tls -+======= -+ $ python ./script/tls.py -+>>>>>>> .their - ``` - - If the script returns that your configuration is using an outdated security -@@ -71,6 +75,7 @@ - Downloading certain files can take a long time. Notice that we are using - `ninja` to build Electron so there is no `Makefile` generated. - -+<<<<<<< .our - To bootstrap for a static, non-developer build, run: - - ```sh -@@ -83,6 +88,11 @@ - ```sh - $ cd electron - $ npm run bootstrap:dev -+======= -+```sh -+$ cd electron -+$ ./script/bootstrap.py --verbose -+>>>>>>> .their - ``` - - If you are using editor supports [JSON compilation database](http://clang.llvm.org/docs/JSONCompilationDatabase.html) based -@@ -121,7 +131,11 @@ - If you would like to build both `Release` and `Debug` targets: - - ```sh -+<<<<<<< .our - $ npm run build -+======= -+$ ./script/build.py -+>>>>>>> .their - ``` - - This script will cause a very large Electron executable to be placed in -@@ -137,6 +151,7 @@ - the `dist` directory. After running the `create-dist.py` script, you - may want to remove the 1.3+ gigabyte binary which is still in `out/R`. - -+<<<<<<< .our - You can also build either the `Debug` or `Release` target on its own: - - ```sh -@@ -145,6 +160,12 @@ - - ```sh - $ npm run build:release -+======= -+You can also build the `Debug` target only: -+ -+```sh -+$ ./script/build.py -c D -+>>>>>>> .their - ``` - - After building is done, you can find the `electron` debug binary under `out/D`. -added in both - our 100644 22dba096b73d1f99ee323f6822abb54a8b453477 docs/development/build-instructions-osx.md - their 100644 157ab0d3e5f38e0c07695128832565f9aeffd27e docs/development/build-instructions-osx.md -@@ -15,7 +15,11 @@ - This depends on both your version of macOS and Python. For a quick test, run: - - ```sh -+<<<<<<< .our - $ npm run check-tls -+======= -+$ python ./script/tls.py -+>>>>>>> .their - ``` - - If the script returns that your configuration is using an outdated security -@@ -69,6 +73,7 @@ - the build project files. Notice that we're using [ninja](https://ninja-build.org/) - to build Electron so there is no Xcode project generated. - -+<<<<<<< .our - To bootstrap for a static, non-developer build, run: - - ```sh -@@ -81,6 +86,11 @@ - ```sh - $ cd electron - $ npm run bootstrap:dev -+======= -+```sh -+$ cd electron -+$ ./script/bootstrap.py -v -+>>>>>>> .their - ``` - - If you are using editor supports [JSON compilation database](http://clang.llvm.org/docs/JSONCompilationDatabase.html) based -@@ -92,6 +102,7 @@ - - ## Building - -+<<<<<<< .our - To build both `Release` and `Debug` targets: - - ```sh -@@ -106,6 +117,18 @@ - - ```sh - $ npm run build:release -+======= -+Build both `Release` and `Debug` targets: -+ -+```sh -+$ ./script/build.py -+``` -+ -+You can also only build the `Debug` target: -+ -+```sh -+$ ./script/build.py -c D -+>>>>>>> .their - ``` - - After building is done, you can find `Electron.app` under `out/D`. -added in both - our 100644 86f9d2b6f82bb28fe8dda7ec2bea9eccd6119fd4 docs/development/build-instructions-windows.md - their 100644 0afd0ef3ea4636acfb2f67c05cb913403f9da2b7 docs/development/build-instructions-windows.md -@@ -4,7 +4,11 @@ - - ## Prerequisites - -+<<<<<<< .our - * Windows 10 / Server 2012 R2 or higher -+======= -+* Windows 7 / Server 2008 R2 or higher -+>>>>>>> .their - * Visual Studio 2017 15.7.2 or higher - [download VS 2017 Community Edition for - free](https://www.visualstudio.com/vs/) - * [Python 2.7](http://www.python.org/download/releases/2.7/) -@@ -37,6 +41,7 @@ - the build project files. Notice that we're using `ninja` to build Electron so - there is no Visual Studio project generated. - -+<<<<<<< .our - To bootstrap for a static, non-developer build, run: - - ```powershell -@@ -49,10 +54,16 @@ - ```powershell - $ cd electron - $ npm run bootstrap:dev -+======= -+```powershell -+$ cd electron -+$ python script\bootstrap.py -v -+>>>>>>> .their - ``` - - ## Building - -+<<<<<<< .our - Build both `Release` and `Debug` targets: - - ```powershell -@@ -67,6 +78,18 @@ - - ```powershell - $ npm run build:release -+======= -+Build both Release and Debug targets: -+ -+```powershell -+$ python script\build.py -+``` -+ -+You can also only build the Debug target: -+ -+```powershell -+$ python script\build.py -c D -+>>>>>>> .their - ``` - - After building is done, you can find `electron.exe` under `out\D` (debug -@@ -166,6 +189,7 @@ - - You may get this error if you are using Git Bash for building, you should use - PowerShell or VS2015 Command Prompt instead. -+<<<<<<< .our - - ### cannot create directory at '...': Filename too long - -@@ -174,3 +198,5 @@ - ```sh - $ git config --system core.longpaths true - ``` -+======= -+>>>>>>> .their -added in both - our 100644 0abaea2417d7e88955bf60c6dd8f2206b51c99af docs/development/coding-style.md - their 100644 870cb85c7f1855a089b1adc76b6ea0cc2819d58d docs/development/coding-style.md -@@ -40,7 +40,11 @@ - - ## Documentation - -+<<<<<<< .our - * Write [remark](https://github.com/remarkjs/remark) markdown style. -+======= -+* Write [remark](https://github.com/remarkjs/remark) markdown style -+>>>>>>> .their - - You can run `npm run lint-docs` to ensure that your documentation changes are - formatted correctly. -added in both - our 100644 95f4cbab47f5a4ae40f733fd3f8942a63bf4382d docs/development/debug-instructions-windows.md - their 100644 b689ef4480365ad1b56c9bdd2fd028f0d797f1be docs/development/debug-instructions-windows.md -@@ -7,8 +7,11 @@ - and the Electron source code, you can enable step-through debugging - with breakpoints inside Electron's source code. - -+<<<<<<< .our - **See also**: There's a wealth of information on debugging Chromium, much of which also applies to Electron, on the Chromium developers site: [Debugging Chromium on Windows](https://www.chromium.org/developers/how-tos/debugging-on-windows). - -+======= -+>>>>>>> .their - ## Requirements - - * **A debug build of Electron**: The easiest way is usually building it -added in both - our 100644 6c2234477a35701b5d2e4f845d954bccbb203977 docs/development/debugging-instructions-macos-xcode.md - their 100644 e136ee9253cea6fb4debe3c4d73454468cbc8551 docs/development/debugging-instructions-macos-xcode.md -@@ -1,12 +1,21 @@ - ## Debugging with XCode - - ### Build Debug Electron with Release libchromiumcontent -+<<<<<<< .our - You can create a debug build of Electron by following [build instructions for macOS](build-instructions-osx.md). - The bootstrap process will download Release version of libchromiumcontent by default, - so you will not be able to step through the Chromium source. - - ### Build Debug Electron with Debug libchromiumcontent - If you want to debug and step through libchromiumcontent, you will have to run the -+======= -+You can create a debug build of electron by following [build instructions for macOS](build-instructions-osx.md). -+The bootstrap process will download Release version of libchromiumcontent by default, -+so you will not be able to step through the chromium source. -+ -+### Build Debug Electron with Debug libchromiumcontent -+If you want to debug and step through libchromiumcontent, you will have to run the -+>>>>>>> .their - bootsrap script with the `--build_debug_libcc` argument. - - ```sh -@@ -25,7 +34,11 @@ - ```sh - $ ./script/build.py -c D --libcc - ``` -+<<<<<<< .our - This will build debug Electron with debug version of libchromiumcontent. -+======= -+This will build debug electron with debug version of libchromiumcontent. -+>>>>>>> .their - - ### Generate xcode project for debugging sources (cannot build code from xcode) - Run the update script with the --xcode argument. -@@ -37,16 +50,30 @@ - - ### Debugging and breakpoints - -+<<<<<<< .our - Launch Electron app after build. - You can now open the xcode workspace created above and attach to the Electron process -+======= -+Launch electron app after build. -+You can now open the xcode workspace created above and attach to the electron process -+>>>>>>> .their - through the Debug > Attach To Process > Electron debug menu. [Note: If you want to debug - the renderer process, you need to attach to the Electron Helper as well.] - - You can now set breakpoints in any of the indexed files. However, you will not be able -+<<<<<<< .our - to set breakpoints directly in the Chromium source. - To set break points in the Chromium source, you can choose Debug > Breakpoints > Create -+======= -+to set breakpoints directly in the chromium source. -+To set break points in the chromium source, you can choose Debug > Breakpoints > Create -+>>>>>>> .their - Symbolic Breakpoint and set any function name as the symbol. This will set the breakpoint - for all functions with that name, from all the classes if there are more than one. - You can also do this step of setting break points prior to attaching the debugger, - however, actual breakpoints for symbolic breakpoint functions may not show up until the -+<<<<<<< .our -+debugger is attached to the app. -+======= - debugger is attached to the app. -+>>>>>>> .their -added in both - our 100644 c7b4ae62d30fe55da6ba4d03ae2df95141920f99 docs/development/pull-requests.md - their 100644 3b404343efa0d00e06e5bbab4b81a3b6eb25c737 docs/development/pull-requests.md -@@ -86,7 +86,14 @@ - uses [semantic commit messages](https://conventionalcommits.org/) to streamline - the release process. - -+<<<<<<< .our - Before a pull request can be merged, it **must** have a pull request title with a semantic prefix. -+======= -+Before a pull request can be merged, it should include at least one semantic -+commit message, though it's not necessary for all commits in the pull request -+to be semantic. Alternatively, you can **update your pull request title** to -+start with a semantic prefix. -+>>>>>>> .their - - Examples of commit messages with semantic prefixes: - -@@ -105,7 +112,10 @@ - - perf: A code change that improves performance - - refactor: A code change that neither fixes a bug nor adds a feature - - style: Changes that do not affect the meaning of the code (linting) -+<<<<<<< .our - - vendor: Bumping a dependency like libchromiumcontent or node -+======= -+>>>>>>> .their - - Other things to keep in mind when writing a commit message: - -added in both - our 100644 85a5fa0a935201521155dc60de45986db5829613 docs/development/releasing.md - their 100644 7fe929515bcdffbbbf3e454cbd72fdda0e25c7cb docs/development/releasing.md -@@ -8,16 +8,25 @@ - information. - - There are a handful of `*_TOKEN` environment variables needed by the release -+<<<<<<< .our - scripts: - - * `ELECTRON_GITHUB_TOKEN`: - Create this by visiting https://github.com/settings/tokens/new?scopes=repo -+======= -+scripts. Once you've generated these per-user tokens, you may want to keep -+them in a local file that you can `source` when starting a release. -+* `ELECTRON_GITHUB_TOKEN`: -+Create as described at https://github.com/settings/tokens/new, -+giving the token repo access scope. -+>>>>>>> .their - * `APPVEYOR_TOKEN`: - Create a token from https://windows-ci.electronjs.org/api-token - If you don't have an account, ask a team member to add you. - * `CIRCLE_TOKEN`: - Create a token from "Personal API Tokens" at https://circleci.com/account/api - * `VSTS_TOKEN`: -+<<<<<<< .our - Create a Personal Access Token at https://github.visualstudio.com/_usersSettings/tokens or https://github.visualstudio.com/_details/security/tokens - with the scope of `Build (read and execute)`. - * `ELECTRON_S3_BUCKET`: -@@ -29,6 +38,10 @@ - of the project. This file is gitignored, and will be loaded into the - environment by the release scripts. - -+======= -+Create a Personal Access Token at https://github.visualstudio.com/_usersSettings/tokens -+with the scope of `Build (read and execute)`. -+>>>>>>> .their - - ## Determine which branch to release from - -@@ -73,7 +86,11 @@ - ``` - ### Patch version change - ```sh -+<<<<<<< .our - npm run prepare-release -- patch --stable -+======= -+npm run prepare-release -- patch -+>>>>>>> .their - ``` - ### Beta version change - ```sh -@@ -212,10 +229,13 @@ - ```sh - $ npm run release -- --validateRelease - ``` -+<<<<<<< .our - Note, if you need to run `--validateRelease` more than once to check the assets, - run it as above the first time, then `node ./script/release.js --validateRelease` - for subsequent calls so that you don't have to rebuild each time you want to - check the assets. -+======= -+>>>>>>> .their - - ## Publish the release - -@@ -259,6 +279,7 @@ - $ npm run publish-to-npm - ``` - -+<<<<<<< .our - After publishing, you can check the `latest` release: - ```sh - $ npm dist-tag ls electron -@@ -274,6 +295,8 @@ - $ npm dist-tag add electron@2.0.0 latest - ``` - -+======= -+>>>>>>> .their - [the releases page]: https://github.com/electron/electron/releases - [this bump commit]: https://github.com/electron/electron/commit/78ec1b8f89b3886b856377a1756a51617bc33f5a - [versioning]: /docs/tutorial/electron-versioning.md -@@ -303,7 +326,11 @@ - ``` - - Additionally you can pass a job name to the script to run an individual job, eg: -+<<<<<<< .our - ```sh -+======= -+````sh -+>>>>>>> .their - node script/ci-release-build.js --ci=AppVeyor --ghRelease --job=electron-x64 TARGET_BRANCH - ``` - -added in both - our 100644 1c61b3ee66504a23d72478c2e35a48ebeba3372a docs/development/upgrading-node.md - their 100644 821a89391dfd06a158d0fe76272a244ead5f3971 docs/development/upgrading-node.md -@@ -61,6 +61,7 @@ - 2. Run `script/update` to get the latest libcc - - This will be time-consuming - 3. Remove our copies of the old Node v8 patches -+<<<<<<< .our - - (In libchromiumcontent repo) Read `patches/common/v8/README.md` to see which patchfiles - were created during the last update - - Remove those files from `patches/common/v8/`: -@@ -77,6 +78,52 @@ - 7. Apply all patches with the [`get-patch` script](https://github.com/electron/libchromiumcontent/blob/master/script/README.md#get-patch): - - `./script/get-patch --repo src/v8 --output-dir patches/v8 --commit abc123 def456 ...` - 8. Update `patches/common/v8/README.md` with references to all new patches that have been added so that the next person will know which need to be removed. -+======= -+ - (In libchromiumcontent repo) Read `patches/v8/README.md` to see which patchfiles -+ were created during the last update -+ - Remove those files from `patches/v8/`: -+ - `git rm` the patchfiles -+ - edit `patches/v8/README.md` -+ - commit these removals -+4. Inspect Node [repo](https://github.com/electron/node) to see what patches upstream Node -+ used with their v8 after bumping its version -+ - `git log --oneline deps/V8` -+5. Create a checklist of the patches. This is useful for tracking your work and for -+ having a quick reference of commit hashes to use in the `git diff-tree` step below. -+6. Read `patches/v8/README.md` to see which patchfiles came from the previous version of V8 and therefore need to be removed. -+ - Delete each patchfile referenced in `patches/v8/README.md` -+7. For each patch, do: -+ - (In node repo) `git diff-tree --patch HASH > ~/path_to_libchromiumcontent/patches/v8/xxx-patch_name.patch` -+ - `xxx` is an incremented three-digit number (to force patch order) -+ - `patch_name` should loosely match the node commit messages, -+ e.g. `030-cherry_pick_cc55747,patch` if the Node commit message was "cherry-pick cc55747" -+ - (remainder of steps in libchromium repo) -+ Manually edit the `.patch` file to match upstream V8's directory: -+ - If a diff section has no instances of `deps/V8`, remove it altogether. -+ - We don’t want those patches because we’re only patching V8. -+ - Replace instances of `a/deps/v8/filename.ext` with `a/filename.ext` -+ - This is needed because upstream Node keeps its V8 files in a subdirectory -+ - Ensure that local status is clean: `git status` to make sure there are no unstaged changes. -+ - Confirm that the patch applies cleanly with -+ `script/patch.py -r src/V8 -p patches/v8/xxx-patch_name.patch.patch` -+ - Create a new copy of the patch: -+ - `cd src/v8 && git diff > ../../test.patch && cd ../..` -+ - This is needed because the first patch has Node commit checksums that we don't want -+ - Confirm that checksums are the only difference between the two patches: -+ - `diff -u test.patch patches/v8/xxx-patch_name.patch` -+ - Replace the old patch with the new: -+ - `mv test.patch patches/v8/xxx-patch_name.patch` -+ - Add the patched code to the index _without_ committing: -+ - `cd src/v8 && git add . && cd ../..` -+ - We don't want to commit the changes (they're kept in the patchfiles) -+ but need them locally so that they don't show up in subsequent diffs -+ while we iterate through more patches -+ - Add the patch file to the index: -+ - `git add a patches/v8/` -+ - (Optionally) commit each patch file to ensure you can back up if you mess up a step: -+ - `git commit patches/v8/` -+8. Update `patches/v8/README.md` with references to all new patches that have been added so that the next person will know which need to be removed. -+>>>>>>> .their - 9. Update Electron's submodule references: - ```sh - $ cd electron/vendor/node -@@ -87,8 +134,13 @@ - electron/vendor/libchromiumcontent$ git checkout upgrade-to-chromium-X - electron/vendor/libchromiumcontent$ cd ../.. - electron$ git add vendor -+<<<<<<< .our - electron$ git commit -m "update submodule references for node and libcc" - electron$ git push origin upgrade-to-chromium- -+======= -+ electron$ git commit -m "update submodule referefences for node and libc" -+ electron$ git pso upgrade-to-chromium-62 -+>>>>>>> .their - electron$ script/bootstrap.py -d - electron$ script/build.py -c -D - ``` -added in both - our 100644 162300c6e17ce19fef7ee7c3baa1d74a2cb0dc7a docs/tutorial/application-architecture.md - their 100644 7411f025823483cb2d755a4a033102e1ca1b1f36 docs/tutorial/application-architecture.md -@@ -39,7 +39,11 @@ - - > #### Aside: Communication Between Processes - > In Electron, we have several ways to communicate between the main process -+<<<<<<< .our - and renderer processes, such as [`ipcRenderer`](../api/ipc-renderer.md) and -+======= -+and renderer processes. Like [`ipcRenderer`](../api/ipc-renderer.md) and -+>>>>>>> .their - [`ipcMain`](../api/ipc-main.md) modules for sending messages, and the - [remote](../api/remote.md) module for RPC style communication. There is also - an FAQ entry on [how to share data between web pages][share-data]. -added in both - our 100644 22b861749cb9c5d7fe6982d273856fb3c4bf04c9 docs/tutorial/application-distribution.md - their 100644 83d7c7bdfe6ac01d981e1bae47c8303f8de9e4fe docs/tutorial/application-distribution.md -@@ -141,7 +141,11 @@ - 2. Create a new S3 bucket and create the following empty directory structure: - - ```sh -+<<<<<<< .our - - electron/ -+======= -+ - atom-shell/ -+>>>>>>> .their - - symbols/ - - dist/ - ``` -@@ -150,7 +154,11 @@ - - * `ELECTRON_GITHUB_TOKEN` - a token that can create releases on GitHub - * `ELECTRON_S3_ACCESS_KEY`, `ELECTRON_S3_BUCKET`, `ELECTRON_S3_SECRET_KEY` - -+<<<<<<< .our - the place where you'll upload Node.js headers as well as symbols -+======= -+ the place where you'll upload node.js headers as well as symbols -+>>>>>>> .their - * `ELECTRON_RELEASE` - Set to `true` and the upload part will run, leave unset - and `surf-build` will do CI-type checks, appropriate to run for every - pull request. -added in both - our 100644 16eb961fabe09001e621b834b297cada6918c102 docs/tutorial/code-signing.md - their 100644 236ebe80ef02f38a094404a79f067120d32adaa7 docs/tutorial/code-signing.md -@@ -66,7 +66,11 @@ - See the [Windows Store Guide]. - - [Apple Developer Program]: https://developer.apple.com/programs/ -+<<<<<<< .our - [`electron-builder`]: https://github.com/electron-userland/electron-builder -+======= -+[`electron-builder`]: https://github.com/electron/electron-builder -+>>>>>>> .their - [`electron-forge`]: https://github.com/electron-userland/electron-forge - [`electron-osx-sign`]: https://github.com/electron-userland/electron-osx-sign - [`electron-packager`]: https://github.com/electron-userland/electron-packager -added in both - our 100644 9629bb98282d080bc53171a619d83a193041a022 docs/tutorial/electron-versioning.md - their 100644 883f20eefa9e59450efaed9fbd4dbafb2632b4e5 docs/tutorial/electron-versioning.md -@@ -49,7 +49,11 @@ - | Chromium version updates | | fix-related chromium patches | - - -+<<<<<<< .our - Note that most Chromium updates will be considered breaking. Fixes that can be backported will likely be cherry-picked as patches. -+======= -+Note that most chromium updates will be considered breaking. Fixes that can be backported will likely be cherry-picked as patches. -+>>>>>>> .their - - # Stabilization Branches - -@@ -136,12 +140,20 @@ - - We seek to increase clarity at all levels of the update and releases process. Starting with `2.0.0` we will require pull requests adhere to the [Conventional Commits](https://conventionalcommits.org/) spec, which can be summarized as follows: - -+<<<<<<< .our - * Commits that would result in a semver **major** bump must start their body with `BREAKING CHANGE:`. -+======= -+* Commits that would result in a semver **major** bump must start with `BREAKING CHANGE:`. -+>>>>>>> .their - * Commits that would result in a semver **minor** bump must start with `feat:`. - * Commits that would result in a semver **patch** bump must start with `fix:`. - - * We allow squashing of commits, provided that the squashed message adheres the the above message format. -+<<<<<<< .our - * It is acceptable for some commits in a pull request to not include a semantic prefix, as long as the pull request title contains a meaningful encompassing semantic message. -+======= -+* It is acceptable for some commits in a pull request to not include a semantic prefix, as long as a later commit in the same pull request contains a meaningful encompassing semantic message. -+>>>>>>> .their - - # Versionless `master` - -added in both - our 100644 081c82031907404938387485dc95414c7de4e4db docs/tutorial/mac-app-store-submission-guide.md - their 100644 e8812a85b57f6d10900b8932ebe790c499ba8476 docs/tutorial/mac-app-store-submission-guide.md -@@ -229,6 +229,20 @@ - See the [Enabling User-Selected File Access documentation][user-selected] for - more details. - -+<<<<<<< .our -+======= -+## Known issues -+ -+### `shell.openItem(filePath)` -+ -+This will fail when the app is signed for distribution in the Mac App Store. -+Subscribe to [#9005](https://github.com/electron/electron/issues/9005) for updates. -+ -+#### Workaround -+ -+`shell.openExternal('file://' + filePath)` will open the file in the default application as long as the extension is associated with an installed app. -+ -+>>>>>>> .their - ## Cryptographic Algorithms Used by Electron - - Depending on the country and region you are located, Mac App Store may require -added in both - our 100644 77f5d9632f58a1874c3d962b981619872a73a8b2 docs/tutorial/security.md - their 100644 70c455236e0b45e540eb55f168feb851625a7f08 docs/tutorial/security.md -@@ -31,7 +31,11 @@ - developers should be aware that upgrading is a serious undertaking - involving - hand-editing dozens or even hundreds of files. Given the resources and - contributions available today, Electron will often not be on the very latest -+<<<<<<< .our - version of Chromium, lagging behind by several weeks or a few months. -+======= -+version of Chromium, lagging behind by either days or weeks. -+>>>>>>> .their - - We feel that our current system of updating the Chromium component strikes an - appropriate balance between the resources we have available and the needs of -@@ -82,7 +86,11 @@ - 11. [``: Do not use `allowpopups`](#11-do-not-use-allowpopups) - 12. [``: Verify options and params](#12-verify-webview-options-before-creation) - 13. [Disable or limit navigation](#13-disable-or-limit-navigation) -+<<<<<<< .our - 14. [Disable or limit creation of new windows](#14-disable-or-limit-creation-of-new-windows) -+======= -+14. [Disable or limit creation of new windows](#13-disable-or-limit-creation-of-new-windows) -+>>>>>>> .their - - ## 1) Only Load Secure Content - -@@ -340,7 +348,16 @@ - Electron can load for that given web page. `https://your-page.com` should - be allowed to load scripts from the origins you defined while scripts from - `https://evil.attacker.com` should not be allowed to run. Defining a CSP is an -+<<<<<<< .our - easy way to improve your application's security. -+======= -+easy way to improve your applications security. -+ -+### How? -+ -+Electron respects [the `Content-Security-Policy` HTTP header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy) -+and the respective `` tag. -+>>>>>>> .their - - The following CSP will allow Electron to execute scripts from the current - website and from `apis.mydomain.com`. -@@ -353,6 +370,7 @@ - Content-Security-Policy: script-src 'self' https://apis.mydomain.com - ``` - -+<<<<<<< .our - ### CSP HTTP Header - - Electron respects the [`Content-Security-Policy` HTTP header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy) -@@ -379,6 +397,8 @@ - - #### `webRequest.onHeadersReceived([filter, ]listener)` - -+======= -+>>>>>>> .their - - ## 7) Override and Disable `eval` - -@@ -446,7 +466,11 @@ - _Recommendation is Electron's default_ - - Advanced users of Electron can enable experimental Chromium features using the -+<<<<<<< .our - `experimentalFeatures` property. -+======= -+`experimentalFeatures` and `experimentalCanvasFeatures` properties. -+>>>>>>> .their - - ### Why? - -@@ -612,13 +636,21 @@ - `https://google.com.attacker.com` through. - - ```js -+<<<<<<< .our - const URL = require('url').URL -+======= -+const URL = require('url') -+>>>>>>> .their - - app.on('web-contents-created', (event, contents) => { - contents.on('will-navigate', (event, navigationUrl) => { - const parsedUrl = new URL(navigationUrl) - -+<<<<<<< .our - if (parsedUrl.origin !== 'https://my-own-server.com') { -+======= -+ if (parsedUrl.hostname !== 'my-own-server.com') { -+>>>>>>> .their - event.preventDefault() - } - }) -added in both - our 100644 bf01dc632319a6dfa147fcbc8376686778e71714 docs/tutorial/using-pepper-flash-plugin.md - their 100644 42ead0d694916bd22dad19e3487ccf73fc9f6190 docs/tutorial/using-pepper-flash-plugin.md -@@ -7,7 +7,11 @@ - ## Prepare a Copy of Flash Plugin - - On macOS and Linux, the details of the Pepper Flash plugin can be found by -+<<<<<<< .our - navigating to `chrome://flash` in the Chrome browser. Its location and version -+======= -+navigating to `chrome://plugins` in the Chrome browser. Its location and version -+>>>>>>> .their - are useful for Electron's Pepper Flash support. You can also copy it to another - location. - -added in both - our 100644 1ceae13473af2a1ccd888924f342e5137c83e7e5 docs/tutorial/using-selenium-and-webdriver.md - their 100644 5df8818d5b83c73469de4b3e5760baa5ee37591a docs/tutorial/using-selenium-and-webdriver.md -@@ -164,7 +164,11 @@ - [place](https://github.com/electron/electron/blob/master/docs/tutorial/application-distribution.md) - your app source into Electron's resource directory. - -+<<<<<<< .our - Alternatively, pass an argument to run with your Electron binary that points to -+======= -+Alternatively, pass an argument to run with your electron binary that points to -+>>>>>>> .their - your app's folder. This eliminates the need to copy-paste your app into - Electron's resource directory. - -added in both - our 100644 944ddab2a3fd879044e31677e4bac2843fffbdee electron.gyp - their 100644 52537ba11dadcd28a6c4b69a61268a64540cb29a electron.gyp -@@ -4,7 +4,11 @@ - 'product_name%': 'Electron', - 'company_name%': 'GitHub, Inc', - 'company_abbr%': 'github', -+<<<<<<< .our - 'version%': '4.0.0-nightly.20180821', -+======= -+ 'version%': '3.0.0-beta.7', -+>>>>>>> .their - 'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c', - }, - 'includes': [ -@@ -48,11 +52,14 @@ - 'ENABLE_VIEW_API', - ], - }], # enable_view_api -+<<<<<<< .our - ['enable_pepper_flash==1', { - 'defines': [ - 'ENABLE_PEPPER_FLASH', - ], - }], # enable_pepper_flash -+======= -+>>>>>>> .their - ], - }, - 'targets': [ -@@ -163,6 +170,12 @@ - ], - }], # OS!="mac" - ['OS=="win"', { -+<<<<<<< .our -+======= -+ 'include_dirs': [ -+ '<(libchromiumcontent_dir)/gen/ui/resources', -+ ], -+>>>>>>> .their - 'msvs_settings': { - 'VCManifestTool': { - 'EmbedManifest': 'true', -@@ -272,6 +285,11 @@ - 'NODE_SHARED_MODE', - 'HAVE_OPENSSL=1', - 'HAVE_INSPECTOR=1', -+<<<<<<< .our -+======= -+ # This is defined in skia/skia_common.gypi. -+ 'SK_SUPPORT_LEGACY_GETTOPDEVICE', -+>>>>>>> .their - # Disable warnings for g_settings_list_schemas. - 'GLIB_DISABLE_DEPRECATION_WARNINGS', - # Defined in Chromium but not exposed in its gyp file. -@@ -285,6 +303,12 @@ - # See Chromium src/third_party/protobuf/BUILD.gn - 'GOOGLE_PROTOBUF_NO_RTTI', - 'GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER', -+<<<<<<< .our -+======= -+ -+ # Enables SkBitmap size 64 operations -+ 'SK_SUPPORT_LEGACY_SAFESIZE64', -+>>>>>>> .their - ], - 'sources': [ - '<@(lib_sources)', -@@ -333,6 +357,7 @@ - 'vendor/pdf_viewer/pdf_viewer.gyp:pdf_viewer', - ], - }], # enable_pdf_viewer -+<<<<<<< .our - ['enable_pepper_flash==1', { - 'include_dirs': [ - '<(libchromiumcontent_src_dir)/chrome/browser/renderer_host/pepper', -@@ -352,6 +377,8 @@ - ], - }, - }], # enable_pepper_flash -+======= -+>>>>>>> .their - ['libchromiumcontent_component', { - 'link_settings': { - 'libraries': [ '<@(libchromiumcontent_v8_libraries)' ], -@@ -363,9 +390,13 @@ - ], - 'link_settings': { - 'libraries': [ -+<<<<<<< .our - '-ldwmapi.lib', - '-limm32.lib', - '-lgdi32.lib', -+======= -+ '-limm32.lib', -+>>>>>>> .their - '-loleacc.lib', - '-lcomctl32.lib', - '-lcomdlg32.lib', -added in both - our 100644 86543a4db1195223a3556fa71583038f15d79a0a features.gypi - their 100644 ae08bc63a5c3bec6a8b1e13e532538e40aed0b05 features.gypi -@@ -7,13 +7,19 @@ - 'enable_pdf_viewer%': 0, # FIXME(deepak1556) - 'enable_run_as_node%': 1, - 'enable_view_api%': 0, -+<<<<<<< .our - 'enable_pepper_flash%': 1, -+======= -+>>>>>>> .their - }, - 'enable_desktop_capturer%': '<(enable_desktop_capturer)', - 'enable_osr%': '<(enable_osr)', - 'enable_pdf_viewer%': '<(enable_pdf_viewer)', - 'enable_run_as_node%': '<(enable_run_as_node)', - 'enable_view_api%': '<(enable_view_api)', -+<<<<<<< .our - 'enable_pepper_flash%': '<(enable_pepper_flash)', -+======= -+>>>>>>> .their - }, - } -added in both - our 100644 f57860558f06b7e5d8a50f48cfc7e53044df0bc6 filenames.gypi - their 100644 a9e59f5cdf4d17f6b669765af9a9e5e2ce55aeef filenames.gypi -@@ -98,6 +98,7 @@ - 'default_app/main.js', - 'default_app/package.json', - 'default_app/renderer.js', -+<<<<<<< .our - 'default_app/styles.css', - 'node_modules/octicons/build/build.css', - 'node_modules/octicons/build/svg/gist.svg', -@@ -105,6 +106,8 @@ - 'node_modules/octicons/build/svg/gear.svg', - 'node_modules/octicons/build/svg/star.svg', - 'node_modules/octicons/build/svg/gift.svg', -+======= -+>>>>>>> .their - ], - 'lib_sources': [ - 'atom/app/atom_content_client.cc', -@@ -317,8 +320,11 @@ - 'atom/browser/request_context_delegate.h', - 'atom/browser/session_preferences.cc', - 'atom/browser/session_preferences.h', -+<<<<<<< .our - 'atom/browser/special_storage_policy.cc', - 'atom/browser/special_storage_policy.h', -+======= -+>>>>>>> .their - 'atom/browser/ui/accelerator_util.cc', - 'atom/browser/ui/accelerator_util.h', - 'atom/browser/ui/accelerator_util_mac.mm', -@@ -533,8 +539,11 @@ - 'atom/common/platform_util_linux.cc', - 'atom/common/platform_util_mac.mm', - 'atom/common/platform_util_win.cc', -+<<<<<<< .our - 'atom/common/promise_util.h', - 'atom/common/promise_util.cc', -+======= -+>>>>>>> .their - 'atom/renderer/api/atom_api_renderer_ipc.h', - 'atom/renderer/api/atom_api_renderer_ipc.cc', - 'atom/renderer/api/atom_api_spell_check_client.cc', -@@ -608,6 +617,23 @@ - 'chromium_src/chrome/browser/process_singleton_posix.cc', - 'chromium_src/chrome/browser/process_singleton_win.cc', - 'chromium_src/chrome/browser/process_singleton.h', -+<<<<<<< .our -+======= -+ 'chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc', -+ 'chromium_src/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h', -+ 'chromium_src/chrome/browser/renderer_host/pepper/monitor_finder_mac.h', -+ 'chromium_src/chrome/browser/renderer_host/pepper/monitor_finder_mac.mm', -+ 'chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.cc', -+ 'chromium_src/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.h', -+ 'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc', -+ 'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h', -+ 'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc', -+ 'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h', -+ 'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.cc', -+ 'chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h', -+ 'chromium_src/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc', -+ 'chromium_src/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h', -+>>>>>>> .their - 'chromium_src/chrome/browser/speech/tts_controller.h', - 'chromium_src/chrome/browser/speech/tts_controller_impl.cc', - 'chromium_src/chrome/browser/speech/tts_controller_impl.h', -@@ -645,6 +671,23 @@ - 'chromium_src/chrome/common/widevine_cdm_constants.h', - 'chromium_src/chrome/renderer/media/chrome_key_systems.cc', - 'chromium_src/chrome/renderer/media/chrome_key_systems.h', -+<<<<<<< .our -+======= -+ 'chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc', -+ 'chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h', -+ 'chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.cc', -+ 'chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.h', -+ 'chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.cc', -+ 'chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.h', -+ 'chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.cc', -+ 'chromium_src/chrome/renderer/pepper/pepper_flash_menu_host.h', -+ 'chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.cc', -+ 'chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.h', -+ 'chromium_src/chrome/renderer/pepper/pepper_helper.cc', -+ 'chromium_src/chrome/renderer/pepper/pepper_helper.h', -+ 'chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.cc', -+ 'chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.h', -+>>>>>>> .their - 'chromium_src/chrome/renderer/printing/print_web_view_helper.cc', - 'chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc', - 'chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm', -added in both - our 100644 66f6ae651acf10fb19b8ec068fc5280850dd3d91 lib/browser/api/app.js - their 100644 a6d94a20a40051faf01c2c15cd6d492235d17a1d lib/browser/api/app.js -@@ -12,12 +12,36 @@ - const {EventEmitter} = require('events') - - let dockMenu = null -+<<<<<<< .our -+======= -+let readyPromise = null -+>>>>>>> .their - - // App is an EventEmitter. - Object.setPrototypeOf(App.prototype, EventEmitter.prototype) - EventEmitter.call(app) - - Object.assign(app, { -+<<<<<<< .our -+======= -+ whenReady () { -+ if (readyPromise !== null) { -+ return readyPromise -+ } -+ -+ if (app.isReady()) { -+ readyPromise = Promise.resolve() -+ } else { -+ readyPromise = new Promise(resolve => { -+ // XXX(alexeykuzmin): Explicitly ignore any data -+ // passed to the event handler to avoid memory leaks. -+ app.once('ready', () => resolve()) -+ }) -+ } -+ -+ return readyPromise -+ }, -+>>>>>>> .their - setApplicationMenu (menu) { - return Menu.setApplicationMenu(menu) - }, -added in both - our 100644 506e3525c10ce142cafe3fc1bf4de1c255e48503 lib/browser/api/menu.js - their 100644 dcc446587913f37a58c86f4d1bf612371589960e lib/browser/api/menu.js -@@ -47,7 +47,11 @@ - this.delegate = delegate - } - -+<<<<<<< .our - Menu.prototype.popup = function (options = {}) { -+======= -+Menu.prototype.popup = function (options) { -+>>>>>>> .their - if (options == null || typeof options !== 'object') { - throw new TypeError('Options must be an object') - } -@@ -156,6 +160,7 @@ - - Menu.buildFromTemplate = function (template) { - if (!Array.isArray(template)) { -+<<<<<<< .our - throw new TypeError('Invalid template for Menu: Menu template must be an array') - } - const menu = new Menu() -@@ -166,18 +171,36 @@ - const sorted = sortTemplate(filtered) - - sorted.forEach((item) => menu.append(new MenuItem(item))) -+======= -+ throw new TypeError('Invalid template for Menu') -+ } -+ -+ const menu = new Menu() -+ const filtered = removeExtraSeparators(template) -+ const sorted = sortTemplate(filtered) -+ -+ sorted.forEach((item) => { -+ if (typeof item !== 'object') { -+ throw new TypeError('Invalid template for MenuItem') -+ } -+ menu.append(new MenuItem(item)) -+ }) -+>>>>>>> .their - - return menu - } - - /* Helper Functions */ - -+<<<<<<< .our - // validate the template against having the wrong attribute - function areValidTemplateItems (template) { - return template.every(item => - item != null && typeof item === 'object' && (item.hasOwnProperty('label') || item.hasOwnProperty('role') || item.type === 'separator')) - } - -+======= -+>>>>>>> .their - function sortTemplate (template) { - const sorted = sortMenuItems(template) - for (let id in sorted) { -added in both - our 100644 3f2d470a270378ce1221c928e549d0857755fa09 lib/browser/api/net.js - their 100644 54ef99d407ff3a7d7e853b8ccda350d5f8d47fa8 lib/browser/api/net.js -@@ -352,10 +352,13 @@ - abort () { - this.urlRequest.cancel() - } -+<<<<<<< .our - - getUploadProgress () { - return this.urlRequest.getUploadProgress() - } -+======= -+>>>>>>> .their - } - - function writeAfterEndNT (self, error, callback) { -added in both - our 100644 1e4029e39a981c85fb6ff18c5ccd52f81b3c56f2 lib/browser/guest-view-manager.js - their 100644 191fa6f3f019bf776f48a18e67a3c4999b1991fe lib/browser/guest-view-manager.js -@@ -158,7 +158,11 @@ - const attachGuest = function (event, embedderFrameId, elementInstanceId, guestInstanceId, params) { - const embedder = event.sender - // Destroy the old guest when attaching. -+<<<<<<< .our - const key = `${embedder.id}-${elementInstanceId}` -+======= -+ const key = `${embedder.getId()}-${elementInstanceId}` -+>>>>>>> .their - const oldGuestInstanceId = embedderElementsMap[key] - if (oldGuestInstanceId != null) { - // Reattachment to the same guest is just a no-op. -@@ -181,7 +185,11 @@ - - // If this guest is already attached to an element then remove it - if (guestInstance.elementInstanceId) { -+<<<<<<< .our - const oldKey = `${guestInstance.embedder.id}-${guestInstance.elementInstanceId}` -+======= -+ const oldKey = `${guestInstance.embedder.getId()}-${guestInstance.elementInstanceId}` -+>>>>>>> .their - delete embedderElementsMap[oldKey] - - // Remove guest from embedder if moving across web views -@@ -269,7 +277,11 @@ - webViewManager.removeGuest(embedder, guestInstanceId) - delete guestInstances[guestInstanceId] - -+<<<<<<< .our - const key = `${embedder.id}-${guestInstance.elementInstanceId}` -+======= -+ const key = `${embedder.getId()}-${guestInstance.elementInstanceId}` -+>>>>>>> .their - delete embedderElementsMap[key] - } - -added in both - our 100644 7253c1942b0956ae6b9b0c80a23470fc26669b8a lib/browser/guest-window-manager.js - their 100644 7985dec4b9ef1ddfc7b88ea4885d7f7136060369 lib/browser/guest-window-manager.js -@@ -63,9 +63,14 @@ - } - - // Inherit certain option values from parent window -+<<<<<<< .our - const webPreferences = embedder.getLastWebPreferences() - for (const [name, value] of inheritedWebPreferences) { - if (webPreferences[name] === value) { -+======= -+ for (const [name, value] of inheritedWebPreferences) { -+ if (embedder.getLastWebPreferences()[name] === value) { -+>>>>>>> .their - options.webPreferences[name] = value - } - } -added in both - our 100644 f03a23d2f6910d6555bb9469180d1b60b94bc313 lib/browser/objects-registry.js - their 100644 3fb0923df10da778f3e6bd096e771038fd026cb8 lib/browser/objects-registry.js -@@ -2,10 +2,13 @@ - - const v8Util = process.atomBinding('v8_util') - -+<<<<<<< .our - const getOwnerKey = (webContents, contextId) => { - return `${webContents.id}-${contextId}` - } - -+======= -+>>>>>>> .their - class ObjectsRegistry { - constructor () { - this.nextId = 0 -@@ -15,7 +18,11 @@ - this.storage = {} - - // Stores the IDs of objects referenced by WebContents. -+<<<<<<< .our - // (ownerKey) => [id] -+======= -+ // (webContentsContextId) => [id] -+>>>>>>> .their - this.owners = {} - } - -@@ -26,10 +33,17 @@ - const id = this.saveToStorage(obj) - - // Add object to the set of referenced objects. -+<<<<<<< .our - const ownerKey = getOwnerKey(webContents, contextId) - let owner = this.owners[ownerKey] - if (!owner) { - owner = this.owners[ownerKey] = new Set() -+======= -+ const webContentsContextId = `${webContents.id}-${contextId}` -+ let owner = this.owners[webContentsContextId] -+ if (!owner) { -+ owner = this.owners[webContentsContextId] = new Set() -+>>>>>>> .their - this.registerDeleteListener(webContents, contextId) - } - if (!owner.has(id)) { -@@ -50,8 +64,13 @@ - // Note that an object may be double-freed (cleared when page is reloaded, and - // then garbage collected in old page). - remove (webContents, contextId, id) { -+<<<<<<< .our - const ownerKey = getOwnerKey(webContents, contextId) - let owner = this.owners[ownerKey] -+======= -+ const webContentsContextId = `${webContents.id}-${contextId}` -+ let owner = this.owners[webContentsContextId] -+>>>>>>> .their - if (owner) { - // Remove the reference in owner. - owner.delete(id) -@@ -62,13 +81,22 @@ - - // Clear all references to objects refrenced by the WebContents. - clear (webContents, contextId) { -+<<<<<<< .our - const ownerKey = getOwnerKey(webContents, contextId) - let owner = this.owners[ownerKey] -+======= -+ const webContentsContextId = `${webContents.id}-${contextId}` -+ let owner = this.owners[webContentsContextId] -+>>>>>>> .their - if (!owner) return - - for (let id of owner) this.dereference(id) - -+<<<<<<< .our - delete this.owners[ownerKey] -+======= -+ delete this.owners[webContentsContextId] -+>>>>>>> .their - } - - // Private: Saves the object into storage and assigns an ID for it. -@@ -87,7 +115,10 @@ - - // Private: Dereference the object from store. - dereference (id) { -+<<<<<<< .our - // FIXME(MarshallOfSound): We should remove this once remote deref works well -+======= -+>>>>>>> .their - if (process.env.ELECTRON_DISABLE_REMOTE_DEREFERENCING) return - - let pointer = this.storage[id] -@@ -101,7 +132,11 @@ - } - } - -+<<<<<<< .our - // Private: Clear the storage when renderer process is destroyed. -+======= -+ // Private: Clear the storage when renderer process is destoryed. -+>>>>>>> .their - registerDeleteListener (webContents, contextId) { - const processId = webContents.getProcessId() - const listener = (event, deletedProcessId) => { -added in both - our 100644 ff9f77321de3a4145946b67f3fe2a597f98e2510 lib/browser/rpc-server.js - their 100644 09ffb13dcb497383bd7d97e0d26ce72688028d11 lib/browser/rpc-server.js -@@ -171,6 +171,10 @@ - // Convert array of meta data from renderer into array of real values. - const unwrapArgs = function (sender, contextId, args) { - const metaToValue = function (meta) { -+<<<<<<< .our -+======= -+ let i, len, member, ref, returnValue -+>>>>>>> .their - switch (meta.type) { - case 'value': - return meta.value -@@ -190,13 +194,24 @@ - let ret = {} - Object.defineProperty(ret.constructor, 'name', { value: meta.name }) - -+<<<<<<< .our - for (const {name, value} of meta.members) { - ret[name] = metaToValue(value) -+======= -+ ref = meta.members -+ for (i = 0, len = ref.length; i < len; i++) { -+ member = ref[i] -+ ret[member.name] = metaToValue(member.value) -+>>>>>>> .their - } - return ret - } - case 'function-with-return-value': -+<<<<<<< .our - const returnValue = metaToValue(meta.value) -+======= -+ returnValue = metaToValue(meta.value) -+>>>>>>> .their - return function () { - return returnValue - } -@@ -210,9 +225,15 @@ - return rendererFunctions.get(objectId) - } - -+<<<<<<< .our - const processId = sender.getProcessId() - let callIntoRenderer = function (...args) { - if (!sender.isDestroyed() && processId === sender.getProcessId()) { -+======= -+ const webContentsId = sender.getId() -+ let callIntoRenderer = function (...args) { -+ if (!sender.isDestroyed() && webContentsId === sender.getId()) { -+>>>>>>> .their - sender.send('ELECTRON_RENDERER_CALLBACK', contextId, meta.id, valueToMeta(sender, contextId, args)) - } else { - removeRemoteListenersAndLogWarning(this, meta, callIntoRenderer) -@@ -234,8 +255,14 @@ - // Call a function and send reply asynchronously if it's a an asynchronous - // style function and the caller didn't pass a callback. - const callFunction = function (event, contextId, func, caller, args) { -+<<<<<<< .our - const funcMarkedAsync = v8Util.getHiddenValue(func, 'asynchronous') - const funcPassedCallback = typeof args[args.length - 1] === 'function' -+======= -+ let err, funcMarkedAsync, funcName, funcPassedCallback, ref, ret -+ funcMarkedAsync = v8Util.getHiddenValue(func, 'asynchronous') -+ funcPassedCallback = typeof args[args.length - 1] === 'function' -+>>>>>>> .their - try { - if (funcMarkedAsync && !funcPassedCallback) { - args.push(function (ret) { -@@ -243,15 +270,24 @@ - }) - func.apply(caller, args) - } else { -+<<<<<<< .our - const ret = func.apply(caller, args) -+======= -+ ret = func.apply(caller, args) -+>>>>>>> .their - event.returnValue = valueToMeta(event.sender, contextId, ret, true) - } - } catch (error) { - // Catch functions thrown further down in function invocation and wrap - // them with the function name so it's easier to trace things like - // `Error processing argument -1.` -+<<<<<<< .our - const funcName = func.name || 'anonymous' - const err = new Error(`Could not call remote function '${funcName}'. Check that the function signature is correct. Underlying error: ${error.message}`) -+======= -+ funcName = ((ref = func.name) != null) ? ref : 'anonymous' -+ err = new Error(`Could not call remote function '${funcName}'. Check that the function signature is correct. Underlying error: ${error.message}`) -+>>>>>>> .their - err.cause = error - throw err - } -@@ -302,7 +338,14 @@ - throwRPCError(`Cannot call constructor on missing remote object ${id}`) - } - -+<<<<<<< .our - event.returnValue = valueToMeta(event.sender, contextId, new constructor(...args)) -+======= -+ // Call new with array of arguments. -+ // http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible -+ let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args)))() -+ event.returnValue = valueToMeta(event.sender, contextId, obj) -+>>>>>>> .their - } catch (error) { - event.returnValue = exceptionToMeta(event.sender, contextId, error) - } -@@ -332,7 +375,14 @@ - throwRPCError(`Cannot call constructor '${method}' on missing remote object ${id}`) - } - -+<<<<<<< .our - event.returnValue = valueToMeta(event.sender, contextId, new object[method](...args)) -+======= -+ // Call new with array of arguments. -+ let constructor = object[method] -+ let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args)))() -+ event.returnValue = valueToMeta(event.sender, contextId, obj) -+>>>>>>> .their - } catch (error) { - event.returnValue = exceptionToMeta(event.sender, contextId, error) - } -@@ -454,6 +504,7 @@ - event.returnValue = { - preloadSrc: preloadSrc, - preloadError: preloadError, -+<<<<<<< .our - process: { - arch: process.arch, - platform: process.platform, -@@ -461,5 +512,10 @@ - version: process.version, - versions: process.versions - } -+======= -+ webContentsId: event.sender.getId(), -+ platform: process.platform, -+ env: process.env -+>>>>>>> .their - } - }) -added in both - our 100644 b24f9e28b879154457be0342b9d4b44c0e651253 lib/renderer/security-warnings.js - their 100644 41557164ce716dec6d934ce49fe654a22c6658e3 lib/renderer/security-warnings.js -@@ -210,7 +210,12 @@ - */ - warnAboutExperimentalFeatures: () => { - const webPreferences = getWebPreferences() -+<<<<<<< .our - if (!webPreferences || (!webPreferences.experimentalFeatures)) { -+======= -+ if (!webPreferences || (!webPreferences.experimentalFeatures && -+ !webPreferences.experimentalCanvasFeatures)) { -+>>>>>>> .their - return - } - -added in both - our 100644 574a2b545597f9d1c05ec9b7147585063e90ae89 lib/renderer/web-view/web-view.js - their 100644 9e7f15bf084bbef671daa348b4264364c56837fc lib/renderer/web-view/web-view.js -@@ -131,7 +131,11 @@ - } - - onElementResize () { -+<<<<<<< .our - const resizeEvent = new Event('resize') -+======= -+ const resizeEvent = new Event('resize', { bubbles: true }) -+>>>>>>> .their - resizeEvent.newWidth = this.webviewNode.clientWidth - resizeEvent.newHeight = this.webviewNode.clientHeight - this.dispatchEvent(resizeEvent) -@@ -288,7 +292,10 @@ - 'inspectElement', - 'setAudioMuted', - 'isAudioMuted', -+<<<<<<< .our - 'isCurrentlyAudible', -+======= -+>>>>>>> .their - 'undo', - 'redo', - 'cut', -@@ -302,6 +309,10 @@ - 'replaceMisspelling', - 'findInPage', - 'stopFindInPage', -+<<<<<<< .our -+======= -+ 'getId', -+>>>>>>> .their - 'downloadURL', - 'inspectServiceWorker', - 'print', -added in both - our 100644 30a3fa55216f6bf7588c3accc07b150a31163b7c lib/sandboxed_renderer/init.js - their 100644 2b0d3b81ceef5480c28e8da249e38d8350808d15 lib/sandboxed_renderer/init.js -@@ -36,9 +36,21 @@ - ]) - - const { -+<<<<<<< .our - preloadSrc, preloadError, process: processProps - } = electron.ipcRenderer.sendSync('ELECTRON_BROWSER_SANDBOX_LOAD') - -+======= -+ preloadSrc, preloadError, webContentsId, platform, env -+} = electron.ipcRenderer.sendSync('ELECTRON_BROWSER_SANDBOX_LOAD') -+ -+Object.defineProperty(process, 'webContentsId', { -+ configurable: false, -+ writable: false, -+ value: webContentsId -+}) -+ -+>>>>>>> .their - require('../renderer/web-frame-init')() - - // Pass different process object to the preload script(which should not have -@@ -49,6 +61,7 @@ - preloadProcess.getHeapStatistics = () => binding.getHeapStatistics() - preloadProcess.getProcessMemoryInfo = () => binding.getProcessMemoryInfo() - preloadProcess.getSystemMemoryInfo = () => binding.getSystemMemoryInfo() -+<<<<<<< .our - preloadProcess.getCPUUsage = () => binding.getCPUUsage() - preloadProcess.getIOCounters = () => binding.getIOCounters() - preloadProcess.argv = process.argv = binding.getArgv() -@@ -59,6 +72,12 @@ - preloadProcess.type = 'renderer' - Object.assign(preloadProcess, processProps) - Object.assign(process, processProps) -+======= -+preloadProcess.argv = process.argv = binding.getArgv() -+preloadProcess.execPath = process.execPath = binding.getExecPath() -+preloadProcess.platform = process.platform = platform -+preloadProcess.env = process.env = env -+>>>>>>> .their - - process.on('exit', () => preloadProcess.emit('exit')) - -@@ -112,8 +131,15 @@ - ${preloadSrc} - })` - -+<<<<<<< .our - // eval in window scope - const preloadFn = binding.createPreloadScript(preloadWrapperSrc) -+======= -+ // eval in window scope: -+ // http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.2 -+ const geval = eval -+ const preloadFn = geval(preloadWrapperSrc) -+>>>>>>> .their - const {setImmediate, clearImmediate} = require('timers') - preloadFn(preloadRequire, preloadProcess, Buffer, global, setImmediate, clearImmediate) - } else if (preloadError) { -added in both - our 100644 bac533f6786ffad78ef1e711bc4a94d5b51cd36d native_mate/native_mate/dictionary.cc - their 100644 3caff114597440fecf0494c8565b4524602f2694 native_mate/native_mate/dictionary.cc -@@ -6,6 +6,7 @@ - - namespace mate { - -+<<<<<<< .our - Dictionary::Dictionary() : isolate_(NULL) {} - - Dictionary::Dictionary(v8::Isolate* isolate, v8::Local object) -@@ -14,6 +15,20 @@ - Dictionary::Dictionary(const Dictionary& other) = default; - - Dictionary::~Dictionary() = default; -+======= -+Dictionary::Dictionary() -+ : isolate_(NULL) { -+} -+ -+Dictionary::Dictionary(v8::Isolate* isolate, -+ v8::Local object) -+ : isolate_(isolate), -+ object_(object) { -+} -+ -+Dictionary::~Dictionary() { -+} -+>>>>>>> .their - - Dictionary Dictionary::CreateEmpty(v8::Isolate* isolate) { - return Dictionary(isolate, v8::Object::New(isolate)); -@@ -24,7 +39,11 @@ - } - - v8::Local Converter::ToV8(v8::Isolate* isolate, -+<<<<<<< .our - Dictionary val) { -+======= -+ Dictionary val) { -+>>>>>>> .their - return val.GetHandle(); - } - -added in both - our 100644 63a1350597604f9a0ab3233f7f6f24b0d3a81c22 native_mate/native_mate/dictionary.h - their 100644 9e80cb99acfdbedbeacc6a98d2398f9a2c17713f native_mate/native_mate/dictionary.h -@@ -35,12 +35,19 @@ - public: - Dictionary(); - Dictionary(v8::Isolate* isolate, v8::Local object); -+<<<<<<< .our - Dictionary(const Dictionary& other); -+======= -+>>>>>>> .their - virtual ~Dictionary(); - - static Dictionary CreateEmpty(v8::Isolate* isolate); - -+<<<<<<< .our - template -+======= -+ template -+>>>>>>> .their - bool Get(const base::StringPiece& key, T* out) const { - // Check for existence before getting, otherwise this method will always - // returns true when T == v8::Local. -@@ -55,30 +62,54 @@ - return ConvertFromV8(isolate_, val, out); - } - -+<<<<<<< .our - template -+======= -+ template -+>>>>>>> .their - bool GetHidden(const base::StringPiece& key, T* out) const { - v8::Local context = isolate_->GetCurrentContext(); - v8::Local privateKey = - v8::Private::ForApi(isolate_, StringToV8(isolate_, key)); - v8::Local value; -+<<<<<<< .our - v8::Maybe result = GetHandle()->HasPrivate(context, privateKey); -+======= -+ v8::Maybe result = -+ GetHandle()->HasPrivate(context, privateKey); -+>>>>>>> .their - if (internal::IsTrue(result) && - GetHandle()->GetPrivate(context, privateKey).ToLocal(&value)) - return ConvertFromV8(isolate_, value, out); - return false; - } - -+<<<<<<< .our - template -+======= -+ template -+>>>>>>> .their - bool Set(const base::StringPiece& key, const T& val) { - v8::Local v8_value; - if (!TryConvertToV8(isolate_, val, &v8_value)) - return false; -+<<<<<<< .our - v8::Maybe result = GetHandle()->Set( - isolate_->GetCurrentContext(), StringToV8(isolate_, key), v8_value); - return !result.IsNothing() && result.FromJust(); - } - - template -+======= -+ v8::Maybe result = -+ GetHandle()->Set(isolate_->GetCurrentContext(), -+ StringToV8(isolate_, key), -+ v8_value); -+ return !result.IsNothing() && result.FromJust(); -+ } -+ -+ template -+>>>>>>> .their - bool SetHidden(const base::StringPiece& key, T val) { - v8::Local v8_value; - if (!TryConvertToV8(isolate_, val, &v8_value)) -@@ -91,11 +122,16 @@ - return !result.IsNothing() && result.FromJust(); - } - -+<<<<<<< .our - template -+======= -+ template -+>>>>>>> .their - bool SetReadOnly(const base::StringPiece& key, T val) { - v8::Local v8_value; - if (!TryConvertToV8(isolate_, val, &v8_value)) - return false; -+<<<<<<< .our - v8::Maybe result = GetHandle()->DefineOwnProperty( - isolate_->GetCurrentContext(), StringToV8(isolate_, key), v8_value, - v8::ReadOnly); -@@ -103,6 +139,17 @@ - } - - template -+======= -+ v8::Maybe result = -+ GetHandle()->DefineOwnProperty(isolate_->GetCurrentContext(), -+ StringToV8(isolate_, key), -+ v8_value, -+ v8::ReadOnly); -+ return !result.IsNothing() && result.FromJust(); -+ } -+ -+ template -+>>>>>>> .their - bool SetMethod(const base::StringPiece& key, const T& callback) { - return GetHandle()->Set( - StringToV8(isolate_, key), -@@ -128,9 +175,16 @@ - v8::Local object_; - }; - -+<<<<<<< .our - template <> - struct Converter { - static v8::Local ToV8(v8::Isolate* isolate, Dictionary val); -+======= -+template<> -+struct Converter { -+ static v8::Local ToV8(v8::Isolate* isolate, -+ Dictionary val); -+>>>>>>> .their - static bool FromV8(v8::Isolate* isolate, - v8::Local val, - Dictionary* out); -added in both - our 100644 6a5e5a0253f4f465747fd0a4d96aad2336784d9c native_mate/native_mate/persistent_dictionary.cc - their 100644 fd68cdced275ed4848a9b866caea02b50fff8613 native_mate/native_mate/persistent_dictionary.cc -@@ -6,7 +6,12 @@ - - namespace mate { - -+<<<<<<< .our - PersistentDictionary::PersistentDictionary() {} -+======= -+PersistentDictionary::PersistentDictionary() { -+} -+>>>>>>> .their - - PersistentDictionary::PersistentDictionary(v8::Isolate* isolate, - v8::Local object) -@@ -14,10 +19,15 @@ - isolate_ = isolate; - } - -+<<<<<<< .our - PersistentDictionary::PersistentDictionary(const PersistentDictionary& other) = - default; - - PersistentDictionary::~PersistentDictionary() {} -+======= -+PersistentDictionary::~PersistentDictionary() { -+} -+>>>>>>> .their - - v8::Local PersistentDictionary::GetHandle() const { - return handle_->NewHandle(); -added in both - our 100644 7a83916f1505d53a8694c9d438485177d6cb539e native_mate/native_mate/persistent_dictionary.h - their 100644 26c8998632bd80876f5448a86a8f57b25e73801e native_mate/native_mate/persistent_dictionary.h -@@ -16,16 +16,27 @@ - public: - PersistentDictionary(); - PersistentDictionary(v8::Isolate* isolate, v8::Local object); -+<<<<<<< .our - PersistentDictionary(const PersistentDictionary& other); - ~PersistentDictionary() override; -+======= -+ virtual ~PersistentDictionary(); -+>>>>>>> .their - - v8::Local GetHandle() const override; - - private: -+<<<<<<< .our - scoped_refptr> handle_; - }; - - template <> -+======= -+ scoped_refptr > handle_; -+}; -+ -+template<> -+>>>>>>> .their - struct Converter { - static bool FromV8(v8::Isolate* isolate, - v8::Local val, -added in both - our 100644 faba6f332e4ac31eb55f08e9a76ae216f0916311 native_mate/native_mate/wrappable.h - their 100644 489c5817481b8663ffc2500ec89bf8c1e72dea0e native_mate/native_mate/wrappable.h -@@ -6,9 +6,15 @@ - #define NATIVE_MATE_WRAPPABLE_H_ - - #include "base/bind.h" -+<<<<<<< .our - #include "gin/per_isolate_data.h" - #include "native_mate/constructor.h" - #include "native_mate/converter.h" -+======= -+#include "native_mate/converter.h" -+#include "native_mate/constructor.h" -+#include "gin/per_isolate_data.h" -+>>>>>>> .their - - namespace mate { - -@@ -18,25 +24,42 @@ - - } // namespace internal - -+<<<<<<< .our - template -+======= -+template -+>>>>>>> .their - class Wrappable : public WrappableBase { - public: - Wrappable() {} - -+<<<<<<< .our - template -+======= -+ template -+>>>>>>> .their - static void SetConstructor(v8::Isolate* isolate, - const base::Callback& constructor) { - v8::Local templ = CreateFunctionTemplate( - isolate, base::Bind(&internal::InvokeNew, constructor)); - templ->InstanceTemplate()->SetInternalFieldCount(1); - T::BuildPrototype(isolate, templ); -+<<<<<<< .our - gin::PerIsolateData::From(isolate)->SetFunctionTemplate(&kWrapperInfo, - templ); -+======= -+ gin::PerIsolateData::From(isolate)->SetFunctionTemplate( -+ &kWrapperInfo, templ); -+>>>>>>> .their - } - - static v8::Local GetConstructor(v8::Isolate* isolate) { - // Fill the object template. -+<<<<<<< .our - auto* data = gin::PerIsolateData::From(isolate); -+======= -+ auto data = gin::PerIsolateData::From(isolate); -+>>>>>>> .their - auto templ = data->GetFunctionTemplate(&kWrapperInfo); - if (templ.IsEmpty()) { - templ = v8::FunctionTemplate::New(isolate); -@@ -55,9 +78,14 @@ - // |wrapper| may be empty in some extreme cases, e.g., when - // Object.prototype.constructor is overwritten. - v8::Local wrapper; -+<<<<<<< .our - if (!templ->InstanceTemplate() - ->NewInstance(isolate->GetCurrentContext()) - .ToLocal(&wrapper)) { -+======= -+ if (!templ->InstanceTemplate()->NewInstance( -+ isolate->GetCurrentContext()).ToLocal(&wrapper)) { -+>>>>>>> .their - // The current wrappable object will be no longer managed by V8. Delete - // this now. - delete this; -@@ -73,8 +101,13 @@ - }; - - // static -+<<<<<<< .our - template - gin::WrapperInfo Wrappable::kWrapperInfo = {gin::kEmbedderNativeGin}; -+======= -+template -+gin::WrapperInfo Wrappable::kWrapperInfo = { gin::kEmbedderNativeGin }; -+>>>>>>> .their - - // This converter handles any subclass of Wrappable. - template -@@ -89,8 +122,13 @@ - } - - static bool FromV8(v8::Isolate* isolate, v8::Local val, T** out) { -+<<<<<<< .our - *out = static_cast( - static_cast(internal::FromV8Impl(isolate, val))); -+======= -+ *out = static_cast(static_cast( -+ internal::FromV8Impl(isolate, val))); -+>>>>>>> .their - return *out != nullptr; - } - }; -added in both - our 100644 b1d8824658ea05c277e82d1ac6c6febab9c55030 package-lock.json - their 100644 5951cdf249d38722c0f19e847ce3f16c750f468f package-lock.json -@@ -1,13 +1,23 @@ - { - "name": "electron", -+<<<<<<< .our - "version": "4.0.0-nightly.20180819", -+======= -+ "version": "3.0.0-nightly.20180821", -+>>>>>>> .their - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/node": { -+<<<<<<< .our - "version": "7.0.69", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.69.tgz", - "integrity": "sha512-S5NC8HV6HnRipg8nC0j30TPl7ktXjRTKqgyINLNe8K/64UJUI8Lq0sRopXC0hProsV2F5ibj8IqPkl1xpGggrw==", -+======= -+ "version": "7.0.68", -+ "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.68.tgz", -+ "integrity": "sha512-ym3LNHwJQU0XDyPrTK6NHJTH5YmGKKe0k56in6pg+Wx4HD8fiKrt8xute6/unHvHujCfzmOQTGz1NoEKgFF5Mw==", -+>>>>>>> .their - "dev": true - }, - "JSONStream": { -@@ -30,7 +40,11 @@ - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", -+<<<<<<< .our - "integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg=", -+======= -+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", -+>>>>>>> .their - "dev": true - }, - "accepts": { -@@ -192,7 +206,11 @@ - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", -+<<<<<<< .our - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", -+======= -+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", -+>>>>>>> .their - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", -@@ -231,7 +249,11 @@ - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", -+<<<<<<< .our - "integrity": "sha1-VT3Lj5HjyImEXf26NMd3IbkLnXo=", -+======= -+ "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", -+>>>>>>> .their - "dev": true, - "requires": { - "micromatch": "2.3.11", -@@ -239,6 +261,7 @@ - } - }, - "arch": { -+<<<<<<< .our - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.1.tgz", - "integrity": "sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg==", -@@ -248,6 +271,11 @@ - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arg/-/arg-2.0.0.tgz", - "integrity": "sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w==", -+======= -+ "version": "2.1.0", -+ "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.0.tgz", -+ "integrity": "sha1-NhOqRhSQZLPB8GB5Gb8dR4boKIk=", -+>>>>>>> .their - "dev": true - }, - "argparse": { -@@ -326,7 +354,11 @@ - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", -+<<<<<<< .our - "integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=", -+======= -+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", -+>>>>>>> .their - "dev": true - }, - "array-filter": { -@@ -611,7 +643,11 @@ - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", -+<<<<<<< .our - "integrity": "sha1-LN4J617jQfSEdGuwMJsyU7GxRC8=", -+======= -+ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", -+>>>>>>> .their - "dev": true - }, - "boolbase": { -@@ -691,7 +727,11 @@ - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", -+<<<<<<< .our - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", -+======= -+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", -+>>>>>>> .their - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", -@@ -834,7 +874,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -1159,7 +1203,11 @@ - "check-for-leaks": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/check-for-leaks/-/check-for-leaks-1.2.0.tgz", -+<<<<<<< .our - "integrity": "sha1-6jtQFk6XV3kzLGKBMZX/jGr4Jsw=", -+======= -+ "integrity": "sha512-bJ2Bzo6RtsYqamMnsjtVzowGvBNVrR5IPK8Bd+lx5W1TNgOKMsF+AyNHVkqFqO7cpDZNfny5SaqH6gEovpV5Gw==", -+>>>>>>> .their - "dev": true, - "requires": { - "anymatch": "1.3.2", -@@ -1239,7 +1287,11 @@ - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", -+<<<<<<< .our - "integrity": "sha1-h2Dk7MJy9MNjUy+SbYdKriwTl94=", -+======= -+ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", -+>>>>>>> .their - "dev": true, - "requires": { - "inherits": "2.0.3", -@@ -1249,7 +1301,11 @@ - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", -+<<<<<<< .our - "integrity": "sha1-gVyZ6oT2gJUp0vRXkb34JxE1LWY=", -+======= -+ "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", -+>>>>>>> .their - "dev": true - }, - "clang-format": { -@@ -1323,7 +1379,11 @@ - "integrity": "sha512-2WNImOvCRe6r63Gk9pShfkwXsVtKCroMAevIbiae021mS850UkWPbevxsBz3tnvjZIEGvlwaqCPsw+4ulzNgJA==", - "dev": true, - "requires": { -+<<<<<<< .our - "arch": "2.1.1", -+======= -+ "arch": "2.1.0", -+>>>>>>> .their - "execa": "0.8.0" - }, - "dependencies": { -@@ -1442,6 +1502,7 @@ - } - }, - "compressible": { -+<<<<<<< .our - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.14.tgz", - "integrity": "sha1-MmxfUH+7BV9UEWeCuWmoG2einac=", -@@ -1462,15 +1523,45 @@ - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz", - "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", -+======= -+ "version": "2.0.13", -+ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.13.tgz", -+ "integrity": "sha1-DRAgq5JLL9tNYnmHXH1tq6a6p6k=", -+ "dev": true, -+ "requires": { -+ "mime-db": "1.33.0" -+ } -+ }, -+ "compression": { -+ "version": "1.7.2", -+ "resolved": "http://registry.npmjs.org/compression/-/compression-1.7.2.tgz", -+ "integrity": "sha1-qv+81qr4VLROuygDU9WtFlH1mmk=", -+>>>>>>> .their - "dev": true, - "requires": { - "accepts": "1.3.5", - "bytes": "3.0.0", -+<<<<<<< .our - "compressible": "2.0.14", - "debug": "2.6.9", - "on-headers": "1.0.1", - "safe-buffer": "5.1.2", - "vary": "1.1.2" -+======= -+ "compressible": "2.0.13", -+ "debug": "2.6.9", -+ "on-headers": "1.0.1", -+ "safe-buffer": "5.1.1", -+ "vary": "1.1.2" -+ }, -+ "dependencies": { -+ "safe-buffer": { -+ "version": "5.1.1", -+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", -+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", -+ "dev": true -+ } -+>>>>>>> .their - } - }, - "concat-map": { -@@ -1535,7 +1626,11 @@ - "dot-prop": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", -+<<<<<<< .our - "integrity": "sha1-HxngwuGqDjJ5fEl5nyg3rGr2nFc=", -+======= -+ "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "is-obj": "1.0.1" -@@ -1836,7 +1931,11 @@ - "boom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", -+<<<<<<< .our - "integrity": "sha1-XdnabuOl8wIHdDYpDLcX0/SlTgI=", -+======= -+ "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", -+>>>>>>> .their - "dev": true, - "requires": { - "hoek": "4.2.1" -@@ -1960,7 +2059,11 @@ - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", -+<<<<<<< .our - "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", -+======= -+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", -+>>>>>>> .their - "dev": true, - "requires": { - "ms": "2.0.0" -@@ -2070,7 +2173,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -2139,9 +2246,15 @@ - "dev": true - }, - "detect-port": { -+<<<<<<< .our - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.2.3.tgz", - "integrity": "sha512-IDbrX6PxqnYy8jV4wSHBaJlErYKTJvW8OQb9F7xivl1iQLqiUYHGa+nZ61Do6+N5uuOn/pReXKNqI9rUn04vug==", -+======= -+ "version": "1.2.2", -+ "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.2.2.tgz", -+ "integrity": "sha512-06H99JMCwgbYbA+codm97aBhFLAjABftetp+v+Z88Pvvlkawp2N+1bP/9J24+mihrvk9yBvUYTyIj3NixG1CsA==", -+>>>>>>> .their - "dev": true, - "requires": { - "address": "1.0.3", -@@ -2441,7 +2554,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -2523,12 +2640,21 @@ - } - }, - "electron-typescript-definitions": { -+<<<<<<< .our - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/electron-typescript-definitions/-/electron-typescript-definitions-1.3.6.tgz", - "integrity": "sha512-Wz6tPaaZ22lbfWwF9bzVSki7LMW96xilCT1M8eeNYZG6LcpA9x34jlrAZg5HZWTHXR2tfbTQhSmrY+FEVulD/A==", - "dev": true, - "requires": { - "@types/node": "7.0.69", -+======= -+ "version": "1.3.5", -+ "resolved": "https://registry.npmjs.org/electron-typescript-definitions/-/electron-typescript-definitions-1.3.5.tgz", -+ "integrity": "sha512-7Ryb7AN0Re63oeX3wHytjX0ScVlDcgj+GSBi6Q8aSNpo4B/sffAgZK6P/b4idqF26hp2jPJWcjBMizUb0VNfAQ==", -+ "dev": true, -+ "requires": { -+ "@types/node": "7.0.68", -+>>>>>>> .their - "colors": "1.2.5", - "debug": "2.6.9", - "electron-docs": "2.0.1", -@@ -2795,7 +2921,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -2901,7 +3031,11 @@ - "eslint-plugin-node": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-4.2.3.tgz", -+<<<<<<< .our - "integrity": "sha1-wEOQq428u2iHF0Aj1vOnJ2nmO5c=", -+======= -+ "integrity": "sha512-vIUQPuwbVYdz/CYnlTLsJrRy7iXHQjdEe5wz0XhhdTym3IInM/zZLlPf9nZ2mThsH0QcsieCOWs2vOeCy/22LQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "ignore": "3.3.8", -@@ -3057,7 +3191,11 @@ - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", -+<<<<<<< .our - "integrity": "sha1-f8vbGY3HGVlDLv4ThCaE4FJaywI=", -+======= -+ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", -+>>>>>>> .their - "dev": true, - "requires": { - "md5.js": "1.3.4", -@@ -3199,7 +3337,11 @@ - "find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", -+<<<<<<< .our - "integrity": "sha1-q8/Iunb3CMQql7PWhbfpRQv7nOQ=", -+======= -+ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", -+>>>>>>> .their - "dev": true - }, - "find-up": { -@@ -3880,7 +4022,11 @@ - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", -+<<<<<<< .our - "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=", -+======= -+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", -+>>>>>>> .their - "dev": true - }, - "generate-function": { -@@ -4059,7 +4205,11 @@ - "github": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/github/-/github-9.3.1.tgz", -+<<<<<<< .our - "integrity": "sha1-ajxanMKhzQtdCXpHuu+50Ryu+J4=", -+======= -+ "integrity": "sha512-LvVb6iR8/7bqYgj0VeAtqys0t427jwIBkv/+or/ssypfIk5R1fnz4aeIEv4udPw6VFoH6vL4gi+foBoD5aazXg==", -+>>>>>>> .their - "dev": true, - "requires": { - "follow-redirects": "0.0.7", -@@ -4112,7 +4262,11 @@ - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", -+<<<<<<< .our - "integrity": "sha1-qjiWs+abSH8X4x7SFD1pqOMMLYo=", -+======= -+ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", -+>>>>>>> .their - "dev": true - }, - "globby": { -@@ -4132,7 +4286,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -4173,7 +4331,11 @@ - "gunzip-maybe": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/gunzip-maybe/-/gunzip-maybe-1.4.1.tgz", -+<<<<<<< .our - "integrity": "sha1-Occu2J0bSbpwjhh3ZQBIiQKlICc=", -+======= -+ "integrity": "sha512-qtutIKMthNJJgeHQS7kZ9FqDq59/Wn0G2HYCRNjpup7yKfVI6/eqwpmroyZGFoCYaG+sW6psNVb4zoLADHpp2g==", -+>>>>>>> .their - "dev": true, - "requires": { - "browserify-zlib": "0.1.4", -@@ -4282,7 +4444,11 @@ - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", -+<<<<<<< .our - "integrity": "sha1-NA3tvmKQGHFRweodd3o0SJNd+EY=", -+======= -+ "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", -+>>>>>>> .their - "dev": true, - "requires": { - "inherits": "2.0.3", -@@ -4292,7 +4458,11 @@ - "hawk": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", -+<<<<<<< .our - "integrity": "sha1-r02RTrBl+bXOTZ0RwcshJu7MMDg=", -+======= -+ "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "boom": "4.3.1", -@@ -4425,7 +4595,11 @@ - "husky": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz", -+<<<<<<< .our - "integrity": "sha1-xp7XTi0neXaaF7qDmbVM4LY8EsM=", -+======= -+ "integrity": "sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA==", -+>>>>>>> .their - "dev": true, - "requires": { - "is-ci": "1.1.0", -@@ -5086,7 +5260,11 @@ - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", -+<<<<<<< .our - "integrity": "sha1-RJnt3NERDgshi6zy+n9/WfVcqAQ=", -+======= -+ "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", -+>>>>>>> .their - "dev": true - } - } -@@ -5683,7 +5861,11 @@ - "matcher-collection": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-1.0.5.tgz", -+<<<<<<< .our - "integrity": "sha1-LuCVQ4Nyy4iE8FgjQTjAXGROwzk=", -+======= -+ "integrity": "sha512-nUCmzKipcJEwYsBVAFh5P+d7JBuhJaW1xs85Hara9xuMLqtCVUrW6DSC0JVIkluxEH2W45nPBM/wjHtBXa/tYA==", -+>>>>>>> .their - "dev": true, - "requires": { - "minimatch": "3.0.4" -@@ -5832,6 +6014,7 @@ - } - }, - "micro": { -+<<<<<<< .our - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/micro/-/micro-9.3.1.tgz", - "integrity": "sha512-83uimpPJqfwkfKvJl2WWontBlV3hmzrIgyJ+L2uhDXKNk7Ll+/ezK3zBz7TljubpKPqjM0JdT2Ker4MTPmhjgA==", -@@ -5879,6 +6062,17 @@ - "has-flag": "3.0.0" - } - } -+======= -+ "version": "9.1.4", -+ "resolved": "https://registry.npmjs.org/micro/-/micro-9.1.4.tgz", -+ "integrity": "sha512-2eQ5QpO33LAPQJ/1iA3BrtLzdYlOCAXlstY4vcIj3SEmv0tsWuNZpsfgn1o8xGAYzf15kb+FXnEx8EklXz+pPg==", -+ "dev": true, -+ "requires": { -+ "content-type": "1.0.4", -+ "is-stream": "1.1.0", -+ "mri": "1.1.0", -+ "raw-body": "2.3.2" -+>>>>>>> .their - } - }, - "micro-compress": { -@@ -5887,7 +6081,11 @@ - "integrity": "sha1-U/WoC0rQMgyhZaVZtuPfFF1PcE8=", - "dev": true, - "requires": { -+<<<<<<< .our - "compression": "1.7.3" -+======= -+ "compression": "1.7.2" -+>>>>>>> .their - } - }, - "micromatch": { -@@ -5914,7 +6112,11 @@ - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", -+<<<<<<< .our - "integrity": "sha1-8IA1HIZbDcViqEYpZtqlNUPHik0=", -+======= -+ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", -+>>>>>>> .their - "dev": true, - "requires": { - "bn.js": "4.11.8", -@@ -5963,7 +6165,11 @@ - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", -+<<<<<<< .our - "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", -+======= -+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", -+>>>>>>> .their - "dev": true, - "requires": { - "brace-expansion": "1.1.11" -@@ -6181,7 +6387,11 @@ - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", -+<<<<<<< .our - "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=", -+======= -+ "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", -+>>>>>>> .their - "dev": true, - "requires": { - "hosted-git-info": "2.6.0", -@@ -6304,6 +6514,7 @@ - "is-extendable": "0.1.1" - } - }, -+<<<<<<< .our - "octicons": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/octicons/-/octicons-7.3.0.tgz", -@@ -6313,6 +6524,8 @@ - "object-assign": "4.1.1" - } - }, -+======= -+>>>>>>> .their - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", -@@ -7247,7 +7460,11 @@ - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", -+<<<<<<< .our - "integrity": "sha1-db3FiioUls7EihKDW8VMjVYjNt0=", -+======= -+ "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "is-equal-shallow": "0.1.3" -@@ -8064,7 +8281,11 @@ - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", -+<<<<<<< .our - "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=", -+======= -+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", -+>>>>>>> .their - "dev": true, - "requires": { - "glob": "7.1.2" -@@ -8073,7 +8294,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -8126,7 +8351,11 @@ - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", -+<<<<<<< .our - "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk=", -+======= -+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", -+>>>>>>> .their - "dev": true, - "optional": true - }, -@@ -8187,15 +8416,22 @@ - } - }, - "serve": { -+<<<<<<< .our - "version": "6.5.8", - "resolved": "https://registry.npmjs.org/serve/-/serve-6.5.8.tgz", - "integrity": "sha512-GZYlJz7f6E7Xq6xbg1rTSvQQV9x4v/yYB/sum6egzSBLa/mdk1PViDSX2JvL0Me83sxu3JpEpQELfakDKbGcrw==", -+======= -+ "version": "6.5.6", -+ "resolved": "https://registry.npmjs.org/serve/-/serve-6.5.6.tgz", -+ "integrity": "sha512-rdbHRzBh94UdZPktcoNjWEUqY0ILanZ8Q+VwNfhw5n93pkCPn86wH8x+hXgRi8II9+xj3DvGMWL/6hGUQyfuXg==", -+>>>>>>> .their - "dev": true, - "requires": { - "args": "4.0.0", - "basic-auth": "2.0.0", - "bluebird": "3.5.1", - "boxen": "1.3.0", -+<<<<<<< .our - "chalk": "2.4.1", - "clipboardy": "1.2.3", - "dargs": "5.1.0", -@@ -8205,6 +8441,17 @@ - "handlebars": "4.0.11", - "ip": "1.1.5", - "micro": "9.3.1", -+======= -+ "chalk": "2.4.0", -+ "clipboardy": "1.2.3", -+ "dargs": "5.1.0", -+ "detect-port": "1.2.2", -+ "filesize": "3.6.1", -+ "fs-extra": "5.0.0", -+ "handlebars": "4.0.11", -+ "ip": "1.1.5", -+ "micro": "9.1.4", -+>>>>>>> .their - "micro-compress": "1.0.0", - "mime-types": "2.1.18", - "node-version": "1.1.3", -@@ -8213,7 +8460,11 @@ - "path-is-inside": "1.0.2", - "path-type": "3.0.0", - "send": "0.16.2", -+<<<<<<< .our - "update-check": "1.5.1" -+======= -+ "update-check": "1.3.2" -+>>>>>>> .their - }, - "dependencies": { - "ansi-styles": { -@@ -8226,9 +8477,15 @@ - } - }, - "chalk": { -+<<<<<<< .our - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", -+======= -+ "version": "2.4.0", -+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.0.tgz", -+ "integrity": "sha512-Wr/w0f4o9LuE7K53cD0qmbAMM+2XNLzR29vFn5hqko4sxGlUsyy363NvmyGIyk5tpe9cjTr9SJYbysEyPkRnFw==", -+>>>>>>> .their - "dev": true, - "requires": { - "ansi-styles": "3.2.1", -@@ -8243,14 +8500,24 @@ - "dev": true - }, - "fs-extra": { -+<<<<<<< .our - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", - "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==", -+======= -+ "version": "5.0.0", -+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", -+ "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "4.0.0", -+<<<<<<< .our - "universalify": "0.1.2" -+======= -+ "universalify": "0.1.1" -+>>>>>>> .their - } - }, - "has-flag": { -@@ -8373,7 +8640,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -8475,7 +8746,11 @@ - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", -+<<<<<<< .our - "integrity": "sha1-YFvZvjA6pZ+zX5Ip++oN3snqB9k=", -+======= -+ "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", -+>>>>>>> .their - "dev": true, - "requires": { - "through": "2.3.8" -@@ -8484,7 +8759,11 @@ - "split2": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", -+<<<<<<< .our - "integrity": "sha1-GGsldbz4PoW30YRldWI47k7kJJM=", -+======= -+ "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", -+>>>>>>> .their - "dev": true, - "requires": { - "through2": "2.0.3" -@@ -8552,7 +8831,11 @@ - "standard-markdown": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/standard-markdown/-/standard-markdown-4.0.2.tgz", -+<<<<<<< .our - "integrity": "sha1-NaC1bLtX5JzuLXQ9ocmERMNK1Lg=", -+======= -+ "integrity": "sha512-h+WTmoGN0qmse8I1VX8VD6V5JeVLXZOPQltvxQP9FfSpSl6RmKYMLTUQ2j/QhdmsdxQKDqulZF/Bf8oEnttIQA==", -+>>>>>>> .their - "dev": true, - "requires": { - "async": "2.6.0", -@@ -8611,7 +8894,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -9055,7 +9342,11 @@ - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", -+<<<<<<< .our - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", -+======= -+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", -+>>>>>>> .their - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", -@@ -9207,7 +9498,11 @@ - "text-extensions": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.7.0.tgz", -+<<<<<<< .our - "integrity": "sha1-+qq6JiXtdG1WiiPk0KrNm/CKizk=", -+======= -+ "integrity": "sha512-AKXZeDq230UaSzaO5s3qQUZOaC7iKbzq0jOFL614R7d9R593HLqAOL0cYoqLdkNrjBSOdmoQI06yigq1TSBXAg==", -+>>>>>>> .their - "dev": true - }, - "text-table": { -@@ -9409,7 +9704,11 @@ - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", -+<<<<<<< .our - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", -+======= -+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "fs.realpath": "1.0.0", -@@ -9744,9 +10043,15 @@ - } - }, - "universalify": { -+<<<<<<< .our - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", -+======= -+ "version": "0.1.1", -+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", -+ "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=", -+>>>>>>> .their - "dev": true - }, - "unpipe": { -@@ -9771,9 +10076,15 @@ - "dev": true - }, - "update-check": { -+<<<<<<< .our - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.1.tgz", - "integrity": "sha512-M3rjq5KwSrWZrm2GVPIQIF+NXpIn5I9mIV67gGoydptQvzRjLp9ZbM6ctFJeNuaWSm5+mNP7aInELjSiLcIw6A==", -+======= -+ "version": "1.3.2", -+ "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.3.2.tgz", -+ "integrity": "sha512-0iGt63gXrsU4VTw4tIGVVk14H6KLHI7ExNPuSmdDdwUrUAQTBnh1hQcRpnoBWetb3/Ab4YyXK1iDWXP7D0VHTQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "registry-auth-token": "3.3.2", -@@ -10002,7 +10313,11 @@ - "walk-sync": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-0.3.2.tgz", -+<<<<<<< .our - "integrity": "sha1-SCcoCvxC0OA1NnxKTjHurA0Tb3U=", -+======= -+ "integrity": "sha512-FMB5VqpLqOCcqrzA9okZFc0wq0Qbmdm396qJxvQZhDpyu0W95G9JCmp74tx7iyYnyOcBtUuKJsgIKAqjozvmmQ==", -+>>>>>>> .their - "dev": true, - "requires": { - "ensure-posix-path": "1.0.2", -@@ -10029,7 +10344,11 @@ - "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", -+<<<<<<< .our - "integrity": "sha1-/wS9/AEO5UfXgL7DjhrBwnd9JTo=", -+======= -+ "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", -+>>>>>>> .their - "dev": true, - "requires": { - "isexe": "2.0.0" -@@ -10142,7 +10461,11 @@ - "write-file-atomic": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", -+<<<<<<< .our - "integrity": "sha1-H/YVdcLipOjlENb6TiQ8zhg5mas=", -+======= -+ "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", -+>>>>>>> .their - "dev": true, - "requires": { - "graceful-fs": "4.1.11", -added in both - our 100644 c081cd89450cd50efba1ec280ff1349a96ea3ce0 package.json - their 100644 76ec83ce2fab14c29f975bef623d45febcb4166e package.json -@@ -1,6 +1,10 @@ - { - "name": "electron", -+<<<<<<< .our - "version": "4.0.0-nightly.20180821", -+======= -+ "version": "3.0.0-beta.7", -+>>>>>>> .their - "repository": "https://github.com/electron/electron", - "description": "Build cross platform desktop apps with JavaScript, HTML, and CSS", - "devDependencies": { -@@ -13,7 +17,11 @@ - "dugite": "^1.45.0", - "electabul": "~0.0.4", - "electron-docs-linter": "^2.3.4", -+<<<<<<< .our - "electron-typescript-definitions": "^1.3.6", -+======= -+ "electron-typescript-definitions": "^1.3.5", -+>>>>>>> .their - "github": "^9.2.0", - "html-entities": "^1.2.1", - "husky": "^0.14.3", -@@ -21,12 +29,19 @@ - "minimist": "^1.2.0", - "node-fetch": "^2.1.2", - "nugget": "^2.0.1", -+<<<<<<< .our - "octicons": "^7.3.0", -+======= -+>>>>>>> .their - "remark-cli": "^4.0.0", - "remark-preset-lint-markdown-style-guide": "^2.1.1", - "request": "^2.68.0", - "semver": "^5.5.0", -+<<<<<<< .our - "serve": "^6.5.8", -+======= -+ "serve": "^6.5.3", -+>>>>>>> .their - "standard": "^10.0.0", - "standard-markdown": "^4.0.0", - "sumchecker": "^2.0.2", -@@ -45,6 +60,7 @@ - "private": true, - "scripts": { - "asar": "asar", -+<<<<<<< .our - "bootstrap:dev": "python ./script/bootstrap.py -d -v", - "bootstrap": "python ./script/bootstrap.py -v", - "browserify": "browserify", -@@ -54,6 +70,13 @@ - "build:release": "python ./script/build.py -c R", - "rebuild-test-modules": "python ./script/rebuild-test-modules.py", - "check-tls": "python ./script/tls.py", -+======= -+ "bootstrap": "python ./script/bootstrap.py", -+ "browserify": "browserify", -+ "bump-version": "./script/bump-version.py", -+ "build": "python ./script/build.py -c D", -+ "rebuild-test-modules": "python ./script/rebuild-test-modules.py", -+>>>>>>> .their - "clean": "python ./script/clean.py", - "clean-build": "python ./script/clean.py --build", - "clang-format": "find atom/ brightray/ chromium_src/ -iname *.h -o -iname *.cc -o -iname *.mm | xargs clang-format -i", -added in both - our 100755 4a6c0c7ce8f275175e48c4c380ff33627f7a5961 script/create-dist.py - their 100755 ae5ce3707c38e61716f96cf5e7627cc909597fb8 script/create-dist.py -@@ -11,6 +11,7 @@ - if sys.platform == "win32": - import _winreg - -+<<<<<<< .our - from lib.config import BASE_URL, PLATFORM, build_env, \ - enable_verbose_mode, get_target_arch, get_zip_name - -@@ -18,6 +19,12 @@ - execute, get_electron_version, make_zip, \ - parse_version, rm_rf, scoped_cwd - -+======= -+from lib.config import BASE_URL, PLATFORM, enable_verbose_mode, \ -+ get_target_arch, get_zip_name, build_env -+from lib.util import scoped_cwd, rm_rf, get_electron_version, make_zip, \ -+ execute, electron_gyp, electron_features, parse_version -+>>>>>>> .their - from lib.env_util import get_vs_location - - -@@ -147,7 +154,11 @@ - - # Copy file and keep the executable bit. - shutil.copyfile(src, dest) -+<<<<<<< .our - add_exec_bit(dest) -+======= -+ os.chmod(dest, os.stat(dest).st_mode | stat.S_IEXEC) -+>>>>>>> .their - - def copy_vcruntime_binaries(): - arch = get_target_arch() -@@ -302,7 +313,11 @@ - dest = os.path.join(DIST_DIR, binary) - # Copy file and keep the executable bit. - shutil.copyfile(src, dest) -+<<<<<<< .our - add_exec_bit(dest) -+======= -+ os.chmod(dest, os.stat(dest).st_mode | stat.S_IEXEC) -+>>>>>>> .their - - dist_name = get_zip_name(binary, version) - zip_file = os.path.join(SOURCE_ROOT, 'dist', dist_name) -added in both - our 100644 d479d5a9556534c5d98ae1fdc97397cdd14376f5 script/lib/util.py - their 100644 617b576b88402a98233dda952a262176221bdc54 script/lib/util.py -@@ -8,7 +8,10 @@ - import re - import shutil - import ssl -+<<<<<<< .our - import stat -+======= -+>>>>>>> .their - import subprocess - import sys - import tarfile -@@ -84,7 +87,10 @@ - if hasattr(ssl, '_create_unverified_context'): - ssl._create_default_https_context = ssl._create_unverified_context - -+<<<<<<< .our - print "Downloading %s to %s" % (url, path) -+======= -+>>>>>>> .their - web_file = urllib2.urlopen(url) - file_size = int(web_file.info().getheaders("Content-Length")[0]) - downloaded_size = 0 -@@ -297,9 +303,12 @@ - else: - execute_stdout(args, env) - -+<<<<<<< .our - def add_exec_bit(filename): - os.chmod(filename, os.stat(filename).st_mode | stat.S_IEXEC) - -+======= -+>>>>>>> .their - def clean_parse_version(v): - return parse_version(v.split("-")[0]) - -@@ -347,7 +356,11 @@ - return make_version(pv[0] , pv[1], pv[2], 'beta.1') - - lv = parse_version(tag_list[-1]) -+<<<<<<< .our - return make_version(pv[0] , pv[1], pv[2], 'beta.' + str(int(lv[3]) + 1)) -+======= -+ return make_version(pv[0], pv[1], pv[2], 'beta.' + str(int(lv[3]) + 1)) -+>>>>>>> .their - - def get_next_stable_from_pre(v): - pv = clean_parse_version(v) -added in both - our 100755 72a28b719bf1ff7770692caef86c76746c4d8edf script/prepare-release.js - their 100755 30b0a0e54967ef967c8e2bb1abc0f72b24b11ace script/prepare-release.js -@@ -141,6 +141,10 @@ - } - - async function createRelease (branchToTarget, isBeta) { -+<<<<<<< .our -+======= -+ console.log('creating release for', branchToTarget, `isBeta=${isBeta}`) -+>>>>>>> .their - let releaseNotes = await getReleaseNotes(branchToTarget) - let newVersion = await getNewVersion() - await tagRelease(newVersion) -@@ -182,6 +186,10 @@ - } - githubOpts.tag_name = newVersion - githubOpts.target_commitish = newVersion.indexOf('nightly') !== -1 ? 'master' : branchToTarget -+<<<<<<< .our -+======= -+ console.log('creating release with github opts', githubOpts) -+>>>>>>> .their - await github.repos.createRelease(githubOpts) - .catch(err => { - console.log(`${fail} Error creating new release: `, err) -added in both - our 100755 0bc9d0f632057f4a17aa811340ba21631433f173 script/update-external-binaries.py - their 100755 e67ac996e2605be675a0431db7fb61fd28a1445c script/update-external-binaries.py -@@ -4,11 +4,19 @@ - import sys - import os - -+<<<<<<< .our - from lib.config import PLATFORM, get_target_arch - from lib.util import add_exec_bit, download, extract_zip, rm_rf, \ - safe_mkdir, tempdir - - VERSION = 'v1.4.0' -+======= -+from lib.config import get_target_arch -+from lib.util import safe_mkdir, rm_rf, extract_zip, tempdir, download -+ -+ -+VERSION = 'v1.3.0' -+>>>>>>> .their - SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) - FRAMEWORKS_URL = 'http://github.com/electron/electron-frameworks/releases' \ - '/download/' + VERSION -@@ -31,6 +39,7 @@ - elif sys.platform in ['cygwin', 'win32']: - download_and_unzip('directxsdk-' + get_target_arch()) - -+<<<<<<< .our - # get sccache & set exec bit. https://bugs.python.org/issue15795 - download_and_unzip('sccache-{0}-x64'.format(PLATFORM)) - appname = 'sccache' -@@ -38,6 +47,8 @@ - appname += '.exe' - add_exec_bit(os.path.join('external_binaries', appname)) - -+======= -+>>>>>>> .their - with open(version_file, 'w') as f: - f.write(VERSION) - -added in both - our 100755 5fe196270e64f8d9b5f16483a10425382135cc2e script/verify-ffmpeg.py - their 100755 1d78515a4ade0f9f283e9064ad08e3637affb003 script/verify-ffmpeg.py -@@ -1,5 +1,9 @@ - #!/usr/bin/env python -+<<<<<<< .our - import argparse -+======= -+ -+>>>>>>> .their - import os - import shutil - import subprocess -@@ -17,10 +21,21 @@ - - - def main(): -+<<<<<<< .our - args = parse_args() - os.chdir(args.source_root) - - app_path = create_app_copy(args) -+======= -+ os.chdir(SOURCE_ROOT) -+ -+ if len(sys.argv) == 2 and sys.argv[1] == '-R': -+ config = 'R' -+ else: -+ config = 'D' -+ -+ app_path = create_app_copy(config) -+>>>>>>> .their - - if sys.platform == 'darwin': - electron = os.path.join(app_path, 'Contents', 'MacOS', PRODUCT_NAME) -@@ -38,12 +53,20 @@ - ffmpeg_name = 'libffmpeg.so' - - # Copy ffmpeg without proprietary codecs into app -+<<<<<<< .our - shutil.copy(os.path.join(args.ffmpeg_path, ffmpeg_name), ffmpeg_app_path) - - returncode = 0 - try: - test_path = os.path.join(SOURCE_ROOT, 'spec', 'fixtures', - 'no-proprietary-codecs.js') -+======= -+ shutil.copy(os.path.join(FFMPEG_LIBCC_PATH, ffmpeg_name), ffmpeg_app_path) -+ -+ returncode = 0 -+ try: -+ test_path = os.path.join('spec', 'fixtures', 'no-proprietary-codecs.js') -+>>>>>>> .their - subprocess.check_call([electron, test_path] + sys.argv[1:]) - except subprocess.CalledProcessError as e: - returncode = e.returncode -@@ -54,10 +77,16 @@ - - - # Create copy of app to install ffmpeg library without proprietary codecs into -+<<<<<<< .our - def create_app_copy(args): - initial_app_path = os.path.join(args.source_root, 'out', args.config) - app_path = os.path.join(args.source_root, 'out', - args.config + '-no-proprietary-codecs') -+======= -+def create_app_copy(config): -+ initial_app_path = os.path.join(SOURCE_ROOT, 'out', config) -+ app_path = os.path.join(SOURCE_ROOT, 'out', config + '-no-proprietary-codecs') -+>>>>>>> .their - - if sys.platform == 'darwin': - app_name = '{0}.app'.format(PRODUCT_NAME) -@@ -68,6 +97,7 @@ - shutil.copytree(initial_app_path, app_path, symlinks=True) - return app_path - -+<<<<<<< .our - def parse_args(): - parser = argparse.ArgumentParser(description='Test non-proprietary ffmpeg') - parser.add_argument('-c', '--config', -@@ -81,6 +111,8 @@ - default=FFMPEG_LIBCC_PATH, - required=False) - return parser.parse_args() -+======= -+>>>>>>> .their - - if __name__ == '__main__': - sys.exit(main()) -added in both - our 100644 d224eda2989332c18d655cef05a8bacc2eb6d4b8 spec/api-app-spec.js - their 100644 37c5520a1d27d6988eb30267b7a8ca6ae83d2b20 spec/api-app-spec.js -@@ -168,9 +168,14 @@ - const electronPath = remote.getGlobal('process').execPath - - appProcess = ChildProcess.spawn(electronPath, [appPath]) -+<<<<<<< .our - appProcess.on('close', (code, signal) => { - expect(signal).to.equal(null, 'exit signal should be null, if you see this please tag @MarshallOfSound') - expect(code).to.equal(123, 'exit code should be 123, if you see this please tag @MarshallOfSound') -+======= -+ appProcess.on('close', code => { -+ expect(code).to.equal(123) -+>>>>>>> .their - done() - }) - }) -@@ -796,7 +801,12 @@ - }) - }) - -+<<<<<<< .our - describe('getAppMetrics() API', () => { -+======= -+ // TODO(marshallofsound): [Ch66] Failed on Windows x64 + ia32 on CI, passes locally -+ xdescribe('getAppMetrics() API', () => { -+>>>>>>> .their - it('returns memory and cpu stats of all running electron processes', () => { - const appMetrics = app.getAppMetrics() - expect(appMetrics).to.be.an('array').and.have.lengthOf.at.least(1, 'App memory info object is not > 0') -@@ -804,6 +814,7 @@ - const types = [] - for (const {memory, pid, type, cpu} of appMetrics) { - expect(memory.workingSetSize).to.be.above(0, 'working set size is not > 0') -+<<<<<<< .our - - // windows causes failures here due to CI server configuration - if (process.platform !== 'win32') { -@@ -811,6 +822,10 @@ - expect(memory.sharedBytes).to.be.above(0, 'shared bytes is not > 0') - } - -+======= -+ expect(memory.privateBytes).to.be.above(0, 'private bytes is not > 0') -+ expect(memory.sharedBytes).to.be.above(0, 'shared bytes is not > 0') -+>>>>>>> .their - expect(pid).to.be.above(0, 'pid is not > 0') - expect(type).to.be.a('string').that.is.not.empty() - -added in both - our 100644 f4cba12ec19d224bc46fca898db42a99baf4972e spec/api-browser-window-spec.js - their 100644 8349bbd4d5b1b19ce52c7cc519cfe757d7c09e3f spec/api-browser-window-spec.js -@@ -1,8 +1,12 @@ - 'use strict' - - const assert = require('assert') -+<<<<<<< .our - const chai = require('chai') - const dirtyChai = require('dirty-chai') -+======= -+const {expect} = require('chai') -+>>>>>>> .their - const fs = require('fs') - const path = require('path') - const os = require('os') -@@ -14,12 +18,19 @@ - const {app, ipcMain, BrowserWindow, BrowserView, protocol, session, webContents} = remote - - const features = process.atomBinding('features') -+<<<<<<< .our - const {expect} = chai - const isCI = remote.getGlobal('isCi') - const nativeModulesEnabled = remote.getGlobal('nativeModulesEnabled') - - chai.use(dirtyChai) - -+======= -+ -+const isCI = remote.getGlobal('isCi') -+const nativeModulesEnabled = remote.getGlobal('nativeModulesEnabled') -+ -+>>>>>>> .their - describe('BrowserWindow module', () => { - const fixtures = path.resolve(__dirname, 'fixtures') - let w = null -@@ -27,6 +38,7 @@ - let server - let postData - -+<<<<<<< .our - const defaultOptions = { - show: false, - width: 400, -@@ -45,6 +57,8 @@ - return w - } - -+======= -+>>>>>>> .their - const closeTheWindow = function () { - return closeWindow(w).then(() => { w = null }) - } -@@ -99,13 +113,32 @@ - server = null - }) - -+<<<<<<< .our - beforeEach(openTheWindow) -+======= -+ beforeEach(() => { -+ w = new BrowserWindow({ -+ show: false, -+ width: 400, -+ height: 400, -+ webPreferences: { -+ backgroundThrottling: false -+ } -+ }) -+ }) -+>>>>>>> .their - - afterEach(closeTheWindow) - - describe('BrowserWindow constructor', () => { - it('allows passing void 0 as the webContents', () => { -+<<<<<<< .our - openTheWindow({ -+======= -+ w.close() -+ w = null -+ w = new BrowserWindow({ -+>>>>>>> .their - webContents: void 0 - }) - }) -@@ -217,7 +250,11 @@ - const contents = w.webContents - w.destroy() - assert.throws(() => { -+<<<<<<< .our - contents.getProcessId() -+======= -+ contents.getId() -+>>>>>>> .their - }, /Object has been destroyed/) - }) - }) -@@ -422,6 +459,7 @@ - }) - - describe('BrowserWindow.capturePage(rect, callback)', () => { -+<<<<<<< .our - it('calls the callback with a Buffer', async () => { - const image = await new Promise((resolve) => { - w.capturePage({ -@@ -452,10 +490,46 @@ - // Check the 25th byte in the PNG. - // Values can be 0,2,3,4, or 6. We want 6, which is RGB + Alpha - expect(imgBuffer[25]).to.equal(6) -+======= -+ it('calls the callback with a Buffer', (done) => { -+ w.capturePage({ -+ x: 0, -+ y: 0, -+ width: 100, -+ height: 100 -+ }, (image) => { -+ assert.equal(image.isEmpty(), true) -+ done() -+ }) -+ }) -+ -+ it('preserves transparency', (done) => { -+ w.close() -+ const width = 400 -+ const height = 400 -+ w = new BrowserWindow({ -+ show: false, -+ width: width, -+ height: height, -+ transparent: true -+ }) -+ w.loadURL('data:text/html,') -+ w.once('ready-to-show', () => { -+ w.show() -+ w.capturePage((image) => { -+ let imgBuffer = image.toPNG() -+ // Check 25th byte in the PNG -+ // Values can be 0,2,3,4, or 6. We want 6, which is RGB + Alpha -+ assert.equal(imgBuffer[25], 6) -+ done() -+ }) -+ }) -+>>>>>>> .their - }) - }) - - describe('BrowserWindow.setSize(width, height)', () => { -+<<<<<<< .our - it('sets the window size', async () => { - const size = [300, 400] - -@@ -464,6 +538,15 @@ - await resized - - assertBoundsEqual(w.getSize(), size) -+======= -+ it('sets the window size', (done) => { -+ const size = [300, 400] -+ w.once('resize', () => { -+ assertBoundsEqual(w.getSize(), size) -+ done() -+ }) -+ w.setSize(size[0], size[1]) -+>>>>>>> .their - }) - }) - -@@ -765,6 +848,7 @@ - }) - }) - -+<<<<<<< .our - describe('BrowserWindow.setWindowButtonVisibility()', () => { - before(function () { - if (process.platform !== 'darwin') { -@@ -792,6 +876,8 @@ - }) - }) - -+======= -+>>>>>>> .their - describe('BrowserWindow.setVibrancy(type)', () => { - it('allows setting, changing, and removing the vibrancy', () => { - assert.doesNotThrow(() => { -@@ -928,6 +1014,7 @@ - }) - }) - -+<<<<<<< .our - describe('BrowserWindow.setShape(rects)', () => { - it('allows setting shape', () => { - assert.doesNotThrow(() => { -@@ -939,6 +1026,8 @@ - }) - }) - -+======= -+>>>>>>> .their - describe('"useContentSize" option', () => { - it('make window created with content size when used', () => { - w.destroy() -@@ -1617,6 +1706,7 @@ - - it('validates process APIs access in sandboxed renderer', (done) => { - ipcMain.once('answer', function (event, test) { -+<<<<<<< .our - assert.equal(test.pid, w.webContents.getOSProcessId()) - assert.equal(test.arch, remote.process.arch) - assert.equal(test.platform, remote.process.platform) -@@ -1627,6 +1717,11 @@ - assert.equal(test.type, 'renderer') - assert.equal(test.version, remote.process.version) - assert.deepEqual(test.versions, remote.process.versions) -+======= -+ assert.equal(test.platform, remote.process.platform) -+ assert.deepEqual(test.env, remote.process.env) -+ assert.equal(test.execPath, remote.process.helperExecPath) -+>>>>>>> .their - done() - }) - remote.process.env.sandboxmain = 'foo' -added in both - our 100644 fb3ee998eace4401d6f129930d802677ce5feb85 spec/api-menu-item-spec.js - their 100644 9bbb2e38da2cecb068528ded21307b387da337f1 spec/api-menu-item-spec.js -@@ -1,11 +1,16 @@ -+<<<<<<< .our - const chai = require('chai') - const dirtyChai = require('dirty-chai') -+======= -+const assert = require('assert') -+>>>>>>> .their - - const {remote} = require('electron') - const {BrowserWindow, app, Menu, MenuItem} = remote - const roles = require('../lib/browser/api/menu-item-roles') - const {closeWindow} = require('./window-helpers') - -+<<<<<<< .our - const {expect} = chai - chai.use(dirtyChai) - -@@ -17,6 +22,16 @@ - click: (item) => { - expect(item.constructor.name).to.equal('MenuItem') - expect(item.label).to.equal('text') -+======= -+describe('MenuItems', () => { -+ describe('MenuItem.click', () => { -+ it('should be called with the item object passed', (done) => { -+ const menu = Menu.buildFromTemplate([{ -+ label: 'text', -+ click: (item) => { -+ assert.equal(item.constructor.name, 'MenuItem') -+ assert.equal(item.label, 'text') -+>>>>>>> .their - done() - } - }]) -@@ -31,9 +46,15 @@ - type: 'checkbox' - }]) - -+<<<<<<< .our - expect(menu.items[0].checked).to.be.false() - menu.delegate.executeCommand(menu, {}, menu.items[0].commandId) - expect(menu.items[0].checked).to.be.true() -+======= -+ assert.equal(menu.items[0].checked, false) -+ menu.delegate.executeCommand(menu, {}, menu.items[0].commandId) -+ assert.equal(menu.items[0].checked, true) -+>>>>>>> .their - }) - - it('clicking an radio item should always make checked property true', () => { -@@ -43,9 +64,15 @@ - }]) - - menu.delegate.executeCommand(menu, {}, menu.items[0].commandId) -+<<<<<<< .our - expect(menu.items[0].checked).to.be.true() - menu.delegate.executeCommand(menu, {}, menu.items[0].commandId) - expect(menu.items[0].checked).to.be.true() -+======= -+ assert.equal(menu.items[0].checked, true) -+ menu.delegate.executeCommand(menu, {}, menu.items[0].commandId) -+ assert.equal(menu.items[0].checked, true) -+>>>>>>> .their - }) - - describe('MenuItem group properties', () => { -@@ -100,7 +127,11 @@ - const groups = findRadioGroups(template) - - groups.forEach(g => { -+<<<<<<< .our - expect(findChecked(menu.items, g.begin, g.end)).to.deep.equal([g.begin]) -+======= -+ assert.deepEqual(findChecked(menu.items, g.begin, g.end), [g.begin]) -+>>>>>>> .their - }) - }) - -@@ -113,12 +144,20 @@ - const groupId = menu.items[g.begin].groupId - - // groupId should be previously unused -+<<<<<<< .our - expect(usedGroupIds.has(groupId)).to.be.false() -+======= -+ assert(!usedGroupIds.has(groupId)) -+>>>>>>> .their - usedGroupIds.add(groupId) - - // everything in the group should have the same id - for (let i = g.begin; i < g.end; ++i) { -+<<<<<<< .our - expect(menu.items[i].groupId).to.equal(groupId) -+======= -+ assert.equal(menu.items[i].groupId, groupId) -+>>>>>>> .their - } - }) - }) -@@ -128,6 +167,7 @@ - - const groups = findRadioGroups(template) - groups.forEach(g => { -+<<<<<<< .our - expect(findChecked(menu.items, g.begin, g.end)).to.deep.equal([]) - - menu.items[g.begin].checked = true -@@ -135,6 +175,15 @@ - - menu.items[g.end - 1].checked = true - expect(findChecked(menu.items, g.begin, g.end)).to.deep.equal([g.end - 1]) -+======= -+ assert.deepEqual(findChecked(menu.items, g.begin, g.end), []) -+ -+ menu.items[g.begin].checked = true -+ assert.deepEqual(findChecked(menu.items, g.begin, g.end), [g.begin]) -+ -+ menu.items[g.end - 1].checked = true -+ assert.deepEqual(findChecked(menu.items, g.begin, g.end), [g.end - 1]) -+>>>>>>> .their - }) - }) - }) -@@ -146,7 +195,11 @@ - let item = new MenuItem({role: 'asdfghjkl'}) - - const canExecute = roles.execute(item.role, win, win.webContents) -+<<<<<<< .our - expect(canExecute).to.be.false() -+======= -+ assert.equal(false, canExecute) -+>>>>>>> .their - - closeWindow(win).then(() => { win = null }) - }) -@@ -156,7 +209,11 @@ - let item = new MenuItem({role: 'reload'}) - - const canExecute = roles.execute(item.role, win, win.webContents) -+<<<<<<< .our - expect(canExecute).to.be.true() -+======= -+ assert.equal(true, canExecute) -+>>>>>>> .their - - closeWindow(win).then(() => { win = null }) - }) -@@ -166,7 +223,11 @@ - let item = new MenuItem({role: 'resetzoom'}) - - const canExecute = roles.execute(item.role, win, win.webContents) -+<<<<<<< .our - expect(canExecute).to.be.true() -+======= -+ assert.equal(true, canExecute) -+>>>>>>> .their - - closeWindow(win).then(() => { win = null }) - }) -@@ -177,31 +238,53 @@ - const item = new MenuItem({label: 'item'}) - - const commandId = item.commandId -+<<<<<<< .our - expect(commandId).to.not.be.undefined() - item.commandId = `${commandId}-modified` - expect(item.commandId).to.equal(commandId) -+======= -+ assert(commandId) -+ item.commandId = `${commandId}-modified` -+ assert.equal(item.commandId, commandId) -+>>>>>>> .their - }) - }) - - describe('MenuItem with invalid type', () => { - it('throws an exception', () => { -+<<<<<<< .our - expect(() => { -+======= -+ assert.throws(() => { -+>>>>>>> .their - Menu.buildFromTemplate([{ - label: 'text', - type: 'not-a-type' - }]) -+<<<<<<< .our - }).to.throw(/Unknown menu item type: not-a-type/) -+======= -+ }, /Unknown menu item type: not-a-type/) -+>>>>>>> .their - }) - }) - - describe('MenuItem with submenu type and missing submenu', () => { - it('throws an exception', () => { -+<<<<<<< .our - expect(() => { -+======= -+ assert.throws(() => { -+>>>>>>> .their - Menu.buildFromTemplate([{ - label: 'text', - type: 'submenu' - }]) -+<<<<<<< .our - }).to.throw(/Invalid submenu/) -+======= -+ }, /Invalid submenu/) -+>>>>>>> .their - }) - }) - -@@ -231,7 +314,11 @@ - - for (let role in roleList) { - const item = new MenuItem({role}) -+<<<<<<< .our - expect(item.getDefaultRoleAccelerator()).to.be.undefined() -+======= -+ assert.equal(item.getDefaultRoleAccelerator(), undefined) -+>>>>>>> .their - } - }) - -@@ -260,7 +347,11 @@ - - for (let role in roleList) { - const item = new MenuItem({role}) -+<<<<<<< .our - expect(item.label).to.equal(roleList[role]) -+======= -+ assert.equal(item.label, roleList[role]) -+>>>>>>> .their - } - }) - -@@ -289,7 +380,11 @@ - - for (let role in roleList) { - const item = new MenuItem({role}) -+<<<<<<< .our - expect(item.getDefaultRoleAccelerator()).to.equal(roleList[role]) -+======= -+ assert.equal(item.getDefaultRoleAccelerator(), roleList[role]) -+>>>>>>> .their - } - }) - -@@ -300,9 +395,15 @@ - accelerator: 'D' - }) - -+<<<<<<< .our - expect(item.label).to.equal('Custom Close!') - expect(item.accelerator).to.equal('D') - expect(item.getDefaultRoleAccelerator()).to.equal('CommandOrControl+W') -+======= -+ assert.equal(item.label, 'Custom Close!') -+ assert.equal(item.accelerator, 'D') -+ assert.equal(item.getDefaultRoleAccelerator(), 'CommandOrControl+W') -+>>>>>>> .their - }) - }) - -@@ -310,6 +411,7 @@ - it('includes a default submenu layout when submenu is empty', () => { - const item = new MenuItem({role: 'editMenu'}) - -+<<<<<<< .our - expect(item.label).to.equal('Edit') - expect(item.submenu.items[0].role).to.equal('undo') - expect(item.submenu.items[1].role).to.equal('redo') -@@ -328,6 +430,26 @@ - expect(item.submenu.items[6].role).to.equal('delete') - expect(item.submenu.items[7].type).to.equal('separator') - expect(item.submenu.items[8].role).to.equal('selectall') -+======= -+ assert.equal(item.label, 'Edit') -+ assert.equal(item.submenu.items[0].role, 'undo') -+ assert.equal(item.submenu.items[1].role, 'redo') -+ assert.equal(item.submenu.items[2].type, 'separator') -+ assert.equal(item.submenu.items[3].role, 'cut') -+ assert.equal(item.submenu.items[4].role, 'copy') -+ assert.equal(item.submenu.items[5].role, 'paste') -+ -+ if (process.platform === 'darwin') { -+ assert.equal(item.submenu.items[6].role, 'pasteandmatchstyle') -+ assert.equal(item.submenu.items[7].role, 'delete') -+ assert.equal(item.submenu.items[8].role, 'selectall') -+ } -+ -+ if (process.platform === 'win32') { -+ assert.equal(item.submenu.items[6].role, 'delete') -+ assert.equal(item.submenu.items[7].type, 'separator') -+ assert.equal(item.submenu.items[8].role, 'selectall') -+>>>>>>> .their - } - }) - -@@ -338,8 +460,13 @@ - role: 'close' - }] - }) -+<<<<<<< .our - expect(item.label).to.equal('Edit') - expect(item.submenu.items[0].role).to.equal('close') -+======= -+ assert.equal(item.label, 'Edit') -+ assert.equal(item.submenu.items[0].role, 'close') -+>>>>>>> .their - }) - }) - -@@ -347,6 +474,7 @@ - it('includes a default submenu layout when submenu is empty', () => { - const item = new MenuItem({role: 'windowMenu'}) - -+<<<<<<< .our - expect(item.label).to.equal('Window') - expect(item.submenu.items[0].role).to.equal('minimize') - expect(item.submenu.items[1].role).to.equal('close') -@@ -354,6 +482,15 @@ - if (process.platform === 'darwin') { - expect(item.submenu.items[2].type).to.equal('separator') - expect(item.submenu.items[3].role).to.equal('front') -+======= -+ assert.equal(item.label, 'Window') -+ assert.equal(item.submenu.items[0].role, 'minimize') -+ assert.equal(item.submenu.items[1].role, 'close') -+ -+ if (process.platform === 'darwin') { -+ assert.equal(item.submenu.items[2].type, 'separator') -+ assert.equal(item.submenu.items[3].role, 'front') -+>>>>>>> .their - } - }) - -@@ -363,8 +500,13 @@ - submenu: [{role: 'copy'}] - }) - -+<<<<<<< .our - expect(item.label).to.equal('Window') - expect(item.submenu.items[0].role).to.equal('copy') -+======= -+ assert.equal(item.label, 'Window') -+ assert.equal(item.submenu.items[0].role, 'copy') -+>>>>>>> .their - }) - }) - -@@ -383,10 +525,17 @@ - overrideProperty: 'oops not allowed' - })) - -+<<<<<<< .our - expect(menu.items[0].customProp).to.equal('foo') - expect(menu.items[0].submenu.items[0].label).to.equal('item 1') - expect(menu.items[0].submenu.items[0].customProp).to.equal('bar') - expect(menu.items[0].submenu.items[0].overrideProperty).to.be.a('function') -+======= -+ assert.equal(menu.items[0].customProp, 'foo') -+ assert.equal(menu.items[0].submenu.items[0].label, 'item 1') -+ assert.equal(menu.items[0].submenu.items[0].customProp, 'bar') -+ assert.equal(typeof menu.items[0].submenu.items[0].overrideProperty, 'function') -+>>>>>>> .their - }) - }) - }) -added in both - our 100644 ed2749700c6c8bf299f507d52606c1ae3f597e5c spec/api-menu-spec.js - their 100644 4a25e3ce4d7c05892374a0e93928e3a33b643174 spec/api-menu-spec.js -@@ -1,14 +1,21 @@ -+<<<<<<< .our - const chai = require('chai') - const dirtyChai = require('dirty-chai') -+======= -+const assert = require('assert') -+>>>>>>> .their - - const {ipcRenderer, remote} = require('electron') - const {BrowserWindow, Menu, MenuItem} = remote - const {sortMenuItems} = require('../lib/browser/api/menu-utils') - const {closeWindow} = require('./window-helpers') - -+<<<<<<< .our - const {expect} = chai - chai.use(dirtyChai) - -+======= -+>>>>>>> .their - describe('Menu module', () => { - describe('Menu.buildFromTemplate', () => { - it('should be able to attach extra fields', () => { -@@ -18,17 +25,29 @@ - extra: 'field' - } - ]) -+<<<<<<< .our - expect(menu.items[0].extra).to.equal('field') -+======= -+ assert.equal(menu.items[0].extra, 'field') -+>>>>>>> .their - }) - - it('does not modify the specified template', () => { - const template = [{label: 'text', submenu: [{label: 'sub'}]}] - const result = ipcRenderer.sendSync('eval', `const template = [{label: 'text', submenu: [{label: 'sub'}]}]\nrequire('electron').Menu.buildFromTemplate(template)\ntemplate`) -+<<<<<<< .our - expect(result).to.deep.equal(template) - }) - - it('does not throw exceptions for undefined/null values', () => { - expect(() => { -+======= -+ assert.deepStrictEqual(result, template) -+ }) -+ -+ it('does not throw exceptions for undefined/null values', () => { -+ assert.doesNotThrow(() => { -+>>>>>>> .their - Menu.buildFromTemplate([ - { - label: 'text', -@@ -39,6 +58,7 @@ - accelerator: null - } - ]) -+<<<<<<< .our - }).to.not.throw() - }) - -@@ -57,6 +77,9 @@ - expect(() => { - Menu.buildFromTemplate([undefined]) - }).to.throw(/Invalid template for MenuItem: must have at least one of label, role or type/) -+======= -+ }) -+>>>>>>> .their - }) - - describe('Menu sorting and building', () => { -@@ -87,7 +110,11 @@ - } - ] - -+<<<<<<< .our - expect(sortMenuItems(items)).to.deep.equal(expected) -+======= -+ assert.deepEqual(sortMenuItems(items), expected) -+>>>>>>> .their - }) - - it('resolves cycles by ignoring things that conflict', () => { -@@ -119,7 +146,11 @@ - } - ] - -+<<<<<<< .our - expect(sortMenuItems(items)).to.deep.equal(expected) -+======= -+ assert.deepEqual(sortMenuItems(items), expected) -+>>>>>>> .their - }) - - it('ignores references to commands that do not exist', () => { -@@ -149,7 +180,11 @@ - } - ] - -+<<<<<<< .our - expect(sortMenuItems(items)).to.deep.equal(expected) -+======= -+ assert.deepEqual(sortMenuItems(items), expected) -+>>>>>>> .their - }) - - it('only respects the first matching [before|after]GroupContaining rule in a given group', () => { -@@ -199,7 +234,11 @@ - } - ] - -+<<<<<<< .our - expect(sortMenuItems(items)).to.deep.equal(expected) -+======= -+ assert.deepEqual(sortMenuItems(items), expected) -+>>>>>>> .their - }) - }) - -@@ -241,7 +280,11 @@ - } - ] - -+<<<<<<< .our - expect(sortMenuItems(items)).to.deep.equal(expected) -+======= -+ assert.deepEqual(sortMenuItems(items), expected) -+>>>>>>> .their - }) - - it("moves all items in the moving item's group", () => { -@@ -289,7 +332,11 @@ - } - ] - -+<<<<<<< .our - expect(sortMenuItems(items)).to.deep.equal(expected) -+======= -+ assert.deepEqual(sortMenuItems(items), expected) -+>>>>>>> .their - }) - - it("ignores positions relative to commands that don't exist", () => { -@@ -339,7 +386,11 @@ - } - ] - -+<<<<<<< .our - expect(sortMenuItems(items)).to.deep.equal(expected) -+======= -+ assert.deepEqual(sortMenuItems(items), expected) -+>>>>>>> .their - }) - - it('can handle recursive group merging', () => { -@@ -377,7 +428,11 @@ - } - ] - -+<<<<<<< .our - expect(sortMenuItems(items)).to.deep.equal(expected) -+======= -+ assert.deepEqual(sortMenuItems(items), expected) -+>>>>>>> .their - }) - - it('can merge multiple groups when given a list of before/after commands', () => { -@@ -415,7 +470,11 @@ - } - ] - -+<<<<<<< .our - expect(sortMenuItems(items)).to.deep.equal(expected) -+======= -+ assert.deepEqual(sortMenuItems(items), expected) -+>>>>>>> .their - }) - - it('can merge multiple groups based on both before/after commands', () => { -@@ -455,7 +514,11 @@ - } - ] - -+<<<<<<< .our - expect(sortMenuItems(items)).to.deep.equal(expected) -+======= -+ assert.deepEqual(sortMenuItems(items), expected) -+>>>>>>> .their - }) - }) - -@@ -474,9 +537,15 @@ - } - ]) - -+<<<<<<< .our - expect(menu.items[0].label).to.equal('one') - expect(menu.items[1].label).to.equal('two') - expect(menu.items[2].label).to.equal('three') -+======= -+ assert.equal(menu.items[0].label, 'one') -+ assert.equal(menu.items[1].label, 'two') -+ assert.equal(menu.items[2].label, 'three') -+>>>>>>> .their - }) - - it('should position after existing item', () => { -@@ -495,9 +564,15 @@ - } - ]) - -+<<<<<<< .our - expect(menu.items[0].label).to.equal('one') - expect(menu.items[1].label).to.equal('two') - expect(menu.items[2].label).to.equal('three') -+======= -+ assert.equal(menu.items[0].label, 'one') -+ assert.equal(menu.items[1].label, 'two') -+ assert.equal(menu.items[2].label, 'three') -+>>>>>>> .their - }) - - it('should filter excess menu separators', () => { -@@ -515,10 +590,17 @@ - } - ]) - -+<<<<<<< .our - expect(menuOne.items).to.have.length(3) - expect(menuOne.items[0].label).to.equal('a') - expect(menuOne.items[1].label).to.equal('b') - expect(menuOne.items[2].label).to.equal('c') -+======= -+ assert.equal(menuOne.items.length, 3) -+ assert.equal(menuOne.items[0].label, 'a') -+ assert.equal(menuOne.items[1].label, 'b') -+ assert.equal(menuOne.items[2].label, 'c') -+>>>>>>> .their - - const menuTwo = Menu.buildFromTemplate([ - { -@@ -538,10 +620,17 @@ - } - ]) - -+<<<<<<< .our - expect(menuTwo.items).to.have.length(3) - expect(menuTwo.items[0].label).to.equal('a') - expect(menuTwo.items[1].label).to.equal('b') - expect(menuTwo.items[2].label).to.equal('c') -+======= -+ assert.equal(menuTwo.items.length, 3) -+ assert.equal(menuTwo.items[0].label, 'a') -+ assert.equal(menuTwo.items[1].label, 'b') -+ assert.equal(menuTwo.items[2].label, 'c') -+>>>>>>> .their - }) - - it('should continue inserting items at next index when no specifier is present', () => { -@@ -565,11 +654,19 @@ - } - ]) - -+<<<<<<< .our - expect(menu.items[0].label).to.equal('one') - expect(menu.items[1].label).to.equal('two') - expect(menu.items[2].label).to.equal('three') - expect(menu.items[3].label).to.equal('four') - expect(menu.items[4].label).to.equal('five') -+======= -+ assert.equal(menu.items[0].label, 'one') -+ assert.equal(menu.items[1].label, 'two') -+ assert.equal(menu.items[2].label, 'three') -+ assert.equal(menu.items[3].label, 'four') -+ assert.equal(menu.items[4].label, 'five') -+>>>>>>> .their - }) - }) - }) -@@ -589,7 +686,11 @@ - } - ]) - const fsc = menu.getMenuItemById('fullScreen') -+<<<<<<< .our - expect(menu.items[0].submenu.items[0]).to.equal(fsc) -+======= -+ assert.equal(menu.items[0].submenu.items[0], fsc) -+>>>>>>> .their - }) - }) - -@@ -604,10 +705,17 @@ - const item = new MenuItem({ label: 'inserted' }) - - menu.insert(1, item) -+<<<<<<< .our - expect(menu.items[0].label).to.equal('1') - expect(menu.items[1].label).to.equal('inserted') - expect(menu.items[2].label).to.equal('2') - expect(menu.items[3].label).to.equal('3') -+======= -+ assert.equal(menu.items[0].label, '1') -+ assert.equal(menu.items[1].label, 'inserted') -+ assert.equal(menu.items[2].label, '2') -+ assert.equal(menu.items[3].label, '3') -+>>>>>>> .their - }) - }) - -@@ -622,10 +730,17 @@ - const item = new MenuItem({ label: 'inserted' }) - menu.append(item) - -+<<<<<<< .our - expect(menu.items[0].label).to.equal('1') - expect(menu.items[1].label).to.equal('2') - expect(menu.items[2].label).to.equal('3') - expect(menu.items[3].label).to.equal('inserted') -+======= -+ assert.equal(menu.items[0].label, '1') -+ assert.equal(menu.items[1].label, '2') -+ assert.equal(menu.items[2].label, '3') -+ assert.equal(menu.items[3].label, 'inserted') -+>>>>>>> .their - }) - }) - -@@ -649,6 +764,7 @@ - }) - - it('throws an error if options is not an object', () => { -+<<<<<<< .our - expect(() => { - menu.popup('this is a string, not an object') - }).to.throw(/Options must be an object/) -@@ -658,6 +774,11 @@ - expect(() => { - menu.popup({}) - }).to.not.throw() -+======= -+ assert.throws(() => { -+ menu.popup() -+ }, /Options must be an object/) -+>>>>>>> .their - }) - - it('should emit menu-will-show event', (done) => { -@@ -674,17 +795,29 @@ - it('returns immediately', () => { - const input = {window: w, x: 100, y: 101} - const output = menu.popup(input) -+<<<<<<< .our - expect(output.x).to.equal(input.x) - expect(output.y).to.equal(input.y) - expect(output.browserWindow).to.equal(input.window) -+======= -+ assert.equal(output.x, input.x) -+ assert.equal(output.y, input.y) -+ assert.equal(output.browserWindow, input.window) -+>>>>>>> .their - }) - - it('works without a given BrowserWindow and options', () => { - const {browserWindow, x, y} = menu.popup({x: 100, y: 101}) - -+<<<<<<< .our - expect(browserWindow.constructor.name).to.equal('BrowserWindow') - expect(x).to.equal(100) - expect(y).to.equal(101) -+======= -+ assert.equal(browserWindow.constructor.name, 'BrowserWindow') -+ assert.equal(x, 100) -+ assert.equal(y, 101) -+>>>>>>> .their - }) - - it('works with a given BrowserWindow, options and callback', (done) => { -@@ -695,8 +828,13 @@ - callback: () => done() - }) - -+<<<<<<< .our - expect(x).to.equal(100) - expect(y).to.equal(101) -+======= -+ assert.equal(x, 100) -+ assert.equal(y, 101) -+>>>>>>> .their - menu.closePopup() - }) - -@@ -714,12 +852,20 @@ - ]) - - Menu.setApplicationMenu(menu) -+<<<<<<< .our - expect(Menu.getApplicationMenu()).to.not.be.null() -+======= -+ assert.notEqual(Menu.getApplicationMenu(), null) -+>>>>>>> .their - }) - - it('unsets a menu with null', () => { - Menu.setApplicationMenu(null) -+<<<<<<< .our - expect(Menu.getApplicationMenu()).to.be.null() -+======= -+ assert.equal(Menu.getApplicationMenu(), null) -+>>>>>>> .their - }) - }) - }) -added in both - our 100644 0546971b716e0d29d1e76d689be0a182c3f4b52d spec/api-native-image-spec.js - their 100644 87399921ff14ac2c594bb88a0c4493d4e9575e49 spec/api-native-image-spec.js -@@ -1,5 +1,6 @@ - 'use strict' - -+<<<<<<< .our - const chai = require('chai') - const dirtyChai = require('dirty-chai') - const {nativeImage} = require('electron') -@@ -8,6 +9,14 @@ - const {expect} = chai - chai.use(dirtyChai) - -+======= -+/* eslint-disable no-unused-expressions */ -+ -+const {expect} = require('chai') -+const {nativeImage} = require('electron') -+const path = require('path') -+ -+>>>>>>> .their - describe('nativeImage module', () => { - const ImageFormat = { - PNG: 'png', -@@ -113,6 +122,7 @@ - expect(empty.toDataURL()).to.equal('data:image/png;base64,') - expect(empty.toDataURL({scaleFactor: 2.0})).to.equal('data:image/png;base64,') - expect(empty.getSize()).to.deep.equal({width: 0, height: 0}) -+<<<<<<< .our - expect(empty.getBitmap()).to.be.empty() - expect(empty.getBitmap({scaleFactor: 2.0})).to.be.empty() - expect(empty.toBitmap()).to.be.empty() -@@ -123,6 +133,18 @@ - - if (process.platform === 'darwin') { - expect(empty.getNativeHandle()).to.be.empty() -+======= -+ expect(empty.getBitmap()).to.be.empty -+ expect(empty.getBitmap({scaleFactor: 2.0})).to.be.empty -+ expect(empty.toBitmap()).to.be.empty -+ expect(empty.toBitmap({scaleFactor: 2.0})).to.be.empty -+ expect(empty.toJPEG(100)).to.be.empty -+ expect(empty.toPNG()).to.be.empty -+ expect(empty.toPNG({scaleFactor: 2.0})).to.be.empty -+ -+ if (process.platform === 'darwin') { -+ expect(empty.getNativeHandle()).to.be.empty -+>>>>>>> .their - } - }) - }) -@@ -137,7 +159,11 @@ - - const imageB = nativeImage.createFromBuffer(imageA.toPNG()) - expect(imageB.getSize()).to.deep.equal({width: 538, height: 190}) -+<<<<<<< .our - expect(imageA.toBitmap().equals(imageB.toBitmap())).to.be.true() -+======= -+ expect(imageA.toBitmap().equals(imageB.toBitmap())).to.be.true -+>>>>>>> .their - - const imageC = nativeImage.createFromBuffer(imageA.toJPEG(100)) - expect(imageC.getSize()).to.deep.equal({width: 538, height: 190}) -@@ -216,7 +242,11 @@ - expect(imageTwo.getSize()).to.deep.equal( - {width: imageData.width, height: imageData.height}) - -+<<<<<<< .our - expect(imageOne.toBitmap().equals(imageTwo.toBitmap())).to.be.true() -+======= -+ expect(imageOne.toBitmap().equals(imageTwo.toBitmap())).to.be.true -+>>>>>>> .their - }) - - it('supports a scale factor', () => { -@@ -251,7 +281,11 @@ - expect(imageC.getSize()).to.deep.equal( - {width: imageData.width, height: imageData.height}) - -+<<<<<<< .our - expect(imageB.toBitmap().equals(imageC.toBitmap())).to.be.true() -+======= -+ expect(imageB.toBitmap().equals(imageC.toBitmap())).to.be.true -+>>>>>>> .their - }) - - it('supports a scale factor', () => { -@@ -280,23 +314,37 @@ - }) - - it('loads images from paths relative to the current working directory', () => { -+<<<<<<< .our - const imagePath = path.relative('.', path.join(__dirname, 'fixtures', 'assets', 'logo.png')) - const image = nativeImage.createFromPath(imagePath) - expect(image.isEmpty()).to.be.false() -+======= -+ const imagePath = `.${path.sep}${path.join('spec', 'fixtures', 'assets', 'logo.png')}` -+ const image = nativeImage.createFromPath(imagePath) -+ expect(image.isEmpty()).to.be.false -+>>>>>>> .their - expect(image.getSize()).to.deep.equal({width: 538, height: 190}) - }) - - it('loads images from paths with `.` segments', () => { - const imagePath = `${path.join(__dirname, 'fixtures')}${path.sep}.${path.sep}${path.join('assets', 'logo.png')}` - const image = nativeImage.createFromPath(imagePath) -+<<<<<<< .our - expect(image.isEmpty()).to.be.false() -+======= -+ expect(image.isEmpty()).to.be.false -+>>>>>>> .their - expect(image.getSize()).to.deep.equal({width: 538, height: 190}) - }) - - it('loads images from paths with `..` segments', () => { - const imagePath = `${path.join(__dirname, 'fixtures', 'api')}${path.sep}..${path.sep}${path.join('assets', 'logo.png')}` - const image = nativeImage.createFromPath(imagePath) -+<<<<<<< .our - expect(image.isEmpty()).to.be.false() -+======= -+ expect(image.isEmpty()).to.be.false -+>>>>>>> .their - expect(image.getSize()).to.deep.equal({width: 538, height: 190}) - }) - -@@ -327,7 +375,11 @@ - - const imagePath = path.join(__dirname, 'fixtures', 'assets', 'icon.ico') - const image = nativeImage.createFromPath(imagePath) -+<<<<<<< .our - expect(image.isEmpty()).to.be.false() -+======= -+ expect(image.isEmpty()).to.be.false -+>>>>>>> .their - expect(image.getSize()).to.deep.equal({width: 256, height: 256}) - }) - }) -@@ -357,7 +409,11 @@ - } - - const image = nativeImage.createFromNamedImage('NSActionTemplate') -+<<<<<<< .our - expect(image.isEmpty()).to.be.false() -+======= -+ expect(image.isEmpty()).to.be.false -+>>>>>>> .their - }) - - it('returns allows an HSL shift for a valid image on darwin', function () { -@@ -368,7 +424,11 @@ - } - - const image = nativeImage.createFromNamedImage('NSActionTemplate', [0.5, 0.2, 0.8]) -+<<<<<<< .our - expect(image.isEmpty()).to.be.false() -+======= -+ expect(image.isEmpty()).to.be.false -+>>>>>>> .their - }) - }) - -@@ -427,7 +487,11 @@ - const cropB = image.crop({width: 25, height: 64, x: 30, y: 40}) - expect(cropA.getSize()).to.deep.equal({width: 25, height: 64}) - expect(cropB.getSize()).to.deep.equal({width: 25, height: 64}) -+<<<<<<< .our - expect(cropA.toPNG().equals(cropB.toPNG())).to.be.false() -+======= -+ expect(cropA.toPNG().equals(cropB.toPNG())).to.be.false -+>>>>>>> .their - }) - }) - -@@ -473,7 +537,11 @@ - buffer: 'invalid' - }) - -+<<<<<<< .our - expect(image.isEmpty()).to.be.false() -+======= -+ expect(image.isEmpty()).to.be.false -+>>>>>>> .their - expect(image.getSize()).to.deep.equal({width: 1, height: 1}) - - expect(image.toDataURL({scaleFactor: 1.0})).to.equal(imageDataOne.dataUrl) -@@ -508,7 +576,11 @@ - dataURL: 'invalid' - }) - -+<<<<<<< .our - expect(image.isEmpty()).to.be.false() -+======= -+ expect(image.isEmpty()).to.be.false -+>>>>>>> .their - expect(image.getSize()).to.deep.equal({width: 1, height: 1}) - - expect(image.toDataURL({scaleFactor: 1.0})).to.equal(imageDataOne.dataUrl) -added in both - our 100644 fa282244df66e955c97554c240f8e7bb7ca4cbf3 spec/api-net-log-spec.js - their 100644 1e9ca66722dc2f5fccc450729ef405d8d2bd8246 spec/api-net-log-spec.js -@@ -1,5 +1,9 @@ -+<<<<<<< .our - const chai = require('chai') - const dirtyChai = require('dirty-chai') -+======= -+const assert = require('assert') -+>>>>>>> .their - const http = require('http') - const fs = require('fs') - const os = require('os') -@@ -11,15 +15,22 @@ - const dumpFile = path.join(os.tmpdir(), 'net_log.json') - const dumpFileDynamic = path.join(os.tmpdir(), 'net_log_dynamic.json') - -+<<<<<<< .our - const {expect} = chai - chai.use(dirtyChai) -+======= -+>>>>>>> .their - const isCI = remote.getGlobal('isCi') - - describe('netLog module', () => { - let server - const connections = new Set() - -+<<<<<<< .our - before(done => { -+======= -+ before((done) => { -+>>>>>>> .their - server = http.createServer() - server.listen(0, '127.0.0.1', () => { - server.url = `http://127.0.0.1:${server.address().port}` -@@ -36,7 +47,11 @@ - }) - }) - -+<<<<<<< .our - after(done => { -+======= -+ after((done) => { -+>>>>>>> .their - for (const connection of connections) { - connection.destroy() - } -@@ -55,6 +70,7 @@ - } - }) - -+<<<<<<< .our - it('should begin and end logging to file when .startLogging() and .stopLogging() is called', done => { - expect(netLog.currentlyLogging).to.be.false() - expect(netLog.currentlyLoggingPath).to.equal('') -@@ -70,11 +86,30 @@ - - expect(path).to.equal(dumpFileDynamic) - expect(fs.existsSync(dumpFileDynamic)).to.be.true() -+======= -+ it('should begin and end logging to file when .startLogging() and .stopLogging() is called', (done) => { -+ assert(!netLog.currentlyLogging) -+ assert.equal(netLog.currentlyLoggingPath, '') -+ -+ netLog.startLogging(dumpFileDynamic) -+ -+ assert(netLog.currentlyLogging) -+ assert.equal(netLog.currentlyLoggingPath, dumpFileDynamic) -+ -+ netLog.stopLogging((path) => { -+ assert(!netLog.currentlyLogging) -+ assert.equal(netLog.currentlyLoggingPath, '') -+ -+ assert.equal(path, dumpFileDynamic) -+ -+ assert(fs.existsSync(dumpFileDynamic)) -+>>>>>>> .their - - done() - }) - }) - -+<<<<<<< .our - it('should silence when .stopLogging() is called without calling .startLogging()', done => { - expect(netLog.currentlyLogging).to.be.false() - expect(netLog.currentlyLoggingPath).to.equal('') -@@ -84,6 +119,17 @@ - expect(netLog.currentlyLoggingPath).to.equal('') - - expect(path).to.equal('') -+======= -+ it('should silence when .stopLogging() is called without calling .startLogging()', (done) => { -+ assert(!netLog.currentlyLogging) -+ assert.equal(netLog.currentlyLoggingPath, '') -+ -+ netLog.stopLogging((path) => { -+ assert(!netLog.currentlyLogging) -+ assert.equal(netLog.currentlyLoggingPath, '') -+ -+ assert.equal(path, '') -+>>>>>>> .their - - done() - }) -@@ -91,7 +137,11 @@ - - // The following tests are skipped on Linux CI - -+<<<<<<< .our - it('should begin and end logging automatically when --log-net-log is passed', done => { -+======= -+ it('should begin and end logging automatically when --log-net-log is passed', (done) => { -+>>>>>>> .their - if (isCI && process.platform === 'linux') { - done() - return -@@ -105,12 +155,20 @@ - }) - - appProcess.once('exit', () => { -+<<<<<<< .our - expect(fs.existsSync(dumpFile)).to.be.true() -+======= -+ assert(fs.existsSync(dumpFile)) -+>>>>>>> .their - done() - }) - }) - -+<<<<<<< .our - it('should begin and end logging automtically when --log-net-log is passed, and behave correctly when .startLogging() and .stopLogging() is called', done => { -+======= -+ it('should begin and end logging automtically when --log-net-log is passed, and behave correctly when .startLogging() and .stopLogging() is called', (done) => { -+>>>>>>> .their - if (isCI && process.platform === 'linux') { - done() - return -@@ -125,18 +183,31 @@ - } - }) - -+<<<<<<< .our - appProcess.stdout.on('data', data => { -+======= -+ appProcess.stdout.on('data', (data) => { -+>>>>>>> .their - console.log(data.toString()) - }) - - appProcess.once('exit', () => { -+<<<<<<< .our - expect(fs.existsSync(dumpFile)).to.be.true() - expect(fs.existsSync(dumpFileDynamic)).to.be.true() -+======= -+ assert(fs.existsSync(dumpFile)) -+ assert(fs.existsSync(dumpFileDynamic)) -+>>>>>>> .their - done() - }) - }) - -+<<<<<<< .our - it('should end logging automatically when only .startLogging() is called', done => { -+======= -+ it('should end logging automatically when only .startLogging() is called', (done) => { -+>>>>>>> .their - if (isCI && process.platform === 'linux') { - done() - return -@@ -151,7 +222,11 @@ - }) - - appProcess.once('exit', () => { -+<<<<<<< .our - expect(fs.existsSync(dumpFileDynamic)).to.be.true() -+======= -+ assert(fs.existsSync(dumpFileDynamic)) -+>>>>>>> .their - done() - }) - }) -added in both - our 100644 9ab56d88e50ae5891364cb271362e5ec0c0edd26 spec/api-notification-dbus-spec.js - their 100644 81c1b68f31d0c9490742d3bd4b4227abaaf72ca3 spec/api-notification-dbus-spec.js -@@ -6,7 +6,11 @@ - // - // See https://pypi.python.org/pypi/python-dbusmock to read about dbusmock. - -+<<<<<<< .our - const {expect} = require('chai') -+======= -+const assert = require('assert') -+>>>>>>> .their - const dbus = require('dbus-native') - const Promise = require('bluebird') - -@@ -27,12 +31,20 @@ - before(async () => { - // init app - app.setName(appName) -+<<<<<<< .our - app.setDesktopName(`${appName}.desktop`) -+======= -+ app.setDesktopName(appName + '.desktop') -+>>>>>>> .their - // init dbus - const path = '/org/freedesktop/Notifications' - const iface = 'org.freedesktop.DBus.Mock' - const bus = dbus.sessionBus() -+<<<<<<< .our - console.log(`session bus: ${process.env.DBUS_SESSION_BUS_ADDRESS}`) -+======= -+ console.log('session bus: ' + process.env.DBUS_SESSION_BUS_ADDRESS) -+>>>>>>> .their - const service = bus.getService(serviceName) - const getInterface = Promise.promisify(service.getInterface, {context: service}) - mock = await getInterface(path, iface) -@@ -48,10 +60,17 @@ - app.setVersion(realAppVersion) - }) - -+<<<<<<< .our - describe(`Notification module using ${serviceName}`, () => { - function onMethodCalled (done) { - function cb (name) { - console.log(`onMethodCalled: ${name}`) -+======= -+ describe('Notification module using ' + serviceName, () => { -+ function onMethodCalled (done) { -+ function cb (name) { -+ console.log('onMethodCalled: ' + name) -+>>>>>>> .their - if (name === 'Notify') { - mock.removeListener('MethodCalled', cb) - console.log('done') -@@ -83,7 +102,11 @@ - } - } - -+<<<<<<< .our - before(done => { -+======= -+ before((done) => { -+>>>>>>> .their - mock.on('MethodCalled', onMethodCalled(done)) - // lazy load Notification after we listen to MethodCalled mock signal - Notification = require('electron').remote.Notification -@@ -98,6 +121,7 @@ - n.show() - }) - -+<<<<<<< .our - it(`should call ${serviceName} to show notifications`, async () => { - const calls = await getCalls() - expect(calls).to.be.an('array').of.lengthOf.at.least(1) -@@ -108,6 +132,16 @@ - - let args = unmarshalDBusNotifyArgs(lastCall[2]) - expect(args).to.deep.equal({ -+======= -+ it('should call ' + serviceName + ' to show notifications', async () => { -+ const calls = await getCalls() -+ assert(calls.length >= 1) -+ let lastCall = calls[calls.length - 1] -+ let methodName = lastCall[1] -+ assert.equal(methodName, 'Notify') -+ let args = unmarshalDBusNotifyArgs(lastCall[2]) -+ assert.deepEqual(args, { -+>>>>>>> .their - app_name: appName, - replaces_id: 0, - app_icon: '', -added in both - our 100644 ad8f1faea14208d2659c505105c1e70938bba2b9 spec/api-process-spec.js - their 100644 1de5e1a19dc7175eac1338b89d0f882a37bd91c0 spec/api-process-spec.js -@@ -1,3 +1,4 @@ -+<<<<<<< .our - const {expect} = require('chai') - - describe('process module', () => { -@@ -13,6 +14,16 @@ - const cpuUsage = process.getCPUUsage() - expect(cpuUsage.percentCPUUsage).to.be.a('number') - expect(cpuUsage.idleWakeupsPerSecond).to.be.a('number') -+======= -+const assert = require('assert') -+ -+describe('process module', () => { -+ describe('process.getCPUUsage()', () => { -+ it('returns a cpu usage object', () => { -+ const cpuUsage = process.getCPUUsage() -+ assert.equal(typeof cpuUsage.percentCPUUsage, 'number') -+ assert.equal(typeof cpuUsage.idleWakeupsPerSecond, 'number') -+>>>>>>> .their - }) - }) - -@@ -25,6 +36,7 @@ - - it('returns an io counters object', () => { - const ioCounters = process.getIOCounters() -+<<<<<<< .our - expect(ioCounters.readOperationCount).to.be.a('number') - expect(ioCounters.writeOperationCount).to.be.a('number') - expect(ioCounters.otherOperationCount).to.be.a('number') -@@ -49,12 +61,21 @@ - const systemMemoryInfo = process.getSystemMemoryInfo() - expect(systemMemoryInfo.free).to.be.a('number') - expect(systemMemoryInfo.total).to.be.a('number') -+======= -+ assert.equal(typeof ioCounters.readOperationCount, 'number') -+ assert.equal(typeof ioCounters.writeOperationCount, 'number') -+ assert.equal(typeof ioCounters.otherOperationCount, 'number') -+ assert.equal(typeof ioCounters.readTransferCount, 'number') -+ assert.equal(typeof ioCounters.writeTransferCount, 'number') -+ assert.equal(typeof ioCounters.otherTransferCount, 'number') -+>>>>>>> .their - }) - }) - - describe('process.getHeapStatistics()', () => { - it('returns heap statistics object', () => { - const heapStats = process.getHeapStatistics() -+<<<<<<< .our - expect(heapStats.totalHeapSize).to.be.a('number') - expect(heapStats.totalHeapSizeExecutable).to.be.a('number') - expect(heapStats.totalPhysicalSize).to.be.a('number') -@@ -64,6 +85,17 @@ - expect(heapStats.mallocedMemory).to.be.a('number') - expect(heapStats.peakMallocedMemory).to.be.a('number') - expect(heapStats.doesZapGarbage).to.be.a('boolean') -+======= -+ assert.equal(typeof heapStats.totalHeapSize, 'number') -+ assert.equal(typeof heapStats.totalHeapSizeExecutable, 'number') -+ assert.equal(typeof heapStats.totalPhysicalSize, 'number') -+ assert.equal(typeof heapStats.totalAvailableSize, 'number') -+ assert.equal(typeof heapStats.usedHeapSize, 'number') -+ assert.equal(typeof heapStats.heapSizeLimit, 'number') -+ assert.equal(typeof heapStats.mallocedMemory, 'number') -+ assert.equal(typeof heapStats.peakMallocedMemory, 'number') -+ assert.equal(typeof heapStats.doesZapGarbage, 'boolean') -+>>>>>>> .their - }) - }) - }) -added in both - our 100644 b9093d1d6335ece5ca713a668a67bf3b40f4fabe spec/api-session-spec.js - their 100644 7ac14e1f1f88549aa6594e96906cc77906c0accd spec/api-session-spec.js -@@ -289,17 +289,24 @@ - res.end(mockPDF) - downloadServer.close() - }) -+<<<<<<< .our - - const isPathEqual = (path1, path2) => { - return path.relative(path1, path2) === '' - } -+======= -+>>>>>>> .their - const assertDownload = (event, state, url, mimeType, - receivedBytes, totalBytes, disposition, - filename, port, savePath, isCustom) => { - assert.equal(state, 'completed') - assert.equal(filename, 'mock.pdf') -+<<<<<<< .our - assert.ok(path.isAbsolute(savePath)) - assert.ok(isPathEqual(savePath, path.join(__dirname, 'fixtures', 'mock.pdf'))) -+======= -+ assert.equal(savePath, path.join(__dirname, 'fixtures', 'mock.pdf')) -+>>>>>>> .their - if (isCustom) { - assert.equal(url, `${protocolName}://item`) - } else { -added in both - our 100644 be02cb3f84001a541d64b11fe6eda50fc32e8afd spec/api-web-contents-spec.js - their 100644 b1b1d206a2934dbc0e6d3b57cffdc9b9345d7b7a spec/api-web-contents-spec.js -@@ -4,6 +4,7 @@ - const http = require('http') - const path = require('path') - const {closeWindow} = require('./window-helpers') -+<<<<<<< .our - const {emittedOnce} = require('./events-helpers') - const chai = require('chai') - const dirtyChai = require('dirty-chai') -@@ -16,6 +17,14 @@ - - chai.use(dirtyChai) - -+======= -+ -+const {ipcRenderer, remote} = require('electron') -+const {BrowserWindow, webContents, ipcMain, session} = remote -+ -+const isCi = remote.getGlobal('isCi') -+ -+>>>>>>> .their - /* The whole webContents API doesn't use standard callbacks */ - /* eslint-disable standard/no-callback-literal */ - -@@ -40,7 +49,11 @@ - it('returns an array of web contents', (done) => { - w.webContents.on('devtools-opened', () => { - const all = webContents.getAllWebContents().sort((a, b) => { -+<<<<<<< .our - return a.id - b.id -+======= -+ return a.getId() - b.getId() -+>>>>>>> .their - }) - - assert.ok(all.length >= 4) -@@ -61,15 +74,26 @@ - if (isCi) return done() - - const specWebContents = remote.getCurrentWebContents() -+<<<<<<< .our - assert.equal(specWebContents.id, webContents.getFocusedWebContents().id) - - specWebContents.once('devtools-opened', () => { - assert.equal(specWebContents.devToolsWebContents.id, webContents.getFocusedWebContents().id) -+======= -+ assert.equal(specWebContents.getId(), webContents.getFocusedWebContents().getId()) -+ -+ specWebContents.once('devtools-opened', () => { -+ assert.equal(specWebContents.devToolsWebContents.getId(), webContents.getFocusedWebContents().getId()) -+>>>>>>> .their - specWebContents.closeDevTools() - }) - - specWebContents.once('devtools-closed', () => { -+<<<<<<< .our - assert.equal(specWebContents.id, webContents.getFocusedWebContents().id) -+======= -+ assert.equal(specWebContents.getId(), webContents.getFocusedWebContents().getId()) -+>>>>>>> .their - done() - }) - -@@ -122,6 +146,7 @@ - }) - }) - -+<<<<<<< .our - // Disabled because flaky. See #13969 - xdescribe('isCurrentlyAudible() API', () => { - it('returns whether audio is playing', async () => { -@@ -138,6 +163,8 @@ - }) - }) - -+======= -+>>>>>>> .their - describe('getWebPreferences() API', () => { - it('should not crash when called for devTools webContents', (done) => { - w.webContents.openDevTools() -added in both - our 100644 d90269769d269e4054d25cba4b6c4ac8a1929aa6 spec/chromium-spec.js - their 100644 938798f001b866a34eae50db37c40e314866c28a spec/chromium-spec.js -@@ -319,7 +319,11 @@ - b = window.open(windowUrl, '', 'nodeIntegration=no,show=no') - }) - -+<<<<<<< .our - // TODO(codebytere): re-enable this test -+======= -+ // TODO(alexeykuzmin): [Ch66] Fix the test. -+>>>>>>> .their - xit('disables node integration when it is disabled on the parent window for chrome devtools URLs', (done) => { - let b - app.once('web-contents-created', (event, contents) => { -added in both - our 100644 6901be56d0c5fa9f0a318edeb235eef60624ac52 spec/fixtures/module/preload-sandbox.js - their 100644 38d14a8be50ce4e0eb5804336e8bc1f2e23dac0e spec/fixtures/module/preload-sandbox.js -@@ -11,6 +11,7 @@ - window.test = { - env: process.env, - execPath: process.execPath, -+<<<<<<< .our - pid: process.pid, - arch: process.arch, - platform: process.platform, -@@ -19,6 +20,9 @@ - type: process.type, - version: process.version, - versions: process.versions -+======= -+ platform: process.platform -+>>>>>>> .their - } - } - } else if (location.href !== 'about:blank') { -added in both - our 100644 675d81e97b7240d61b49fbbbee857144033a0378 spec/fixtures/pages/a.html - their 100644 568973aed1cf5d40100d8b233fb9548d61bbebf2 spec/fixtures/pages/a.html -@@ -1,7 +1,10 @@ - - - -+<<<<<<< .our - -+======= -+>>>>>>> .their - - , -+ Chrome , -+ and Electron . -+ -+ -+``` -+ -+## Run your app -+ -+Once you've created your initial `main.js`, `index.html`, and `package.json` files, -+you'll probably want to try running your app locally to test it and make sure it's -+working as expected. -+ -+### `electron` -+ -+[`electron`](https://github.com/electron-userland/electron-prebuilt) is -+an `npm` module that contains pre-compiled versions of Electron. -+ -+If you've installed it globally with `npm`, then you will only need to run the -+following in your app's source directory: -+ -+```bash -+electron . -+``` -+ -+If you've installed it locally, then run: -+ -+#### macOS / Linux -+ -+```bash -+$ ./node_modules/.bin/electron . -+``` -+ -+#### Windows -+ -+``` -+$ .\node_modules\.bin\electron . -+``` -+ -+### Manually Downloaded Electron Binary -+ -+If you downloaded Electron manually, you can also use the included -+binary to execute your app directly. -+ -+#### macOS -+ -+```bash -+$ ./Electron.app/Contents/MacOS/Electron your-app/ -+``` -+ -+#### Linux -+ -+```bash -+$ ./electron/electron your-app/ -+``` -+ -+#### Windows -+ -+``` -+$ .\electron\electron.exe your-app\ -+``` -+ -+`Electron.app` here is part of the Electron's release package, you can download -+it from [here](https://github.com/electron/electron/releases). -+ -+### Run as a distribution -+ -+After you're done writing your app, you can create a distribution by -+following the [Application Distribution](./application-distribution.md) guide -+and then executing the packaged app. -+ -+### Try this Example -+ -+Clone and run the code in this tutorial by using the [`electron/electron-quick-start`](https://github.com/electron/electron-quick-start) -+repository. -+ -+**Note**: Running this requires [Git](https://git-scm.com) and [Node.js](https://nodejs.org/en/download/) (which includes [npm](https://npmjs.org)) on your system. -+ -+```bash -+# Clone the repository -+$ git clone https://github.com/electron/electron-quick-start -+# Go into the repository -+$ cd electron-quick-start -+# Install dependencies -+$ npm install -+# Run the app -+$ npm start -+``` -+ -+For more example apps, see the -+[list of boilerplates](https://electron.atom.io/community/#boilerplates) -+created by the awesome electron community. -+ -+[share-data]: ../faq.md#how-to-share-data-between-web-pages -+>>>>>>> .their diff --git a/app/test/fixtures/merge-parser/electron/merge-enable-pdf-plugin-into-master.txt b/app/test/fixtures/merge-parser/electron/merge-enable-pdf-plugin-into-master.txt deleted file mode 100644 index be099a5743c..00000000000 --- a/app/test/fixtures/merge-parser/electron/merge-enable-pdf-plugin-into-master.txt +++ /dev/null @@ -1,51 +0,0 @@ -merged - result 100644 5022302700f45bd875996efdc27f43cd9d9b8b0a atom/app/atom_content_client.cc - our 100644 f17ae3137032f0b0e26eb735d37cfb3daaeebcfc atom/app/atom_content_client.cc -@@ -30,6 +30,7 @@ - #if defined(ENABLE_PDF_VIEWER) - #include "atom/common/atom_constants.h" - #include "pdf/pdf.h" -+#include "pdf/pdf_ppapi.h" - #endif // defined(ENABLE_PDF_VIEWER) - - namespace atom { -merged - result 100644 3621d64ef8b8077243b8c6038b39cbfca58fc89f atom/browser/atom_resource_dispatcher_host_delegate.cc - our 100644 934b0ebaa49b711490c58fc73b91985633cba439 atom/browser/atom_resource_dispatcher_host_delegate.cc -@@ -17,7 +17,9 @@ - - #if defined(ENABLE_PDF_VIEWER) - #include "atom/common/atom_constants.h" -+#include "atom/common/options_switches.h" - #include "base/strings/stringprintf.h" -+#include "content/public/browser/download_request_utils.h" - #include "content/public/browser/stream_info.h" - #include "net/url_request/url_request.h" - #endif // defined(ENABLE_PDF_VIEWER) -@@ -76,7 +78,7 @@ - content::BrowserContext::GetDownloadManager(browser_context); - - download_manager->DownloadUrl( -- content::DownloadUrlParameters::CreateForWebContentsMainFrame( -+ content::DownloadRequestUtils::CreateDownloadForWebContentsMainFrame( - web_contents, original_url, NO_TRAFFIC_ANNOTATION_YET)); - return; - } -changed in both - base 100644 23d7d9907c2351fc3d7e6cd42a1e836524d727b1 features.gypi - our 100644 86543a4db1195223a3556fa71583038f15d79a0a features.gypi - their 100644 f8b835f7e436c99cc0b1ae0d6dcaa2fb855e4267 features.gypi -@@ -3,8 +3,13 @@ - 'variables': { - 'variables': { - 'enable_desktop_capturer%': 1, -+<<<<<<< .our - 'enable_osr%': 1, - 'enable_pdf_viewer%': 0, # FIXME(deepak1556) -+======= -+ 'enable_osr%': 0, # FIXME(alexeykuzmin) -+ 'enable_pdf_viewer%': 1, # FIXME(deepak1556) -+>>>>>>> .their - 'enable_run_as_node%': 1, - 'enable_view_api%': 0, - 'enable_pepper_flash%': 1, diff --git a/app/test/fixtures/merge-parser/electron/merge-enable-weak-ptr-dcheck-into-master.txt b/app/test/fixtures/merge-parser/electron/merge-enable-weak-ptr-dcheck-into-master.txt deleted file mode 100644 index b827d62ac70..00000000000 --- a/app/test/fixtures/merge-parser/electron/merge-enable-weak-ptr-dcheck-into-master.txt +++ /dev/null @@ -1,20 +0,0 @@ -changed in both - base 100644 8aec763b31771896ffc2a38a9ab80d3373f24a6c DEPS - our 100644 b3b9d650b27274f4f98f7408319b1e6b35f63abf DEPS - their 100644 8e71aa33161a9d4652625d8cd003b8d950eb7aed DEPS -@@ -2,7 +2,11 @@ - 'chromium_version': - '66.0.3359.181', - 'libchromiumcontent_revision': -+<<<<<<< .our - 'c85470a1c379b1c4bedb372c146521bc4be9b75d', -+======= -+ '40d7857234c85c05932eac11adae3c030c84d041', -+>>>>>>> .their - 'node_version': - 'ece0a06ac8147efb5b5af431c21f312f1884616e', - -changed in both - base 160000 5ff3486fc02a6a7b4b9e31d81034c4583c21114a vendor/libchromiumcontent - our 160000 c85470a1c379b1c4bedb372c146521bc4be9b75d vendor/libchromiumcontent - their 160000 40d7857234c85c05932eac11adae3c030c84d041 vendor/libchromiumcontent diff --git a/app/test/fixtures/merge-parser/electron/merge-event-subscriber-clean-into-master.txt b/app/test/fixtures/merge-parser/electron/merge-event-subscriber-clean-into-master.txt deleted file mode 100644 index 9d2203c1c4d..00000000000 --- a/app/test/fixtures/merge-parser/electron/merge-event-subscriber-clean-into-master.txt +++ /dev/null @@ -1,885 +0,0 @@ -removed in remote - base 100644 6ad4610d5d541fd1ef7c1e811175a272ed0c06ce atom/browser/api/event_subscriber.cc - our 100644 afcd8012766c483d17ccee157f2edd078742733d atom/browser/api/event_subscriber.cc -@@ -1,121 +0,0 @@ --// Copyright (c) 2017 GitHub, Inc. --// Use of this source code is governed by the MIT license that can be --// found in the LICENSE file. --#include -- --#include "atom/browser/api/event_subscriber.h" --#include "atom/common/native_mate_converters/callback.h" -- --namespace { -- --// A FunctionTemplate lifetime is bound to the v8 context, so it can be safely --// stored as a global here since there's only one for the main process. --v8::Global g_cached_template; -- --struct JSHandlerData { -- JSHandlerData(v8::Isolate* isolate, -- mate::internal::EventSubscriberBase* subscriber) -- : handle_(isolate, v8::External::New(isolate, this)), -- subscriber_(subscriber) { -- handle_.SetWeak(this, GC, v8::WeakCallbackType::kFinalizer); -- } -- -- static void GC(const v8::WeakCallbackInfo& data) { -- delete data.GetParameter(); -- } -- -- v8::Global handle_; -- mate::internal::EventSubscriberBase* subscriber_; --}; -- --void InvokeCallback(const v8::FunctionCallbackInfo& info) { -- v8::Locker locker(info.GetIsolate()); -- v8::HandleScope handle_scope(info.GetIsolate()); -- v8::Local context = info.GetIsolate()->GetCurrentContext(); -- v8::Context::Scope context_scope(context); -- mate::Arguments args(info); -- v8::Local handler, event; -- args.GetNext(&handler); -- args.GetNext(&event); -- DCHECK(handler->IsExternal()); -- DCHECK(event->IsString()); -- JSHandlerData* handler_data = static_cast( -- v8::Local::Cast(handler)->Value()); -- handler_data->subscriber_->EventEmitted(mate::V8ToString(event), &args); --} -- --} // namespace -- --namespace mate { -- --namespace internal { -- --EventSubscriberBase::EventSubscriberBase(v8::Isolate* isolate, -- v8::Local emitter) -- : isolate_(isolate), emitter_(isolate, emitter) { -- if (g_cached_template.IsEmpty()) { -- g_cached_template = v8::Global( -- isolate_, v8::FunctionTemplate::New(isolate_, InvokeCallback)); -- } --} -- --EventSubscriberBase::~EventSubscriberBase() { -- if (!isolate_) { -- return; -- } -- RemoveAllListeners(); -- emitter_.Reset(); -- DCHECK_EQ(js_handlers_.size(), 0u); --} -- --void EventSubscriberBase::On(const std::string& event_name) { -- DCHECK(js_handlers_.find(event_name) == js_handlers_.end()); -- v8::Locker locker(isolate_); -- v8::Isolate::Scope isolate_scope(isolate_); -- v8::HandleScope handle_scope(isolate_); -- auto fn_template = g_cached_template.Get(isolate_); -- auto event = mate::StringToV8(isolate_, event_name); -- auto* js_handler_data = new JSHandlerData(isolate_, this); -- v8::Local fn = internal::BindFunctionWith( -- isolate_, isolate_->GetCurrentContext(), fn_template->GetFunction(), -- js_handler_data->handle_.Get(isolate_), event); -- js_handlers_.insert( -- std::make_pair(event_name, v8::Global(isolate_, fn))); -- internal::ValueVector converted_args = {event, fn}; -- internal::CallMethodWithArgs(isolate_, emitter_.Get(isolate_), "on", -- &converted_args); --} -- --void EventSubscriberBase::Off(const std::string& event_name) { -- v8::Locker locker(isolate_); -- v8::Isolate::Scope isolate_scope(isolate_); -- v8::HandleScope handle_scope(isolate_); -- auto js_handler = js_handlers_.find(event_name); -- DCHECK(js_handler != js_handlers_.end()); -- RemoveListener(js_handler); --} -- --void EventSubscriberBase::RemoveAllListeners() { -- v8::Locker locker(isolate_); -- v8::Isolate::Scope isolate_scope(isolate_); -- v8::HandleScope handle_scope(isolate_); -- while (!js_handlers_.empty()) { -- RemoveListener(js_handlers_.begin()); -- } --} -- --std::map>::iterator --EventSubscriberBase::RemoveListener( -- std::map>::iterator it) { -- internal::ValueVector args = {StringToV8(isolate_, it->first), -- it->second.Get(isolate_)}; -- internal::CallMethodWithArgs( -- isolate_, v8::Local::Cast(emitter_.Get(isolate_)), -- "removeListener", &args); -- it->second.Reset(); -- return js_handlers_.erase(it); --} -- --} // namespace internal -- --} // namespace mate -removed in remote - base 100644 8f09a61460a5aaa934f6d8c0129eaf7ba57ccb1e atom/browser/api/event_subscriber.h - our 100644 8e9dcf518d988978597582c147877c5f233b91ab atom/browser/api/event_subscriber.h -@@ -1,139 +0,0 @@ --// Copyright (c) 2017 GitHub, Inc. --// Use of this source code is governed by the MIT license that can be --// found in the LICENSE file. -- --#ifndef ATOM_BROWSER_API_EVENT_SUBSCRIBER_H_ --#define ATOM_BROWSER_API_EVENT_SUBSCRIBER_H_ -- --#include --#include -- --#include "atom/common/api/event_emitter_caller.h" --#include "base/synchronization/lock.h" --#include "content/public/browser/browser_thread.h" --#include "native_mate/arguments.h" -- --namespace mate { -- --namespace internal { -- --class EventSubscriberBase { -- public: -- EventSubscriberBase(v8::Isolate* isolate, v8::Local emitter); -- virtual ~EventSubscriberBase(); -- virtual void EventEmitted(const std::string& event_name, -- mate::Arguments* args) = 0; -- -- protected: -- void On(const std::string& event_name); -- void Off(const std::string& event_name); -- void RemoveAllListeners(); -- -- private: -- std::map>::iterator RemoveListener( -- std::map>::iterator it); -- -- v8::Isolate* isolate_; -- v8::Global emitter_; -- std::map> js_handlers_; -- -- DISALLOW_COPY_AND_ASSIGN(EventSubscriberBase); --}; -- --} // namespace internal -- --template --class EventSubscriber : internal::EventSubscriberBase { -- public: -- using EventCallback = void (HandlerType::*)(mate::Arguments* args); -- // Alias to unique_ptr with deleter. -- using unique_ptr = std::unique_ptr, -- void (*)(EventSubscriber*)>; -- // EventSubscriber should only be created/deleted in the main thread since it -- // communicates with the V8 engine. This smart pointer makes it simpler to -- // bind the lifetime of EventSubscriber with a class whose lifetime is managed -- // by a non-UI thread. -- class SafePtr : public unique_ptr { -- public: -- SafePtr() : SafePtr(nullptr) {} -- explicit SafePtr(EventSubscriber* ptr) -- : unique_ptr(ptr, Deleter) {} -- -- private: -- // Custom deleter that schedules destructor invocation to the main thread. -- static void Deleter(EventSubscriber* ptr) { -- DCHECK( -- !::content::BrowserThread::CurrentlyOn(::content::BrowserThread::UI)); -- DCHECK(ptr); -- // Acquire handler lock and reset handler_ to ensure that any new events -- // emitted will be ignored after this function returns -- base::AutoLock auto_lock(ptr->handler_lock_); -- ptr->handler_ = nullptr; -- content::BrowserThread::PostTask( -- content::BrowserThread::UI, FROM_HERE, -- base::BindOnce( -- [](EventSubscriber* subscriber) { -- { -- // It is possible that this function will execute in the UI -- // thread before the outer function has returned and destroyed -- // its auto_lock. We need to acquire the lock before deleting -- // or risk a crash. -- base::AutoLock auto_lock(subscriber->handler_lock_); -- } -- delete subscriber; -- }, -- ptr)); -- } -- }; -- -- EventSubscriber(HandlerType* handler, -- v8::Isolate* isolate, -- v8::Local emitter) -- : EventSubscriberBase(isolate, emitter), handler_(handler) { -- DCHECK_CURRENTLY_ON(::content::BrowserThread::UI); -- } -- -- void On(const std::string& event, EventCallback callback) { -- DCHECK_CURRENTLY_ON(::content::BrowserThread::UI); -- EventSubscriberBase::On(event); -- callbacks_.insert(std::make_pair(event, callback)); -- } -- -- void Off(const std::string& event) { -- DCHECK_CURRENTLY_ON(::content::BrowserThread::UI); -- EventSubscriberBase::Off(event); -- DCHECK(callbacks_.find(event) != callbacks_.end()); -- callbacks_.erase(callbacks_.find(event)); -- } -- -- void RemoveAllListeners() { -- DCHECK_CURRENTLY_ON(::content::BrowserThread::UI); -- EventSubscriberBase::RemoveAllListeners(); -- callbacks_.clear(); -- } -- -- private: -- void EventEmitted(const std::string& event_name, -- mate::Arguments* args) override { -- DCHECK_CURRENTLY_ON(::content::BrowserThread::UI); -- base::AutoLock auto_lock(handler_lock_); -- if (!handler_) { -- // handler_ was probably destroyed by another thread and we should not -- // access it. -- return; -- } -- auto it = callbacks_.find(event_name); -- if (it != callbacks_.end()) { -- auto method = it->second; -- (handler_->*method)(args); -- } -- } -- -- HandlerType* handler_; -- base::Lock handler_lock_; -- std::map callbacks_; --}; -- --} // namespace mate -- --#endif // ATOM_BROWSER_API_EVENT_SUBSCRIBER_H_ -added in remote - their 100644 7954b0240eee95725eaca0e42358ef9e29c08f0b atom/browser/api/stream_subscriber.cc -@@ -0,0 +1,114 @@ -+// Copyright (c) 2017 GitHub, Inc. -+// Use of this source code is governed by the MIT license that can be -+// found in the LICENSE file. -+ -+#include "atom/browser/api/stream_subscriber.h" -+ -+#include -+ -+#include "atom/browser/net/url_request_stream_job.h" -+#include "atom/common/api/event_emitter_caller.h" -+#include "atom/common/native_mate_converters/callback.h" -+ -+#include "atom/common/node_includes.h" -+ -+namespace mate { -+ -+StreamSubscriber::StreamSubscriber( -+ v8::Isolate* isolate, -+ v8::Local emitter, -+ base::WeakPtr url_job) -+ : isolate_(isolate), -+ emitter_(isolate, emitter), -+ url_job_(url_job), -+ weak_factory_(this) { -+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); -+ auto weak_self = weak_factory_.GetWeakPtr(); -+ On("data", base::Bind(&StreamSubscriber::OnData, weak_self)); -+ On("end", base::Bind(&StreamSubscriber::OnEnd, weak_self)); -+ On("error", base::Bind(&StreamSubscriber::OnError, weak_self)); -+} -+ -+StreamSubscriber::~StreamSubscriber() { -+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); -+ RemoveAllListeners(); -+} -+ -+void StreamSubscriber::On(const std::string& event, EventCallback&& callback) { // NOLINT -+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); -+ DCHECK(js_handlers_.find(event) == js_handlers_.end()); -+ -+ v8::Locker locker(isolate_); -+ v8::Isolate::Scope isolate_scope(isolate_); -+ v8::HandleScope handle_scope(isolate_); -+ -+ // emitter.on(event, EventEmitted) -+ auto fn = CallbackToV8(isolate_, callback); -+ js_handlers_[event] = v8::Global(isolate_, fn); -+ internal::ValueVector args = { StringToV8(isolate_, event), fn }; -+ internal::CallMethodWithArgs(isolate_, emitter_.Get(isolate_), "on", &args); -+} -+ -+void StreamSubscriber::Off(const std::string& event) { -+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); -+ DCHECK(js_handlers_.find(event) != js_handlers_.end()); -+ -+ v8::Locker locker(isolate_); -+ v8::Isolate::Scope isolate_scope(isolate_); -+ v8::HandleScope handle_scope(isolate_); -+ auto js_handler = js_handlers_.find(event); -+ DCHECK(js_handler != js_handlers_.end()); -+ RemoveListener(js_handler); -+} -+ -+void StreamSubscriber::OnData(mate::Arguments* args) { -+ v8::Local buf; -+ args->GetNext(&buf); -+ if (!node::Buffer::HasInstance(buf)) { -+ args->ThrowError("data must be Buffer"); -+ return; -+ } -+ -+ const char* data = node::Buffer::Data(buf); -+ size_t length = node::Buffer::Length(buf); -+ if (length == 0) -+ return; -+ -+ // Pass the data to the URLJob in IO thread. -+ std::vector buffer(data, data + length); -+ content::BrowserThread::PostTask( -+ content::BrowserThread::IO, FROM_HERE, -+ base::Bind(&atom::URLRequestStreamJob::OnData, -+ url_job_, base::Passed(&buffer))); -+} -+ -+void StreamSubscriber::OnEnd(mate::Arguments* args) { -+ content::BrowserThread::PostTask( -+ content::BrowserThread::IO, FROM_HERE, -+ base::Bind(&atom::URLRequestStreamJob::OnEnd, url_job_)); -+} -+ -+void StreamSubscriber::OnError(mate::Arguments* args) { -+ content::BrowserThread::PostTask( -+ content::BrowserThread::IO, FROM_HERE, -+ base::Bind(&atom::URLRequestStreamJob::OnError, url_job_)); -+} -+ -+void StreamSubscriber::RemoveAllListeners() { -+ v8::Locker locker(isolate_); -+ v8::Isolate::Scope isolate_scope(isolate_); -+ v8::HandleScope handle_scope(isolate_); -+ while (!js_handlers_.empty()) { -+ RemoveListener(js_handlers_.begin()); -+ } -+} -+ -+void StreamSubscriber::RemoveListener(JSHandlersMap::iterator it) { -+ internal::ValueVector args = { StringToV8(isolate_, it->first), -+ it->second.Get(isolate_) }; -+ internal::CallMethodWithArgs(isolate_, emitter_.Get(isolate_), -+ "removeListener", &args); -+ js_handlers_.erase(it); -+} -+ -+} // namespace mate -added in remote - their 100644 10184e4ec6c58dbdc0a4fa2ba5aa7a091a0032c4 atom/browser/api/stream_subscriber.h -@@ -0,0 +1,57 @@ -+// Copyright (c) 2017 GitHub, Inc. -+// Use of this source code is governed by the MIT license that can be -+// found in the LICENSE file. -+ -+#ifndef ATOM_BROWSER_API_STREAM_SUBSCRIBER_H_ -+#define ATOM_BROWSER_API_STREAM_SUBSCRIBER_H_ -+ -+#include -+#include -+#include -+ -+#include "base/callback.h" -+#include "base/memory/weak_ptr.h" -+#include "content/public/browser/browser_thread.h" -+#include "v8/include/v8.h" -+ -+namespace atom { -+class URLRequestStreamJob; -+} -+ -+namespace mate { -+ -+class Arguments; -+ -+class StreamSubscriber { -+ public: -+ StreamSubscriber(v8::Isolate* isolate, -+ v8::Local emitter, -+ base::WeakPtr url_job); -+ ~StreamSubscriber(); -+ -+ private: -+ using JSHandlersMap = std::map>; -+ using EventCallback = base::Callback; -+ -+ void On(const std::string& event, EventCallback&& callback); // NOLINT -+ void Off(const std::string& event); -+ -+ void OnData(mate::Arguments* args); -+ void OnEnd(mate::Arguments* args); -+ void OnError(mate::Arguments* args); -+ -+ void RemoveAllListeners(); -+ void RemoveListener(JSHandlersMap::iterator it); -+ -+ v8::Isolate* isolate_; -+ v8::Global emitter_; -+ base::WeakPtr url_job_; -+ -+ JSHandlersMap js_handlers_; -+ -+ base::WeakPtrFactory weak_factory_; -+}; -+ -+} // namespace mate -+ -+#endif // ATOM_BROWSER_API_STREAM_SUBSCRIBER_H_ -changed in both - base 100644 99e4e74cd776fcb26a60beb1d0102010dc182b40 atom/browser/net/url_request_stream_job.cc - our 100644 f52e2822df8a783ac0c90ccaf6837cc17335ea29 atom/browser/net/url_request_stream_job.cc - their 100644 dbcefe431d14a0870a2b6de214c5f0583a973e99 atom/browser/net/url_request_stream_job.cc -@@ -2,11 +2,12 @@ - // Use of this source code is governed by the MIT license that can be - // found in the LICENSE file. - -+#include "atom/browser/net/url_request_stream_job.h" -+ - #include - #include - #include - --#include "atom/browser/net/url_request_stream_job.h" - #include "atom/common/api/event_emitter_caller.h" - #include "atom/common/atom_constants.h" - #include "atom/common/native_mate_converters/net_converter.h" -@@ -14,6 +15,7 @@ - #include "base/strings/string_number_conversions.h" - #include "base/strings/string_util.h" - #include "base/time/time.h" -+#include "net/base/net_errors.h" - #include "net/filter/gzip_source_stream.h" - - namespace atom { -@@ -21,16 +23,32 @@ - URLRequestStreamJob::URLRequestStreamJob(net::URLRequest* request, - net::NetworkDelegate* network_delegate) - : JsAsker(request, network_delegate), -+<<<<<<< .our - weak_factory_(this) {} - - URLRequestStreamJob::~URLRequestStreamJob() = default; -+======= -+ pending_buf_(nullptr), -+ pending_buf_size_(0), -+ ended_(false), -+ has_error_(false), -+ response_headers_(nullptr), -+ weak_factory_(this) {} -+ -+URLRequestStreamJob::~URLRequestStreamJob() { -+ if (subscriber_) { -+ content::BrowserThread::DeleteSoon(content::BrowserThread::UI, FROM_HERE, -+ std::move(subscriber_)); -+ } -+} -+>>>>>>> .their - - void URLRequestStreamJob::BeforeStartInUI(v8::Isolate* isolate, - v8::Local value) { - if (value->IsNull() || value->IsUndefined() || !value->IsObject()) { - // Invalid opts. - ended_ = true; -- errored_ = true; -+ has_error_ = true; - return; - } - -@@ -68,69 +86,89 @@ - !data.Get("removeListener", &value) || !value->IsFunction()) { - // If data is passed but it is not a stream, signal an error. - ended_ = true; -- errored_ = true; -+ has_error_ = true; - return; - } - -- subscriber_.reset(new mate::EventSubscriber( -- this, isolate, data.GetHandle())); -- subscriber_->On("data", &URLRequestStreamJob::OnData); -- subscriber_->On("end", &URLRequestStreamJob::OnEnd); -- subscriber_->On("error", &URLRequestStreamJob::OnError); -+ subscriber_.reset(new mate::StreamSubscriber(isolate, data.GetHandle(), -+ weak_factory_.GetWeakPtr())); - } - - void URLRequestStreamJob::StartAsync(std::unique_ptr options) { -+ if (has_error_) { -+ OnError(); -+ return; -+ } - NotifyHeadersComplete(); - } - --void URLRequestStreamJob::OnData(mate::Arguments* args) { -- v8::Local node_data; -- args->GetNext(&node_data); -- if (node_data->IsUint8Array()) { -- const char* data = node::Buffer::Data(node_data); -- size_t data_size = node::Buffer::Length(node_data); -- std::copy(data, data + data_size, std::back_inserter(buffer_)); -+void URLRequestStreamJob::OnData(std::vector&& buffer) { // NOLINT -+ if (write_buffer_.empty()) { -+ // Quick branch without copying. -+ write_buffer_ = std::move(buffer); - } else { -- NOTREACHED(); -+ // write_buffer_ += buffer -+ size_t len = write_buffer_.size(); -+ write_buffer_.resize(len + buffer.size()); -+ std::copy(buffer.begin(), buffer.end(), write_buffer_.begin() + len); - } -- if (pending_io_buf_) { -- CopyMoreData(pending_io_buf_, pending_io_buf_size_); -+ -+ // Copy to output. -+ if (pending_buf_) { -+ int len = BufferCopy(&write_buffer_, pending_buf_.get(), pending_buf_size_); -+ write_buffer_.erase(write_buffer_.begin(), write_buffer_.begin() + len); -+ ReadRawDataComplete(len); - } - } - --void URLRequestStreamJob::OnEnd(mate::Arguments* args) { -+void URLRequestStreamJob::OnEnd() { - ended_ = true; -- if (pending_io_buf_) { -- CopyMoreData(pending_io_buf_, pending_io_buf_size_); -- } -+ ReadRawDataComplete(0); - } - --void URLRequestStreamJob::OnError(mate::Arguments* args) { -- errored_ = true; -- if (pending_io_buf_) { -- CopyMoreData(pending_io_buf_, pending_io_buf_size_); -- } -+void URLRequestStreamJob::OnError() { -+ NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, -+ net::ERR_FAILED)); - } - - int URLRequestStreamJob::ReadRawData(net::IOBuffer* dest, int dest_size) { -+<<<<<<< .our - content::BrowserThread::PostTask( - content::BrowserThread::UI, FROM_HERE, - base::BindOnce(&URLRequestStreamJob::CopyMoreData, - weak_factory_.GetWeakPtr(), WrapRefCounted(dest), - dest_size)); - return net::ERR_IO_PENDING; -+======= -+ if (ended_) -+ return 0; -+ -+ // When write_buffer_ is empty, there is no data valable yet, we have to save -+ // the dest buffer util DataAvailable. -+ if (write_buffer_.empty()) { -+ pending_buf_ = dest; -+ pending_buf_size_ = dest_size; -+ return net::ERR_IO_PENDING; -+ } -+ -+ // Read from the write buffer and clear them after reading. -+ int len = BufferCopy(&write_buffer_, dest, dest_size); -+ write_buffer_.erase(write_buffer_.begin(), write_buffer_.begin() + len); -+ return len; -+>>>>>>> .their - } - - void URLRequestStreamJob::DoneReading() { -- subscriber_.reset(); -- buffer_.clear(); -- ended_ = true; -+ content::BrowserThread::DeleteSoon(content::BrowserThread::UI, FROM_HERE, -+ std::move(subscriber_)); -+ write_buffer_.clear(); - } - - void URLRequestStreamJob::DoneReadingRedirectResponse() { - DoneReading(); - } - -+<<<<<<< .our - void URLRequestStreamJob::CopyMoreDataDone(scoped_refptr io_buf, - int status) { - if (status <= 0) { -@@ -169,6 +207,8 @@ - } - } - -+======= -+>>>>>>> .their - std::unique_ptr URLRequestStreamJob::SetUpSourceStream() { - std::unique_ptr source = - net::URLRequestJob::SetUpSourceStream(); -@@ -199,4 +239,11 @@ - info->headers = response_headers_; - } - -+int URLRequestStreamJob::BufferCopy(std::vector* source, -+ net::IOBuffer* target, int target_size) { -+ int bytes_written = std::min(static_cast(source->size()), target_size); -+ memcpy(target->data(), source->data(), bytes_written); -+ return bytes_written; -+} -+ - } // namespace atom -changed in both - base 100644 372cad7e2d5f8c1039c9ac6d8bcfaf48cafd73d2 atom/browser/net/url_request_stream_job.h - our 100644 742ded7f1b95b3b76d636bb152f1e94d5937906a atom/browser/net/url_request_stream_job.h - their 100644 a967ca145322b9d424c0936a5d78f79089510c33 atom/browser/net/url_request_stream_job.h -@@ -5,10 +5,11 @@ - #ifndef ATOM_BROWSER_NET_URL_REQUEST_STREAM_JOB_H_ - #define ATOM_BROWSER_NET_URL_REQUEST_STREAM_JOB_H_ - --#include -+#include - #include -+#include - --#include "atom/browser/api/event_subscriber.h" -+#include "atom/browser/api/stream_subscriber.h" - #include "atom/browser/net/js_asker.h" - #include "base/memory/ref_counted_memory.h" - #include "native_mate/persistent_dictionary.h" -@@ -25,9 +26,9 @@ - net::NetworkDelegate* network_delegate); - ~URLRequestStreamJob() override; - -- void OnData(mate::Arguments* args); -- void OnEnd(mate::Arguments* args); -- void OnError(mate::Arguments* args); -+ void OnData(std::vector&& buffer); // NOLINT -+ void OnEnd(); -+ void OnError(); - - // URLRequestJob - void GetResponseInfo(net::HttpResponseInfo* info) override; -@@ -47,17 +48,29 @@ - void StartAsync(std::unique_ptr options) override; - void OnResponse(bool success, std::unique_ptr value); - -- // Callback after data is asynchronously read from the file into |buf|. -- void CopyMoreData(scoped_refptr io_buf, int io_buf_size); -- void CopyMoreDataDone(scoped_refptr io_buf, int read_count); -+ int BufferCopy(std::vector* source, -+ net::IOBuffer* target, int target_size); - -+ // Saved arguments passed to ReadRawData. -+ scoped_refptr pending_buf_; -+ int pending_buf_size_; -+ -+ // Saved arguments passed to OnData. -+ std::vector write_buffer_; -+ -+<<<<<<< .our - std::deque buffer_; - bool ended_ = false; - bool errored_ = false; - scoped_refptr pending_io_buf_; - int pending_io_buf_size_ = 0; -+======= -+ bool ended_; -+ bool has_error_; -+>>>>>>> .their - scoped_refptr response_headers_; -- mate::EventSubscriber::SafePtr subscriber_; -+ std::unique_ptr subscriber_; -+ - base::WeakPtrFactory weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(URLRequestStreamJob); -changed in both - base 100644 0132ae7858279e5548ddfb73b75a4019c3539428 atom/common/native_mate_converters/callback.cc - our 100644 f33cec720ea5df1c17c8d02d4aa2b70d2979e13b atom/common/native_mate_converters/callback.cc - their 100644 62d928d2cdfa09b65073759d7ab77dd19c555181 atom/common/native_mate_converters/callback.cc -@@ -4,6 +4,8 @@ - - #include "atom/common/native_mate_converters/callback.h" - -+#include "native_mate/dictionary.h" -+ - using content::BrowserThread; - - namespace mate { -@@ -13,6 +15,22 @@ - namespace { - - struct TranslaterHolder { -+ explicit TranslaterHolder(v8::Isolate* isolate) -+ : handle(isolate, v8::External::New(isolate, this)) { -+ handle.SetWeak(this, &GC, v8::WeakCallbackType::kFinalizer); -+ } -+ ~TranslaterHolder() { -+ if (!handle.IsEmpty()) { -+ handle.ClearWeak(); -+ handle.Reset(); -+ } -+ } -+ -+ static void GC(const v8::WeakCallbackInfo& data) { -+ delete data.GetParameter(); -+ } -+ -+ v8::Global handle; - Translater translater; - }; - -@@ -22,20 +40,27 @@ - void CallTranslater(v8::Local external, - v8::Local state, - mate::Arguments* args) { -+ // Whether the callback should only be called for once. - v8::Isolate* isolate = args->isolate(); -+ bool one_time = state->Has(mate::StringToSymbol(isolate, "oneTime")); - - // Check if the callback has already been called. -- v8::Local called_symbol = mate::StringToSymbol(isolate, "called"); -- if (state->Has(called_symbol)) { -- args->ThrowError("callback can only be called for once"); -- return; -- } else { -- state->Set(called_symbol, v8::Boolean::New(isolate, true)); -+ if (one_time) { -+ auto called_symbol = mate::StringToSymbol(isolate, "called"); -+ if (state->Has(called_symbol)) { -+ args->ThrowError("callback can only be called for once"); -+ return; -+ } else { -+ state->Set(called_symbol, v8::Boolean::New(isolate, true)); -+ } - } - - TranslaterHolder* holder = static_cast(external->Value()); - holder->translater.Run(args); -- delete holder; -+ -+ // Free immediately for one-time callback. -+ if (one_time) -+ delete holder; - } - - } // namespace -@@ -90,8 +115,12 @@ - } - - v8::Local CreateFunctionFromTranslater( -+<<<<<<< .our - v8::Isolate* isolate, - const Translater& translater) { -+======= -+ v8::Isolate* isolate, const Translater& translater, bool one_time) { -+>>>>>>> .their - // The FunctionTemplate is cached. - if (g_call_translater.IsEmpty()) - g_call_translater.Reset(isolate, mate::CreateFunctionTemplate( -@@ -99,11 +128,22 @@ - - v8::Local call_translater = - v8::Local::New(isolate, g_call_translater); -- auto* holder = new TranslaterHolder; -+ auto* holder = new TranslaterHolder(isolate); - holder->translater = translater; -+<<<<<<< .our - return BindFunctionWith( - isolate, isolate->GetCurrentContext(), call_translater->GetFunction(), - v8::External::New(isolate, holder), v8::Object::New(isolate)); -+======= -+ Dictionary state = mate::Dictionary::CreateEmpty(isolate); -+ if (one_time) -+ state.Set("oneTime", true); -+ return BindFunctionWith(isolate, -+ isolate->GetCurrentContext(), -+ call_translater->GetFunction(), -+ holder->handle.Get(isolate), -+ state.GetHandle()); -+>>>>>>> .their - } - - // func.bind(func, arg1). -changed in both - base 100644 fc93e83d312bd722227507610a9e26fd94e8111f atom/common/native_mate_converters/callback.h - our 100644 06140a3a7a7a928143e44e22113288b514409929 atom/common/native_mate_converters/callback.h - their 100644 a71ec2d212c20e88555e86d3c1c813223eb530bc atom/common/native_mate_converters/callback.h -@@ -108,8 +108,13 @@ - - // Helper to pass a C++ funtion to JavaScript. - using Translater = base::Callback; -+<<<<<<< .our - v8::Local CreateFunctionFromTranslater(v8::Isolate* isolate, - const Translater& translater); -+======= -+v8::Local CreateFunctionFromTranslater( -+ v8::Isolate* isolate, const Translater& translater, bool one_time); -+>>>>>>> .their - v8::Local BindFunctionWith(v8::Isolate* isolate, - v8::Local context, - v8::Local func, -@@ -152,9 +157,17 @@ - const base::RepeatingCallback& val) { - // We don't use CreateFunctionTemplate here because it creates a new - // FunctionTemplate everytime, which is cached by V8 and causes leaks. -+<<<<<<< .our - internal::Translater translater = - base::BindRepeating(&internal::NativeFunctionInvoker::Go, val); - return internal::CreateFunctionFromTranslater(isolate, translater); -+======= -+ internal::Translater translater = base::Bind( -+ &internal::NativeFunctionInvoker::Go, val); -+ // To avoid memory leak, we ensure that the callback can only be called -+ // for once. -+ return internal::CreateFunctionFromTranslater(isolate, translater, true); -+>>>>>>> .their - } - static bool FromV8(v8::Isolate* isolate, - v8::Local val, -@@ -168,6 +181,16 @@ - } - }; - -+// Convert a callback to V8 without the call number limitation, this can easily -+// cause memory leaks so use it with caution. -+template -+v8::Local CallbackToV8(v8::Isolate* isolate, -+ const base::Callback& val) { -+ internal::Translater translater = base::Bind( -+ &internal::NativeFunctionInvoker::Go, val); -+ return internal::CreateFunctionFromTranslater(isolate, translater, false); -+} -+ - } // namespace mate - - #endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_H_ -changed in both - base 100644 e9f0f43b97ec2de992952404c00227f3075a791c filenames.gypi - our 100644 f57860558f06b7e5d8a50f48cfc7e53044df0bc6 filenames.gypi - their 100644 e5c5f50049c531d2dffcd563d9c9e4447cec90c0 filenames.gypi -@@ -188,8 +188,8 @@ - 'atom/browser/api/event.h', - 'atom/browser/api/event_emitter.cc', - 'atom/browser/api/event_emitter.h', -- 'atom/browser/api/event_subscriber.cc', -- 'atom/browser/api/event_subscriber.h', -+ 'atom/browser/api/stream_subscriber.cc', -+ 'atom/browser/api/stream_subscriber.h', - 'atom/browser/api/trackable_object.cc', - 'atom/browser/api/trackable_object.h', - 'atom/browser/api/frame_subscriber.cc', diff --git a/app/test/fixtures/merge-parser/electron/merge-expect-browser-window-spec-into-master.txt b/app/test/fixtures/merge-parser/electron/merge-expect-browser-window-spec-into-master.txt deleted file mode 100644 index 62f10553859..00000000000 --- a/app/test/fixtures/merge-parser/electron/merge-expect-browser-window-spec-into-master.txt +++ /dev/null @@ -1,3980 +0,0 @@ -changed in both - base 100644 711354fd6dff0c7cd231a39ef6cfd1c71d80d035 spec/api-browser-window-spec.js - our 100644 f4cba12ec19d224bc46fca898db42a99baf4972e spec/api-browser-window-spec.js - their 100644 e08cb69dc2de9de419c8a6fa50f1818e9080d8b6 spec/api-browser-window-spec.js -@@ -1,6 +1,9 @@ - 'use strict' - -+<<<<<<< .our - const assert = require('assert') -+======= -+>>>>>>> .their - const chai = require('chai') - const dirtyChai = require('dirty-chai') - const fs = require('fs') -@@ -9,7 +12,14 @@ - const qs = require('querystring') - const http = require('http') - const {closeWindow} = require('./window-helpers') -+<<<<<<< .our - const {emittedOnce} = require('./events-helpers') -+======= -+ -+const {expect} = chai -+chai.use(dirtyChai) -+ -+>>>>>>> .their - const {ipcRenderer, remote, screen} = require('electron') - const {app, ipcMain, BrowserWindow, BrowserView, protocol, session, webContents} = remote - -@@ -18,15 +28,20 @@ - const isCI = remote.getGlobal('isCi') - const nativeModulesEnabled = remote.getGlobal('nativeModulesEnabled') - -+<<<<<<< .our - chai.use(dirtyChai) - - describe('BrowserWindow module', () => { -+======= -+describe.only('BrowserWindow module', () => { -+>>>>>>> .their - const fixtures = path.resolve(__dirname, 'fixtures') - let w = null - let ws = null - let server - let postData - -+<<<<<<< .our - const defaultOptions = { - show: false, - width: 400, -@@ -48,8 +63,11 @@ - const closeTheWindow = function () { - return closeWindow(w).then(() => { w = null }) - } -+======= -+ const closeTheWindow = () => closeWindow(w).then(() => { w = null }) -+>>>>>>> .their - -- before((done) => { -+ before(done => { - const filePath = path.join(fixtures, 'pages', 'a.html') - const fileStats = fs.statSync(filePath) - postData = [ -@@ -69,7 +87,7 @@ - function respond () { - if (req.method === 'POST') { - let body = '' -- req.on('data', (data) => { -+ req.on('data', data => { - if (data) body += data - }) - req.on('end', () => { -@@ -105,16 +123,22 @@ - - describe('BrowserWindow constructor', () => { - it('allows passing void 0 as the webContents', () => { -+<<<<<<< .our - openTheWindow({ - webContents: void 0 - }) -+======= -+ w.close() -+ w = null -+ w = new BrowserWindow({ webContents: void 0 }) -+>>>>>>> .their - }) - }) - - describe('BrowserWindow.close()', () => { - let server - -- before((done) => { -+ before(done => { - server = http.createServer((request, response) => { - switch (request.url) { - case '/404': -@@ -148,23 +172,26 @@ - server = null - }) - -- it('should emit unload handler', (done) => { -+ it('should emit unload handler', done => { - w.webContents.on('did-finish-load', () => { w.close() }) - w.once('closed', () => { - const test = path.join(fixtures, 'api', 'unload') - const content = fs.readFileSync(test) - fs.unlinkSync(test) -- assert.equal(String(content), 'unload') -+ -+ expect(String(content)).to.equal('unload') - done() - }) -- w.loadURL('file://' + path.join(fixtures, 'api', 'unload.html')) -+ w.loadURL(`file://${path.join(fixtures, 'api', 'unload.html')}`) - }) -- it('should emit beforeunload handler', (done) => { -+ -+ it('should emit beforeunload handler', done => { - w.once('onbeforeunload', () => { done() }) - w.webContents.on('did-finish-load', () => { w.close() }) - w.loadURL(`file://${path.join(fixtures, 'api', 'beforeunload-false.html')}`) - }) -- it('should not crash when invoked synchronously inside navigation observer', (done) => { -+ -+ it('should not crash when invoked synchronously inside navigation observer', done => { - const events = [ - { name: 'did-start-loading', url: `${server.url}/200` }, - { name: 'dom-ready', url: `${server.url}/200` }, -@@ -196,17 +223,19 @@ - }) - - describe('window.close()', () => { -- it('should emit unload handler', (done) => { -+ it('should emit unload handler', done => { - w.once('closed', () => { - const test = path.join(fixtures, 'api', 'close') - const content = fs.readFileSync(test) - fs.unlinkSync(test) -- assert.equal(String(content), 'close') -+ -+ expect(String(content)).to.equal('close') - done() - }) - w.loadURL(`file://${path.join(fixtures, 'api', 'close.html')}`) - }) -- it('should emit beforeunload handler', (done) => { -+ -+ it('should emit beforeunload handler', done => { - w.once('onbeforeunload', () => { done() }) - w.loadURL(`file://${path.join(fixtures, 'api', 'close-beforeunload-false.html')}`) - }) -@@ -216,58 +245,104 @@ - it('prevents users to access methods of webContents', () => { - const contents = w.webContents - w.destroy() -+<<<<<<< .our - assert.throws(() => { - contents.getProcessId() - }, /Object has been destroyed/) -+======= -+ expect(() => { -+ contents.getId() -+ }).to.throw(/Object has been destroyed/) -+>>>>>>> .their - }) - }) - - describe('BrowserWindow.loadURL(url)', () => { -- it('should emit did-start-loading event', (done) => { -+ it('should emit did-start-loading event', done => { - w.webContents.on('did-start-loading', () => { done() }) - w.loadURL('about:blank') - }) -- it('should emit ready-to-show event', (done) => { -+ -+ it('should emit ready-to-show event', done => { - w.on('ready-to-show', () => { done() }) - w.loadURL('about:blank') - }) -+<<<<<<< .our - it('should emit did-fail-load event for files that do not exist', (done) => { -+======= -+ -+ // TODO(nitsakh): Deprecated -+ it('should emit did-get-response-details(deprecated) event', done => { -+ // expected {fileName: resourceType} pairs -+ const expectedResources = { -+ 'did-get-response-details.html': 'mainFrame', -+ 'logo.png': 'image' -+ } -+ -+ let responses = 0 -+ w.webContents.on('-did-get-response-details', (event, status, newUrl, oldUrl, responseCode, method, referrer, headers, resourceType) => { -+ responses += 1 -+ const fileName = newUrl.slice(newUrl.lastIndexOf('/') + 1) -+ const expectedType = expectedResources[fileName] -+ -+ expect(!!expectedType).to.be(true, `Unexpected response details for ${newUrl}`) -+ expect(status).to.be.a('boolean', 'status should be boolean') -+ expect(responseCode).to.equal(200) -+ expect(method).to.equal('GET') -+ -+ expect(referrer).to.be.a('string', 'referrer should be string') -+ expect(!!headers).to.equal(true, 'headers should be present') -+ -+ expect(headers).to.be.an('object', 'headers should be object') -+ expect(resourceType).to.equal(expectedType, 'Incorrect resourceType') -+ -+ if (responses === Object.keys(expectedResources).length) done() -+ }) -+ w.loadURL(`file://${path.join(fixtures, 'pages', 'did-get-response-details.html')}`) -+ }) -+ -+ it('should emit did-fail-load event for files that do not exist', done => { -+>>>>>>> .their - w.webContents.on('did-fail-load', (event, code, desc, url, isMainFrame) => { -- assert.equal(code, -6) -- assert.equal(desc, 'ERR_FILE_NOT_FOUND') -- assert.equal(isMainFrame, true) -+ expect(code).to.equal(-6) -+ expect(desc).to.equal('ERR_FILE_NOT_FOUND') -+ expect(isMainFrame).equal(true) - done() - }) - w.loadURL('file://a.txt') - }) -- it('should emit did-fail-load event for invalid URL', (done) => { -+ -+ it('should emit did-fail-load event for invalid URL', done => { - w.webContents.on('did-fail-load', (event, code, desc, url, isMainFrame) => { -- assert.equal(desc, 'ERR_INVALID_URL') -- assert.equal(code, -300) -- assert.equal(isMainFrame, true) -+ expect(desc).to.equal('ERR_INVALID_URL') -+ expect(code).to.equal(-300) -+ expect(isMainFrame).to.equal(true) - done() - }) - w.loadURL('http://example:port') - }) -- it('should set `mainFrame = false` on did-fail-load events in iframes', (done) => { -+ -+ it('should set `mainFrame = false` on did-fail-load events in iframes', done => { - w.webContents.on('did-fail-load', (event, code, desc, url, isMainFrame) => { -- assert.equal(isMainFrame, false) -+ expect(isMainFrame).to.equal(false) - done() - }) - w.loadURL(`file://${path.join(fixtures, 'api', 'did-fail-load-iframe.html')}`) - }) -- it('does not crash in did-fail-provisional-load handler', (done) => { -+ -+ it('does not crash in did-fail-provisional-load handler', done => { - w.webContents.once('did-fail-provisional-load', () => { - w.loadURL('http://127.0.0.1:11111') - done() - }) - w.loadURL('http://127.0.0.1:11111') - }) -- it('should emit did-fail-load event for URL exceeding character limit', (done) => { -+ -+ it('should emit did-fail-load event for URL exceeding character limit', done => { - w.webContents.on('did-fail-load', (event, code, desc, url, isMainFrame) => { -- assert.equal(desc, 'ERR_INVALID_URL') -- assert.equal(code, -300) -- assert.equal(isMainFrame, true) -+ expect(desc).to.equal('ERR_INVALID_URL') -+ expect(code).to.equal(-300) -+ expect(isMainFrame).to.equal(true) - done() - }) - const data = Buffer.alloc(2 * 1024 * 1024).toString('base64') -@@ -277,14 +352,15 @@ - describe('POST navigations', () => { - afterEach(() => { w.webContents.session.webRequest.onBeforeSendHeaders(null) }) - -- it('supports specifying POST data', (done) => { -+ it('supports specifying POST data', done => { - w.webContents.on('did-finish-load', () => done()) - w.loadURL(server.url, {postData: postData}) - }) -- it('sets the content type header on URL encoded forms', (done) => { -+ -+ it('sets the content type header on URL encoded forms', done => { - w.webContents.on('did-finish-load', () => { - w.webContents.session.webRequest.onBeforeSendHeaders((details, callback) => { -- assert.equal(details.requestHeaders['content-type'], 'application/x-www-form-urlencoded') -+ expect(details.requestHeaders['content-type']).to.equal('application/x-www-form-urlencoded') - done() - }) - w.webContents.executeJavaScript(` -@@ -297,10 +373,12 @@ - }) - w.loadURL(server.url) - }) -- it('sets the content type header on multi part forms', (done) => { -+ -+ it('sets the content type header on multi part forms', done => { - w.webContents.on('did-finish-load', () => { - w.webContents.session.webRequest.onBeforeSendHeaders((details, callback) => { -- assert(details.requestHeaders['content-type'].startsWith('multipart/form-data; boundary=----WebKitFormBoundary')) -+ const headers = details.requestHeaders['content-type'] -+ expect(headers).includes('multipart/form-data; boundary=----WebKitFormBoundary') - done() - }) - w.webContents.executeJavaScript(` -@@ -320,9 +398,9 @@ - }) - }) - -- it('should support support base url for data urls', (done) => { -+ it('should support support base url for data urls', done => { - ipcMain.once('answer', (event, test) => { -- assert.equal(test, 'test') -+ expect(test).to.equal('test') - done() - }) - w.loadURL('data:text/html,', {baseURLForDataURL: `file://${path.join(fixtures, 'api')}${path.sep}`}) -@@ -330,7 +408,7 @@ - }) - - describe('will-navigate event', () => { -- it('allows the window to be closed from the event listener', (done) => { -+ it('allows the window to be closed from the event listener', done => { - ipcRenderer.send('close-on-will-navigate', w.id) - ipcRenderer.once('closed-on-will-navigate', () => { done() }) - w.loadURL(`file://${fixtures}/pages/will-navigate.html`) -@@ -346,15 +424,15 @@ - - it('should focus on window', () => { - w.show() -- assert(w.isFocused()) -+ expect(w.isFocused()).to.equal(true) - }) - it('should make the window visible', () => { - w.show() -- assert(w.isVisible()) -+ expect(w.isVisible()).to.equal(true) - }) -- it('emits when window is shown', (done) => { -+ it('emits when window is shown', done => { - w.once('show', () => { -- assert.equal(w.isVisible(), true) -+ expect(w.isVisible()).to.equal(true) - done() - }) - w.show() -@@ -370,17 +448,19 @@ - - it('should defocus on window', () => { - w.hide() -- assert(!w.isFocused()) -+ expect(w.isFocused()).to.equal(false) - }) -+ - it('should make the window not visible', () => { - w.show() - w.hide() -- assert(!w.isVisible()) -+ expect(!w.isVisible()).to.equal(false) - }) -- it('emits when window is hidden', (done) => { -+ -+ it('emits when window is hidden', done => { - w.show() - w.once('hide', () => { -- assert.equal(w.isVisible(), false) -+ expect(w.isVisible()).to.equal(false) - done() - }) - w.hide() -@@ -390,31 +470,36 @@ - describe('BrowserWindow.showInactive()', () => { - it('should not focus on window', () => { - w.showInactive() -- assert(!w.isFocused()) -+ expect(w.isFocused()).to.be(false) - }) - }) - - describe('BrowserWindow.focus()', () => { - it('does not make the window become visible', () => { -- assert.equal(w.isVisible(), false) -+ expect(w.isVisible()).to.equal(false) - w.focus() -- assert.equal(w.isVisible(), false) -+ expect(w.isVisible()).to.equal(false) - }) - }) - - describe('BrowserWindow.blur()', () => { - it('removes focus from window', () => { - w.blur() -- assert(!w.isFocused()) -+ expect(w.isFocused()).to.equal(false) - }) - }) - -+<<<<<<< .our - // TODO(alexeykuzmin): [Ch66] Enable the test. Passes locally. - xdescribe('BrowserWindow.getFocusedWindow()', (done) => { - it('returns the opener window when dev tools window is focused', (done) => { -+======= -+ describe('BrowserWindow.getFocusedWindow()', done => { -+ it('returns the opener window when dev tools window is focused', done => { -+>>>>>>> .their - w.show() - w.webContents.once('devtools-focused', () => { -- assert.deepEqual(BrowserWindow.getFocusedWindow(), w) -+ expect(BrowserWindow.getFocusedWindow()).to.deep.equal(w) - done() - }) - w.webContents.openDevTools({mode: 'undocked'}) -@@ -422,6 +507,7 @@ - }) - - describe('BrowserWindow.capturePage(rect, callback)', () => { -+<<<<<<< .our - it('calls the callback with a Buffer', async () => { - const image = await new Promise((resolve) => { - w.capturePage({ -@@ -430,19 +516,39 @@ - width: 100, - height: 100 - }, resolve) -+======= -+ it('calls the callback with a Buffer', done => { -+ w.capturePage({ -+ x: 0, -+ y: 0, -+ width: 100, -+ height: 100 -+ }, (image) => { -+ expect(image.isEmpty()).to.equal(true) -+ done() -+>>>>>>> .their - }) - - expect(image.isEmpty()).to.be.true() - }) - -+<<<<<<< .our - it('preserves transparency', async () => { - const w = await openTheWindow({ -+======= -+ it('preserves transparency', done => { -+ w.close() -+ const width = 400 -+ const height = 400 -+ w = new BrowserWindow({ -+>>>>>>> .their - show: false, - width: 400, - height: 400, - transparent: true - }) - w.loadURL('data:text/html,') -+<<<<<<< .our - await emittedOnce(w, 'ready-to-show') - w.show() - -@@ -452,11 +558,27 @@ - // Check the 25th byte in the PNG. - // Values can be 0,2,3,4, or 6. We want 6, which is RGB + Alpha - expect(imgBuffer[25]).to.equal(6) -+======= -+ w.once('ready-to-show', () => { -+ w.show() -+ w.capturePage((image) => { -+ let imgBuffer = image.toPNG() -+ // Check 25th byte in the PNG -+ // Values can be 0,2,3,4, or 6. We want 6, which is RGB + Alpha -+ expect(imgBuffer[25]).to.equal(6) -+ done() -+ }) -+ }) -+>>>>>>> .their - }) - }) - - describe('BrowserWindow.setSize(width, height)', () => { -+<<<<<<< .our - it('sets the window size', async () => { -+======= -+ it('sets the window size', done => { -+>>>>>>> .their - const size = [300, 400] - - const resized = emittedOnce(w, 'resize') -@@ -469,8 +591,8 @@ - - describe('BrowserWindow.setMinimum/MaximumSize(width, height)', () => { - it('sets the maximum and minimum size of the window', () => { -- assert.deepEqual(w.getMinimumSize(), [0, 0]) -- assert.deepEqual(w.getMaximumSize(), [0, 0]) -+ expect(w.getMinimumSize()).to.deep.equal([0, 0]) -+ expect(w.getMaximumSize()).to.deep.equal([0, 0]) - - w.setMinimumSize(100, 100) - assertBoundsEqual(w.getMinimumSize(), [100, 100]) -@@ -483,7 +605,7 @@ - }) - - describe('BrowserWindow.setAspectRatio(ratio)', () => { -- it('resets the behaviour when passing in 0', (done) => { -+ it('resets the behaviour when passing in 0', done => { - const size = [300, 400] - w.setAspectRatio(1 / 2) - w.setAspectRatio(0) -@@ -496,12 +618,12 @@ - }) - - describe('BrowserWindow.setPosition(x, y)', () => { -- it('sets the window position', (done) => { -+ it('sets the window position', done => { - const pos = [10, 10] - w.once('move', () => { - const newPos = w.getPosition() -- assert.equal(newPos[0], pos[0]) -- assert.equal(newPos[1], pos[1]) -+ expect(newPos[0]).to.equal(pos[0]) -+ expect(newPos[1]).to.equal(pos[1]) - done() - }) - w.setPosition(pos[0], pos[1]) -@@ -513,9 +635,10 @@ - const size = [400, 400] - w.setContentSize(size[0], size[1]) - var after = w.getContentSize() -- assert.equal(after[0], size[0]) -- assert.equal(after[1], size[1]) -+ expect(after[0]).to.equal(size[0]) -+ expect(after[1]).to.equal(size[1]) - }) -+ - it('works for a frameless window', () => { - w.destroy() - w = new BrowserWindow({ -@@ -527,13 +650,13 @@ - const size = [400, 400] - w.setContentSize(size[0], size[1]) - const after = w.getContentSize() -- assert.equal(after[0], size[0]) -- assert.equal(after[1], size[1]) -+ expect(after[0]).to.equal(size[0]) -+ expect(after[1]).to.equal(size[1]) - }) - }) - - describe('BrowserWindow.setContentBounds(bounds)', () => { -- it('sets the content size and position', (done) => { -+ it('sets the content size and position', done => { - const bounds = {x: 10, y: 10, width: 250, height: 250} - w.once('resize', () => { - assertBoundsEqual(w.getContentBounds(), bounds) -@@ -541,7 +664,8 @@ - }) - w.setContentBounds(bounds) - }) -- it('works for a frameless window', (done) => { -+ -+ it('works for a frameless window', done => { - w.destroy() - w = new BrowserWindow({ - show: false, -@@ -551,7 +675,7 @@ - }) - const bounds = {x: 10, y: 10, width: 250, height: 250} - w.once('resize', () => { -- assert.deepEqual(w.getContentBounds(), bounds) -+ expect(w.getContentBounds()).to.deep.equal(bounds) - done() - }) - w.setContentBounds(bounds) -@@ -560,7 +684,7 @@ - - describe('BrowserWindow.setProgressBar(progress)', () => { - it('sets the progress', () => { -- assert.doesNotThrow(() => { -+ expect(() => { - if (process.platform === 'darwin') { - app.dock.setIcon(path.join(fixtures, 'assets', 'logo.png')) - } -@@ -570,35 +694,36 @@ - app.dock.setIcon(null) - } - w.setProgressBar(-1) -- }) -+ }).to.not.throw() - }) -+ - it('sets the progress using "paused" mode', () => { -- assert.doesNotThrow(() => { -- w.setProgressBar(0.5, {mode: 'paused'}) -- }) -+ expect(() => { w.setProgressBar(0.5, {mode: 'paused'}) }).to.not.throw() - }) -+ - it('sets the progress using "error" mode', () => { -- assert.doesNotThrow(() => { -- w.setProgressBar(0.5, {mode: 'error'}) -- }) -+ expect(() => { w.setProgressBar(0.5, {mode: 'error'}) }) - }) -+ - it('sets the progress using "normal" mode', () => { -- assert.doesNotThrow(() => { -- w.setProgressBar(0.5, {mode: 'normal'}) -- }) -+ expect(() => { w.setProgressBar(0.5, {mode: 'normal'}) }).to.not.throw() - }) - }) - - describe('BrowserWindow.setAlwaysOnTop(flag, level)', () => { - it('sets the window as always on top', () => { -- assert.equal(w.isAlwaysOnTop(), false) -+ expect(w.isAlwaysOnTop()).to.equal(false) -+ - w.setAlwaysOnTop(true, 'screen-saver') -- assert.equal(w.isAlwaysOnTop(), true) -+ expect(w.isAlwaysOnTop()).to.equal(true) -+ - w.setAlwaysOnTop(false) -- assert.equal(w.isAlwaysOnTop(), false) -+ expect(w.isAlwaysOnTop()).to.equal(false) -+ - w.setAlwaysOnTop(true) -- assert.equal(w.isAlwaysOnTop(), true) -+ expect(w.isAlwaysOnTop()).to.equal(true) - }) -+ - it('raises an error when relativeLevel is out of bounds', function () { - if (process.platform !== 'darwin') { - // FIXME(alexeykuzmin): Skip the test instead of marking it as passed. -@@ -609,13 +734,8 @@ - return - } - -- assert.throws(() => { -- w.setAlwaysOnTop(true, '', -2147483644) -- }) -- -- assert.throws(() => { -- w.setAlwaysOnTop(true, '', 2147483632) -- }) -+ expect(() => { w.setAlwaysOnTop(true, '', -2147483644) }).to.throw() -+ expect(() => { w.setAlwaysOnTop(true, '', 2147483632) }).to.throw() - }) - }) - -@@ -628,13 +748,16 @@ - }) - - it('resets the windows level on minimize', () => { -- assert.equal(w.isAlwaysOnTop(), false) -+ expect(w.isAlwaysOnTop()).to.equal(false) -+ - w.setAlwaysOnTop(true, 'screen-saver') -- assert.equal(w.isAlwaysOnTop(), true) -+ expect(w.isAlwaysOnTop()).to.equal(true) -+ - w.minimize() -- assert.equal(w.isAlwaysOnTop(), false) -+ expect(w.isAlwaysOnTop()).to.equal(false) -+ - w.restore() -- assert.equal(w.isAlwaysOnTop(), true) -+ expect(w.isAlwaysOnTop()).to.equal(true) - }) - }) - -@@ -647,10 +770,10 @@ - }) - - it('allows changing cursor auto-hiding', () => { -- assert.doesNotThrow(() => { -+ expect(() => { - w.setAutoHideCursor(false) - w.setAutoHideCursor(true) -- }) -+ }).to.not.throw() - }) - }) - -@@ -662,7 +785,7 @@ - }) - - it('is not available', () => { -- assert.ok(!w.setAutoHideCursor) -+ expect(!w.setAutoHideCursor).to.equal(true) - }) - }) - }) -@@ -675,9 +798,7 @@ - }) - - it('does not throw', () => { -- assert.doesNotThrow(() => { -- w.selectPreviousTab() -- }) -+ expect(() => { w.selectPreviousTab() }).to.not.throw() - }) - }) - -@@ -689,9 +810,7 @@ - }) - - it('does not throw', () => { -- assert.doesNotThrow(() => { -- w.selectNextTab() -- }) -+ expect(() => { w.selectNextTab() }).to.not.throw() - }) - }) - -@@ -703,9 +822,7 @@ - }) - - it('does not throw', () => { -- assert.doesNotThrow(() => { -- w.mergeAllWindows() -- }) -+ expect(() => { w.mergeAllWindows() }).to.not.throw() - }) - }) - -@@ -717,9 +834,7 @@ - }) - - it('does not throw', () => { -- assert.doesNotThrow(() => { -- w.moveTabToNewWindow() -- }) -+ expect(() => { w.moveTabToNewWindow() }).to.not.throw() - }) - }) - -@@ -731,9 +846,7 @@ - }) - - it('does not throw', () => { -- assert.doesNotThrow(() => { -- w.toggleTabBar() -- }) -+ expect(() => { w.toggleTabBar() }).to.not.throw() - }) - }) - -@@ -744,24 +857,24 @@ - } - }) - -- it('does not throw', (done) => { -+ it('does not throw', done => { - const tabbedWindow = new BrowserWindow({}) -- assert.doesNotThrow(() => { -- w.addTabbedWindow(tabbedWindow) -- }) -+ expect(() => { w.addTabbedWindow(tabbedWindow) }).to.not.throw() - -- assert.equal(BrowserWindow.getAllWindows().length, 3) // Test window + w + tabbedWindow -+ // Test window + w + tabbedWindow -+ expect(BrowserWindow.getAllWindows()).to.have.length(3) - - closeWindow(tabbedWindow, {assertSingleWindow: false}).then(() => { -- assert.equal(BrowserWindow.getAllWindows().length, 2) // Test window + w -+ // Test window + w -+ expect(BrowserWindow.getAllWindows()).to.have.length(3) - done() - }) - }) - - it('throws when called on itself', () => { -- assert.throws(() => { -+ expect(() => { - w.addTabbedWindow(w) -- }, /AddTabbedWindow cannot be called by a window on itself./) -+ }).to.throw(/AddTabbedWindow cannot be called by a window on itself./) - }) - }) - -@@ -794,13 +907,13 @@ - - describe('BrowserWindow.setVibrancy(type)', () => { - it('allows setting, changing, and removing the vibrancy', () => { -- assert.doesNotThrow(() => { -+ expect(() => { - w.setVibrancy('light') - w.setVibrancy('dark') - w.setVibrancy(null) - w.setVibrancy('ultra-dark') - w.setVibrancy('') -- }) -+ }).to.not.throw() - }) - }) - -@@ -814,7 +927,7 @@ - it('supports setting the app details', () => { - const iconPath = path.join(fixtures, 'assets', 'icon.ico') - -- assert.doesNotThrow(() => { -+ expect(() => { - w.setAppDetails({appId: 'my.app.id'}) - w.setAppDetails({appIconPath: iconPath, appIconIndex: 0}) - w.setAppDetails({appIconPath: iconPath}) -@@ -829,17 +942,17 @@ - relaunchDisplayName: 'My app name' - }) - w.setAppDetails({}) -- }) -+ }).to.not.throw() - -- assert.throws(() => { -+ expect(() => { - w.setAppDetails() -- }, /Insufficient number of arguments\./) -+ }).to.throw(/Insufficient number of arguments\./) - }) - }) - - describe('BrowserWindow.fromId(id)', () => { - it('returns the window with id', () => { -- assert.equal(w.id, BrowserWindow.fromId(w.id).id) -+ expect(w.id).to.equal(BrowserWindow.fromId(w.id).id) - }) - }) - -@@ -851,8 +964,8 @@ - afterEach(() => { contents.destroy() }) - - it('returns the window with the webContents', () => { -- assert.equal(BrowserWindow.fromWebContents(w.webContents).id, w.id) -- assert.equal(BrowserWindow.fromWebContents(contents), undefined) -+ expect(BrowserWindow.fromWebContents(w.webContents).id).to.equal(w.id) -+ expect(BrowserWindow.fromWebContents(contents)).to.equal(undefined) - }) - }) - -@@ -863,11 +976,11 @@ - - afterEach(() => { contents.destroy() }) - -- it('returns the window with the webContents', (done) => { -+ it('returns the window with the webContents', done => { - w.webContents.once('devtools-opened', () => { -- assert.equal(BrowserWindow.fromDevToolsWebContents(w.devToolsWebContents).id, w.id) -- assert.equal(BrowserWindow.fromDevToolsWebContents(w.webContents), undefined) -- assert.equal(BrowserWindow.fromDevToolsWebContents(contents), undefined) -+ expect(BrowserWindow.fromDevToolsWebContents(w.devToolsWebContents).id).to.equal(w.id) -+ expect(BrowserWindow.fromDevToolsWebContents(w.webContents)).to.equal(undefined) -+ expect(BrowserWindow.fromDevToolsWebContents(contents)).to.equal(undefined) - done() - }) - w.webContents.openDevTools() -@@ -896,12 +1009,12 @@ - }) - - it('returns the window with the browserView', () => { -- assert.equal(BrowserWindow.fromBrowserView(bv).id, w.id) -+ expect(BrowserWindow.fromBrowserView(bv).id).to.equal(w.id) - }) - - it('returns undefined if not attached', () => { - w.setBrowserView(null) -- assert.equal(BrowserWindow.fromBrowserView(bv), undefined) -+ expect(BrowserWindow.fromBrowserView(bv)).to.equal(undefined) - }) - }) - -@@ -914,16 +1027,17 @@ - height: 400, - opacity: 0.5 - }) -- assert.equal(w.getOpacity(), 0.5) -+ expect(w.getOpacity()).to.equal(0.5) - }) -+ - it('allows setting the opacity', () => { -- assert.doesNotThrow(() => { -+ expect(() => { - w.setOpacity(0.0) -- assert.equal(w.getOpacity(), 0.0) -+ expect(w.getOpacity()).to.equal(0.0) - w.setOpacity(0.5) -- assert.equal(w.getOpacity(), 0.5) -+ expect(w.getOpacity()).to.equal(0.5) - w.setOpacity(1.0) -- assert.equal(w.getOpacity(), 1.0) -+ expect(w.getOpacity()).to.equal(1.0) - }) - }) - }) -@@ -949,14 +1063,16 @@ - useContentSize: true - }) - const contentSize = w.getContentSize() -- assert.equal(contentSize[0], 400) -- assert.equal(contentSize[1], 400) -+ expect(contentSize[0]).to.equal(400) -+ expect(contentSize[1]).to.equal(400) - }) -+ - it('make window created with window size when not used', () => { - const size = w.getSize() -- assert.equal(size[0], 400) -- assert.equal(size[1], 400) -+ expect(size[0]).to.equal(400) -+ expect(size[1]).to.equal(400) - }) -+ - it('works for a frameless window', () => { - w.destroy() - w = new BrowserWindow({ -@@ -967,11 +1083,11 @@ - useContentSize: true - }) - const contentSize = w.getContentSize() -- assert.equal(contentSize[0], 400) -- assert.equal(contentSize[1], 400) -+ expect(contentSize[0]).to.equal(400) -+ expect(contentSize[1]).to.equal(400) - const size = w.getSize() -- assert.equal(size[0], 400) -- assert.equal(size[1], 400) -+ expect(size[0]).to.equal(400) -+ expect(size[1]).to.equal(400) - }) - }) - -@@ -995,8 +1111,9 @@ - titleBarStyle: 'hidden' - }) - const contentSize = w.getContentSize() -- assert.equal(contentSize[1], 400) -+ expect(contentSize[1]).to.equal(400) - }) -+ - it('creates browser window with hidden inset title bar', () => { - w.destroy() - w = new BrowserWindow({ -@@ -1006,7 +1123,7 @@ - titleBarStyle: 'hiddenInset' - }) - const contentSize = w.getContentSize() -- assert.equal(contentSize[1], 400) -+ expect(contentSize[1]).to.equal(400) - }) - }) - -@@ -1030,9 +1147,10 @@ - it('can move the window out of screen', () => { - w.setPosition(-10, -10) - const after = w.getPosition() -- assert.equal(after[0], -10) -- assert.equal(after[1], -10) -+ expect(after[0]).to.equal(-10) -+ expect(after[1]).to.equal(-10) - }) -+ - it('can set the window larger than screen', () => { - const size = screen.getPrimaryDisplay().size - size.width += 100 -@@ -1058,7 +1176,7 @@ - zoomToPageWidth: true - }) - w.maximize() -- assert.equal(w.getSize()[0], 500) -+ expect(w.getSize()[0]).to.equal(500) - }) - }) - -@@ -1080,10 +1198,10 @@ - afterEach(() => { ipcMain.removeAllListeners('answer') }) - - describe('"preload" option', () => { -- it('loads the script before other scripts in window', (done) => { -+ it('loads the script before other scripts in window', done => { - const preload = path.join(fixtures, 'module', 'set-global.js') - ipcMain.once('answer', (event, test) => { -- assert.equal(test, 'preload') -+ expect(test).to.equal('preload') - done() - }) - w.destroy() -@@ -1095,10 +1213,11 @@ - }) - w.loadURL(`file://${path.join(fixtures, 'api', 'preload.html')}`) - }) -- it('can successfully delete the Buffer global', (done) => { -+ -+ it('can successfully delete the Buffer global', done => { - const preload = path.join(fixtures, 'module', 'delete-buffer.js') - ipcMain.once('answer', (event, test) => { -- assert.equal(test.toString(), 'buffer') -+ expect(test.toString()).to.equal('buffer') - done() - }) - w.destroy() -@@ -1112,7 +1231,7 @@ - }) - }) - -- describe('session preload scripts', function () { -+ describe('session preload scripts', () => { - const preloads = [ - path.join(fixtures, 'module', 'set-global-preload-1.js'), - path.join(fixtures, 'module', 'set-global-preload-2.js') -@@ -1120,24 +1239,26 @@ - const defaultSession = session.defaultSession - - beforeEach(() => { -- assert.deepEqual(defaultSession.getPreloads(), []) -+ expect(defaultSession.getPreloads()).to.deep.equal([]) - defaultSession.setPreloads(preloads) - }) -+ - afterEach(() => { - defaultSession.setPreloads([]) - }) - -- it('can set multiple session preload script', function () { -- assert.deepEqual(defaultSession.getPreloads(), preloads) -+ it('can set multiple session preload script', () => { -+ expect(defaultSession.getPreloads()).to.deep.equal(preloads) - }) - -- it('loads the script before other scripts in window including normal preloads', function (done) { -- ipcMain.once('vars', function (event, preload1, preload2, preload3) { -- assert.equal(preload1, 'preload-1') -- assert.equal(preload2, 'preload-1-2') -- assert.equal(preload3, 'preload-1-2-3') -+ it('loads the script before other scripts in window including normal preloads', done => { -+ ipcMain.once('vars', (event, preload1, preload2, preload3) => { -+ expect(preload1).to.equal('preload-1') -+ expect(preload2).to.equal('preload-1-2') -+ expect(preload3).equal('preload-1-2-3') - done() - }) -+ - w.destroy() - w = new BrowserWindow({ - show: false, -@@ -1145,15 +1266,15 @@ - preload: path.join(fixtures, 'module', 'set-global-preload-3.js') - } - }) -- w.loadURL('file://' + path.join(fixtures, 'api', 'preloads.html')) -+ w.loadURL(`file://${path.join(fixtures, 'api', 'preloads.html')}`) - }) - }) - - describe('"additionalArguments" option', () => { -- it('adds extra args to process.argv in the renderer process', (done) => { -+ it('adds extra args to process.argv in the renderer process', done => { - const preload = path.join(fixtures, 'module', 'check-arguments.js') - ipcMain.once('answer', (event, argv) => { -- assert.ok(argv.includes('--my-magic-arg')) -+ expect(argv).to.include('--my-magic-arg') - done() - }) - w.destroy() -@@ -1167,12 +1288,13 @@ - w.loadURL(`file://${path.join(fixtures, 'api', 'blank.html')}`) - }) - -- it('adds extra value args to process.argv in the renderer process', (done) => { -+ it('adds extra value args to process.argv in the renderer process', done => { - const preload = path.join(fixtures, 'module', 'check-arguments.js') - ipcMain.once('answer', (event, argv) => { -- assert.ok(argv.includes('--my-magic-arg=foo')) -+ expect(argv).to.include('--my-magic-arg=foo') - done() - }) -+ - w.destroy() - w = new BrowserWindow({ - show: false, -@@ -1186,13 +1308,14 @@ - }) - - describe('"node-integration" option', () => { -- it('disables node integration when specified to false', (done) => { -+ it('disables node integration when specified to false', done => { - const preload = path.join(fixtures, 'module', 'send-later.js') - ipcMain.once('answer', (event, typeofProcess, typeofBuffer) => { -- assert.equal(typeofProcess, 'undefined') -- assert.equal(typeofBuffer, 'undefined') -+ expect(typeofProcess).to.equal('undefined') -+ expect(typeofBuffer).to.equal('undefined') - done() - }) -+ - w.destroy() - w = new BrowserWindow({ - show: false, -@@ -1228,23 +1351,24 @@ - }) - } - -- before((done) => { -+ before(done => { - protocol.interceptStringProtocol('http', crossDomainHandler, () => { - done() - }) - }) - -- after((done) => { -+ after(done => { - protocol.uninterceptProtocol('http', () => { - done() - }) - }) - -- it('exposes ipcRenderer to preload script', (done) => { -- ipcMain.once('answer', function (event, test) { -- assert.equal(test, 'preload') -+ it('exposes ipcRenderer to preload script', done => { -+ ipcMain.once('answer', (event, test) => { -+ expect(test).to.equal('preload') - done() - }) -+ - w.destroy() - w = new BrowserWindow({ - show: false, -@@ -1253,13 +1377,13 @@ - preload: preload - } - }) -- w.loadURL('file://' + path.join(fixtures, 'api', 'preload.html')) -+ w.loadURL(`file://${path.join(fixtures, 'api', 'preload.html')}`) - }) - -- it('exposes ipcRenderer to preload script (path has special chars)', function (done) { -+ it('exposes ipcRenderer to preload script (path has special chars)', done => { - const preloadSpecialChars = path.join(fixtures, 'module', 'preload-sandboxæø åü.js') -- ipcMain.once('answer', function (event, test) { -- assert.equal(test, 'preload') -+ ipcMain.once('answer', (event, test) => { -+ expect(test).to.equal('preload') - done() - }) - w.destroy() -@@ -1270,10 +1394,10 @@ - preload: preloadSpecialChars - } - }) -- w.loadURL('file://' + path.join(fixtures, 'api', 'preload.html')) -+ w.loadURL(`file://${path.join(fixtures, 'api', 'preload.html')}`) - }) - -- it('exposes "exit" event to preload script', function (done) { -+ it('exposes "exit" event to preload script', done => { - w.destroy() - w = new BrowserWindow({ - show: false, -@@ -1283,19 +1407,20 @@ - } - }) - let htmlPath = path.join(fixtures, 'api', 'sandbox.html?exit-event') -- const pageUrl = 'file://' + htmlPath -+ const pageUrl = `file://${htmlPath}` -+ - w.loadURL(pageUrl) -- ipcMain.once('answer', function (event, url) { -+ ipcMain.once('answer', (event, url) => { - let expectedUrl = pageUrl - if (process.platform === 'win32') { -- expectedUrl = 'file:///' + htmlPath.replace(/\\/g, '/') -+ expectedUrl = `file:///${htmlPath.replace(/\\/g, '/')}` - } -- assert.equal(url, expectedUrl) -+ expect(url).to.equal(expectedUrl) - done() - }) - }) - -- it('should open windows in same domain with cross-scripting enabled', (done) => { -+ it('should open windows in same domain with cross-scripting enabled', done => { - w.destroy() - w = new BrowserWindow({ - show: false, -@@ -1304,27 +1429,30 @@ - preload: preload - } - }) -+ - ipcRenderer.send('set-web-preferences-on-next-new-window', w.webContents.id, 'preload', preload) - let htmlPath = path.join(fixtures, 'api', 'sandbox.html?window-open') -- const pageUrl = 'file://' + htmlPath -+ const pageUrl = `file://${htmlPath}` - w.loadURL(pageUrl) -+ - w.webContents.once('new-window', (e, url, frameName, disposition, options) => { - let expectedUrl = pageUrl - if (process.platform === 'win32') { -- expectedUrl = 'file:///' + htmlPath.replace(/\\/g, '/') -+ expectedUrl = `file:///${htmlPath.replace(/\\/g, '/')}` - } -- assert.equal(url, expectedUrl) -- assert.equal(frameName, 'popup!') -- assert.equal(options.width, 500) -- assert.equal(options.height, 600) -- ipcMain.once('answer', function (event, html) { -- assert.equal(html, '

scripting from opener

') -+ expect(url).to.equal(expectedUrl) -+ expect(frameName).to.equal('popup!') -+ expect(options.width).to.equal(500) -+ expect(options.height).to.equal(600) -+ -+ ipcMain.once('answer', (event, html) => { -+ expect(html).equal('

scripting from opener

') - done() - }) - }) - }) - -- it('should open windows in another domain with cross-scripting disabled', (done) => { -+ it('should open windows in another domain with cross-scripting disabled', done => { - w.destroy() - w = new BrowserWindow({ - show: false, -@@ -1333,20 +1461,23 @@ - preload: preload - } - }) -+ - ipcRenderer.send('set-web-preferences-on-next-new-window', w.webContents.id, 'preload', preload) - let htmlPath = path.join(fixtures, 'api', 'sandbox.html?window-open-external') -- const pageUrl = 'file://' + htmlPath -+ const pageUrl = `file://${htmlPath}` - let popupWindow - w.loadURL(pageUrl) -+ - w.webContents.once('new-window', (e, url, frameName, disposition, options) => { -- assert.equal(url, 'http://www.google.com/#q=electron') -- assert.equal(options.width, 505) -- assert.equal(options.height, 605) -- ipcMain.once('child-loaded', function (event, openerIsNull, html) { -- assert(openerIsNull) -- assert.equal(html, '

http://www.google.com/#q=electron

') -- ipcMain.once('answer', function (event, exceptionMessage) { -- assert(/Blocked a frame with origin/.test(exceptionMessage)) -+ expect(url).to.equal('http://www.google.com/#q=electron') -+ expect(options.width).to.equal(505) -+ expect(options.height).to.equal(605) -+ -+ ipcMain.once('child-loaded', (event, openerIsNull, html) => { -+ expect(openerIsNull).to.be.true() -+ expect(html).to.equal('

http://www.google.com/#q=electron

') -+ ipcMain.once('answer', (event, exceptionMessage) => { -+ expect(/Blocked a frame with origin/.test(exceptionMessage)).to.be.true() - - // FIXME this popup window should be closed in sandbox.html - closeWindow(popupWindow, {assertSingleWindow: false}).then(() => { -@@ -1358,12 +1489,12 @@ - }) - }) - -- app.once('browser-window-created', function (event, window) { -+ app.once('browser-window-created', (event, window) => { - popupWindow = window - }) - }) - -- it('should inherit the sandbox setting in opened windows', (done) => { -+ it('should inherit the sandbox setting in opened windows', done => { - w.destroy() - w = new BrowserWindow({ - show: false, -@@ -1375,13 +1506,13 @@ - const preloadPath = path.join(fixtures, 'api', 'new-window-preload.js') - ipcRenderer.send('set-web-preferences-on-next-new-window', w.webContents.id, 'preload', preloadPath) - ipcMain.once('answer', (event, args) => { -- assert.equal(args.includes('--enable-sandbox'), true) -+ expect(args).to.include('--enable-sandbox') - done() - }) - w.loadURL(`file://${path.join(fixtures, 'api', 'new-window.html')}`) - }) - -- it('should open windows with the options configured via new-window event listeners', (done) => { -+ it('should open windows with the options configured via new-window event listeners', done => { - w.destroy() - w = new BrowserWindow({ - show: false, -@@ -1394,13 +1525,13 @@ - ipcRenderer.send('set-web-preferences-on-next-new-window', w.webContents.id, 'preload', preloadPath) - ipcRenderer.send('set-web-preferences-on-next-new-window', w.webContents.id, 'foo', 'bar') - ipcMain.once('answer', (event, args, webPreferences) => { -- assert.equal(webPreferences.foo, 'bar') -+ expect(webPreferences.foo).to.equal('bar') - done() - }) - w.loadURL(`file://${path.join(fixtures, 'api', 'new-window.html')}`) - }) - -- it('should set ipc event sender correctly', (done) => { -+ it('should set ipc event sender correctly', done => { - w.destroy() - w = new BrowserWindow({ - show: false, -@@ -1409,24 +1540,31 @@ - preload: preload - } - }) -+<<<<<<< .our - ipcRenderer.send('set-web-preferences-on-next-new-window', w.webContents.id, 'preload', preload) -+======= -+>>>>>>> .their - - let htmlPath = path.join(fixtures, 'api', 'sandbox.html?verify-ipc-sender') -- const pageUrl = 'file://' + htmlPath -+ const pageUrl = `file://${htmlPath}` - let childWc -+ - w.webContents.once('new-window', (e, url, frameName, disposition, options) => { - childWc = options.webContents -- assert.notEqual(w.webContents, childWc) -+ expect(w.webContents).to.not.equal(childWc) - }) -- ipcMain.once('parent-ready', function (event) { -- assert.equal(w.webContents, event.sender) -+ -+ ipcMain.once('parent-ready', event => { -+ expect(w.webContents).to.equal(event.sender) - event.sender.send('verified') - }) -- ipcMain.once('child-ready', function (event) { -- assert(childWc) -- assert.equal(childWc, event.sender) -+ -+ ipcMain.once('child-ready', event => { -+ expect(childWc).to.exist() -+ expect(childWc).to.equal(event.sender) - event.sender.send('verified') - }) -+ - waitForEvents(ipcMain, [ - 'parent-answer', - 'child-answer' -@@ -1435,23 +1573,23 @@ - }) - - describe('event handling', () => { -- it('works for window events', (done) => { -+ it('works for window events', done => { - waitForEvents(w, [ - 'page-title-updated' - ], done) -- w.loadURL('file://' + path.join(fixtures, 'api', 'sandbox.html?window-events')) -+ w.loadURL(`file://${path.join(fixtures, 'api', 'sandbox.html?window-events')}`) - }) - -- it('works for stop events', (done) => { -+ it('works for stop events', done => { - waitForEvents(w.webContents, [ - 'did-navigate', - 'did-fail-load', - 'did-stop-loading' - ], done) -- w.loadURL('file://' + path.join(fixtures, 'api', 'sandbox.html?webcontents-stop')) -+ w.loadURL(`file://${path.join(fixtures, 'api', 'sandbox.html?webcontents-stop')}`) - }) - -- it('works for web contents events', (done) => { -+ it('works for web contents events', done => { - waitForEvents(w.webContents, [ - 'did-finish-load', - 'did-frame-finish-load', -@@ -1462,11 +1600,11 @@ - 'did-frame-finish-load', - 'dom-ready' - ], done) -- w.loadURL('file://' + path.join(fixtures, 'api', 'sandbox.html?webcontents-events')) -+ w.loadURL(`file://${path.join(fixtures, 'api', 'sandbox.html?webcontents-events')}`) - }) - }) - -- it('can get printer list', (done) => { -+ it('can get printer list', done => { - w.destroy() - w = new BrowserWindow({ - show: false, -@@ -1475,15 +1613,16 @@ - preload: preload - } - }) -+ - w.loadURL('data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E') - w.webContents.once('did-finish-load', () => { - const printers = w.webContents.getPrinters() -- assert.equal(Array.isArray(printers), true) -+ expect(printers).to.be.an('array') - done() - }) - }) - -- it('can print to PDF', (done) => { -+ it('can print to PDF', done => { - w.destroy() - w = new BrowserWindow({ - show: false, -@@ -1492,18 +1631,19 @@ - preload: preload - } - }) -+ - w.loadURL('data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E') - w.webContents.once('did-finish-load', () => { -- w.webContents.printToPDF({}, function (error, data) { -- assert.equal(error, null) -- assert.equal(data instanceof Buffer, true) -- assert.notEqual(data.length, 0) -+ w.webContents.printToPDF({}, (error, data) => { -+ expect(error).to.be.null() -+ expect(data).to.be.an.instanceOf('Buffer') -+ expect(data.length).to.not.equal(0) - done() - }) - }) - }) - -- it('supports calling preventDefault on new-window events', (done) => { -+ it('supports calling preventDefault on new-window events', done => { - w.destroy() - w = new BrowserWindow({ - show: false, -@@ -1511,20 +1651,21 @@ - sandbox: true - } - }) -+ - const initialWebContents = webContents.getAllWebContents().map((i) => i.id) - ipcRenderer.send('prevent-next-new-window', w.webContents.id) - w.webContents.once('new-window', () => { - // We need to give it some time so the windows get properly disposed (at least on OSX). - setTimeout(() => { - const currentWebContents = webContents.getAllWebContents().map((i) => i.id) -- assert.deepEqual(currentWebContents, initialWebContents) -+ expect(currentWebContents).to.deep.equal(initialWebContents) - done() - }, 100) - }) -- w.loadURL('file://' + path.join(fixtures, 'pages', 'window-open.html')) -+ w.loadURL(`file://${path.join(fixtures, 'pages', 'window-open.html')}`) - }) - -- it('releases memory after popup is closed', (done) => { -+ it('releases memory after popup is closed', done => { - w.destroy() - w = new BrowserWindow({ - show: false, -@@ -1533,21 +1674,22 @@ - sandbox: true - } - }) -- w.loadURL('file://' + path.join(fixtures, 'api', 'sandbox.html?allocate-memory')) -- ipcMain.once('answer', function (event, {bytesBeforeOpen, bytesAfterOpen, bytesAfterClose}) { -+ -+ w.loadURL(`file://${path.join(fixtures, 'api', 'sandbox.html?allocate-memory')}`) -+ ipcMain.once('answer', (event, {bytesBeforeOpen, bytesAfterOpen, bytesAfterClose}) => { - const memoryIncreaseByOpen = bytesAfterOpen - bytesBeforeOpen - const memoryDecreaseByClose = bytesAfterOpen - bytesAfterClose - // decreased memory should be less than increased due to factors we - // can't control, but given the amount of memory allocated in the - // fixture, we can reasonably expect decrease to be at least 70% of - // increase -- assert(memoryDecreaseByClose > memoryIncreaseByOpen * 0.7) -+ expect(memoryDecreaseByClose > memoryIncreaseByOpen * 0.7).to.be.true() - done() - }) - }) - - // see #9387 -- it('properly manages remote object references after page reload', (done) => { -+ it('properly manages remote object references after page reload', done => { - w.destroy() - w = new BrowserWindow({ - show: false, -@@ -1556,31 +1698,31 @@ - sandbox: true - } - }) -- w.loadURL('file://' + path.join(fixtures, 'api', 'sandbox.html?reload-remote')) -+ w.loadURL(`file://${path.join(fixtures, 'api', 'sandbox.html?reload-remote')}`) - -- ipcMain.on('get-remote-module-path', (event) => { -+ ipcMain.on('get-remote-module-path', event => { - event.returnValue = path.join(fixtures, 'module', 'hello.js') - }) - - let reload = false -- ipcMain.on('reloaded', (event) => { -+ ipcMain.on('reloaded', event => { - event.returnValue = reload - reload = !reload - }) - -- ipcMain.once('reload', (event) => { -+ ipcMain.once('reload', event => { - event.sender.reload() - }) - - ipcMain.once('answer', (event, arg) => { - ipcMain.removeAllListeners('reloaded') - ipcMain.removeAllListeners('get-remote-module-path') -- assert.equal(arg, 'hi') -+ expect(arg).to.equal('hi') - done() - }) - }) - -- it('properly manages remote object references after page reload in child window', (done) => { -+ it('properly manages remote object references after page reload in child window', done => { - w.destroy() - w = new BrowserWindow({ - show: false, -@@ -1589,32 +1731,37 @@ - sandbox: true - } - }) -+<<<<<<< .our - ipcRenderer.send('set-web-preferences-on-next-new-window', w.webContents.id, 'preload', preload) - - w.loadURL('file://' + path.join(fixtures, 'api', 'sandbox.html?reload-remote-child')) -+======= -+ w.loadURL(`file://${path.join(fixtures, 'api', 'sandbox.html?reload-remote-child')}`) -+>>>>>>> .their - -- ipcMain.on('get-remote-module-path', (event) => { -+ ipcMain.on('get-remote-module-path', event => { - event.returnValue = path.join(fixtures, 'module', 'hello-child.js') - }) - - let reload = false -- ipcMain.on('reloaded', (event) => { -+ ipcMain.on('reloaded', event => { - event.returnValue = reload - reload = !reload - }) - -- ipcMain.once('reload', (event) => { -+ ipcMain.once('reload', event => { - event.sender.reload() - }) - - ipcMain.once('answer', (event, arg) => { - ipcMain.removeAllListeners('reloaded') - ipcMain.removeAllListeners('get-remote-module-path') -- assert.equal(arg, 'hi child window') -+ expect(arg).to.equal('hi child window') - done() - }) - }) - -+<<<<<<< .our - it('validates process APIs access in sandboxed renderer', (done) => { - ipcMain.once('answer', function (event, test) { - assert.equal(test.pid, w.webContents.getOSProcessId()) -@@ -1627,8 +1774,14 @@ - assert.equal(test.type, 'renderer') - assert.equal(test.version, remote.process.version) - assert.deepEqual(test.versions, remote.process.versions) -+======= -+ it('validate process.env access in sandbox renderer', done => { -+ ipcMain.once('answer', (event, test) => { -+ expect(test).to.equal('foo') -+>>>>>>> .their - done() - }) -+ - remote.process.env.sandboxmain = 'foo' - w.destroy() - w = new BrowserWindow({ -@@ -1638,7 +1791,7 @@ - preload: preload - } - }) -- w.loadURL('file://' + path.join(fixtures, 'api', 'preload.html')) -+ w.loadURL(`file://${path.join(fixtures, 'api', 'preload.html')}`) - }) - - it('webview in sandbox renderer', async () => { -@@ -1670,48 +1823,53 @@ - }) - }) - -- it('opens window of about:blank with cross-scripting enabled', (done) => { -+ it('opens window of about:blank with cross-scripting enabled', done => { - ipcMain.once('answer', (event, content) => { -- assert.equal(content, 'Hello') -+ expect(content).to.equal('Hello') - done() - }) - w.loadURL(`file://${path.join(fixtures, 'api', 'native-window-open-blank.html')}`) - }) -- it('opens window of same domain with cross-scripting enabled', (done) => { -+ -+ it('opens window of same domain with cross-scripting enabled', done => { - ipcMain.once('answer', (event, content) => { -- assert.equal(content, 'Hello') -+ expect(content).to.equal('Hello') - done() - }) - w.loadURL(`file://${path.join(fixtures, 'api', 'native-window-open-file.html')}`) - }) -- it('blocks accessing cross-origin frames', (done) => { -+ -+ it('blocks accessing cross-origin frames', done => { - ipcMain.once('answer', (event, content) => { -- assert.equal(content, 'Blocked a frame with origin "file://" from accessing a cross-origin frame.') -+ expect(content).to.equal('Blocked a frame with origin "file://" from accessing a cross-origin frame.') - done() - }) - w.loadURL(`file://${path.join(fixtures, 'api', 'native-window-open-cross-origin.html')}`) - }) -- it('opens window from