// Copyright (c) 2000-2017 Ericsson Telecom AB                                                       //
// All rights reserved. This program and the accompanying materials are made available under the     //
// terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at //
// http://www.eclipse.org/legal/epl-v10.html                                                         //
///////////////////////////////////////////////////////////////////////////////////////////////////////
/*
 * ## What is polyfill?
 * - https://remysharp.com/2010/10/08/what-is-a-polyfill
 * - https://en.wikipedia.org/wiki/Polyfill
 *
 * Polyfill is a kind of regressive enhancement, a backport of native APIs in managed code.
 */
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
if (!Object.keys) {
    Object.keys = (function() {
        'use strict';
        var hasOwnProperty = Object.prototype.hasOwnProperty,
            hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
            dontEnums = [
                'toString',
                'toLocaleString',
                'valueOf',
                'hasOwnProperty',
                'isPrototypeOf',
                'propertyIsEnumerable',
                'constructor'
            ],
            dontEnumsLength = dontEnums.length;

        return function(obj) {
            if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
                throw new TypeError('Object.keys called on non-object');
            }

            var result = [], prop, i;

            for (prop in obj) {
                if (hasOwnProperty.call(obj, prop)) {
                    result.push(prop);
                }
            }

            if (hasDontEnumBug) {
                for (i = 0; i < dontEnumsLength; i++) {
                    if (hasOwnProperty.call(obj, dontEnums[i])) {
                        result.push(dontEnums[i]);
                    }
                }
            }
            return result;
        };
    }());
}

/*
 * From https://github.com/itsa/polyfill/blob/master/old-lib/object.defineproperty.js
 */
if (!Object.defineProperty) {
    Object.defineProperty =  function(object, property, descriptor) {
        'use strict';
        object[property] = descriptor.value;
    };
}

/*
 * From https://github.com/itsa/polyfill/blob/master/old-lib/object.defineproperty.js
 */
if (!Object.defineProperties) {
    Object.defineProperties = function(object, descriptors) {
        'use strict';
        var property;
        for (property in descriptors) {
            Object.defineProperty(object, property, descriptors[property]);
        }
        return object;
    };
}

if (!Date.now) { //  ECMA-262 5th edition, not in IE9-
    Date.now = function now() {
        "use strict";
        return new Date().getTime();
    };
}

if (!String.prototype.includes) { // ECMAScript 6 only.
  String.prototype.includes = function() {'use strict';
    return String.prototype.indexOf.apply(this, arguments) !== -1;
  };
}

if (!String.prototype.startsWith) { // ECMAScript 6 only.
  String.prototype.startsWith = function(searchString, position) {'use strict';
    position = position || 0;
    return this.indexOf(searchString, position) === position;
  };
}

if (!String.prototype.endsWith) { // ECMAScript 6 only.
  String.prototype.endsWith = function(searchString, position) {'use strict';
      var subjectString = this.toString();
      if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
        position = subjectString.length;
      }
      position -= searchString.length;
      var lastIndex = subjectString.indexOf(searchString, position);
      return lastIndex !== -1 && lastIndex === position;
  };
}

// Production steps of ECMA-262, Edition 5, 15.4.4.21
// Reference: http://es5.github.io/#x15.4.4.21
if (!Array.prototype.reduce) { // IE9+
  Array.prototype.reduce = function(callback, initialValue) {
    'use strict';
    if (this == null) {
      throw new TypeError('Array.prototype.reduce called on null or undefined');
    }
    if (typeof callback !== 'function') {
      throw new TypeError(callback + ' is not a function');
    }
    var t = Object(this), len = t.length >>> 0, k = 0, value;
    if (arguments.length === 2) {
      value = initialValue;
    } else {
      while (k < len && !(k in t)) {
        k++;
      }
      if (k >= len) {
        throw new TypeError('Reduce of empty array with no initial value');
      }
      value = t[k++];
    }
    for (; k < len; k++) {
      if (k in t) {
        value = callback(value, t[k], k, t);
      }
    }
    return value;
  };
}

window.performance = (window.performance || {
    offset: Date.now(), // Timestamp of init.
    now: function now(){ // ms elapsed since offset.
        return Date.now() - this.offset;
    }
});

(function (global) { // console NOOP for oldff
    "use strict";
    var CONSOLE = {
        log: function() { /* NOOP */ },
        info: function() { /* NOOP */ },
        warn: function() { /* NOOP */ },
        error: function() { /* NOOP */ }
    };
    global.console || (function(GlobalPrototype) {
        GlobalPrototype.console = CONSOLE;
    }(global.prototype));
}(typeof global !== 'undefined' ? global : this));

Number.isInteger = Number.isInteger || function(value) {
    return typeof value === "number" && isFinite(value) && Math.floor(value) === value;
};

//# sourceURL=Utils\Polyfill.js
