text: // Copyright (c) 2015 - 2017 Uber Technologies, Inc.
  //
  // 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.
  
  /**
   * Access properties of nested containers using dot-path notation
   * - Supports plain objects and arrays, as well as classes with `get` methods
   *   such as ES6 Maps, Immutable.js objects etc
   * - Returns undefined if any container is not valid, instead of throwing
   *
   * @param {Object} container - container that supports get
   * @param {String|*} compositeKey - key to access, can be '.'-separated string
   * @return {*} - value in the final key of the nested container
   */
  export function get(container, compositeKey) {
    // Split the key into subkeys
    const keyList = getKeys(compositeKey); // Recursively get the value of each key;
  
    let value = container;
  
    for (const key of keyList) {
      // If any intermediate subfield is not a container, return undefined
      if (!isObject(value)) {
        return undefined;
      } // Get the `getter` for this container
  
  
      const getter = getGetter(value); // Use the getter to get the value for the key
  
      value = getter(value, key);
    }
  
    return value;
  }
  /**
   * Checks if argument is an indexable object (not a primitive value, nor null)
   * @param {*} value - JavaScript value to be tested
   * @return {Boolean} - true if argument is a JavaScript object
   */
  
  function isObject(value) {
    return value !== null && typeof value === 'object';
  } // Default getter is container indexing
  
  
  const squareBracketGetter = (container, key) => container[key];
  
  const getMethodGetter = (obj, key) => obj.get(key); // Cache key to key arrays for speed
  
  
  const keyMap = {}; // Looks for a `get` function on the prototype
  // TODO - follow prototype chain?
  // @private
  // @return {Function} - get function: (container, key) => value
  
  function getGetter(container) {
    // Check if container has a special get method
    const prototype = Object.getPrototypeOf(container);
    return prototype.get ? getMethodGetter : squareBracketGetter;
  } // Takes a string of '.' separated keys and returns an array of keys
  // E.g. 'feature.geometry.type' => 'feature', 'geometry', 'type'
  // @private
  
  
  function getKeys(compositeKey) {
    if (typeof compositeKey === 'string') {
      // else assume string and split around dots
      let keyList = keyMap[compositeKey];
  
      if (!keyList) {
        keyList = compositeKey.split('.');
        keyMap[compositeKey] = keyList;
      }
  
      return keyList;
    } // Wrap in array if needed
  
  
    return Array.isArray(compositeKey) ? compositeKey : [compositeKey];
  }
  //# sourceMappingURL=get.js.map