mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-18 14:45:12 +02:00
Merge branch 'master' into sh
This commit is contained in:
@@ -450,6 +450,11 @@ en:
|
||||
description:
|
||||
# description=*
|
||||
label: Description
|
||||
devices:
|
||||
# devices=*
|
||||
label: Number of Devices
|
||||
# devices field placeholder
|
||||
placeholder: '1, 2, 3...'
|
||||
diaper:
|
||||
# diaper=*
|
||||
label: Diaper Changing Available
|
||||
@@ -546,6 +551,9 @@ en:
|
||||
label: Type
|
||||
# ford field placeholder
|
||||
placeholder: Default
|
||||
frequency:
|
||||
# frequency=*
|
||||
label: Operating Frequency
|
||||
fuel:
|
||||
# fuel=*
|
||||
label: Fuel
|
||||
@@ -977,6 +985,11 @@ en:
|
||||
payment_multi:
|
||||
# 'payment:=*'
|
||||
label: Payment Types
|
||||
phases:
|
||||
# phases=*
|
||||
label: Number of Phases
|
||||
# phases field placeholder
|
||||
placeholder: '1, 2, 3...'
|
||||
phone:
|
||||
# phone=*
|
||||
label: Phone
|
||||
@@ -1078,6 +1091,9 @@ en:
|
||||
railway:
|
||||
# railway=*
|
||||
label: Type
|
||||
rating:
|
||||
# rating=*
|
||||
label: Power Rating
|
||||
recycling_accepts:
|
||||
# 'recycling:=*'
|
||||
label: Accepts
|
||||
@@ -1443,6 +1459,26 @@ en:
|
||||
'no': 'No: pathless, excellent orientation skills required'
|
||||
# trail_visibility field placeholder
|
||||
placeholder: 'Excellent, Good, Bad...'
|
||||
transformer:
|
||||
# transformer=*
|
||||
label: Type of Transformer
|
||||
options:
|
||||
# transformer=auto
|
||||
auto: Autotransformer
|
||||
# transformer=auxiliary
|
||||
auxiliary: Auxiliarty
|
||||
# transformer=converter
|
||||
converter: Converter
|
||||
# transformer=distribution
|
||||
distribution: Distribution
|
||||
# transformer=generator
|
||||
generator: Generator
|
||||
# transformer=phase_angle_regulator
|
||||
phase_angle_regulator: Phase Angle Regulator
|
||||
# transformer=traction
|
||||
traction: Traction
|
||||
# transformer=yes
|
||||
'yes': Unknown
|
||||
trees:
|
||||
# trees=*
|
||||
label: Trees
|
||||
@@ -1484,6 +1520,15 @@ en:
|
||||
shield: Shield
|
||||
# 'volcano:type=stratovolcano'
|
||||
stratovolcano: Stratovolcano
|
||||
voltage/primary:
|
||||
# 'voltage:primary=*'
|
||||
label: Primary Voltage
|
||||
voltage/secondary:
|
||||
# 'voltage:secondary=*'
|
||||
label: Secondary Voltage
|
||||
voltage/tertiary:
|
||||
# 'voltage:tertiary=*'
|
||||
label: Tertiary Voltage
|
||||
wall:
|
||||
# wall=*
|
||||
label: Type
|
||||
@@ -1513,6 +1558,29 @@ en:
|
||||
wikipedia:
|
||||
# 'wikipedia=*, wikidata=*'
|
||||
label: Wikipedia
|
||||
windings:
|
||||
# windings=*
|
||||
label: Number of Windings
|
||||
# windings field placeholder
|
||||
placeholder: '1, 2, 3...'
|
||||
windings/configuration:
|
||||
# 'windings:configuration=*'
|
||||
label: Windings Configuration
|
||||
options:
|
||||
# 'windings:configuration=delta'
|
||||
delta: Delta
|
||||
# 'windings:configuration=leblanc'
|
||||
leblanc: Leblanc
|
||||
# 'windings:configuration=open'
|
||||
open: Open
|
||||
# 'windings:configuration=open-delta'
|
||||
open-delta: Open Delta
|
||||
# 'windings:configuration=scott'
|
||||
scott: Scott
|
||||
# 'windings:configuration=star'
|
||||
star: Star / Wye
|
||||
# 'windings:configuration=zigzag'
|
||||
zigzag: Zig Zag
|
||||
presets:
|
||||
address:
|
||||
# 'addr:*=*'
|
||||
|
||||
@@ -594,6 +594,12 @@
|
||||
"label": "Description",
|
||||
"universal": true
|
||||
},
|
||||
"devices": {
|
||||
"key": "devices",
|
||||
"type": "number",
|
||||
"label": "Number of Devices",
|
||||
"placeholder": "1, 2, 3..."
|
||||
},
|
||||
"diaper": {
|
||||
"key": "diaper",
|
||||
"type": "combo",
|
||||
@@ -740,6 +746,11 @@
|
||||
"label": "Type",
|
||||
"placeholder": "Default"
|
||||
},
|
||||
"frequency": {
|
||||
"key": "frequency",
|
||||
"type": "combo",
|
||||
"label": "Operating Frequency"
|
||||
},
|
||||
"fuel_multi": {
|
||||
"key": "fuel:",
|
||||
"type": "multiCombo",
|
||||
@@ -1316,6 +1327,12 @@
|
||||
"type": "multiCombo",
|
||||
"label": "Payment Types"
|
||||
},
|
||||
"phases": {
|
||||
"key": "phases",
|
||||
"type": "number",
|
||||
"label": "Number of Phases",
|
||||
"placeholder": "1, 2, 3..."
|
||||
},
|
||||
"phone": {
|
||||
"key": "phone",
|
||||
"type": "tel",
|
||||
@@ -1435,6 +1452,12 @@
|
||||
"type": "typeCombo",
|
||||
"label": "Type"
|
||||
},
|
||||
"rating": {
|
||||
"key": "rating",
|
||||
"type": "combo",
|
||||
"label": "Power Rating",
|
||||
"snake_case": false
|
||||
},
|
||||
"recycling_accepts": {
|
||||
"key": "recycling:",
|
||||
"type": "multiCombo",
|
||||
@@ -1964,6 +1987,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"transformer": {
|
||||
"key": "transformer",
|
||||
"type": "combo",
|
||||
"label": "Type of Transformer",
|
||||
"strings": {
|
||||
"options": {
|
||||
"distribution": "Distribution",
|
||||
"generator": "Generator",
|
||||
"converter": "Converter",
|
||||
"traction": "Traction",
|
||||
"auto": "Autotransformer",
|
||||
"phase_angle_regulator": "Phase Angle Regulator",
|
||||
"auxiliary": "Auxiliarty",
|
||||
"yes": "Unknown"
|
||||
}
|
||||
}
|
||||
},
|
||||
"trees": {
|
||||
"key": "trees",
|
||||
"type": "semiCombo",
|
||||
@@ -2016,6 +2056,21 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"voltage/primary": {
|
||||
"key": "voltage:primary",
|
||||
"type": "combo",
|
||||
"label": "Primary Voltage"
|
||||
},
|
||||
"voltage/secondary": {
|
||||
"key": "voltage:secondary",
|
||||
"type": "combo",
|
||||
"label": "Secondary Voltage"
|
||||
},
|
||||
"voltage/tertiary": {
|
||||
"key": "voltage:tertiary",
|
||||
"type": "combo",
|
||||
"label": "Tertiary Voltage"
|
||||
},
|
||||
"wall": {
|
||||
"key": "wall",
|
||||
"type": "combo",
|
||||
@@ -2076,6 +2131,28 @@
|
||||
"icon": "wikipedia",
|
||||
"universal": true,
|
||||
"label": "Wikipedia"
|
||||
},
|
||||
"windings": {
|
||||
"key": "windings",
|
||||
"type": "number",
|
||||
"label": "Number of Windings",
|
||||
"placeholder": "1, 2, 3..."
|
||||
},
|
||||
"windings/configuration": {
|
||||
"key": "windings:configuration",
|
||||
"type": "combo",
|
||||
"label": "Windings Configuration",
|
||||
"strings": {
|
||||
"options": {
|
||||
"star": "Star / Wye",
|
||||
"delta": "Delta",
|
||||
"open-delta": "Open Delta",
|
||||
"zigzag": "Zig Zag",
|
||||
"open": "Open",
|
||||
"scott": "Scott",
|
||||
"leblanc": "Leblanc"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"key": "devices",
|
||||
"type": "number",
|
||||
"label": "Number of Devices",
|
||||
"placeholder": "1, 2, 3..."
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"key": "frequency",
|
||||
"type": "combo",
|
||||
"label": "Operating Frequency"
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"key": "phases",
|
||||
"type": "number",
|
||||
"label": "Number of Phases",
|
||||
"placeholder": "1, 2, 3..."
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"key": "rating",
|
||||
"type": "combo",
|
||||
"label": "Power Rating",
|
||||
"snake_case": false
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"key": "transformer",
|
||||
"type": "combo",
|
||||
"label": "Type of Transformer",
|
||||
"strings": {
|
||||
"options": {
|
||||
"distribution": "Distribution",
|
||||
"generator": "Generator",
|
||||
"converter": "Converter",
|
||||
"traction": "Traction",
|
||||
"auto": "Autotransformer",
|
||||
"phase_angle_regulator": "Phase Angle Regulator",
|
||||
"auxiliary": "Auxiliarty",
|
||||
"yes": "Unknown"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"key": "voltage:primary",
|
||||
"type": "combo",
|
||||
"label": "Primary Voltage"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"key": "voltage:secondary",
|
||||
"type": "combo",
|
||||
"label": "Secondary Voltage"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"key": "voltage:tertiary",
|
||||
"type": "combo",
|
||||
"label": "Tertiary Voltage"
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"key": "windings",
|
||||
"type": "number",
|
||||
"label": "Number of Windings",
|
||||
"placeholder": "1, 2, 3..."
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"key": "windings:configuration",
|
||||
"type": "combo",
|
||||
"label": "Windings Configuration",
|
||||
"strings": {
|
||||
"options": {
|
||||
"star": "Star / Wye",
|
||||
"delta": "Delta",
|
||||
"open-delta": "Open Delta",
|
||||
"zigzag": "Zig Zag",
|
||||
"open": "Open",
|
||||
"scott": "Scott",
|
||||
"leblanc": "Leblanc"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12026,6 +12026,19 @@
|
||||
},
|
||||
"power/transformer": {
|
||||
"icon": "poi-power",
|
||||
"fields": [
|
||||
"transformer",
|
||||
"location",
|
||||
"rating",
|
||||
"devices",
|
||||
"phases",
|
||||
"frequency",
|
||||
"voltage/primary",
|
||||
"voltage/secondary",
|
||||
"voltage/tertiary",
|
||||
"windings",
|
||||
"windings/configuration"
|
||||
],
|
||||
"geometry": [
|
||||
"point",
|
||||
"vertex",
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
{
|
||||
"icon": "poi-power",
|
||||
"fields": [
|
||||
"transformer",
|
||||
"location",
|
||||
"rating",
|
||||
"devices",
|
||||
"phases",
|
||||
"frequency",
|
||||
"voltage/primary",
|
||||
"voltage/secondary",
|
||||
"voltage/tertiary",
|
||||
"windings",
|
||||
"windings/configuration"
|
||||
],
|
||||
"geometry": [
|
||||
"point",
|
||||
"vertex",
|
||||
|
||||
Vendored
+52
@@ -1472,6 +1472,10 @@
|
||||
"description": {
|
||||
"label": "Description"
|
||||
},
|
||||
"devices": {
|
||||
"label": "Number of Devices",
|
||||
"placeholder": "1, 2, 3..."
|
||||
},
|
||||
"diaper": {
|
||||
"label": "Diaper Changing Available"
|
||||
},
|
||||
@@ -1553,6 +1557,9 @@
|
||||
"label": "Type",
|
||||
"placeholder": "Default"
|
||||
},
|
||||
"frequency": {
|
||||
"label": "Operating Frequency"
|
||||
},
|
||||
"fuel_multi": {
|
||||
"label": "Fuel Types"
|
||||
},
|
||||
@@ -1911,6 +1918,10 @@
|
||||
"payment_multi": {
|
||||
"label": "Payment Types"
|
||||
},
|
||||
"phases": {
|
||||
"label": "Number of Phases",
|
||||
"placeholder": "1, 2, 3..."
|
||||
},
|
||||
"phone": {
|
||||
"label": "Phone",
|
||||
"placeholder": "+31 42 123 4567"
|
||||
@@ -1990,6 +2001,9 @@
|
||||
"railway": {
|
||||
"label": "Type"
|
||||
},
|
||||
"rating": {
|
||||
"label": "Power Rating"
|
||||
},
|
||||
"recycling_accepts": {
|
||||
"label": "Accepts"
|
||||
},
|
||||
@@ -2299,6 +2313,19 @@
|
||||
"no": "No: pathless, excellent orientation skills required"
|
||||
}
|
||||
},
|
||||
"transformer": {
|
||||
"label": "Type of Transformer",
|
||||
"options": {
|
||||
"distribution": "Distribution",
|
||||
"generator": "Generator",
|
||||
"converter": "Converter",
|
||||
"traction": "Traction",
|
||||
"auto": "Autotransformer",
|
||||
"phase_angle_regulator": "Phase Angle Regulator",
|
||||
"auxiliary": "Auxiliarty",
|
||||
"yes": "Unknown"
|
||||
}
|
||||
},
|
||||
"trees": {
|
||||
"label": "Trees"
|
||||
},
|
||||
@@ -2333,6 +2360,15 @@
|
||||
"scoria": "Scoria"
|
||||
}
|
||||
},
|
||||
"voltage/primary": {
|
||||
"label": "Primary Voltage"
|
||||
},
|
||||
"voltage/secondary": {
|
||||
"label": "Secondary Voltage"
|
||||
},
|
||||
"voltage/tertiary": {
|
||||
"label": "Tertiary Voltage"
|
||||
},
|
||||
"wall": {
|
||||
"label": "Type"
|
||||
},
|
||||
@@ -2360,6 +2396,22 @@
|
||||
},
|
||||
"wikipedia": {
|
||||
"label": "Wikipedia"
|
||||
},
|
||||
"windings": {
|
||||
"label": "Number of Windings",
|
||||
"placeholder": "1, 2, 3..."
|
||||
},
|
||||
"windings/configuration": {
|
||||
"label": "Windings Configuration",
|
||||
"options": {
|
||||
"star": "Star / Wye",
|
||||
"delta": "Delta",
|
||||
"open-delta": "Open Delta",
|
||||
"zigzag": "Zig Zag",
|
||||
"open": "Open",
|
||||
"scott": "Scott",
|
||||
"leblanc": "Leblanc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"presets": {
|
||||
|
||||
@@ -9,10 +9,10 @@ import _union from 'lodash-es/union';
|
||||
import _uniq from 'lodash-es/uniq';
|
||||
import _without from 'lodash-es/without';
|
||||
|
||||
import { diff3Merge } from 'node-diff3';
|
||||
import { t } from '../util/locale';
|
||||
import { actionDeleteMultiple } from './delete_multiple';
|
||||
import { osmEntity } from '../osm';
|
||||
import { diff3_merge } from '../util/diff3';
|
||||
import { dataDiscarded } from '../../data';
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ export function actionMergeRemoteChanges(id, localGraph, remoteGraph, formatUser
|
||||
a = target.nodes || [],
|
||||
b = remote.nodes || [],
|
||||
nodes = [],
|
||||
hunks = diff3_merge(a, o, b, true);
|
||||
hunks = diff3Merge(a, o, b, true);
|
||||
|
||||
for (var i = 0; i < hunks.length; i++) {
|
||||
var hunk = hunks[i];
|
||||
@@ -65,7 +65,7 @@ export function actionMergeRemoteChanges(id, localGraph, remoteGraph, formatUser
|
||||
nodes.push.apply(nodes, hunk.ok);
|
||||
} else {
|
||||
// for all conflicts, we can assume c.a !== c.b
|
||||
// because `diff3_merge` called with `true` option to exclude false conflicts..
|
||||
// because `diff3Merge` called with `true` option to exclude false conflicts..
|
||||
var c = hunk.conflict;
|
||||
if (_isEqual(c.o, c.a)) { // only changed remotely
|
||||
nodes.push.apply(nodes, c.b);
|
||||
|
||||
@@ -264,7 +264,7 @@ export default {
|
||||
// A few OSM keys expect values to contain uppercase values (see #3377).
|
||||
// This is not an exhaustive list (e.g. `name` also has uppercase values)
|
||||
// but these are the fields where taginfo value lookup is most useful.
|
||||
var re = /network|taxon|genus|species|brand|grape_variety|_hours|_times/;
|
||||
var re = /network|taxon|genus|species|brand|grape_variety|rating|:output|_hours|_times/;
|
||||
var allowUpperCase = (params.key.match(re) !== null);
|
||||
var f = filterValues(allowUpperCase);
|
||||
|
||||
|
||||
@@ -1,421 +0,0 @@
|
||||
// Copyright (c) 2006, 2008 Tony Garnock-Jones <tonyg@lshift.net>
|
||||
// Copyright (c) 2006, 2008 LShift Ltd. <query@lshift.net>
|
||||
//
|
||||
// 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.
|
||||
|
||||
// source: https://bitbucket.org/lshift/synchrotron/src
|
||||
export function longest_common_subsequence(file1, file2) {
|
||||
/* Text diff algorithm following Hunt and McIlroy 1976.
|
||||
* J. W. Hunt and M. D. McIlroy, An algorithm for differential file
|
||||
* comparison, Bell Telephone Laboratories CSTR #41 (1976)
|
||||
* http://www.cs.dartmouth.edu/~doug/
|
||||
*
|
||||
* Expects two arrays of strings.
|
||||
*/
|
||||
var equivalenceClasses;
|
||||
var file2indices;
|
||||
var newCandidate;
|
||||
var candidates;
|
||||
var line;
|
||||
var c, i, j, jX, r, s;
|
||||
|
||||
equivalenceClasses = {};
|
||||
for (j = 0; j < file2.length; j++) {
|
||||
line = file2[j];
|
||||
if (equivalenceClasses[line]) {
|
||||
equivalenceClasses[line].push(j);
|
||||
} else {
|
||||
equivalenceClasses[line] = [j];
|
||||
}
|
||||
}
|
||||
|
||||
candidates = [{file1index: -1,
|
||||
file2index: -1,
|
||||
chain: null}];
|
||||
|
||||
for (i = 0; i < file1.length; i++) {
|
||||
line = file1[i];
|
||||
file2indices = equivalenceClasses[line] || [];
|
||||
|
||||
r = 0;
|
||||
c = candidates[0];
|
||||
|
||||
for (jX = 0; jX < file2indices.length; jX++) {
|
||||
j = file2indices[jX];
|
||||
|
||||
for (s = 0; s < candidates.length; s++) {
|
||||
if ((candidates[s].file2index < j) &&
|
||||
((s === candidates.length - 1) ||
|
||||
(candidates[s + 1].file2index > j)))
|
||||
break;
|
||||
}
|
||||
|
||||
if (s < candidates.length) {
|
||||
newCandidate = {file1index: i,
|
||||
file2index: j,
|
||||
chain: candidates[s]};
|
||||
if (r === candidates.length) {
|
||||
candidates.push(c);
|
||||
} else {
|
||||
candidates[r] = c;
|
||||
}
|
||||
r = s + 1;
|
||||
c = newCandidate;
|
||||
if (r === candidates.length) {
|
||||
break; // no point in examining further (j)s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
candidates[r] = c;
|
||||
}
|
||||
|
||||
// At this point, we know the LCS: it's in the reverse of the
|
||||
// linked-list through .chain of
|
||||
// candidates[candidates.length - 1].
|
||||
|
||||
return candidates[candidates.length - 1];
|
||||
}
|
||||
|
||||
export function diff_comm(file1, file2) {
|
||||
// We apply the LCS to build a "comm"-style picture of the
|
||||
// differences between file1 and file2.
|
||||
|
||||
var result = [];
|
||||
var tail1 = file1.length;
|
||||
var tail2 = file2.length;
|
||||
var common = {common: []};
|
||||
|
||||
function processCommon() {
|
||||
if (common.common.length) {
|
||||
common.common.reverse();
|
||||
result.push(common);
|
||||
common = {common: []};
|
||||
}
|
||||
}
|
||||
|
||||
for (var candidate = longest_common_subsequence(file1, file2);
|
||||
candidate !== null;
|
||||
candidate = candidate.chain)
|
||||
{
|
||||
var different = {file1: [], file2: []};
|
||||
|
||||
while (--tail1 > candidate.file1index) {
|
||||
different.file1.push(file1[tail1]);
|
||||
}
|
||||
|
||||
while (--tail2 > candidate.file2index) {
|
||||
different.file2.push(file2[tail2]);
|
||||
}
|
||||
|
||||
if (different.file1.length || different.file2.length) {
|
||||
processCommon();
|
||||
different.file1.reverse();
|
||||
different.file2.reverse();
|
||||
result.push(different);
|
||||
}
|
||||
|
||||
if (tail1 >= 0) {
|
||||
common.common.push(file1[tail1]);
|
||||
}
|
||||
}
|
||||
|
||||
processCommon();
|
||||
|
||||
result.reverse();
|
||||
return result;
|
||||
}
|
||||
|
||||
export function diff_patch(file1, file2) {
|
||||
// We apply the LCD to build a JSON representation of a
|
||||
// diff(1)-style patch.
|
||||
|
||||
var result = [];
|
||||
var tail1 = file1.length;
|
||||
var tail2 = file2.length;
|
||||
|
||||
function chunkDescription(file, offset, length) {
|
||||
var chunk = [];
|
||||
for (var i = 0; i < length; i++) {
|
||||
chunk.push(file[offset + i]);
|
||||
}
|
||||
return {offset: offset,
|
||||
length: length,
|
||||
chunk: chunk};
|
||||
}
|
||||
|
||||
for (var candidate = longest_common_subsequence(file1, file2);
|
||||
candidate !== null;
|
||||
candidate = candidate.chain)
|
||||
{
|
||||
var mismatchLength1 = tail1 - candidate.file1index - 1;
|
||||
var mismatchLength2 = tail2 - candidate.file2index - 1;
|
||||
tail1 = candidate.file1index;
|
||||
tail2 = candidate.file2index;
|
||||
|
||||
if (mismatchLength1 || mismatchLength2) {
|
||||
result.push({file1: chunkDescription(file1,
|
||||
candidate.file1index + 1,
|
||||
mismatchLength1),
|
||||
file2: chunkDescription(file2,
|
||||
candidate.file2index + 1,
|
||||
mismatchLength2)});
|
||||
}
|
||||
}
|
||||
|
||||
result.reverse();
|
||||
return result;
|
||||
}
|
||||
|
||||
export function strip_patch(patch) {
|
||||
// Takes the output of Diff3.diff_patch(), and removes
|
||||
// information from it. It can still be used by patch(),
|
||||
// below, but can no longer be inverted.
|
||||
var newpatch = [];
|
||||
for (var i = 0; i < patch.length; i++) {
|
||||
var chunk = patch[i];
|
||||
newpatch.push({file1: {offset: chunk.file1.offset,
|
||||
length: chunk.file1.length},
|
||||
file2: {chunk: chunk.file2.chunk}});
|
||||
}
|
||||
return newpatch;
|
||||
}
|
||||
|
||||
export function invert_patch (patch) {
|
||||
// Takes the output of Diff3.diff_patch(), and inverts the
|
||||
// sense of it, so that it can be applied to file2 to give
|
||||
// file1 rather than the other way around.
|
||||
|
||||
for (var i = 0; i < patch.length; i++) {
|
||||
var chunk = patch[i];
|
||||
var tmp = chunk.file1;
|
||||
chunk.file1 = chunk.file2;
|
||||
chunk.file2 = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
export function patch (file, patch) {
|
||||
// Applies a patch to a file.
|
||||
//
|
||||
// Given file1 and file2, Diff3.patch(file1,
|
||||
// Diff3.diff_patch(file1, file2)) should give file2.
|
||||
|
||||
var result = [];
|
||||
var commonOffset = 0;
|
||||
|
||||
function copyCommon(targetOffset) {
|
||||
while (commonOffset < targetOffset) {
|
||||
result.push(file[commonOffset]);
|
||||
commonOffset++;
|
||||
}
|
||||
}
|
||||
|
||||
for (var chunkIndex = 0; chunkIndex < patch.length; chunkIndex++) {
|
||||
var chunk = patch[chunkIndex];
|
||||
copyCommon(chunk.file1.offset);
|
||||
for (var lineIndex = 0; lineIndex < chunk.file2.chunk.length; lineIndex++) {
|
||||
result.push(chunk.file2.chunk[lineIndex]);
|
||||
}
|
||||
commonOffset += chunk.file1.length;
|
||||
}
|
||||
|
||||
copyCommon(file.length);
|
||||
return result;
|
||||
}
|
||||
|
||||
export function diff_indices(file1, file2) {
|
||||
// We apply the LCS to give a simple representation of the
|
||||
// offsets and lengths of mismatched chunks in the input
|
||||
// files. This is used by diff3_merge_indices below.
|
||||
|
||||
var result = [];
|
||||
var tail1 = file1.length;
|
||||
var tail2 = file2.length;
|
||||
|
||||
for (var candidate = longest_common_subsequence(file1, file2);
|
||||
candidate !== null;
|
||||
candidate = candidate.chain)
|
||||
{
|
||||
var mismatchLength1 = tail1 - candidate.file1index - 1;
|
||||
var mismatchLength2 = tail2 - candidate.file2index - 1;
|
||||
tail1 = candidate.file1index;
|
||||
tail2 = candidate.file2index;
|
||||
|
||||
if (mismatchLength1 || mismatchLength2) {
|
||||
result.push({file1: [tail1 + 1, mismatchLength1],
|
||||
file2: [tail2 + 1, mismatchLength2]});
|
||||
}
|
||||
}
|
||||
|
||||
result.reverse();
|
||||
return result;
|
||||
}
|
||||
|
||||
export function diff3_merge_indices (a, o, b) {
|
||||
// Given three files, A, O, and B, where both A and B are
|
||||
// independently derived from O, returns a fairly complicated
|
||||
// internal representation of merge decisions it's taken. The
|
||||
// interested reader may wish to consult
|
||||
//
|
||||
// Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce. "A
|
||||
// Formal Investigation of Diff3." In Arvind and Prasad,
|
||||
// editors, Foundations of Software Technology and Theoretical
|
||||
// Computer Science (FSTTCS), December 2007.
|
||||
//
|
||||
// (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf)
|
||||
var i;
|
||||
|
||||
var m1 = diff_indices(o, a);
|
||||
var m2 = diff_indices(o, b);
|
||||
|
||||
var hunks = [];
|
||||
function addHunk(h, side) {
|
||||
hunks.push([h.file1[0], side, h.file1[1], h.file2[0], h.file2[1]]);
|
||||
}
|
||||
for (i = 0; i < m1.length; i++) { addHunk(m1[i], 0); }
|
||||
for (i = 0; i < m2.length; i++) { addHunk(m2[i], 2); }
|
||||
hunks.sort();
|
||||
|
||||
var result = [];
|
||||
var commonOffset = 0;
|
||||
function copyCommon(targetOffset) {
|
||||
if (targetOffset > commonOffset) {
|
||||
result.push([1, commonOffset, targetOffset - commonOffset]);
|
||||
commonOffset = targetOffset;
|
||||
}
|
||||
}
|
||||
|
||||
for (var hunkIndex = 0; hunkIndex < hunks.length; hunkIndex++) {
|
||||
var firstHunkIndex = hunkIndex;
|
||||
var hunk = hunks[hunkIndex];
|
||||
var regionLhs = hunk[0];
|
||||
var regionRhs = regionLhs + hunk[2];
|
||||
while (hunkIndex < hunks.length - 1) {
|
||||
var maybeOverlapping = hunks[hunkIndex + 1];
|
||||
var maybeLhs = maybeOverlapping[0];
|
||||
if (maybeLhs > regionRhs) break;
|
||||
regionRhs = maybeLhs + maybeOverlapping[2];
|
||||
hunkIndex++;
|
||||
}
|
||||
|
||||
copyCommon(regionLhs);
|
||||
if (firstHunkIndex === hunkIndex) {
|
||||
// The "overlap" was only one hunk long, meaning that
|
||||
// there's no conflict here. Either a and o were the
|
||||
// same, or b and o were the same.
|
||||
if (hunk[4] > 0) {
|
||||
result.push([hunk[1], hunk[3], hunk[4]]);
|
||||
}
|
||||
} else {
|
||||
// A proper conflict. Determine the extents of the
|
||||
// regions involved from a, o and b. Effectively merge
|
||||
// all the hunks on the left into one giant hunk, and
|
||||
// do the same for the right; then, correct for skew
|
||||
// in the regions of o that each side changed, and
|
||||
// report appropriate spans for the three sides.
|
||||
var regions = {
|
||||
0: [a.length, -1, o.length, -1],
|
||||
2: [b.length, -1, o.length, -1]
|
||||
};
|
||||
for (i = firstHunkIndex; i <= hunkIndex; i++) {
|
||||
hunk = hunks[i];
|
||||
var side = hunk[1];
|
||||
var r = regions[side];
|
||||
var oLhs = hunk[0];
|
||||
var oRhs = oLhs + hunk[2];
|
||||
var abLhs = hunk[3];
|
||||
var abRhs = abLhs + hunk[4];
|
||||
r[0] = Math.min(abLhs, r[0]);
|
||||
r[1] = Math.max(abRhs, r[1]);
|
||||
r[2] = Math.min(oLhs, r[2]);
|
||||
r[3] = Math.max(oRhs, r[3]);
|
||||
}
|
||||
var aLhs = regions[0][0] + (regionLhs - regions[0][2]);
|
||||
var aRhs = regions[0][1] + (regionRhs - regions[0][3]);
|
||||
var bLhs = regions[2][0] + (regionLhs - regions[2][2]);
|
||||
var bRhs = regions[2][1] + (regionRhs - regions[2][3]);
|
||||
result.push([-1,
|
||||
aLhs, aRhs - aLhs,
|
||||
regionLhs, regionRhs - regionLhs,
|
||||
bLhs, bRhs - bLhs]);
|
||||
}
|
||||
commonOffset = regionRhs;
|
||||
}
|
||||
|
||||
copyCommon(o.length);
|
||||
return result;
|
||||
}
|
||||
|
||||
export function diff3_merge (a, o, b, excludeFalseConflicts) {
|
||||
// Applies the output of Diff3.diff3_merge_indices to actually
|
||||
// construct the merged file; the returned result alternates
|
||||
// between "ok" and "conflict" blocks.
|
||||
|
||||
var result = [];
|
||||
var files = [a, o, b];
|
||||
var indices = diff3_merge_indices(a, o, b);
|
||||
|
||||
var okLines = [];
|
||||
function flushOk() {
|
||||
if (okLines.length) {
|
||||
result.push({ok: okLines});
|
||||
}
|
||||
okLines = [];
|
||||
}
|
||||
function pushOk(xs) {
|
||||
for (var j = 0; j < xs.length; j++) {
|
||||
okLines.push(xs[j]);
|
||||
}
|
||||
}
|
||||
|
||||
function isTrueConflict(rec) {
|
||||
if (rec[2] !== rec[6]) return true;
|
||||
var aoff = rec[1];
|
||||
var boff = rec[5];
|
||||
for (var j = 0; j < rec[2]; j++) {
|
||||
if (a[j + aoff] !== b[j + boff]) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < indices.length; i++) {
|
||||
var x = indices[i];
|
||||
var side = x[0];
|
||||
if (side === -1) {
|
||||
if (excludeFalseConflicts && !isTrueConflict(x)) {
|
||||
pushOk(files[0].slice(x[1], x[1] + x[2]));
|
||||
} else {
|
||||
flushOk();
|
||||
result.push({conflict: {a: a.slice(x[1], x[1] + x[2]),
|
||||
aIndex: x[1],
|
||||
o: o.slice(x[3], x[3] + x[4]),
|
||||
oIndex: x[3],
|
||||
b: b.slice(x[5], x[5] + x[6]),
|
||||
bIndex: x[5]}});
|
||||
}
|
||||
} else {
|
||||
pushOk(files[side].slice(x[1], x[1] + x[2]));
|
||||
}
|
||||
}
|
||||
|
||||
flushOk();
|
||||
return result;
|
||||
}
|
||||
@@ -31,6 +31,7 @@
|
||||
"diacritics": "1.3.0",
|
||||
"lodash-es": "4.17.4",
|
||||
"marked": "0.3.6",
|
||||
"node-diff3": "bhousel/node-diff3.git#v0.1.0",
|
||||
"osm-auth": "1.0.2",
|
||||
"rbush": "2.0.1",
|
||||
"wmf-sitematrix": "0.1.4"
|
||||
|
||||
@@ -77,7 +77,6 @@
|
||||
|
||||
<script src='spec/lib/d3.combobox.js'></script>
|
||||
<script src='spec/lib/d3.keybinding.js'></script>
|
||||
<!-- <script src='spec/lib/diff3.js'></script> -->
|
||||
<script src='spec/lib/locale.js'></script>
|
||||
|
||||
<script src='spec/modes/add_point.js'></script>
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/* global Diff3:false */
|
||||
describe('diff3', function() {
|
||||
function split(s) {
|
||||
return s ? s.split(/ /) : [];
|
||||
}
|
||||
|
||||
it('performs diff3 merge', function() {
|
||||
var o = split('AA ZZ 00 M 99'),
|
||||
a = split('AA a b c ZZ new 00 a a M 99'),
|
||||
b = split('AA a d c ZZ 11 M z z 99'),
|
||||
res = Diff3.diff3_merge(a, o, b);
|
||||
|
||||
/*
|
||||
AA
|
||||
<<<<<<< a
|
||||
a
|
||||
b
|
||||
c
|
||||
||||||| o
|
||||
=======
|
||||
a
|
||||
d
|
||||
c
|
||||
>>>>>>> b
|
||||
ZZ
|
||||
<<<<<<< a
|
||||
new
|
||||
00
|
||||
a
|
||||
a
|
||||
||||||| o
|
||||
00
|
||||
=======
|
||||
11
|
||||
>>>>>>> b
|
||||
M
|
||||
z
|
||||
z
|
||||
99
|
||||
*/
|
||||
|
||||
expect(res[0].ok).to.eql(['AA']);
|
||||
expect(res[0].conflict).to.be.undefined;
|
||||
|
||||
expect(res[1].ok).to.be.undefined;
|
||||
expect(res[1].conflict.o).to.eql([]);
|
||||
expect(res[1].conflict.a).to.eql(['a', 'b', 'c']);
|
||||
expect(res[1].conflict.b).to.eql(['a', 'd', 'c']);
|
||||
|
||||
expect(res[2].ok).to.eql(['ZZ']);
|
||||
expect(res[2].conflict).to.be.undefined;
|
||||
|
||||
expect(res[3].ok).to.be.undefined;
|
||||
expect(res[3].conflict.o).to.eql(['00']);
|
||||
expect(res[3].conflict.a).to.eql(['new', '00', 'a', 'a']);
|
||||
expect(res[3].conflict.b).to.eql(['11']);
|
||||
|
||||
expect(res[4].ok).to.eql(['M', 'z', 'z', '99']);
|
||||
expect(res[4].conflict).to.be.undefined;
|
||||
});
|
||||
|
||||
it('can include false conflicts', function() {
|
||||
var o = split('AA ZZ'),
|
||||
a = split('AA a b c ZZ'),
|
||||
b = split('AA a b c ZZ'),
|
||||
res = Diff3.diff3_merge(a, o, b, false);
|
||||
|
||||
expect(res[0].ok).to.eql(['AA']);
|
||||
expect(res[0].conflict).to.be.undefined;
|
||||
|
||||
expect(res[1].ok).to.be.undefined;
|
||||
expect(res[1].conflict.o).to.eql([]);
|
||||
expect(res[1].conflict.a).to.eql(['a', 'b', 'c']);
|
||||
expect(res[1].conflict.b).to.eql(['a', 'b', 'c']);
|
||||
|
||||
expect(res[2].ok).to.eql(['ZZ']);
|
||||
expect(res[2].conflict).to.be.undefined;
|
||||
});
|
||||
|
||||
it('can exclude false conflicts', function() {
|
||||
var o = split('AA ZZ'),
|
||||
a = split('AA a b c ZZ'),
|
||||
b = split('AA a b c ZZ'),
|
||||
res = Diff3.diff3_merge(a, o, b, true);
|
||||
|
||||
expect(res[0].ok).to.eql(['AA', 'a', 'b', 'c', 'ZZ']);
|
||||
expect(res[0].conflict).to.be.undefined;
|
||||
});
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user