//https://github.com/jquery/jquery-migrate/blob/master/src/migrate.js
var warnedAbout = {};

// List of warnings already given; public read only
jQuery.migrateWarnings = [];

// Set to true to prevent console output; migrateWarnings still maintained
jQuery.migrateMute = true;

// Show a message on the console so devs know we're active
if ( !jQuery.migrateMute && window.console && window.console.log ) {
  window.console.log("JQMIGRATE: Logging is active");
}

// Set to false to disable traces that appear with warnings
if ( jQuery.migrateTrace === undefined ) {
  jQuery.migrateTrace = true;
}

// Forget any warnings we've already given; public
jQuery.migrateReset = function() {
  warnedAbout = {};
  jQuery.migrateWarnings.length = 0;
};

function migrateWarn( msg) {
  var console = window.console;
  if ( !warnedAbout[ msg ] ) {
    warnedAbout[ msg ] = true;
    jQuery.migrateWarnings.push( msg );
    if ( console && console.warn && !jQuery.migrateMute ) {
      console.warn( "JQMIGRATE: " + msg );
      if ( jQuery.migrateTrace && console.trace ) {
        console.trace();
      }
    }
  }
}

function migrateWarnProp( obj, prop, value, msg ) {
  if ( Object.defineProperty ) {
    // On ES5 browsers (non-oldIE), warn if the code tries to get prop;
    // allow property to be overwritten in case some other plugin wants it
    try {
      Object.defineProperty( obj, prop, {
        configurable: true,
        enumerable: true,
        get: function() {
          migrateWarn( msg );
          return value;
        },
        set: function( newValue ) {
          migrateWarn( msg );
          value = newValue;
        }
      });
      return;
    } catch( err ) {
      // IE8 is a dope about Object.defineProperty, can't warn there
    }
  }

  // Non-ES5 (or broken) browser; just set the property
  jQuery._definePropertyBroken = true;
  obj[ prop ] = value;
}

if ( document.compatMode === "BackCompat" ) {
  // jQuery has never supported or tested Quirks Mode
  migrateWarn( "jQuery is not compatible with Quirks Mode" );
}

//https://github.com/jquery/jquery-migrate/blob/master/src/core.js
var matched, browser,
  oldInit = jQuery.fn.init,
  oldParseJSON = jQuery.parseJSON,
  rspaceAngle = /^\s*</,
// Note: XSS check is done below after string is trimmed
  rquickExpr = /^([^<]*)(<[\w\W]+>)([^>]*)$/;

// $(html) "looks like html" rule change
jQuery.fn.init = function( selector, context, rootjQuery ) {
  var match, ret;

  if ( selector && typeof selector === "string" && !jQuery.isPlainObject( context ) &&
    (match = rquickExpr.exec( jQuery.trim( selector ) )) && match[ 0 ] ) {
    // This is an HTML string according to the "old" rules; is it still?
    if ( !rspaceAngle.test( selector ) ) {
      migrateWarn("$(html) HTML strings must start with '<' character");
    }
    if ( match[ 3 ] ) {
      migrateWarn("$(html) HTML text after last tag is ignored");
    }

    // Consistently reject any HTML-like string starting with a hash (#9521)
    // Note that this may break jQuery 1.6.x code that otherwise would work.
    if ( match[ 0 ].charAt( 0 ) === "#" ) {
      migrateWarn("HTML string cannot start with a '#' character");
      jQuery.error("JQMIGRATE: Invalid selector string (XSS)");
    }
    // Now process using loose rules; let pre-1.8 play too
    if ( context && context.context ) {
      // jQuery object as context; parseHTML expects a DOM object
      context = context.context;
    }
    if ( jQuery.parseHTML ) {
      return oldInit.call( this,
        jQuery.parseHTML( match[ 2 ], context && context.ownerDocument || context, true ),
        context, rootjQuery );
    }
  }

  // jQuery( "#" ) is a bogus ID selector, but it returned an empty set before jQuery 3.0
  if ( selector === "#" ) {
    migrateWarn( "jQuery( '#' ) is not a valid selector" );
    selector = [];
  }

  ret = oldInit.apply( this, arguments );

  // Fill in selector and context properties so .live() works
  if ( selector && selector.selector !== undefined ) {
    // A jQuery object, copy its properties
    ret.selector = selector.selector;
    ret.context = selector.context;

  } else {
    ret.selector = typeof selector === "string" ? selector : "";
    if ( selector ) {
      ret.context = selector.nodeType? selector : context || document;
    }
  }

  return ret;
};
jQuery.fn.init.prototype = jQuery.fn;

// Let $.parseJSON(falsy_value) return null
jQuery.parseJSON = function( json ) {
  if ( !json ) {
    migrateWarn("jQuery.parseJSON requires a valid JSON string");
    return null;
  }
  return oldParseJSON.apply( this, arguments );
};

jQuery.uaMatch = function( ua ) {
  ua = ua.toLowerCase();

  var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
    /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
    /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
    /(msie) ([\w.]+)/.exec( ua ) ||
    ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
    [];

  return {
    browser: match[ 1 ] || "",
    version: match[ 2 ] || "0"
  };
};

// Don't clobber any existing jQuery.browser in case it's different
if ( !jQuery.browser ) {
  matched = jQuery.uaMatch( navigator.userAgent );
  browser = {};

  if ( matched.browser ) {
    browser[ matched.browser ] = true;
    browser.name = matched.browser;
    browser.version = matched.version;
  }

  // Chrome is Webkit, but Webkit is also Safari.
  if ( browser.chrome ) {
    browser.webkit = true;
  } else if ( browser.webkit ) {
    browser.safari = true;
  }

  jQuery.browser = browser;
}

// Warn if the code tries to get jQuery.browser
// migrateWarnProp( jQuery, "browser", jQuery.browser, "jQuery.browser is deprecated" );

// jQuery.boxModel deprecated in 1.3, jQuery.support.boxModel deprecated in 1.7
jQuery.boxModel = jQuery.support.boxModel = (document.compatMode === "CSS1Compat");
migrateWarnProp( jQuery, "boxModel", jQuery.boxModel, "jQuery.boxModel is deprecated" );
migrateWarnProp( jQuery.support, "boxModel", jQuery.support.boxModel, "jQuery.support.boxModel is deprecated" );

jQuery.sub = function() {
  function jQuerySub( selector, context ) {
    return new jQuerySub.fn.init( selector, context );
  }
  jQuery.extend( true, jQuerySub, this );
  jQuerySub.superclass = this;
  jQuerySub.fn = jQuerySub.prototype = this();
  jQuerySub.fn.constructor = jQuerySub;
  jQuerySub.sub = this.sub;
  jQuerySub.fn.init = function init( selector, context ) {
    var instance = jQuery.fn.init.call( this, selector, context, rootjQuerySub );
    return instance instanceof jQuerySub ?
      instance :
      jQuerySub( instance );
  };
  jQuerySub.fn.init.prototype = jQuerySub.fn;
  var rootjQuerySub = jQuerySub(document);
  migrateWarn( "jQuery.sub() is deprecated" );
  return jQuerySub;
};

// The number of elements contained in the matched element set
jQuery.fn.size = function() {
  migrateWarn( "jQuery.fn.size() is deprecated; use the .length property" );
  return this.length;
};