{"version":3,"sources":["jsdelivr-header.js","/projects/xliffmerge/src/lib/xliffmerge.module.ts","/node_modules/tslib/tslib.es6.js","/projects/xliffmerge/src/common/util.ts","/projects/xliffmerge/src/common/command-output.ts","/projects/xliffmerge/src/common/writer-to-string.ts","/projects/xliffmerge/src/xliffmerge/xliff-merge-error.ts","/projects/xliffmerge/src/common/file-util.ts","/projects/xliffmerge/src/xliffmerge/ngx-translate-extraction-pattern.ts","/projects/xliffmerge/src/xliffmerge/ngx-translate-extractor.ts","/projects/xliffmerge/src/xliffmerge/xliff-merge-parameters.ts","/projects/xliffmerge/src/xliffmerge/version.ts","/projects/xliffmerge/src/xliffmerge/xml-reader.ts","/projects/xliffmerge/src/xliffmerge/translation-messages-file-reader.ts","/projects/xliffmerge/src/xliffmerge/xliff-merge.ts"],"names":[],"mappings":"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","file":"/npm/xliffmerge@1.0.0/bundles/xliffmerge.umd.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/xliffmerge@1.0.0/bundles/xliffmerge.umd.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","import { NgModule } from '@angular/core';\n\n@NgModule({\n  declarations: [],\n  imports: [],\n  exports: [],\n})\nexport class XliffmergeModule {}\n","/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n    extendStatics = Object.setPrototypeOf ||\r\n        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n        function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n    return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n    if (typeof b !== \"function\" && b !== null)\r\n        throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n    extendStatics(d, b);\r\n    function __() { this.constructor = d; }\r\n    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n    __assign = Object.assign || function __assign(t) {\r\n        for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n            s = arguments[i];\r\n            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n        }\r\n        return t;\r\n    }\r\n    return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n    var t = {};\r\n    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n        t[p] = s[p];\r\n    if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n                t[p[i]] = s[p[i]];\r\n        }\r\n    return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n    if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n    return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n    return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n    if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n    return new (P || (P = Promise))(function (resolve, reject) {\r\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n    });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n    return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n    function verb(n) { return function (v) { return step([n, v]); }; }\r\n    function step(op) {\r\n        if (f) throw new TypeError(\"Generator is already executing.\");\r\n        while (_) try {\r\n            if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n            if (y = 0, t) op = [op[0] & 2, t.value];\r\n            switch (op[0]) {\r\n                case 0: case 1: t = op; break;\r\n                case 4: _.label++; return { value: op[1], done: false };\r\n                case 5: _.label++; y = op[1]; op = [0]; continue;\r\n                case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n                default:\r\n                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n                    if (t[2]) _.ops.pop();\r\n                    _.trys.pop(); continue;\r\n            }\r\n            op = body.call(thisArg, _);\r\n        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n    }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n    if (k2 === undefined) k2 = k;\r\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n    if (k2 === undefined) k2 = k;\r\n    o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n    for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n    var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n    if (m) return m.call(o);\r\n    if (o && typeof o.length === \"number\") return {\r\n        next: function () {\r\n            if (o && i >= o.length) o = void 0;\r\n            return { value: o && o[i++], done: !o };\r\n        }\r\n    };\r\n    throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n    var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n    if (!m) return o;\r\n    var i = m.call(o), r, ar = [], e;\r\n    try {\r\n        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n    }\r\n    catch (error) { e = { error: error }; }\r\n    finally {\r\n        try {\r\n            if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n        }\r\n        finally { if (e) throw e.error; }\r\n    }\r\n    return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n    for (var ar = [], i = 0; i < arguments.length; i++)\r\n        ar = ar.concat(__read(arguments[i]));\r\n    return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n    for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n            r[k] = a[j];\r\n    return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n        if (ar || !(i in from)) {\r\n            if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n            ar[i] = from[i];\r\n        }\r\n    }\r\n    return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n    return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n    var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n    return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n    function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n    function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n    function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n    function fulfill(value) { resume(\"next\", value); }\r\n    function reject(value) { resume(\"throw\", value); }\r\n    function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n    var i, p;\r\n    return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n    function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n    var m = o[Symbol.asyncIterator], i;\r\n    return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n    function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n    function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n    if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n    return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n    o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n    if (mod && mod.__esModule) return mod;\r\n    var result = {};\r\n    if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n    __setModuleDefault(result, mod);\r\n    return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n    return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n    if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n    if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n    return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n    if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n    if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n    if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n    return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n","/**\n * Collection of utility functions that are deprecated in nodes util.\n */\n\n/**\n * Replaces node isNullOrUndefined.\n */\nexport function isNullOrUndefined(value: any) {\n    return value === undefined || value === null;\n}\n\n/**\n * Replaces node isString.\n */\nexport function isString(value: any) {\n    return typeof value === 'string';\n}\n\n/**\n * Replaces node isBoolean.\n */\nexport function isBoolean(value: any) {\n    return typeof value === 'boolean';\n}\n\n/**\n * Replaces node isNumber.\n */\nexport function isNumber(value: any) {\n    return typeof value === 'number';\n}\n\n/**\n * Replaces node isArray.\n */\nexport function isArray(value: any) {\n    return Array.isArray(value);\n}\n","/**\n * Created by martin on 17.02.2017.\n * Very simple class to control the output of a command.\n * Output can be errors, warnings, infos and debug-Outputs.\n * The output can be controlled via 2 flags, quiet and verbose.\n * If quit is enabled only error messages are shown.\n * If verbose is enabled, everything is shown.\n * If both are not enabled (the default) errors, warnings and infos are shown.\n * If not are enabled (strange), we assumed the default.\n */\n\nimport * as chalk from 'chalk';\nimport WritableStream = NodeJS.WritableStream;\nimport { format } from 'util';\n\nenum LogLevel {\n  'ERROR',\n  'WARN',\n  'INFO',\n  'DEBUG',\n}\n\nexport class CommandOutput {\n  /**\n   * verbose enables output of everything.\n   */\n  public _verbose: boolean;\n\n  /**\n   * quiet disables output of everything but errors.\n   */\n  public _quiet: boolean;\n\n  private outputStream: WritableStream;\n\n  constructor(stdout?: WritableStream) {\n    this._quiet = false;\n    this._verbose = false;\n    if (stdout) {\n      this.outputStream = stdout;\n    } else {\n      this.outputStream = process.stdout;\n    }\n  }\n\n  public setVerbose() {\n    this._verbose = true;\n  }\n\n  public setQuiet() {\n    this._quiet = true;\n  }\n\n  /**\n   * Test, wether verbose is enabled.\n   * @return wether verbose is enabled.\n   */\n  public verbose(): boolean {\n    return this._verbose;\n  }\n\n  /**\n   * Test, wether quiet is enabled.\n   * @return wether quiet is enabled.\n   */\n  public quiet(): boolean {\n    return this._quiet;\n  }\n\n  public error(msg, ...params: any[]) {\n    this.log(LogLevel.ERROR, msg, params);\n  }\n\n  public warn(msg, ...params: any[]) {\n    this.log(LogLevel.WARN, msg, params);\n  }\n\n  public info(msg, ...params: any[]) {\n    this.log(LogLevel.INFO, msg, params);\n  }\n\n  public debug(msg, ...params: any[]) {\n    this.log(LogLevel.DEBUG, msg, params);\n  }\n\n  private log(level: LogLevel, msg, params: any[]) {\n    if (!this.isOutputEnabled(level)) {\n      return;\n    }\n    let coloredMessage;\n    switch (level) {\n      case LogLevel.ERROR:\n        coloredMessage = chalk.red('ERROR: ' + msg);\n        break;\n      case LogLevel.WARN:\n        coloredMessage = chalk.magenta('WARNING: ' + msg);\n        break;\n      default:\n        coloredMessage = chalk.gray('* ' + msg);\n        break;\n    }\n    const outMsg = format(coloredMessage, ...params);\n    this.outputStream.write(outMsg + '\\n');\n  }\n\n  private isOutputEnabled(level: LogLevel): boolean {\n    let quietEnabled, verboseEnabled: boolean;\n    if (this._quiet && this._verbose) {\n      quietEnabled = false;\n      verboseEnabled = false;\n    } else {\n      quietEnabled = this._quiet;\n      verboseEnabled = this._verbose;\n    }\n    switch (level) {\n      case LogLevel.ERROR:\n        return true; // always output errors\n      case LogLevel.WARN:\n        return !quietEnabled;\n      case LogLevel.INFO:\n        return verboseEnabled && !quietEnabled;\n      case LogLevel.DEBUG:\n        return verboseEnabled;\n      default:\n        return true;\n    }\n  }\n}\n","import {Writable} from 'stream';\nimport {isString} from './util';\n/**\n * Created by martin on 20.02.2017.\n * A helper class for testing.\n * Can be used as a WritableStream and writes everything (synchronously) into a string,\n * that can easily be read by the tests.\n */\n\nexport class WriterToString extends Writable {\n\n    private resultString: string;\n\n    constructor() {\n        super();\n        this.resultString = '';\n    }\n\n    public _write(chunk: any, encoding: string, callback: Function): void {\n        let chunkString;\n        if (isString(chunk)) {\n            chunkString = chunk;\n        } else if (chunk instanceof Buffer) {\n            chunkString = chunk.toString();\n        } else {\n            chunkString = Buffer.alloc(chunk).toString(encoding);\n        }\n        this.resultString = this.resultString + chunkString;\n        callback();\n    }\n\n    /**\n     * Returns a string of everything, that was written to the stream so far.\n     * @return written data\n     */\n    public writtenData(): string {\n        return this.resultString;\n    }\n}\n","/**\n * Created by martin on 17.02.2017.\n */\n\nexport class XliffMergeError extends Error {\n\n    constructor(msg: string) {\n        super(msg);\n\n        // Set the prototype explicitly.\n        Object.setPrototypeOf(this, XliffMergeError.prototype);\n    }\n}\n","import * as fs from 'fs';\n\n/**\n * Created by martin on 17.02.2017.\n * Some (a few) simple utils for file operations.\n * Just for convenience.\n */\n\nexport class FileUtil {\n\n    /**\n     * Check for existence.\n     * @param filename filename\n     * @return wether file exists\n     */\n    public static exists(filename: string) {\n        return fs.existsSync(filename);\n    }\n\n    /**\n     * Read a file.\n     * @param filename filename\n     * @param encoding encoding\n     * @return content of file\n     */\n    public static read(filename: string, encoding: string) {\n        return fs.readFileSync(filename, encoding);\n    }\n\n    /**\n     * Write a file with given content.\n     * @param filename filename\n     * @param newContent newContent\n     * @param encoding encoding\n     */\n    public static replaceContent(filename: string, newContent: string, encoding: string) {\n        fs.writeFileSync(filename, newContent, {encoding: encoding});\n    }\n\n    public static copy(srcFile: string, destFile: string) {\n        const BUF_LENGTH = 64 * 1024;\n        const buff = Buffer.alloc(BUF_LENGTH);\n        const fdr = fs.openSync(srcFile, 'r');\n        const fdw = fs.openSync(destFile, 'w');\n        let bytesRead = 1;\n        let pos = 0;\n        while (bytesRead > 0) {\n            bytesRead = fs.readSync(fdr, buff, 0, BUF_LENGTH, pos);\n            fs.writeSync(fdw, buff, 0, bytesRead);\n            pos += bytesRead;\n        }\n        fs.closeSync(fdr);\n        fs.closeSync(fdw);\n    }\n\n    /**\n     * Delete the folder and all of its content (rm -rf).\n     * @param path path\n     */\n    public static deleteFolderRecursive(path: string) {\n        let files = [];\n        if (fs.existsSync(path) ) {\n            files = fs.readdirSync(path);\n            files.forEach(function(file) {\n                const curPath = path + '/' + file;\n                if (fs.lstatSync(curPath).isDirectory()) { // recurse\n                    FileUtil.deleteFolderRecursive(curPath);\n                } else { // delete file\n                    fs.unlinkSync(curPath);\n                }\n            });\n            fs.rmdirSync(path);\n        }\n    }\n\n    /**\n     * Delete folders content recursively, but do not delete folder.\n     * Folder is left empty at the end.\n     * @param path path\n     */\n    public static deleteFolderContentRecursive(path: string) {\n        let files = [];\n        if (fs.existsSync(path) ) {\n            files = fs.readdirSync(path);\n            files.forEach(function(file) {\n                const curPath = path + '/' + file;\n                if (fs.lstatSync(curPath).isDirectory()) { // recurse\n                    FileUtil.deleteFolderRecursive(curPath);\n                } else { // delete file\n                    fs.unlinkSync(curPath);\n                }\n            });\n        }\n    }\n\n    /**\n     * Delete a file.\n     * @param path path\n     */\n    public static deleteFile(path: string) {\n        fs.unlinkSync(path);\n    }\n}\n","/**\n * Helper class to parse ngx translate extraction pattern\n * and to decide wether a given message matches the pattern.\n */\nexport class NgxTranslateExtractionPattern {\n\n    private _matchExplicitId: boolean;\n    private _descriptionPatterns: string[];\n\n    /**\n     * Construct the pattern from given description string\n     * @param extractionPatternString extractionPatternString\n     * @throws an error, if there is a syntax error\n     */\n    constructor(private extractionPatternString: string) {\n        const parts = extractionPatternString.split('|');\n        this._matchExplicitId = false;\n        this._descriptionPatterns = [];\n        for (let i = 0; i < parts.length; i++) {\n            const part = parts[i];\n            if (part === '@@') {\n                if (this._matchExplicitId) {\n                    throw new Error('extraction pattern must not contain @@ twice');\n                }\n                this._matchExplicitId = true;\n            } else {\n                const errorString = this.checkValidDescriptionPattern(part);\n                if (errorString) {\n                    throw new Error(errorString);\n                }\n                this._descriptionPatterns.push(part);\n            }\n        }\n    }\n\n    /**\n     * Check, wether an explicitly set id matches the pattern.\n     * @param id id\n     * @return wether an explicitly set id matches the pattern.\n     */\n    public isExplicitIdMatched(id: string): boolean {\n        return id && this._matchExplicitId;\n    }\n\n    /**\n     * Check, wether a given description matches the pattern.\n     * @param description description\n     * @return wether a given description matches the pattern.\n     */\n    public isDescriptionMatched(description: string): boolean {\n        return this._descriptionPatterns.indexOf(description) >= 0;\n    }\n\n    private checkValidDescriptionPattern(descriptionPattern: string): string {\n        if (!descriptionPattern) {\n            return 'empty value not allowed';\n        }\n        if (/^[a-zA-Z_][a-zA-Z_-]*$/.test(descriptionPattern)) {\n            return null; // it is ok\n        } else {\n            return 'description pattern must be an identifier containing only letters, digits, _ or -';\n        }\n    }\n}\n","import {\n  ITranslationMessagesFile,\n  ITransUnit,\n  NORMALIZATION_FORMAT_NGXTRANSLATE,\n} from 'i18nsupport-lib';\nimport { FileUtil } from '../common/file-util';\nimport { isNullOrUndefined } from '../common/util';\nimport { NgxTranslateExtractionPattern } from './ngx-translate-extraction-pattern';\n/**\n * Created by roobm on 15.03.2017.\n * A tool for extracting messages in ngx-translate format.\n * Generates a json-file to be used with ngx-translate.\n */\n\n/**\n * The interface used for translations in ngx-translate.\n * A hash that contains either the translation or another hash.\n */\ninterface NgxTranslations {\n  [id: string]: NgxTranslations | string;\n}\n\n/**\n * internal,\n * a message with id (a dot-separated string).\n */\ninterface NgxMessage {\n  id: string; // dot separated name, e.g. \"myapp.service1.message1\"\n  message: string; // the message, placeholder are in {{n}} syntax, e.g. \"a test with value: {{0}}\n}\n\nexport class NgxTranslateExtractor {\n  public static DefaultExtractionPattern = '@@|ngx-translate';\n  private extractionPattern: NgxTranslateExtractionPattern;\n\n  /**\n   * Check, wether extractionPattern has valid syntax.\n   * @param extractionPatternString extractionPatternString\n   * @return null, if pattern is ok, string describing the error, if it is not ok.\n   */\n  public static checkPattern(extractionPatternString: string): string {\n    try {\n      if (new NgxTranslateExtractionPattern(extractionPatternString)) {\n        return null;\n      }\n    } catch (error: any) {\n      return error.message;\n    }\n    return null;\n  }\n\n  public static extract(\n    messagesFile: ITranslationMessagesFile,\n    extractionPattern: string,\n    outputFile: string\n  ) {\n    new NgxTranslateExtractor(messagesFile, extractionPattern).extractTo(\n      outputFile\n    );\n  }\n\n  constructor(\n    private messagesFile: ITranslationMessagesFile,\n    extractionPatternString: string\n  ) {\n    this.extractionPattern = new NgxTranslateExtractionPattern(\n      extractionPatternString\n    );\n  }\n\n  /**\n   * Extact messages and write them to a file.\n   * @param outputFile outputFile\n   */\n  public extractTo(outputFile: string) {\n    const translations: NgxTranslations = this.toNgxTranslations(\n      this.extract()\n    );\n    if (translations && Object.keys(translations).length > 0) {\n      FileUtil.replaceContent(\n        outputFile,\n        JSON.stringify(translations, null, 4),\n        'UTF-8'\n      );\n    } else {\n      if (FileUtil.exists(outputFile)) {\n        FileUtil.deleteFile(outputFile);\n      }\n    }\n  }\n\n  /**\n   *  Extract messages and convert them to ngx translations.\n   *  @return the translation objects.\n   */\n  private extract(): NgxMessage[] {\n    const result: NgxMessage[] = [];\n    this.messagesFile.forEachTransUnit((tu: ITransUnit) => {\n      const ngxId = this.ngxTranslateIdFromTU(tu);\n      if (ngxId) {\n        const messagetext = tu\n          .targetContentNormalized()\n          .asDisplayString(NORMALIZATION_FORMAT_NGXTRANSLATE);\n        result.push({ id: ngxId, message: messagetext });\n      }\n    });\n    return result;\n  }\n\n  /**\n   * Check, wether this tu should be extracted for ngx-translate usage, and return its id for ngx-translate.\n   * There are 2 possibilities:\n   * 1. description is set to \"ngx-translate\" and meaning contains the id.\n   * 2. id is explicitly set to a string.\n   * @param tu tu\n   * @return an ngx id or null, if this tu should not be extracted.\n   */\n  private ngxTranslateIdFromTU(tu: ITransUnit): string {\n    if (this.isExplicitlySetId(tu.id)) {\n      if (this.extractionPattern.isExplicitIdMatched(tu.id)) {\n        return tu.id;\n      } else {\n        return null;\n      }\n    }\n    const description = tu.description();\n    if (\n      description &&\n      this.extractionPattern.isDescriptionMatched(description)\n    ) {\n      return tu.meaning();\n    }\n  }\n\n  /**\n   * Test, wether ID was explicitly set (via i18n=\"@myid).\n   * Just heuristic, an ID is explicitly, if it does not look like a generated one.\n   * @param id id\n   * @return wether ID was explicitly set (via i18n=\"@myid).\n   */\n  private isExplicitlySetId(id: string): boolean {\n    if (isNullOrUndefined(id)) {\n      return false;\n    }\n    // generated IDs are either decimal or sha1 hex\n    const reForGeneratedId = /^[0-9a-f]{11,}$/;\n    return !reForGeneratedId.test(id);\n  }\n\n  /**\n   * Convert list of relevant TUs to ngx translations object.\n   * @param msgList msgList\n   */\n  private toNgxTranslations(msgList: NgxMessage[]): NgxTranslations {\n    const translationObject: NgxTranslations = {};\n    msgList.forEach((msg: NgxMessage) => {\n      this.putInTranslationObject(translationObject, msg);\n    });\n    return translationObject;\n  }\n\n  /**\n   * Put a new messages into the translation data object.\n   * If you add, e.g. \"{id: 'myapp.example', message: 'test'}\",\n   * the translation object will then contain an object myapp that has property example:\n   * {myapp: {\n   *   example: 'test'\n   *   }}\n   * @param translationObject translationObject\n   * @param msg msg\n   */\n  private putInTranslationObject(\n    translationObject: NgxTranslations,\n    msg: NgxMessage\n  ) {\n    let firstPartOfId: string;\n    let restOfId: string;\n    const indexOfDot = msg.id.indexOf('.');\n    if (indexOfDot === 0 || indexOfDot === msg.id.length - 1) {\n      throw new Error('bad nxg-translate id \"' + msg.id + '\"');\n    }\n    if (indexOfDot < 0) {\n      firstPartOfId = msg.id;\n      restOfId = '';\n    } else {\n      firstPartOfId = msg.id.substring(0, indexOfDot);\n      restOfId = msg.id.substring(indexOfDot + 1);\n    }\n    let object = translationObject[firstPartOfId];\n    if (isNullOrUndefined(object)) {\n      if (restOfId === '') {\n        translationObject[firstPartOfId] = msg.message;\n        return;\n      }\n      object = {};\n      translationObject[firstPartOfId] = object;\n    } else {\n      if (restOfId === '') {\n        throw new Error('duplicate id praefix \"' + msg.id + '\"');\n      }\n    }\n    this.putInTranslationObject(<NgxTranslations>object, {\n      id: restOfId,\n      message: msg.message,\n    });\n  }\n}\n","/**\n * Created by martin on 17.02.2017.\n * Collection of all parameters used by the tool.\n * The parameters are read form the profile or defaults are used.\n */\n\nimport * as fs from 'fs';\nimport {XliffMergeError} from './xliff-merge-error';\nimport {Stats} from 'fs';\nimport {CommandOutput} from '../common/command-output';\nimport {format} from 'util';\nimport {isArray, isNullOrUndefined} from '../common/util';\nimport {ProgramOptions, IConfigFile} from './i-xliff-merge-options';\nimport {FileUtil} from '../common/file-util';\nimport {NgxTranslateExtractor} from './ngx-translate-extractor';\nimport {dirname, isAbsolute, join, normalize} from 'path';\n\nconst PROFILE_CANDIDATES = ['package.json', '.angular-cli.json'];\n\nexport class XliffMergeParameters {\n\n    private usedProfilePath: string;\n    private _quiet: boolean;\n    private _verbose: boolean;\n    private _allowIdChange: boolean;\n    private _defaultLanguage: string;\n    private _srcDir: string;\n    private _i18nBaseFile: string;\n    private _i18nFile: string;\n    private _i18nFormat: string;\n    private _encoding: string;\n    private _genDir: string;\n    private _languages: string[];\n    private _removeUnusedIds: boolean;\n    private _supportNgxTranslate: boolean;\n    private _ngxTranslateExtractionPattern: string;\n    private _useSourceAsTarget: boolean;\n    private _targetPraefix: string;\n    private _targetSuffix: string;\n    private _beautifyOutput: boolean;\n    private _preserveOrder: boolean;\n    private _autotranslate: boolean|string[];\n    private _apikey: string;\n    private _apikeyfile: string;\n\n    public errorsFound: XliffMergeError[];\n    public warningsFound: string[];\n\n    /**\n     * Create Parameters.\n     * @param options command options\n     * @param profileContent given profile (if not, it is read from the profile path from options).\n     */\n    public static createFromOptions(options: ProgramOptions, profileContent?: IConfigFile) {\n        const parameters = new XliffMergeParameters();\n        parameters.configure(options, profileContent);\n        return parameters;\n    }\n\n    private constructor() {\n        this.errorsFound = [];\n        this.warningsFound = [];\n    }\n\n    /**\n     * Read potential profile.\n     * To be a candidate, file must exist and contain property \"xliffmergeOptions\".\n     * @param profilePath path of profile\n     * @return parsed content of file or null, if file does not exist or is not a profile candidate.\n     */\n    private static readProfileCandidate(profilePath: string): IConfigFile {\n        let content: string;\n        try {\n            content = fs.readFileSync(profilePath, 'UTF-8');\n        } catch (err) {\n            return null;\n        }\n        const parsedContent: IConfigFile = JSON.parse(content);\n        if (parsedContent && parsedContent.xliffmergeOptions) {\n            return parsedContent;\n        } else {\n            return null;\n        }\n    }\n\n    /**\n     * Initialize me from the profile content.\n     * (public only for test usage).\n     * @param options options given at runtime via command line\n     * @param profileContent if null, read it from profile.\n     */\n    private configure(options: ProgramOptions, profileContent?: IConfigFile) {\n        this.errorsFound = [];\n        this.warningsFound = [];\n        if (!profileContent) {\n            profileContent = this.readProfile(options);\n        }\n        const validProfile: boolean = (!!profileContent);\n        if (options.quiet) {\n            this._quiet = options.quiet;\n        }\n        if (options.verbose) {\n            this._verbose = options.verbose;\n        }\n        if (validProfile) {\n            this.initializeFromConfig(profileContent);\n            // if languages are given as parameters, they ovveride everything said in profile\n            if (!!options.languages && options.languages.length > 0) {\n                this._languages = options.languages;\n                if (!this._defaultLanguage) {\n                    this._defaultLanguage = this._languages[0];\n                }\n            }\n            this.checkParameters();\n        }\n    }\n\n    /**\n     * Read profile.\n     * @param options program options\n     * @return the read profile (empty, if none, null if errors)\n     */\n    private readProfile(options: ProgramOptions): IConfigFile {\n        const profilePath: string = options.profilePath;\n        if (!profilePath) {\n            for (const configfilename of PROFILE_CANDIDATES) {\n                const profile = XliffMergeParameters.readProfileCandidate(configfilename);\n                if (profile) {\n                    this.usedProfilePath = configfilename;\n                    return profile;\n                }\n            }\n            return {};\n        }\n        let content: string;\n        try {\n            content = fs.readFileSync(profilePath, 'UTF-8');\n        } catch (err) {\n            this.errorsFound.push(new XliffMergeError('could not read profile \"' + profilePath + '\"'));\n            return null;\n        }\n        this.usedProfilePath = profilePath;\n        const profileContent: IConfigFile = JSON.parse(content);\n        // replace all pathes in options by absolute paths\n        const xliffmergeOptions = profileContent.xliffmergeOptions;\n        xliffmergeOptions.srcDir = this.adjustPathToProfilePath(profilePath, xliffmergeOptions.srcDir);\n        xliffmergeOptions.genDir = this.adjustPathToProfilePath(profilePath, xliffmergeOptions.genDir);\n        xliffmergeOptions.apikeyfile = this.adjustPathToProfilePath(profilePath, xliffmergeOptions.apikeyfile);\n        return profileContent;\n    }\n\n    private adjustPathToProfilePath(profilePath: string, pathToAdjust: string | undefined): string | undefined {\n        if (!pathToAdjust || isAbsolute(pathToAdjust)) {\n            return pathToAdjust;\n        }\n        return join(dirname(profilePath), pathToAdjust).replace(/\\\\/g, '/');\n    }\n\n    private initializeFromConfig(profileContent: IConfigFile) {\n        if (!profileContent) {\n            return;\n        }\n        const profile = profileContent.xliffmergeOptions;\n        if (profile) {\n            if (!isNullOrUndefined(profile.quiet)) {\n                this._quiet = profile.quiet;\n            }\n            if (!isNullOrUndefined(profile.verbose)) {\n                this._verbose = profile.verbose;\n            }\n            if (!isNullOrUndefined(profile.allowIdChange)) {\n                this._allowIdChange = profile.allowIdChange;\n            }\n            if (profile.defaultLanguage) {\n                this._defaultLanguage = profile.defaultLanguage;\n            }\n            if (profile.languages) {\n                this._languages = profile.languages;\n            }\n            if (profile.srcDir) {\n                this._srcDir = profile.srcDir;\n            }\n            if (profile.angularCompilerOptions) {\n                if (profile.angularCompilerOptions.genDir) {\n                    this._genDir = profile.angularCompilerOptions.genDir;\n                }\n            }\n            if (profile.genDir) {\n                // this must be after angularCompilerOptions to be preferred\n                this._genDir = profile.genDir;\n            }\n            if (profile.i18nBaseFile) {\n                this._i18nBaseFile = profile.i18nBaseFile;\n            }\n            if (profile.i18nFile) {\n                this._i18nFile = profile.i18nFile;\n            }\n            if (profile.i18nFormat) {\n                this._i18nFormat = profile.i18nFormat;\n            }\n            if (profile.encoding) {\n                this._encoding = profile.encoding;\n            }\n            if (!isNullOrUndefined(profile.removeUnusedIds)) {\n                this._removeUnusedIds = profile.removeUnusedIds;\n            }\n            if (!isNullOrUndefined(profile.supportNgxTranslate)) {\n                this._supportNgxTranslate = profile.supportNgxTranslate;\n            }\n            if (!isNullOrUndefined(profile.ngxTranslateExtractionPattern)) {\n                this._ngxTranslateExtractionPattern = profile.ngxTranslateExtractionPattern;\n            }\n            if (!isNullOrUndefined(profile.useSourceAsTarget)) {\n                this._useSourceAsTarget = profile.useSourceAsTarget;\n            }\n            if (!isNullOrUndefined(profile.targetPraefix)) {\n                this._targetPraefix = profile.targetPraefix;\n            }\n            if (!isNullOrUndefined(profile.targetSuffix)) {\n                this._targetSuffix = profile.targetSuffix;\n            }\n            if (!isNullOrUndefined(profile.autotranslate)) {\n                this._autotranslate = profile.autotranslate;\n            }\n            if (!isNullOrUndefined(profile.beautifyOutput)) {\n                this._beautifyOutput = profile.beautifyOutput;\n            }\n            if (!isNullOrUndefined(profile.preserveOrder)) {\n                this._preserveOrder = profile.preserveOrder;\n            }\n            if (!isNullOrUndefined(profile.apikey)) {\n                this._apikey = profile.apikey;\n            }\n            if (!isNullOrUndefined(profile.apikeyfile)) {\n                this._apikeyfile = profile.apikeyfile;\n            }\n        } else {\n            this.warningsFound.push('did not find \"xliffmergeOptions\" in profile, using defaults');\n        }\n    }\n\n    /**\n     * Check all Parameters, wether they are complete and consistent.\n     * if something is wrong with the parameters, it is collected in errorsFound.\n     */\n    private checkParameters(): void {\n        this.checkLanguageSyntax(this.defaultLanguage());\n        if (this.languages().length === 0) {\n            this.errorsFound.push(new XliffMergeError('no languages specified'));\n        }\n        this.languages().forEach((lang) => {\n            this.checkLanguageSyntax(lang);\n        });\n        let stats: Stats;\n        let err: any;\n        // srcDir should exists\n        try {\n            stats = fs.statSync(this.srcDir());\n        } catch (e) {\n            err = e;\n        }\n        if (!!err || !stats.isDirectory()) {\n            this.errorsFound.push(new XliffMergeError('srcDir \"' + this.srcDir() + '\" is not a directory'));\n        }\n        // genDir should exists\n        try {\n            stats = fs.statSync(this.genDir());\n        } catch (e) {\n            err = e;\n        }\n        if (!!err || !stats.isDirectory()) {\n            this.errorsFound.push(new XliffMergeError('genDir \"' + this.genDir() + '\" is not a directory'));\n        }\n        // master file MUST exist\n        try {\n            fs.accessSync(this.i18nFile(), fs.constants.R_OK);\n        } catch (err) {\n            this.errorsFound.push(new XliffMergeError('i18nFile \"' + this.i18nFile() + '\" is not readable'));\n        }\n        // i18nFormat must be xlf xlf2 or xmb\n        if (!(this.i18nFormat() === 'xlf' || this.i18nFormat() === 'xlf2' || this.i18nFormat() === 'xmb')) {\n            this.errorsFound.push(new XliffMergeError('i18nFormat \"' + this.i18nFormat() + '\" invalid, must be \"xlf\" or \"xlf2\" or \"xmb\"'));\n        }\n        // autotranslate requires api key\n        if (this.autotranslate() && !this.apikey()) {\n            this.errorsFound.push(new XliffMergeError('autotranslate requires an API key, please set one'));\n        }\n        // autotranslated languages must be in list of all languages\n        this.autotranslatedLanguages().forEach((lang) => {\n            if (this.languages().indexOf(lang) < 0) {\n                this.errorsFound.push(new XliffMergeError('autotranslate language \"' + lang + '\" is not in list of languages'));\n            }\n            if (lang === this.defaultLanguage()) {\n                this.errorsFound.push(\n                    new XliffMergeError('autotranslate language \"' + lang + '\" cannot be translated, because it is the source language'));\n            }\n        });\n        // ngx translate pattern check\n        if (this.supportNgxTranslate()) {\n            const checkResult = NgxTranslateExtractor.checkPattern(this.ngxTranslateExtractionPattern());\n            if (!isNullOrUndefined(checkResult)) {\n                this.errorsFound.push(\n                    new XliffMergeError('ngxTranslateExtractionPattern \"' + this.ngxTranslateExtractionPattern() + '\": ' + checkResult));\n            }\n        }\n        // targetPraefix and targetSuffix check\n        if (!this.useSourceAsTarget()) {\n            if (this.targetPraefix().length > 0) {\n                this.warningsFound.push(\n                    'configured targetPraefix \"' + this.targetPraefix() + '\" will not be used because \"useSourceAsTarget\" is disabled\"');\n            }\n            if (this.targetSuffix().length > 0) {\n                this.warningsFound.push(\n                    'configured targetSuffix \"' + this.targetSuffix() + '\" will not be used because \"useSourceAsTarget\" is disabled\"');\n            }\n        }\n     }\n\n    /**\n     * Check syntax of language.\n     * Must be compatible with XML Schema type xsd:language.\n     * Pattern: [a-zA-Z]{1,8}((-|_)[a-zA-Z0-9]{1,8})*\n     * @param lang language to check\n     */\n    private checkLanguageSyntax(lang: string) {\n        const pattern = /^[a-zA-Z]{1,8}([-_][a-zA-Z0-9]{1,8})*$/;\n        if (!pattern.test(lang)) {\n            this.errorsFound.push(new XliffMergeError('language \"' + lang + '\" is not valid'));\n        }\n    }\n\n    public allowIdChange(): boolean {\n        return (isNullOrUndefined(this._allowIdChange)) ? false : this._allowIdChange;\n    }\n\n    public verbose(): boolean {\n        return (isNullOrUndefined(this._verbose)) ? false : this._verbose;\n    }\n\n    public quiet(): boolean {\n        return (isNullOrUndefined(this._quiet)) ? false : this._quiet;\n    }\n\n    /**\n     * Debug output all parameters to commandOutput.\n     */\n    public showAllParameters(commandOutput: CommandOutput): void {\n        commandOutput.debug('xliffmerge Used Parameters:');\n        commandOutput.debug('usedProfilePath:\\t\"%s\"', this.usedProfilePath);\n        commandOutput.debug('defaultLanguage:\\t\"%s\"', this.defaultLanguage());\n        commandOutput.debug('srcDir:\\t\"%s\"', this.srcDir());\n        commandOutput.debug('genDir:\\t\"%s\"', this.genDir());\n        commandOutput.debug('i18nBaseFile:\\t\"%s\"', this.i18nBaseFile());\n        commandOutput.debug('i18nFile:\\t\"%s\"', this.i18nFile());\n        commandOutput.debug('languages:\\t%s', this.languages());\n        for (const language of this.languages()) {\n            commandOutput.debug('outputFile[%s]:\\t%s', language, this.generatedI18nFile(language));\n        }\n        commandOutput.debug('removeUnusedIds:\\t%s', this.removeUnusedIds());\n        commandOutput.debug('supportNgxTranslate:\\t%s', this.supportNgxTranslate());\n        if (this.supportNgxTranslate()) {\n            commandOutput.debug('ngxTranslateExtractionPattern:\\t%s', this.ngxTranslateExtractionPattern());\n        }\n        commandOutput.debug('useSourceAsTarget:\\t%s', this.useSourceAsTarget());\n        if (this.useSourceAsTarget()) {\n            commandOutput.debug('targetPraefix:\\t\"%s\"', this.targetPraefix());\n            commandOutput.debug('targetSuffix:\\t\"%s\"', this.targetSuffix());\n        }\n        commandOutput.debug('allowIdChange:\\t%s', this.allowIdChange());\n        commandOutput.debug('beautifyOutput:\\t%s', this.beautifyOutput());\n        commandOutput.debug('preserveOrder:\\t%s', this.preserveOrder());\n        commandOutput.debug('autotranslate:\\t%s', this.autotranslate());\n        if (this.autotranslate()) {\n            commandOutput.debug('autotranslated languages:\\t%s', this.autotranslatedLanguages());\n            commandOutput.debug('apikey:\\t%s', this.apikey() ? '****' : 'NOT SET');\n            commandOutput.debug('apikeyfile:\\t%s', this.apikeyfile());\n        }\n    }\n\n    /**\n     * Default-Language, default en.\n     * @return default language\n     */\n    public defaultLanguage(): string {\n        return this._defaultLanguage ? this._defaultLanguage : 'en';\n    }\n\n    /**\n     * Liste der zu bearbeitenden Sprachen.\n     * @return languages\n     */\n    public languages(): string[] {\n        return this._languages ? this._languages : [];\n    }\n\n    /**\n     * src directory, where the master xlif is located.\n     * @return srcDir\n     */\n    public srcDir(): string {\n        return this._srcDir ? this._srcDir : '.';\n    }\n\n    /**\n     * The base file name of the xlif file for input and output.\n     * Default is messages\n     * @return base file\n     */\n    public i18nBaseFile(): string {\n        return this._i18nBaseFile ? this._i18nBaseFile : 'messages';\n    }\n\n    /**\n     * The master xlif file (the one generated by ng-xi18n).\n     * Default is <srcDir>/<i18nBaseFile>.xlf.\n     * @return master file\n     */\n    public i18nFile(): string {\n        return join(this.srcDir(),\n            (this._i18nFile ? this._i18nFile : this.i18nBaseFile() + '.' + this.suffixForGeneratedI18nFile())\n        ).replace(/\\\\/g, '/');\n    }\n\n    /**\n     * Format of the master xlif file.\n     * Default is \"xlf\", possible are \"xlf\" or \"xlf2\" or \"xmb\".\n     * @return format\n     */\n    public i18nFormat(): string {\n        return (this._i18nFormat ? this._i18nFormat : 'xlf');\n    }\n\n    /**\n     * potentially to be generated I18n-File with the translations for one language.\n     * @param lang language shortcut\n     * @return Path of file\n     */\n    public generatedI18nFile(lang: string): string {\n        return join(this.genDir(), this.i18nBaseFile() + '.' + lang + '.' + this.suffixForGeneratedI18nFile()).replace(/\\\\/g, '/');\n    }\n\n    private suffixForGeneratedI18nFile(): string {\n        switch (this.i18nFormat()) {\n            case 'xlf':\n                return 'xlf';\n            case 'xlf2':\n                return 'xlf';\n            case 'xmb':\n                return 'xtb';\n        }\n    }\n\n    /**\n     * potentially to be generated translate-File for ngx-translate with the translations for one language.\n     * @param lang language shortcut\n     * @return Path of file\n     */\n    public generatedNgxTranslateFile(lang: string): string {\n        return join(this.genDir(), this.i18nBaseFile() + '.' + lang + '.' + 'json').replace(/\\\\/g, '/');\n    }\n\n    /**\n     * The encoding used to write new XLIFF-files.\n     * @return encoding\n     */\n    public encoding(): string {\n        return this._encoding ? this._encoding : 'UTF-8';\n    }\n\n     /**\n      * Output-Directory, where the output is written to.\n      * Default is <srcDir>.\n     */\n    public genDir(): string {\n        return this._genDir ? this._genDir : this.srcDir();\n    }\n\n    public removeUnusedIds(): boolean {\n        return (isNullOrUndefined(this._removeUnusedIds)) ? true : this._removeUnusedIds;\n    }\n\n    public supportNgxTranslate(): boolean {\n        return (isNullOrUndefined(this._supportNgxTranslate)) ? false : this._supportNgxTranslate;\n    }\n\n    public ngxTranslateExtractionPattern(): string {\n        return (isNullOrUndefined(this._ngxTranslateExtractionPattern)) ?\n            NgxTranslateExtractor.DefaultExtractionPattern : this._ngxTranslateExtractionPattern;\n    }\n\n    /**\n     * Whether source must be used as target for new trans-units\n     * Default is true\n     */\n    public useSourceAsTarget(): boolean {\n        return (isNullOrUndefined(this._useSourceAsTarget)) ? true : this._useSourceAsTarget;\n    }\n\n    /**\n     * Praefix used for target when copying new trans-units\n     * Default is \"\"\n     */\n    public targetPraefix(): string {\n        return (isNullOrUndefined(this._targetPraefix)) ? '' : this._targetPraefix;\n    }\n\n    /**\n     * Suffix used for target when copying new trans-units\n     * Default is \"\"\n     */\n    public targetSuffix(): string {\n        return (isNullOrUndefined(this._targetSuffix)) ? '' : this._targetSuffix;\n    }\n\n    /**\n     * If set, run xml result through beautifier (pretty-data).\n     */\n    public beautifyOutput(): boolean {\n        return (isNullOrUndefined(this._beautifyOutput)) ? false : this._beautifyOutput;\n    }\n\n    /**\n     * If set, order of new trans units will be as in master.\n     * Otherwise they are added at the end.\n     */\n    public preserveOrder(): boolean {\n        return (isNullOrUndefined(this._preserveOrder)) ? true : this._preserveOrder;\n    }\n\n    /**\n     * Whether to use autotranslate for new trans-units\n     * Default is false\n     */\n    public autotranslate(): boolean {\n        if (isNullOrUndefined(this._autotranslate)) {\n            return false;\n        }\n        if (isArray(this._autotranslate)) {\n            return (<string[]>this._autotranslate).length > 0;\n        }\n        return <boolean> this._autotranslate;\n    }\n\n    /**\n     * Whether to use autotranslate for a given language.\n     * @param lang language code.\n     */\n    public autotranslateLanguage(lang: string): boolean {\n        return this.autotranslatedLanguages().indexOf(lang) >= 0;\n    }\n\n    /**\n     * Return a list of languages to be autotranslated.\n     */\n    public autotranslatedLanguages(): string[] {\n        if (isNullOrUndefined(this._autotranslate) || this._autotranslate === false) {\n            return [];\n        }\n        if (isArray(this._autotranslate)) {\n            return (<string[]>this._autotranslate);\n        }\n        return this.languages().slice(1); // first is source language\n    }\n\n    /**\n     * API key to be used for Google Translate\n     * @return api key\n     */\n    public apikey(): string {\n        if (!isNullOrUndefined(this._apikey)) {\n            return this._apikey;\n        } else {\n            const apikeyPath = this.apikeyfile();\n            if (this.apikeyfile()) {\n                if (fs.existsSync(apikeyPath)) {\n                    return FileUtil.read(apikeyPath, 'utf-8');\n                } else {\n                    throw new Error(format('api key file not found: API_KEY_FILE=%s', apikeyPath));\n                }\n            } else {\n                return null;\n            }\n        }\n    }\n\n    /**\n     * file name for API key to be used for Google Translate.\n     * Explicitly set or read from env var API_KEY_FILE.\n     * @return file of api key\n     */\n    public apikeyfile(): string {\n        if (this._apikeyfile) {\n            return this._apikeyfile;\n        } else if (process.env.API_KEY_FILE) {\n            return process.env.API_KEY_FILE;\n        } else {\n            return null;\n        }\n    }\n}\n","/**\n * Created by martin on 19.02.2017.\n */\nimport * as path from 'path';\n\nlet pkg = null;\ntry {\n    pkg = require(path.resolve(__dirname, '..', 'package.json'));\n} catch (e) {\n    try {\n        pkg = require(path.resolve(__dirname, '..', '..', 'package.json'));\n    } catch (e) {\n        pkg = null;\n    }\n}\n\nexport const VERSION = (pkg ? pkg.version : 'unknown');\n","import {FileUtil} from '../common/file-util';\n/**\n * Created by martin on 10.03.2017.\n * Helper class to read XMl with a correct encoding.\n */\n\nexport class XmlReader {\n    static DEFAULT_ENCODING = 'UTF-8';\n\n    /**\n     * Read an xml-File.\n     * @param path Path to file\n     * @param encoding optional encoding of the xml.\n     * This is read from the file, but if you know it before, you can avoid reading the file twice.\n     * @return file content and encoding found in the file.\n     */\n    public static readXmlFileContent(path: string, encoding?: string): {content: string, encoding: string} {\n        if (!encoding) {\n            encoding = XmlReader.DEFAULT_ENCODING;\n        }\n        let content: string = FileUtil.read(path, encoding);\n        const foundEncoding = XmlReader.encodingFromXml(content);\n        if (foundEncoding !== encoding) {\n            // read again with the correct encoding\n            content = FileUtil.read(path, foundEncoding);\n        }\n        return {\n            content: content,\n            encoding: foundEncoding\n        };\n    }\n\n    /**\n     * Read the encoding from the xml.\n     * xml File starts with .. encoding=\"..\"\n     * @param xmlString xmlString\n     * @return encoding\n     */\n    private static encodingFromXml(xmlString: string): string {\n        const index = xmlString.indexOf('encoding=\"');\n        if (index < 0) {\n            return this.DEFAULT_ENCODING; // default in xml if not explicitly set\n        }\n        const endIndex = xmlString.indexOf('\"', index + 10); // 10 = length of 'encoding=\"'\n        return xmlString.substring(index + 10, endIndex);\n    }\n\n}\n\n","/**\n * Created by roobm on 21.03.2017.\n */\nimport {\n  TranslationMessagesFileFactory,\n  ITranslationMessagesFile,\n} from 'i18nsupport-lib';\nimport { FileUtil } from '../common/file-util';\nimport { XmlReader } from './xml-reader';\n\n/**\n * Helper class to read translation files depending on format.\n */\nexport class TranslationMessagesFileReader {\n  /**\n   * Read file function, result depends on format, either XliffFile or XmbFile.\n   * @param i18nFormat format\n   * @param path path\n   * @param encoding encoding\n   * @param optionalMasterFilePath optionalMasterFilePath\n   * @return XliffFile\n   */\n  public static fromFile(\n    i18nFormat: string,\n    path: string,\n    encoding: string,\n    optionalMasterFilePath?: string\n  ): ITranslationMessagesFile {\n    const xmlContent = XmlReader.readXmlFileContent(path, encoding);\n    const optionalMaster = TranslationMessagesFileReader.masterFileContent(\n      optionalMasterFilePath,\n      encoding\n    );\n    return TranslationMessagesFileFactory.fromFileContent(\n      i18nFormat,\n      xmlContent.content,\n      path,\n      xmlContent.encoding,\n      optionalMaster\n    );\n  }\n\n  /**\n   * Read file function, result depends on format, either XliffFile or XmbFile.\n   * @param path path\n   * @param encoding encoding\n   * @param optionalMasterFilePath optionalMasterFilePath\n   * @return XliffFile\n   */\n  public static fromUnknownFormatFile(\n    path: string,\n    encoding: string,\n    optionalMasterFilePath?: string\n  ): ITranslationMessagesFile {\n    const xmlContent = XmlReader.readXmlFileContent(path, encoding);\n    const optionalMaster = TranslationMessagesFileReader.masterFileContent(\n      optionalMasterFilePath,\n      encoding\n    );\n    return TranslationMessagesFileFactory.fromUnknownFormatFileContent(\n      xmlContent.content,\n      path,\n      xmlContent.encoding,\n      optionalMaster\n    );\n  }\n\n  /**\n   * Read master xmb file\n   * @param optionalMasterFilePath optionalMasterFilePath\n   * @param encoding encoding\n   * @return content and encoding of file\n   */\n  private static masterFileContent(\n    optionalMasterFilePath: string,\n    encoding: string\n  ): { xmlContent: string; path: string; encoding: string } {\n    if (optionalMasterFilePath) {\n      const masterXmlContent = XmlReader.readXmlFileContent(\n        optionalMasterFilePath,\n        encoding\n      );\n      return {\n        xmlContent: masterXmlContent.content,\n        path: optionalMasterFilePath,\n        encoding: masterXmlContent.encoding,\n      };\n    } else {\n      return null;\n    }\n  }\n\n  /**\n   * Save edited file.\n   * @param messagesFile messagesFile\n   * @param beautifyOutput Flag whether to use pretty-data to format the output.\n   * XMLSerializer produces some correct but strangely formatted output, which pretty-data can correct.\n   * See issue #64 for details.\n   * Default is false.\n   */\n  public static save(\n    messagesFile: ITranslationMessagesFile,\n    beautifyOutput?: boolean\n  ) {\n    FileUtil.replaceContent(\n      messagesFile.filename(),\n      messagesFile.editedContent(beautifyOutput),\n      messagesFile.encoding()\n    );\n  }\n}\n","import { CommandOutput } from '../common/command-output';\nimport { XliffMergeParameters } from './xliff-merge-parameters';\nimport { XliffMergeError } from './xliff-merge-error';\nimport { FileUtil } from '../common/file-util';\nimport { VERSION } from './version';\nimport { format } from 'util';\nimport { isNullOrUndefined } from '../common/util';\nimport {\n  ITranslationMessagesFile,\n  ITransUnit,\n  FORMAT_XMB,\n  FORMAT_XTB,\n  NORMALIZATION_FORMAT_DEFAULT,\n  STATE_FINAL,\n  STATE_TRANSLATED,\n} from 'i18nsupport-lib';\nimport { ProgramOptions, IConfigFile } from './i-xliff-merge-options';\nimport { NgxTranslateExtractor } from './ngx-translate-extractor';\nimport { TranslationMessagesFileReader } from './translation-messages-file-reader';\nimport { Observable, of, forkJoin } from 'rxjs';\nimport { map, catchError } from 'rxjs/operators';\n\n/**\n * Created by martin on 17.02.2017.\n * XliffMerge - read xliff or xmb file and put untranslated parts in language specific xliff or xmb files.\n *\n */\n\nexport class XliffMerge {\n  private readonly commandOutput: CommandOutput;\n\n  private readonly options: ProgramOptions;\n\n  private parameters: XliffMergeParameters;\n\n  /**\n   * The read master xlf file.\n   */\n  private master: ITranslationMessagesFile; // XliffFile or Xliff2File or XmbFile\n\n  static main(argv: string[]) {\n    const options = XliffMerge.parseArgs(argv);\n    if (options) {\n      new XliffMerge(new CommandOutput(process.stdout), options).run(\n        (result) => {\n          process.exit(result);\n        }\n      );\n    }\n  }\n\n  static parseArgs(argv: string[]): ProgramOptions {\n    const options: ProgramOptions = {\n      languages: [],\n    };\n    for (let i = 1; i < argv.length; i++) {\n      const arg = argv[i];\n      if (arg === '--version' || arg === '-version') {\n        console.log('xliffmerge ' + VERSION);\n      } else if (arg === '--verbose' || arg === '-v') {\n        options.verbose = true;\n      } else if (arg === '--profile' || arg === '-p') {\n        i++;\n        if (i >= argv.length) {\n          console.log('missing config file');\n          XliffMerge.showUsage();\n          return null;\n        } else {\n          options.profilePath = argv[i];\n        }\n      } else if (arg === '--quiet' || arg === '-q') {\n        options.quiet = true;\n      } else if (arg === '--help' || arg === '-help' || arg === '-h') {\n        XliffMerge.showUsage();\n      } else if (arg.length > 0 && arg.charAt(0) === '-') {\n        console.log('unknown option');\n        return null;\n      } else {\n        options.languages.push(arg);\n      }\n    }\n    return options;\n  }\n\n  static showUsage() {\n    console.log('usage: xliffmerge <option>* <language>*');\n    console.log('Options');\n    console.log(\n      '\\t-p|--profile a json configuration file containing all relevant parameters.'\n    );\n    console.log(\n      '\\t\\tfor details please consult the home page https://github.com/martinroob/ngx-i18nsupport'\n    );\n    console.log('\\t-v|--verbose show some output for debugging purposes');\n    console.log('\\t-q|--quiet only show errors, nothing else');\n    console.log('\\t-version|--version show version string');\n    console.log('');\n    console.log(\n      '\\t<language> has to be a valid language short string, e,g. \"en\", \"de\", \"de-ch\"'\n    );\n  }\n\n  /**\n   * For Tests, create instance with given profile\n   * @param commandOutput commandOutput\n   * @param options options\n   * @param profileContent profileContent\n   */\n  public static createFromOptions(\n    commandOutput: CommandOutput,\n    options: ProgramOptions,\n    profileContent?: IConfigFile\n  ) {\n    const instance = new XliffMerge(commandOutput, options);\n    instance.parameters = XliffMergeParameters.createFromOptions(\n      options,\n      profileContent\n    );\n    return instance;\n  }\n\n  constructor(commandOutput: CommandOutput, options: ProgramOptions) {\n    this.commandOutput = commandOutput;\n    this.options = options;\n    this.parameters = null;\n  }\n\n  /**\n   * Run the command.\n   * This runs async.\n   * @param callbackFunction when command is executed, called with the return code (0 for ok), if given.\n   * @param errorFunction callbackFunction for error handling\n   */\n  public run(\n    callbackFunction?: (retcode: number) => any,\n    errorFunction?: (error: any) => any\n  ) {\n    this.runAsync().subscribe(\n      (retcode: number) => {\n        if (!isNullOrUndefined(callbackFunction)) {\n          callbackFunction(retcode);\n        }\n      },\n      (error) => {\n        if (!isNullOrUndefined(errorFunction)) {\n          errorFunction(error);\n        }\n      }\n    );\n  }\n\n  /**\n   * Execute merge-Process.\n   * @return Async operation, on completion returns retcode 0=ok, other = error.\n   */\n  public runAsync(): Observable<number> {\n    if (this.options && this.options.quiet) {\n      this.commandOutput.setQuiet();\n    }\n    if (this.options && this.options.verbose) {\n      this.commandOutput.setVerbose();\n    }\n    if (!this.parameters) {\n      this.parameters = XliffMergeParameters.createFromOptions(this.options);\n    }\n    this.commandOutput.info('xliffmerge version %s', VERSION);\n    if (this.parameters.verbose()) {\n      this.parameters.showAllParameters(this.commandOutput);\n    }\n    if (this.parameters.errorsFound.length > 0) {\n      for (const err of this.parameters.errorsFound) {\n        this.commandOutput.error(err.message);\n      }\n      return of(-1);\n    }\n    if (this.parameters.warningsFound.length > 0) {\n      for (const warn of this.parameters.warningsFound) {\n        this.commandOutput.warn(warn);\n      }\n    }\n    this.readMaster();\n\n    const executionForAllLanguages: Observable<number>[] = [];\n    this.parameters.languages().forEach((lang: string) => {\n      executionForAllLanguages.push(this.processLanguage(lang));\n    });\n    return forkJoin(executionForAllLanguages).pipe(\n      map((retcodes: number[]) => this.totalRetcode(retcodes))\n    );\n  }\n\n  /**\n   * Give an array of retcodes for the different languages, return the total retcode.\n   * If all are 0, it is 0, otherwise the first non zero.\n   * @param retcodes retcodes\n   * @return number\n   */\n  private totalRetcode(retcodes: number[]): number {\n    for (let i = 0; i < retcodes.length; i++) {\n      if (retcodes[i] !== 0) {\n        return retcodes[i];\n      }\n    }\n    return 0;\n  }\n\n  /**\n   * Return the name of the generated file for given lang.\n   * @param lang language\n   * @return name of generated file\n   */\n  public generatedI18nFile(lang: string): string {\n    return this.parameters.generatedI18nFile(lang);\n  }\n\n  /**\n   * Return the name of the generated ngx-translation file for given lang.\n   * @param lang language\n   * @return name of translate file\n   */\n  public generatedNgxTranslateFile(lang: string): string {\n    return this.parameters.generatedNgxTranslateFile(lang);\n  }\n\n  /**\n   * Warnings found during the run.\n   * @return warnings\n   */\n  public warnings(): string[] {\n    return this.parameters.warningsFound;\n  }\n\n  private readMaster() {\n    try {\n      this.master = TranslationMessagesFileReader.fromFile(\n        this.parameters.i18nFormat(),\n        this.parameters.i18nFile(),\n        this.parameters.encoding()\n      );\n      this.master.warnings().forEach((warning: string) => {\n        this.commandOutput.warn(warning);\n      });\n      const count = this.master.numberOfTransUnits();\n      const missingIdCount = this.master.numberOfTransUnitsWithMissingId();\n      this.commandOutput.info('master contains %s trans-units', count);\n      if (missingIdCount > 0) {\n        this.commandOutput.warn(\n          'master contains %s trans-units, but there are %s without id',\n          count,\n          missingIdCount\n        );\n      }\n      const sourceLang: string = this.master.sourceLanguage();\n      if (sourceLang && sourceLang !== this.parameters.defaultLanguage()) {\n        this.commandOutput.warn(\n          'master says to have source-language=\"%s\", should be \"%s\" (your defaultLanguage)',\n          sourceLang,\n          this.parameters.defaultLanguage()\n        );\n        this.master.setSourceLanguage(this.parameters.defaultLanguage());\n        TranslationMessagesFileReader.save(\n          this.master,\n          this.parameters.beautifyOutput()\n        );\n        this.commandOutput.warn(\n          'changed master source-language=\"%s\" to \"%s\"',\n          sourceLang,\n          this.parameters.defaultLanguage()\n        );\n      }\n    } catch (err) {\n      if (err instanceof XliffMergeError) {\n        this.commandOutput.error(err.message);\n        return of(-1);\n      } else {\n        // unhandled\n        const currentFilename = this.parameters.i18nFile();\n        const filenameString = currentFilename\n          ? format('file \"%s\", ', currentFilename)\n          : '';\n        this.commandOutput.error(filenameString + 'oops ' + err);\n        throw err;\n      }\n    }\n  }\n\n  /**\n   * Process the given language.\n   * Async operation.\n   * @param lang language\n   * @return on completion 0 for ok, other for error\n   */\n  private processLanguage(lang: string): Observable<number> {\n    this.commandOutput.debug('processing language %s', lang);\n    const languageXliffFile = this.parameters.generatedI18nFile(lang);\n    const currentFilename = languageXliffFile;\n    let result: Observable<void>;\n    if (!FileUtil.exists(languageXliffFile)) {\n      result = this.createUntranslatedXliff(lang, languageXliffFile);\n    } else {\n      result = this.mergeMasterTo(lang, languageXliffFile);\n    }\n    return result.pipe(\n      map(() => {\n        if (this.parameters.supportNgxTranslate()) {\n          const languageSpecificMessagesFile: ITranslationMessagesFile =\n            TranslationMessagesFileReader.fromFile(\n              this.translationFormat(this.parameters.i18nFormat()),\n              languageXliffFile,\n              this.parameters.encoding(),\n              this.master.filename()\n            );\n          NgxTranslateExtractor.extract(\n            languageSpecificMessagesFile,\n            this.parameters.ngxTranslateExtractionPattern(),\n            this.parameters.generatedNgxTranslateFile(lang)\n          );\n        }\n        return 0;\n      }),\n      catchError((err) => {\n        if (err instanceof XliffMergeError) {\n          this.commandOutput.error(err.message);\n          return of(-1);\n        } else {\n          // unhandled\n          const filenameString = currentFilename\n            ? format('file \"%s\", ', currentFilename)\n            : '';\n          this.commandOutput.error(filenameString + 'oops ' + err);\n          throw err;\n        }\n      })\n    );\n  }\n\n  /**\n   * create a new file for the language, which contains no translations, but all keys.\n   * in principle, this is just a copy of the master with target-language set.\n   * @param lang language\n   * @param languageXliffFilePath name of file\n   */\n  private createUntranslatedXliff(\n    lang: string,\n    languageXliffFilePath: string\n  ): Observable<void> {\n    // copy master ...\n    // and set target-language\n    // and copy source to target if necessary\n    const isDefaultLang: boolean = lang === this.parameters.defaultLanguage();\n    this.master.setNewTransUnitTargetPraefix(this.parameters.targetPraefix());\n    this.master.setNewTransUnitTargetSuffix(this.parameters.targetSuffix());\n    const languageSpecificMessagesFile: ITranslationMessagesFile =\n      this.master.createTranslationFileForLang(\n        lang,\n        languageXliffFilePath,\n        isDefaultLang,\n        this.parameters.useSourceAsTarget()\n      );\n    return;\n  }\n\n  /**\n   * Map the input format to the format of the translation.\n   * Normally they are the same but for xmb the translation format is xtb.\n   * @param i18nFormat format\n   */\n  private translationFormat(i18nFormat: string): string {\n    if (i18nFormat === FORMAT_XMB) {\n      return FORMAT_XTB;\n    } else {\n      return i18nFormat;\n    }\n  }\n\n  /**\n   * Merge all\n   * @param lang language\n   * @param languageXliffFilePath filename\n   */\n  private mergeMasterTo(\n    lang: string,\n    languageXliffFilePath: string\n  ): Observable<void> {\n    // read lang specific file\n    const languageSpecificMessagesFile: ITranslationMessagesFile =\n      TranslationMessagesFileReader.fromFile(\n        this.translationFormat(this.parameters.i18nFormat()),\n        languageXliffFilePath,\n        this.parameters.encoding()\n      );\n    const isDefaultLang: boolean = lang === this.parameters.defaultLanguage();\n    let newCount = 0;\n    let correctSourceContentCount = 0;\n    let correctSourceRefCount = 0;\n    let correctDescriptionOrMeaningCount = 0;\n    let idChangedCount = 0;\n    languageSpecificMessagesFile.setNewTransUnitTargetPraefix(\n      this.parameters.targetPraefix()\n    );\n    languageSpecificMessagesFile.setNewTransUnitTargetSuffix(\n      this.parameters.targetSuffix()\n    );\n    let lastProcessedUnit: ITransUnit = null;\n    this.master.forEachTransUnit((masterTransUnit) => {\n      const transUnit: ITransUnit =\n        languageSpecificMessagesFile.transUnitWithId(masterTransUnit.id);\n\n      if (!transUnit) {\n        // oops, no translation, must be a new key, so add it\n        let newUnit;\n        if (\n          this.parameters.allowIdChange() &&\n          (newUnit = this.processChangedIdUnit(\n            masterTransUnit,\n            languageSpecificMessagesFile,\n            lastProcessedUnit\n          ))\n        ) {\n          lastProcessedUnit = newUnit;\n          idChangedCount++;\n        } else {\n          lastProcessedUnit = languageSpecificMessagesFile.importNewTransUnit(\n            masterTransUnit,\n            isDefaultLang,\n            this.parameters.useSourceAsTarget(),\n            this.parameters.preserveOrder() ? lastProcessedUnit : undefined\n          );\n          newCount++;\n        }\n      } else {\n        // check for changed source content and change it if needed\n        // (can only happen if ID is explicitely set, otherwise ID would change if source content is changed.\n        if (\n          transUnit.supportsSetSourceContent() &&\n          !this.areSourcesNearlyEqual(masterTransUnit, transUnit)\n        ) {\n          transUnit.setSourceContent(masterTransUnit.sourceContent());\n          if (isDefaultLang) {\n            // #81 changed source must be copied to target for default lang\n            transUnit.translate(masterTransUnit.sourceContent());\n            transUnit.setTargetState(STATE_FINAL);\n          } else {\n            if (transUnit.targetState() === STATE_FINAL) {\n              // source is changed, so translation has to be checked again\n              transUnit.setTargetState(STATE_TRANSLATED);\n            }\n          }\n          correctSourceContentCount++;\n        }\n        // check for missing or changed source ref and add it if needed\n        if (\n          transUnit.supportsSetSourceReferences() &&\n          !this.areSourceReferencesEqual(\n            masterTransUnit.sourceReferences(),\n            transUnit.sourceReferences()\n          )\n        ) {\n          transUnit.setSourceReferences(masterTransUnit.sourceReferences());\n          correctSourceRefCount++;\n        }\n        // check for changed description or meaning\n        if (transUnit.supportsSetDescriptionAndMeaning()) {\n          let changed = false;\n          if (transUnit.description() !== masterTransUnit.description()) {\n            transUnit.setDescription(masterTransUnit.description());\n            changed = true;\n          }\n          if (transUnit.meaning() !== masterTransUnit.meaning()) {\n            transUnit.setMeaning(masterTransUnit.meaning());\n            changed = true;\n          }\n          if (changed) {\n            correctDescriptionOrMeaningCount++;\n          }\n        }\n        lastProcessedUnit = transUnit;\n      }\n    });\n    if (newCount > 0) {\n      this.commandOutput.warn(\n        'merged %s trans-units from master to \"%s\"',\n        newCount,\n        lang\n      );\n    }\n    if (correctSourceContentCount > 0) {\n      this.commandOutput.warn(\n        'transferred %s changed source content from master to \"%s\"',\n        correctSourceContentCount,\n        lang\n      );\n    }\n    if (correctSourceRefCount > 0) {\n      this.commandOutput.warn(\n        'transferred %s source references from master to \"%s\"',\n        correctSourceRefCount,\n        lang\n      );\n    }\n    if (idChangedCount > 0) {\n      this.commandOutput.warn(\n        'found %s changed id\\'s in \"%s\"',\n        idChangedCount,\n        lang\n      );\n    }\n    if (correctDescriptionOrMeaningCount > 0) {\n      this.commandOutput.warn(\n        'transferred %s changed descriptions/meanings from master to \"%s\"',\n        correctDescriptionOrMeaningCount,\n        lang\n      );\n    }\n\n    // remove all elements that are no longer used\n    let removeCount = 0;\n    languageSpecificMessagesFile.forEachTransUnit((transUnit: ITransUnit) => {\n      const existsInMaster = !isNullOrUndefined(\n        this.master.transUnitWithId(transUnit.id)\n      );\n      if (!existsInMaster) {\n        if (this.parameters.removeUnusedIds()) {\n          languageSpecificMessagesFile.removeTransUnitWithId(transUnit.id);\n        }\n        removeCount++;\n      }\n    });\n    if (removeCount > 0) {\n      if (this.parameters.removeUnusedIds()) {\n        this.commandOutput.warn(\n          'removed %s unused trans-units in \"%s\"',\n          removeCount,\n          lang\n        );\n      } else {\n        this.commandOutput.warn(\n          'keeping %s unused trans-units in \"%s\", because removeUnused is disabled',\n          removeCount,\n          lang\n        );\n      }\n    }\n\n    if (\n      newCount === 0 &&\n      removeCount === 0 &&\n      correctSourceContentCount === 0 &&\n      correctSourceRefCount === 0 &&\n      correctDescriptionOrMeaningCount === 0\n    ) {\n      this.commandOutput.info('file for \"%s\" was up to date', lang);\n      return of(null);\n    }\n  }\n\n  /**\n   * Handle the case of changed id due to small white space changes.\n   * @param masterTransUnit unit in master file\n   * @param languageSpecificMessagesFile translation file\n   * @param lastProcessedUnit Unit before the one processed here. New unit will be inserted after this one.\n   * @return processed unit, if done, null if no changed unit found\n   */\n  private processChangedIdUnit(\n    masterTransUnit: ITransUnit,\n    languageSpecificMessagesFile: ITranslationMessagesFile,\n    lastProcessedUnit: ITransUnit\n  ): ITransUnit {\n    let changedTransUnit: ITransUnit = null;\n    languageSpecificMessagesFile.forEachTransUnit((languageTransUnit) => {\n      if (this.areSourcesNearlyEqual(languageTransUnit, masterTransUnit)) {\n        changedTransUnit = languageTransUnit;\n      }\n    });\n    if (!changedTransUnit) {\n      return null;\n    }\n    const mergedTransUnit = languageSpecificMessagesFile.importNewTransUnit(\n      masterTransUnit,\n      false,\n      false,\n      this.parameters.preserveOrder() ? lastProcessedUnit : undefined\n    );\n    const translatedContent = changedTransUnit.targetContent();\n    if (translatedContent) {\n      // issue #68 set translated only, if it is really translated\n      mergedTransUnit.translate(translatedContent);\n      mergedTransUnit.setTargetState(STATE_TRANSLATED);\n    }\n    return mergedTransUnit;\n  }\n\n  /**\n   * test wether the sources of 2 trans units are equal ignoring white spaces.\n   * @param tu1 tu1\n   * @param tu2 tu2\n   */\n  private areSourcesNearlyEqual(tu1: ITransUnit, tu2: ITransUnit): boolean {\n    if ((tu1 && !tu2) || (tu2 && !tu1)) {\n      return false;\n    }\n    const tu1Normalized = tu1.sourceContentNormalized();\n    const tu2Normalized = tu2.sourceContentNormalized();\n    if (tu1Normalized.isICUMessage()) {\n      if (tu2Normalized.isICUMessage()) {\n        const icu1Normalized = tu1Normalized\n          .getICUMessage()\n          .asNativeString()\n          .trim();\n        const icu2Normalized = tu2Normalized\n          .getICUMessage()\n          .asNativeString()\n          .trim();\n        return icu1Normalized === icu2Normalized;\n      } else {\n        return false;\n      }\n    }\n    if (tu1Normalized.containsICUMessageRef()) {\n      const icuref1Normalized = tu1Normalized.asNativeString().trim();\n      const icuref2Normalized = tu2Normalized.asNativeString().trim();\n      return icuref1Normalized === icuref2Normalized;\n    }\n    const s1Normalized = tu1Normalized\n      .asDisplayString(NORMALIZATION_FORMAT_DEFAULT)\n      .trim();\n    const s2Normalized = tu2Normalized\n      .asDisplayString(NORMALIZATION_FORMAT_DEFAULT)\n      .trim();\n    return s1Normalized === s2Normalized;\n  }\n\n  private areSourceReferencesEqual(\n    ref1: { sourcefile: string; linenumber: number }[],\n    ref2: { sourcefile: string; linenumber: number }[]\n  ): boolean {\n    if (\n      (isNullOrUndefined(ref1) && !isNullOrUndefined(ref2)) ||\n      (isNullOrUndefined(ref2) && !isNullOrUndefined(ref1))\n    ) {\n      return false;\n    }\n    if (isNullOrUndefined(ref1) && isNullOrUndefined(ref2)) {\n      return true;\n    }\n    // bot refs are set now, convert to set to compare them\n    const set1: Set<string> = new Set<string>();\n    ref1.forEach((ref) => {\n      set1.add(ref.sourcefile + ':' + ref.linenumber);\n    });\n    const set2: Set<string> = new Set<string>();\n    ref2.forEach((ref) => {\n      set2.add(ref.sourcefile + ':' + ref.linenumber);\n    });\n    if (set1.size !== set2.size) {\n      return false;\n    }\n    let match = true;\n    set2.forEach((ref) => {\n      if (!set1.has(ref)) {\n        match = false;\n      }\n    });\n    return match;\n  }\n}\n"]}