text: /**
  * Copyright 2012-2018, Plotly, Inc.
  * All rights reserved.
  *
  * This source code is licensed under the MIT license found in the
  * LICENSE file in the root directory of this source tree.
  */
  
  
  'use strict';
  
  var isNumeric = require('fast-isnumeric');
  var Lib = require('../../lib');
  
  var Registry = require('../../registry');
  
  module.exports = function handleXYZDefaults(traceIn, traceOut, coerce, layout, xName, yName) {
      var z = coerce('z');
      xName = xName || 'x';
      yName = yName || 'y';
      var x, y;
  
      if(z === undefined || !z.length) return 0;
  
      if(Lib.isArray1D(traceIn.z)) {
          x = coerce(xName);
          y = coerce(yName);
  
          // column z must be accompanied by xName and yName arrays
          if(!(x && x.length && y && y.length)) return 0;
  
          traceOut._length = Math.min(x.length, y.length, z.length);
      }
      else {
          x = coordDefaults(xName, coerce);
          y = coordDefaults(yName, coerce);
  
          // TODO put z validation elsewhere
          if(!isValidZ(z)) return 0;
  
          coerce('transpose');
  
          traceOut._length = null;
      }
  
      var handleCalendarDefaults = Registry.getComponentMethod('calendars', 'handleTraceDefaults');
      handleCalendarDefaults(traceIn, traceOut, [xName, yName], layout);
  
      return true;
  };
  
  function coordDefaults(coordStr, coerce) {
      var coord = coerce(coordStr),
          coordType = coord ?
              coerce(coordStr + 'type', 'array') :
              'scaled';
  
      if(coordType === 'scaled') {
          coerce(coordStr + '0');
          coerce('d' + coordStr);
      }
  
      return coord;
  }
  
  function isValidZ(z) {
      var allRowsAreArrays = true,
          oneRowIsFilled = false,
          hasOneNumber = false,
          zi;
  
      /*
       * Without this step:
       *
       * hasOneNumber = false breaks contour but not heatmap
       * allRowsAreArrays = false breaks contour but not heatmap
       * oneRowIsFilled = false breaks both
       */
  
      for(var i = 0; i < z.length; i++) {
          zi = z[i];
          if(!Lib.isArrayOrTypedArray(zi)) {
              allRowsAreArrays = false;
              break;
          }
          if(zi.length > 0) oneRowIsFilled = true;
          for(var j = 0; j < zi.length; j++) {
              if(isNumeric(zi[j])) {
                  hasOneNumber = true;
                  break;
              }
          }
      }
  
      return (allRowsAreArrays && oneRowIsFilled && hasOneNumber);
  }
  