/**
 * HTML elements and other resources for web-based applications that need to
 * interact with the browser and the DOM (Document Object Model).
 *
 * This library includes DOM element types, CSS styling, local storage,
 * media, speech, events, and more.
 * To get started,
 * check out the [Element] class, the base class for many of the HTML
 * DOM types.
 *
 * For information on writing web apps with Dart, see https://webdev.dartlang.org.
 *
 * {@category Web}
 */
library dart.dom.html;

import 'dart:async';
import 'dart:collection' hide LinkedList, LinkedListEntry;
import 'dart:_internal' hide Symbol;
import 'dart:html_common';
import 'dart:indexed_db';
import "dart:convert";
import 'dart:math';
import 'dart:_native_typed_data';
import 'dart:typed_data';
import 'dart:svg' as svg;
import 'dart:svg' show Matrix;
import 'dart:svg' show SvgSvgElement;
import 'dart:web_audio' as web_audio;
import 'dart:web_audio' show AudioBuffer, AudioTrack, AudioTrackList;
import 'dart:web_gl' as gl;
import 'dart:web_gl' show RenderingContext, RenderingContext2;
import 'dart:web_sql';
import 'dart:_foreign_helper' show JS, JS_INTERCEPTOR_CONSTANT;
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// DO NOT EDIT - unless you are editing documentation as per:
// https://code.google.com/p/dart/wiki/ContributingHTMLDocumentation
// Auto-generated dart:html library.

// Not actually used, but imported since dart:html can generate these objects.
import 'dart:_js_helper'
    show
        convertDartClosureToJS,
        Creates,
        JavaScriptIndexingBehavior,
        JSName,
        Native,
        Returns,
        ForceInline,
        findDispatchTagForInterceptorClass,
        setNativeSubclassDispatchRecord,
        makeLeafDispatchRecord,
        registerGlobalObject,
        applyExtension;
import 'dart:_interceptors'
    show
        Interceptor,
        JavaScriptFunction,
        JSExtendableArray,
        JSUInt31,
        findInterceptorConstructorForType,
        findConstructorForNativeSubclassType,
        getNativeInterceptor,
        setDispatchProperty;

export 'dart:math' show Rectangle, Point;

/**
 * Top-level container for a web page, which is usually a browser tab or window.
 *
 * Each web page loaded in the browser has its own [Window], which is a
 * container for the web page.
 *
 * If the web page has any `<iframe>` elements, then each `<iframe>` has its own
 * [Window] object, which is accessible only to that `<iframe>`.
 *
 * See also:
 *
 *   * [Window](https://developer.mozilla.org/en-US/docs/Web/API/window) from MDN.
 */
Window get window => JS('Window', 'window');

/**
 * Root node for all content in a web page.
 */
HtmlDocument get document =>
    JS('returns:HtmlDocument;depends:none;effects:none;gvn:true', 'document');

// Supoort to convert JS Promise to a Dart Future.
Future<T> promiseToFuture<T>(jsPromise) {
  var completer = new Completer<T>();

  var thenSuccessCode = (promiseValue) => completer.complete(promiseValue);
  var thenErrorCode = (promiseError) => completer.completeError(promiseError);

  JS("", "#.then(#, #)", jsPromise, convertDartClosureToJS(thenSuccessCode, 1),
      convertDartClosureToJS(thenErrorCode, 1));

  return completer.future;
}

// Supoort to convert JS Promise to a Dart Future<Map<String, dynamic>>.  Each property of the JS
// object is added to the Map as a key of type String with a value of type dynamic.
Future<Map<String, dynamic>> promiseToFutureAsMap(jsPromise) {
  var completer = new Completer<Map<String, dynamic>>();

  var thenSuccessCode = (promiseValue) =>
      completer.complete(convertNativeToDart_Dictionary(promiseValue));
  var thenErrorCode = (promiseError) => completer.completeError(promiseError);

  JS("", "#.then(#, #)", jsPromise, convertDartClosureToJS(thenSuccessCode, 1),
      convertDartClosureToJS(thenErrorCode, 1));

  return completer.future;
}

// Workaround for tags like <cite> that lack their own Element subclass --
// Dart issue 1990.
@Native("HTMLElement")
class HtmlElement extends Element implements NoncedElement {
  factory HtmlElement() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HtmlElement.created() : super.created();

  // From NoncedElement
  String nonce;
}

/**
 * Emitted for any setlike IDL entry needs a callback signature.
 * Today there is only one.
 */
typedef void FontFaceSetForEachCallback(
    FontFace fontFace, FontFace fontFaceAgain, FontFaceSet set);

WorkerGlobalScope get _workerSelf => JS('WorkerGlobalScope', 'self');

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AbortPaymentEvent")
class AbortPaymentEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory AbortPaymentEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory AbortPaymentEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return AbortPaymentEvent._create_1(type, eventInitDict_1);
  }
  static AbortPaymentEvent _create_1(type, eventInitDict) => JS(
      'AbortPaymentEvent', 'new AbortPaymentEvent(#,#)', type, eventInitDict);

  void respondWith(Future paymentAbortedResponse) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AbsoluteOrientationSensor")
class AbsoluteOrientationSensor extends OrientationSensor {
  // To suppress missing implicit constructor warnings.
  factory AbsoluteOrientationSensor._() {
    throw new UnsupportedError("Not supported");
  }

  factory AbsoluteOrientationSensor([Map sensorOptions]) {
    if (sensorOptions != null) {
      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
      return AbsoluteOrientationSensor._create_1(sensorOptions_1);
    }
    return AbsoluteOrientationSensor._create_2();
  }
  static AbsoluteOrientationSensor _create_1(sensorOptions) => JS(
      'AbsoluteOrientationSensor',
      'new AbsoluteOrientationSensor(#)',
      sensorOptions);
  static AbsoluteOrientationSensor _create_2() =>
      JS('AbsoluteOrientationSensor', 'new AbsoluteOrientationSensor()');
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class AbstractWorker extends Interceptor implements EventTarget {
  // To suppress missing implicit constructor warnings.
  factory AbstractWorker._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [AbstractWorker].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /// Stream of `error` events handled by this [AbstractWorker].
  Stream<Event> get onError => errorEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Accelerometer")
class Accelerometer extends Sensor {
  // To suppress missing implicit constructor warnings.
  factory Accelerometer._() {
    throw new UnsupportedError("Not supported");
  }

  factory Accelerometer([Map sensorOptions]) {
    if (sensorOptions != null) {
      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
      return Accelerometer._create_1(sensorOptions_1);
    }
    return Accelerometer._create_2();
  }
  static Accelerometer _create_1(sensorOptions) =>
      JS('Accelerometer', 'new Accelerometer(#)', sensorOptions);
  static Accelerometer _create_2() =>
      JS('Accelerometer', 'new Accelerometer()');

  final num x;

  final num y;

  final num z;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AccessibleNode")
class AccessibleNode extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory AccessibleNode._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> accessibleClickEvent =
      const EventStreamProvider<Event>('accessibleclick');

  static const EventStreamProvider<Event> accessibleContextMenuEvent =
      const EventStreamProvider<Event>('accessiblecontextmenu');

  static const EventStreamProvider<Event> accessibleDecrementEvent =
      const EventStreamProvider<Event>('accessibledecrement');

  static const EventStreamProvider<Event> accessibleFocusEvent =
      const EventStreamProvider<Event>('accessiblefocus');

  static const EventStreamProvider<Event> accessibleIncrementEvent =
      const EventStreamProvider<Event>('accessibleincrement');

  static const EventStreamProvider<Event> accessibleScrollIntoViewEvent =
      const EventStreamProvider<Event>('accessiblescrollintoview');

  factory AccessibleNode() {
    return AccessibleNode._create_1();
  }
  static AccessibleNode _create_1() =>
      JS('AccessibleNode', 'new AccessibleNode()');

  AccessibleNode activeDescendant;

  bool atomic;

  String autocomplete;

  bool busy;

  String checked;

  int colCount;

  int colIndex;

  int colSpan;

  AccessibleNodeList controls;

  String current;

  AccessibleNodeList describedBy;

  AccessibleNode details;

  bool disabled;

  AccessibleNode errorMessage;

  bool expanded;

  AccessibleNodeList flowTo;

  String hasPopUp;

  bool hidden;

  String invalid;

  String keyShortcuts;

  String label;

  AccessibleNodeList labeledBy;

  int level;

  String live;

  bool modal;

  bool multiline;

  bool multiselectable;

  String orientation;

  AccessibleNodeList owns;

  String placeholder;

  int posInSet;

  String pressed;

  bool readOnly;

  String relevant;

  bool required;

  String role;

  String roleDescription;

  int rowCount;

  int rowIndex;

  int rowSpan;

  bool selected;

  int setSize;

  String sort;

  num valueMax;

  num valueMin;

  num valueNow;

  String valueText;

  void appendChild(AccessibleNode child) native;

  Stream<Event> get onAccessibleClick => accessibleClickEvent.forTarget(this);

  Stream<Event> get onAccessibleContextMenu =>
      accessibleContextMenuEvent.forTarget(this);

  Stream<Event> get onAccessibleDecrement =>
      accessibleDecrementEvent.forTarget(this);

  Stream<Event> get onAccessibleFocus => accessibleFocusEvent.forTarget(this);

  Stream<Event> get onAccessibleIncrement =>
      accessibleIncrementEvent.forTarget(this);

  Stream<Event> get onAccessibleScrollIntoView =>
      accessibleScrollIntoViewEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AccessibleNodeList")
class AccessibleNodeList extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory AccessibleNodeList._() {
    throw new UnsupportedError("Not supported");
  }

  factory AccessibleNodeList([List<AccessibleNode> nodes]) {
    if (nodes != null) {
      return AccessibleNodeList._create_1(nodes);
    }
    return AccessibleNodeList._create_2();
  }
  static AccessibleNodeList _create_1(nodes) =>
      JS('AccessibleNodeList', 'new AccessibleNodeList(#)', nodes);
  static AccessibleNodeList _create_2() =>
      JS('AccessibleNodeList', 'new AccessibleNodeList()');

  int length;

  void __setter__(int index, AccessibleNode node) native;

  void add(AccessibleNode node, AccessibleNode before) native;

  AccessibleNode item(int index) native;

  void remove(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AmbientLightSensor")
class AmbientLightSensor extends Sensor {
  // To suppress missing implicit constructor warnings.
  factory AmbientLightSensor._() {
    throw new UnsupportedError("Not supported");
  }

  factory AmbientLightSensor([Map sensorOptions]) {
    if (sensorOptions != null) {
      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
      return AmbientLightSensor._create_1(sensorOptions_1);
    }
    return AmbientLightSensor._create_2();
  }
  static AmbientLightSensor _create_1(sensorOptions) =>
      JS('AmbientLightSensor', 'new AmbientLightSensor(#)', sensorOptions);
  static AmbientLightSensor _create_2() =>
      JS('AmbientLightSensor', 'new AmbientLightSensor()');

  final num illuminance;
}
// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLAnchorElement")
class AnchorElement extends HtmlElement implements HtmlHyperlinkElementUtils {
  // To suppress missing implicit constructor warnings.
  factory AnchorElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory AnchorElement({String href}) {
    AnchorElement e = JS('returns:AnchorElement;creates:AnchorElement;new:true',
        '#.createElement(#)', document, "a");
    if (href != null) e.href = href;
    return e;
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  AnchorElement.created() : super.created();

  String download;

  String hreflang;

  String referrerPolicy;

  String rel;

  String target;

  String type;

  // From HTMLHyperlinkElementUtils

  String hash;

  String host;

  String hostname;

  String href;

  final String origin;

  String password;

  String pathname;

  String port;

  String protocol;

  String search;

  String username;

  String toString() => JS('String', 'String(#)', this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Animation")
class Animation extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory Animation._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> cancelEvent =
      const EventStreamProvider<Event>('cancel');

  static const EventStreamProvider<Event> finishEvent =
      const EventStreamProvider<Event>('finish');

  factory Animation(
      [AnimationEffectReadOnly effect, AnimationTimeline timeline]) {
    if (timeline != null) {
      return Animation._create_1(effect, timeline);
    }
    if (effect != null) {
      return Animation._create_2(effect);
    }
    return Animation._create_3();
  }
  static Animation _create_1(effect, timeline) =>
      JS('Animation', 'new Animation(#,#)', effect, timeline);
  static Animation _create_2(effect) =>
      JS('Animation', 'new Animation(#)', effect);
  static Animation _create_3() => JS('Animation', 'new Animation()');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(document.body.animate)');

  num currentTime;

  AnimationEffectReadOnly effect;

  Future<Animation> get finished =>
      promiseToFuture<Animation>(JS("", "#.finished", this));

  String id;

  final String playState;

  num playbackRate;

  Future<Animation> get ready =>
      promiseToFuture<Animation>(JS("", "#.ready", this));

  num startTime;

  final AnimationTimeline timeline;

  void cancel() native;

  void finish() native;

  void pause() native;

  void play() native;

  void reverse() native;

  Stream<Event> get onCancel => cancelEvent.forTarget(this);

  Stream<Event> get onFinish => finishEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AnimationEffectReadOnly")
class AnimationEffectReadOnly extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory AnimationEffectReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  final AnimationEffectTimingReadOnly timing;

  Map getComputedTiming() {
    return convertNativeToDart_Dictionary(_getComputedTiming_1());
  }

  @JSName('getComputedTiming')
  _getComputedTiming_1() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AnimationEffectTiming")
class AnimationEffectTiming extends AnimationEffectTimingReadOnly {
  // To suppress missing implicit constructor warnings.
  factory AnimationEffectTiming._() {
    throw new UnsupportedError("Not supported");
  }

  // Shadowing definition.
  num get delay => JS("num", "#.delay", this);

  set delay(num value) {
    JS("void", "#.delay = #", this, value);
  }

  // Shadowing definition.
  String get direction => JS("String", "#.direction", this);

  set direction(String value) {
    JS("void", "#.direction = #", this, value);
  }

  // Shadowing definition.
  Object get duration => JS("Object", "#.duration", this);

  set duration(Object value) {
    JS("void", "#.duration = #", this, value);
  }

  // Shadowing definition.
  String get easing => JS("String", "#.easing", this);

  set easing(String value) {
    JS("void", "#.easing = #", this, value);
  }

  // Shadowing definition.
  num get endDelay => JS("num", "#.endDelay", this);

  set endDelay(num value) {
    JS("void", "#.endDelay = #", this, value);
  }

  // Shadowing definition.
  String get fill => JS("String", "#.fill", this);

  set fill(String value) {
    JS("void", "#.fill = #", this, value);
  }

  // Shadowing definition.
  num get iterationStart => JS("num", "#.iterationStart", this);

  set iterationStart(num value) {
    JS("void", "#.iterationStart = #", this, value);
  }

  // Shadowing definition.
  num get iterations => JS("num", "#.iterations", this);

  set iterations(num value) {
    JS("void", "#.iterations = #", this, value);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AnimationEffectTimingReadOnly")
class AnimationEffectTimingReadOnly extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory AnimationEffectTimingReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  final num delay;

  final String direction;

  final Object duration;

  final String easing;

  final num endDelay;

  final String fill;

  final num iterationStart;

  final num iterations;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AnimationEvent")
class AnimationEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory AnimationEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory AnimationEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return AnimationEvent._create_1(type, eventInitDict_1);
    }
    return AnimationEvent._create_2(type);
  }
  static AnimationEvent _create_1(type, eventInitDict) =>
      JS('AnimationEvent', 'new AnimationEvent(#,#)', type, eventInitDict);
  static AnimationEvent _create_2(type) =>
      JS('AnimationEvent', 'new AnimationEvent(#)', type);

  final String animationName;

  final num elapsedTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AnimationPlaybackEvent")
class AnimationPlaybackEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory AnimationPlaybackEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory AnimationPlaybackEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return AnimationPlaybackEvent._create_1(type, eventInitDict_1);
    }
    return AnimationPlaybackEvent._create_2(type);
  }
  static AnimationPlaybackEvent _create_1(type, eventInitDict) => JS(
      'AnimationPlaybackEvent',
      'new AnimationPlaybackEvent(#,#)',
      type,
      eventInitDict);
  static AnimationPlaybackEvent _create_2(type) =>
      JS('AnimationPlaybackEvent', 'new AnimationPlaybackEvent(#)', type);

  final num currentTime;

  final num timelineTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AnimationTimeline")
class AnimationTimeline extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory AnimationTimeline._() {
    throw new UnsupportedError("Not supported");
  }

  final num currentTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AnimationWorkletGlobalScope")
class AnimationWorkletGlobalScope extends WorkletGlobalScope {
  // To suppress missing implicit constructor warnings.
  factory AnimationWorkletGlobalScope._() {
    throw new UnsupportedError("Not supported");
  }

  void registerAnimator(String name, Object animatorConstructor) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * ApplicationCache is accessed via [Window.applicationCache].
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.OPERA)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
@Native("ApplicationCache,DOMApplicationCache,OfflineResourceList")
class ApplicationCache extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory ApplicationCache._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `cached` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> cachedEvent =
      const EventStreamProvider<Event>('cached');

  /**
   * Static factory designed to expose `checking` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> checkingEvent =
      const EventStreamProvider<Event>('checking');

  /**
   * Static factory designed to expose `downloading` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> downloadingEvent =
      const EventStreamProvider<Event>('downloading');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `noupdate` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> noUpdateEvent =
      const EventStreamProvider<Event>('noupdate');

  /**
   * Static factory designed to expose `obsolete` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> obsoleteEvent =
      const EventStreamProvider<Event>('obsolete');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> progressEvent =
      const EventStreamProvider<ProgressEvent>('progress');

  /**
   * Static factory designed to expose `updateready` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> updateReadyEvent =
      const EventStreamProvider<Event>('updateready');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.applicationCache)');

  static const int CHECKING = 2;

  static const int DOWNLOADING = 3;

  static const int IDLE = 1;

  static const int OBSOLETE = 5;

  static const int UNCACHED = 0;

  static const int UPDATEREADY = 4;

  final int status;

  void abort() native;

  void swapCache() native;

  void update() native;

  /// Stream of `cached` events handled by this [ApplicationCache].
  Stream<Event> get onCached => cachedEvent.forTarget(this);

  /// Stream of `checking` events handled by this [ApplicationCache].
  Stream<Event> get onChecking => checkingEvent.forTarget(this);

  /// Stream of `downloading` events handled by this [ApplicationCache].
  Stream<Event> get onDownloading => downloadingEvent.forTarget(this);

  /// Stream of `error` events handled by this [ApplicationCache].
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `noupdate` events handled by this [ApplicationCache].
  Stream<Event> get onNoUpdate => noUpdateEvent.forTarget(this);

  /// Stream of `obsolete` events handled by this [ApplicationCache].
  Stream<Event> get onObsolete => obsoleteEvent.forTarget(this);

  /// Stream of `progress` events handled by this [ApplicationCache].
  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);

  /// Stream of `updateready` events handled by this [ApplicationCache].
  Stream<Event> get onUpdateReady => updateReadyEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ApplicationCacheErrorEvent")
class ApplicationCacheErrorEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory ApplicationCacheErrorEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory ApplicationCacheErrorEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return ApplicationCacheErrorEvent._create_1(type, eventInitDict_1);
    }
    return ApplicationCacheErrorEvent._create_2(type);
  }
  static ApplicationCacheErrorEvent _create_1(type, eventInitDict) => JS(
      'ApplicationCacheErrorEvent',
      'new ApplicationCacheErrorEvent(#,#)',
      type,
      eventInitDict);
  static ApplicationCacheErrorEvent _create_2(type) => JS(
      'ApplicationCacheErrorEvent', 'new ApplicationCacheErrorEvent(#)', type);

  final String message;

  final String reason;

  final int status;

  final String url;
}
// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * DOM Area Element, which links regions of an image map with a hyperlink.
 *
 * The element can also define an uninteractive region of the map.
 *
 * See also:
 *
 * * [`<area>`](https://developer.mozilla.org/en-US/docs/HTML/Element/area)
 * on MDN.
 */
@Native("HTMLAreaElement")
class AreaElement extends HtmlElement implements HtmlHyperlinkElementUtils {
  // To suppress missing implicit constructor warnings.
  factory AreaElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory AreaElement() => JS(
      'returns:AreaElement;creates:AreaElement;new:true',
      '#.createElement(#)',
      document,
      "area");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  AreaElement.created() : super.created();

  String alt;

  String coords;

  String download;

  String referrerPolicy;

  String rel;

  String shape;

  String target;

  // From HTMLHyperlinkElementUtils

  String hash;

  String host;

  String hostname;

  String href;

  final String origin;

  String password;

  String pathname;

  String port;

  String protocol;

  String search;

  String username;

  String toString() => JS('String', 'String(#)', this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLAudioElement")
class AudioElement extends MediaElement {
  factory AudioElement._([String src]) {
    if (src != null) {
      return AudioElement._create_1(src);
    }
    return AudioElement._create_2();
  }
  static AudioElement _create_1(src) => JS('AudioElement', 'new Audio(#)', src);
  static AudioElement _create_2() => JS('AudioElement', 'new Audio()');
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  AudioElement.created() : super.created();

  factory AudioElement([String src]) => new AudioElement._(src);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AuthenticatorAssertionResponse")
class AuthenticatorAssertionResponse extends AuthenticatorResponse {
  // To suppress missing implicit constructor warnings.
  factory AuthenticatorAssertionResponse._() {
    throw new UnsupportedError("Not supported");
  }

  final ByteBuffer authenticatorData;

  final ByteBuffer signature;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AuthenticatorAttestationResponse")
class AuthenticatorAttestationResponse extends AuthenticatorResponse {
  // To suppress missing implicit constructor warnings.
  factory AuthenticatorAttestationResponse._() {
    throw new UnsupportedError("Not supported");
  }

  final ByteBuffer attestationObject;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("AuthenticatorResponse")
class AuthenticatorResponse extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory AuthenticatorResponse._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('clientDataJSON')
  final ByteBuffer clientDataJson;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLBRElement")
class BRElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory BRElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory BRElement() => JS('returns:BRElement;creates:BRElement;new:true',
      '#.createElement(#)', document, "br");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  BRElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BackgroundFetchClickEvent")
class BackgroundFetchClickEvent extends BackgroundFetchEvent {
  // To suppress missing implicit constructor warnings.
  factory BackgroundFetchClickEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory BackgroundFetchClickEvent(String type, Map init) {
    var init_1 = convertDartToNative_Dictionary(init);
    return BackgroundFetchClickEvent._create_1(type, init_1);
  }
  static BackgroundFetchClickEvent _create_1(type, init) => JS(
      'BackgroundFetchClickEvent',
      'new BackgroundFetchClickEvent(#,#)',
      type,
      init);

  final String state;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BackgroundFetchEvent")
class BackgroundFetchEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory BackgroundFetchEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory BackgroundFetchEvent(String type, Map init) {
    var init_1 = convertDartToNative_Dictionary(init);
    return BackgroundFetchEvent._create_1(type, init_1);
  }
  static BackgroundFetchEvent _create_1(type, init) =>
      JS('BackgroundFetchEvent', 'new BackgroundFetchEvent(#,#)', type, init);

  final String id;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BackgroundFetchFailEvent")
class BackgroundFetchFailEvent extends BackgroundFetchEvent {
  // To suppress missing implicit constructor warnings.
  factory BackgroundFetchFailEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory BackgroundFetchFailEvent(String type, Map init) {
    var init_1 = convertDartToNative_Dictionary(init);
    return BackgroundFetchFailEvent._create_1(type, init_1);
  }
  static BackgroundFetchFailEvent _create_1(type, init) => JS(
      'BackgroundFetchFailEvent',
      'new BackgroundFetchFailEvent(#,#)',
      type,
      init);

  final List<BackgroundFetchSettledFetch> fetches;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BackgroundFetchFetch")
class BackgroundFetchFetch extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory BackgroundFetchFetch._() {
    throw new UnsupportedError("Not supported");
  }

  final _Request request;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BackgroundFetchManager")
class BackgroundFetchManager extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory BackgroundFetchManager._() {
    throw new UnsupportedError("Not supported");
  }

  Future<BackgroundFetchRegistration> fetch(String id, Object requests,
      [Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture<BackgroundFetchRegistration>(
        JS("", "#.fetch(#, #, #)", this, id, requests, options_dict));
  }

  Future<BackgroundFetchRegistration> get(String id) =>
      promiseToFuture<BackgroundFetchRegistration>(
          JS("", "#.get(#)", this, id));

  Future<List<String>> getIds() =>
      promiseToFuture<List<String>>(JS("", "#.getIds()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BackgroundFetchRegistration")
class BackgroundFetchRegistration extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory BackgroundFetchRegistration._() {
    throw new UnsupportedError("Not supported");
  }

  final int downloadTotal;

  final int downloaded;

  final String id;

  final String title;

  final int totalDownloadSize;

  final int uploadTotal;

  final int uploaded;

  Future<bool> abort() => promiseToFuture<bool>(JS("", "#.abort()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BackgroundFetchSettledFetch")
class BackgroundFetchSettledFetch extends BackgroundFetchFetch {
  // To suppress missing implicit constructor warnings.
  factory BackgroundFetchSettledFetch._() {
    throw new UnsupportedError("Not supported");
  }

  factory BackgroundFetchSettledFetch(_Request request, _Response response) {
    return BackgroundFetchSettledFetch._create_1(request, response);
  }
  static BackgroundFetchSettledFetch _create_1(request, response) => JS(
      'BackgroundFetchSettledFetch',
      'new BackgroundFetchSettledFetch(#,#)',
      request,
      response);

  final _Response response;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BackgroundFetchedEvent")
class BackgroundFetchedEvent extends BackgroundFetchEvent {
  // To suppress missing implicit constructor warnings.
  factory BackgroundFetchedEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory BackgroundFetchedEvent(String type, Map init) {
    var init_1 = convertDartToNative_Dictionary(init);
    return BackgroundFetchedEvent._create_1(type, init_1);
  }
  static BackgroundFetchedEvent _create_1(type, init) => JS(
      'BackgroundFetchedEvent', 'new BackgroundFetchedEvent(#,#)', type, init);

  final List<BackgroundFetchSettledFetch> fetches;

  Future updateUI(String title) =>
      promiseToFuture(JS("", "#.updateUI(#)", this, title));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#barprop
@deprecated // standard
@Native("BarProp")
class BarProp extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory BarProp._() {
    throw new UnsupportedError("Not supported");
  }

  final bool visible;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BarcodeDetector")
class BarcodeDetector extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory BarcodeDetector._() {
    throw new UnsupportedError("Not supported");
  }

  factory BarcodeDetector() {
    return BarcodeDetector._create_1();
  }
  static BarcodeDetector _create_1() =>
      JS('BarcodeDetector', 'new BarcodeDetector()');

  Future<List<DetectedBarcode>> detect(/*ImageBitmapSource*/ image) =>
      promiseToFuture<List<DetectedBarcode>>(
          JS("", "#.detect(#)", this, image));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLBaseElement")
class BaseElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory BaseElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory BaseElement() => JS(
      'returns:BaseElement;creates:BaseElement;new:true',
      '#.createElement(#)',
      document,
      "base");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  BaseElement.created() : super.created();

  String href;

  String target;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BatteryManager")
class BatteryManager extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory BatteryManager._() {
    throw new UnsupportedError("Not supported");
  }

  final bool charging;

  final num chargingTime;

  final num dischargingTime;

  final num level;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BeforeInstallPromptEvent")
class BeforeInstallPromptEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory BeforeInstallPromptEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory BeforeInstallPromptEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return BeforeInstallPromptEvent._create_1(type, eventInitDict_1);
    }
    return BeforeInstallPromptEvent._create_2(type);
  }
  static BeforeInstallPromptEvent _create_1(type, eventInitDict) => JS(
      'BeforeInstallPromptEvent',
      'new BeforeInstallPromptEvent(#,#)',
      type,
      eventInitDict);
  static BeforeInstallPromptEvent _create_2(type) =>
      JS('BeforeInstallPromptEvent', 'new BeforeInstallPromptEvent(#)', type);

  final List<String> platforms;

  Future<Map<String, dynamic>> get userChoice =>
      promiseToFutureAsMap(JS("", "#.userChoice", this));

  Future prompt() => promiseToFuture(JS("", "#.prompt()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BeforeUnloadEvent")
class BeforeUnloadEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory BeforeUnloadEvent._() {
    throw new UnsupportedError("Not supported");
  }

  // Shadowing definition.
  String get returnValue => JS("String", "#.returnValue", this);

  set returnValue(String value) {
    JS("void", "#.returnValue = #", this, value);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Blob")
class Blob extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Blob._() {
    throw new UnsupportedError("Not supported");
  }

  final int size;

  final String type;

  Blob slice([int start, int end, String contentType]) native;

  factory Blob(List blobParts, [String type, String endings]) {
    // TODO: validate that blobParts is a JS Array and convert if not.
    // TODO: any coercions on the elements of blobParts, e.g. coerce a typed
    // array to ArrayBuffer if it is a total view.
    if (type == null && endings == null) {
      return _create_1(blobParts);
    }
    var bag = _create_bag();
    if (type != null) _bag_set(bag, 'type', type);
    if (endings != null) _bag_set(bag, 'endings', endings);
    return _create_2(blobParts, bag);
  }

  static _create_1(parts) => JS('Blob', 'new self.Blob(#)', parts);
  static _create_2(parts, bag) => JS('Blob', 'new self.Blob(#, #)', parts, bag);

  static _create_bag() => JS('var', '{}');
  static _bag_set(bag, key, value) {
    JS('void', '#[#] = #', bag, key, value);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void BlobCallback(Blob blob);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BlobEvent")
class BlobEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory BlobEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory BlobEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return BlobEvent._create_1(type, eventInitDict_1);
  }
  static BlobEvent _create_1(type, eventInitDict) =>
      JS('BlobEvent', 'new BlobEvent(#,#)', type, eventInitDict);

  final Blob data;

  final num timecode;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BluetoothRemoteGATTDescriptor")
class BluetoothRemoteGattDescriptor extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory BluetoothRemoteGattDescriptor._() {
    throw new UnsupportedError("Not supported");
  }

  final _BluetoothRemoteGATTCharacteristic characteristic;

  final String uuid;

  final ByteData value;

  Future readValue() => promiseToFuture(JS("", "#.readValue()", this));

  Future writeValue(/*BufferSource*/ value) =>
      promiseToFuture(JS("", "#.writeValue(#)", this, value));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Body")
class Body extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Body._() {
    throw new UnsupportedError("Not supported");
  }

  final bool bodyUsed;

  Future arrayBuffer() => promiseToFuture(JS("", "#.arrayBuffer()", this));

  Future<Blob> blob() => promiseToFuture<Blob>(JS("", "#.blob()", this));

  Future<FormData> formData() =>
      promiseToFuture<FormData>(JS("", "#.formData()", this));

  Future json() => promiseToFuture(JS("", "#.json()", this));

  Future<String> text() => promiseToFuture<String>(JS("", "#.text()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLBodyElement")
class BodyElement extends HtmlElement implements WindowEventHandlers {
  // To suppress missing implicit constructor warnings.
  factory BodyElement._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `blur` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> blurEvent =
      const EventStreamProvider<Event>('blur');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `focus` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> focusEvent =
      const EventStreamProvider<Event>('focus');

  /**
   * Static factory designed to expose `hashchange` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> hashChangeEvent =
      const EventStreamProvider<Event>('hashchange');

  /**
   * Static factory designed to expose `load` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> loadEvent =
      const EventStreamProvider<Event>('load');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `offline` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> offlineEvent =
      const EventStreamProvider<Event>('offline');

  /**
   * Static factory designed to expose `online` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> onlineEvent =
      const EventStreamProvider<Event>('online');

  /**
   * Static factory designed to expose `popstate` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<PopStateEvent> popStateEvent =
      const EventStreamProvider<PopStateEvent>('popstate');

  /**
   * Static factory designed to expose `resize` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> resizeEvent =
      const EventStreamProvider<Event>('resize');

  static const EventStreamProvider<Event> scrollEvent =
      const EventStreamProvider<Event>('scroll');

  /**
   * Static factory designed to expose `storage` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<StorageEvent> storageEvent =
      const EventStreamProvider<StorageEvent>('storage');

  /**
   * Static factory designed to expose `unload` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> unloadEvent =
      const EventStreamProvider<Event>('unload');

  factory BodyElement() => JS(
      'returns:BodyElement;creates:BodyElement;new:true',
      '#.createElement(#)',
      document,
      "body");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  BodyElement.created() : super.created();

  /// Stream of `blur` events handled by this [BodyElement].
  ElementStream<Event> get onBlur => blurEvent.forElement(this);

  /// Stream of `error` events handled by this [BodyElement].
  ElementStream<Event> get onError => errorEvent.forElement(this);

  /// Stream of `focus` events handled by this [BodyElement].
  ElementStream<Event> get onFocus => focusEvent.forElement(this);

  /// Stream of `hashchange` events handled by this [BodyElement].
  ElementStream<Event> get onHashChange => hashChangeEvent.forElement(this);

  /// Stream of `load` events handled by this [BodyElement].
  ElementStream<Event> get onLoad => loadEvent.forElement(this);

  /// Stream of `message` events handled by this [BodyElement].
  ElementStream<MessageEvent> get onMessage => messageEvent.forElement(this);

  /// Stream of `offline` events handled by this [BodyElement].
  ElementStream<Event> get onOffline => offlineEvent.forElement(this);

  /// Stream of `online` events handled by this [BodyElement].
  ElementStream<Event> get onOnline => onlineEvent.forElement(this);

  /// Stream of `popstate` events handled by this [BodyElement].
  ElementStream<PopStateEvent> get onPopState => popStateEvent.forElement(this);

  /// Stream of `resize` events handled by this [BodyElement].
  ElementStream<Event> get onResize => resizeEvent.forElement(this);

  ElementStream<Event> get onScroll => scrollEvent.forElement(this);

  /// Stream of `storage` events handled by this [BodyElement].
  ElementStream<StorageEvent> get onStorage => storageEvent.forElement(this);

  /// Stream of `unload` events handled by this [BodyElement].
  ElementStream<Event> get onUnload => unloadEvent.forElement(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BroadcastChannel")
class BroadcastChannel extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory BroadcastChannel._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  factory BroadcastChannel(String name) {
    return BroadcastChannel._create_1(name);
  }
  static BroadcastChannel _create_1(name) =>
      JS('BroadcastChannel', 'new BroadcastChannel(#)', name);

  final String name;

  void close() native;

  void postMessage(Object message) native;

  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BudgetState")
class BudgetState extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory BudgetState._() {
    throw new UnsupportedError("Not supported");
  }

  final num budgetAt;

  final int time;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLButtonElement")
class ButtonElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ButtonElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory ButtonElement() => JS(
      'returns:ButtonElement;creates:ButtonElement;new:true',
      '#.createElement(#)',
      document,
      "button");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ButtonElement.created() : super.created();

  bool autofocus;

  bool disabled;

  final FormElement form;

  String formAction;

  String formEnctype;

  String formMethod;

  bool formNoValidate;

  String formTarget;

  @Unstable()
  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> labels;

  String name;

  String type;

  final String validationMessage;

  final ValidityState validity;

  String value;

  final bool willValidate;

  bool checkValidity() native;

  bool reportValidity() native;

  void setCustomValidity(String error) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://dom.spec.whatwg.org/#cdatasection
@deprecated // deprecated
@Native("CDATASection")
class CDataSection extends Text {
  // To suppress missing implicit constructor warnings.
  factory CDataSection._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CacheStorage")
class CacheStorage extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CacheStorage._() {
    throw new UnsupportedError("Not supported");
  }

  Future delete(String cacheName) =>
      promiseToFuture(JS("", "#.delete(#)", this, cacheName));

  Future has(String cacheName) =>
      promiseToFuture(JS("", "#.has(#)", this, cacheName));

  Future keys() => promiseToFuture(JS("", "#.keys()", this));

  Future match(/*RequestInfo*/ request, [Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(
        JS("", "#.match(#, #)", this, request, options_dict));
  }

  Future open(String cacheName) =>
      promiseToFuture(JS("", "#.open(#)", this, cacheName));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CanMakePaymentEvent")
class CanMakePaymentEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory CanMakePaymentEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory CanMakePaymentEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return CanMakePaymentEvent._create_1(type, eventInitDict_1);
  }
  static CanMakePaymentEvent _create_1(type, eventInitDict) => JS(
      'CanMakePaymentEvent',
      'new CanMakePaymentEvent(#,#)',
      type,
      eventInitDict);

  final List methodData;

  final List modifiers;

  final String paymentRequestOrigin;

  final String topLevelOrigin;

  void respondWith(Future canMakePaymentResponse) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CanvasCaptureMediaStreamTrack")
class CanvasCaptureMediaStreamTrack extends MediaStreamTrack {
  // To suppress missing implicit constructor warnings.
  factory CanvasCaptureMediaStreamTrack._() {
    throw new UnsupportedError("Not supported");
  }

  final CanvasElement canvas;

  void requestFrame() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLCanvasElement")
class CanvasElement extends HtmlElement implements CanvasImageSource {
  // To suppress missing implicit constructor warnings.
  factory CanvasElement._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `webglcontextlost` events to event
   * handlers that are not necessarily instances of [CanvasElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<gl.ContextEvent> webGlContextLostEvent =
      const EventStreamProvider<gl.ContextEvent>('webglcontextlost');

  /**
   * Static factory designed to expose `webglcontextrestored` events to event
   * handlers that are not necessarily instances of [CanvasElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<gl.ContextEvent> webGlContextRestoredEvent =
      const EventStreamProvider<gl.ContextEvent>('webglcontextrestored');

  factory CanvasElement({int width, int height}) {
    CanvasElement e = JS('returns:CanvasElement;creates:CanvasElement;new:true',
        '#.createElement(#)', document, "canvas");
    if (width != null) e.width = width;
    if (height != null) e.height = height;
    return e;
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  CanvasElement.created() : super.created();

  /// The height of this canvas element in CSS pixels.
  int height;

  /// The width of this canvas element in CSS pixels.
  int width;

  MediaStream captureStream([num frameRate]) native;

  @Creates('CanvasRenderingContext2D|RenderingContext|RenderingContext2')
  @Returns('CanvasRenderingContext2D|RenderingContext|RenderingContext2|Null')
  Object getContext(String contextId, [Map attributes]) {
    if (attributes != null) {
      var attributes_1 = convertDartToNative_Dictionary(attributes);
      return _getContext_1(contextId, attributes_1);
    }
    return _getContext_2(contextId);
  }

  @JSName('getContext')
  @Creates('CanvasRenderingContext2D|RenderingContext|RenderingContext2')
  @Returns('CanvasRenderingContext2D|RenderingContext|RenderingContext2|Null')
  Object _getContext_1(contextId, attributes) native;
  @JSName('getContext')
  @Creates('CanvasRenderingContext2D|RenderingContext|RenderingContext2')
  @Returns('CanvasRenderingContext2D|RenderingContext|RenderingContext2|Null')
  Object _getContext_2(contextId) native;

  void toBlob(BlobCallback callback, String type, [Object arguments]) native;

  @JSName('toDataURL')
  String _toDataUrl(String type, [arguments_OR_quality]) native;

  OffscreenCanvas transferControlToOffscreen() native;

  /// Stream of `webglcontextlost` events handled by this [CanvasElement].
  ElementStream<gl.ContextEvent> get onWebGlContextLost =>
      webGlContextLostEvent.forElement(this);

  /// Stream of `webglcontextrestored` events handled by this [CanvasElement].
  ElementStream<gl.ContextEvent> get onWebGlContextRestored =>
      webGlContextRestoredEvent.forElement(this);

  /** An API for drawing on this canvas. */
  CanvasRenderingContext2D get context2D =>
      JS('Null|CanvasRenderingContext2D', '#.getContext(#)', this, '2d');

  /**
   * Returns a new Web GL context for this canvas.
   *
   * ## Other resources
   *
   * * [WebGL fundamentals](http://www.html5rocks.com/en/tutorials/webgl/webgl_fundamentals/)
   *   from HTML5Rocks.
   * * [WebGL homepage](http://get.webgl.org/).
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  gl.RenderingContext getContext3d(
      {alpha: true,
      depth: true,
      stencil: false,
      antialias: true,
      premultipliedAlpha: true,
      preserveDrawingBuffer: false}) {
    var options = {
      'alpha': alpha,
      'depth': depth,
      'stencil': stencil,
      'antialias': antialias,
      'premultipliedAlpha': premultipliedAlpha,
      'preserveDrawingBuffer': preserveDrawingBuffer,
    };
    var context = getContext('webgl', options);
    if (context == null) {
      context = getContext('experimental-webgl', options);
    }
    return context;
  }

  /**
   * Returns a data URI containing a representation of the image in the
   * format specified by type (defaults to 'image/png').
   *
   * Data Uri format is as follow
   * `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`
   *
   * Optional parameter [quality] in the range of 0.0 and 1.0 can be used when
   * requesting [type] 'image/jpeg' or 'image/webp'. If [quality] is not passed
   * the default value is used. Note: the default value varies by browser.
   *
   * If the height or width of this canvas element is 0, then 'data:' is
   * returned, representing no data.
   *
   * If the type requested is not 'image/png', and the returned value is
   * 'data:image/png', then the requested type is not supported.
   *
   * Example usage:
   *
   *     CanvasElement canvas = new CanvasElement();
   *     var ctx = canvas.context2D
   *     ..fillStyle = "rgb(200,0,0)"
   *     ..fillRect(10, 10, 55, 50);
   *     var dataUrl = canvas.toDataUrl("image/jpeg", 0.95);
   *     // The Data Uri would look similar to
   *     // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
   *     // AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
   *     // 9TXL0Y4OHwAAAABJRU5ErkJggg=='
   *     //Create a new image element from the data URI.
   *     var img = new ImageElement();
   *     img.src = dataUrl;
   *     document.body.children.add(img);
   *
   * See also:
   *
   * * [Data URI Scheme](http://en.wikipedia.org/wiki/Data_URI_scheme) from Wikipedia.
   *
   * * [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/DOM/HTMLCanvasElement) from MDN.
   *
   * * [toDataUrl](http://dev.w3.org/html5/spec/the-canvas-element.html#dom-canvas-todataurl) from W3C.
   */
  String toDataUrl([String type = 'image/png', num quality]) =>
      _toDataUrl(type, quality);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * An opaque canvas object representing a gradient.
 *
 * Created by calling [createLinearGradient] or [createRadialGradient] on a
 * [CanvasRenderingContext2D] object.
 *
 * Example usage:
 *
 *     var canvas = new CanvasElement(width: 600, height: 600);
 *     var ctx = canvas.context2D;
 *     ctx.clearRect(0, 0, 600, 600);
 *     ctx.save();
 *     // Create radial gradient.
 *     CanvasGradient gradient = ctx.createRadialGradient(0, 0, 0, 0, 0, 600);
 *     gradient.addColorStop(0, '#000');
 *     gradient.addColorStop(1, 'rgb(255, 255, 255)');
 *     // Assign gradients to fill.
 *     ctx.fillStyle = gradient;
 *     // Draw a rectangle with a gradient fill.
 *     ctx.fillRect(0, 0, 600, 600);
 *     ctx.save();
 *     document.body.children.add(canvas);
 *
 * See also:
 *
 * * [CanvasGradient](https://developer.mozilla.org/en-US/docs/DOM/CanvasGradient) from MDN.
 * * [CanvasGradient](https://html.spec.whatwg.org/multipage/scripting.html#canvasgradient)
 *   from WHATWG.
 * * [CanvasGradient](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvasgradient) from W3C.
 */
@Native("CanvasGradient")
class CanvasGradient extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CanvasGradient._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Adds a color stop to this gradient at the offset.
   *
   * The [offset] can range between 0.0 and 1.0.
   *
   * See also:
   *
   * * [Multiple Color Stops](https://developer.mozilla.org/en-US/docs/CSS/linear-gradient#Gradient_with_multiple_color_stops) from MDN.
   */
  void addColorStop(num offset, String color) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * An opaque object representing a pattern of image, canvas, or video.
 *
 * Created by calling [createPattern] on a [CanvasRenderingContext2D] object.
 *
 * Example usage:
 *
 *     var canvas = new CanvasElement(width: 600, height: 600);
 *     var ctx = canvas.context2D;
 *     var img = new ImageElement();
 *     // Image src needs to be loaded before pattern is applied.
 *     img.onLoad.listen((event) {
 *       // When the image is loaded, create a pattern
 *       // from the ImageElement.
 *       CanvasPattern pattern = ctx.createPattern(img, 'repeat');
 *       ctx.rect(0, 0, canvas.width, canvas.height);
 *       ctx.fillStyle = pattern;
 *       ctx.fill();
 *     });
 *     img.src = "images/foo.jpg";
 *     document.body.children.add(canvas);
 *
 * See also:
 * * [CanvasPattern](https://developer.mozilla.org/en-US/docs/DOM/CanvasPattern) from MDN.
 * * [CanvasPattern](https://html.spec.whatwg.org/multipage/scripting.html#canvaspattern)
 *   from WHATWG.
 * * [CanvasPattern](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvaspattern) from W3C.
 */
@Native("CanvasPattern")
class CanvasPattern extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CanvasPattern._() {
    throw new UnsupportedError("Not supported");
  }

  void setTransform(Matrix transform) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class CanvasRenderingContext {
  CanvasElement get canvas;
}

@Native("CanvasRenderingContext2D")
class CanvasRenderingContext2D extends Interceptor
    implements CanvasRenderingContext {
  // To suppress missing implicit constructor warnings.
  factory CanvasRenderingContext2D._() {
    throw new UnsupportedError("Not supported");
  }

  final CanvasElement canvas;

  Matrix currentTransform;

  String direction;

  @Creates('String|CanvasGradient|CanvasPattern')
  @Returns('String|CanvasGradient|CanvasPattern')
  Object fillStyle;

  String filter;

  String font;

  num globalAlpha;

  String globalCompositeOperation;

  /**
   * Whether images and patterns on this canvas will be smoothed when this
   * canvas is scaled.
   *
   * ## Other resources
   *
   * * [Image
   *   smoothing](https://html.spec.whatwg.org/multipage/scripting.html#image-smoothing)
   *   from WHATWG.
   */
  bool imageSmoothingEnabled;

  String imageSmoothingQuality;

  String lineCap;

  String lineJoin;

  num lineWidth;

  num miterLimit;

  num shadowBlur;

  String shadowColor;

  num shadowOffsetX;

  num shadowOffsetY;

  @Creates('String|CanvasGradient|CanvasPattern')
  @Returns('String|CanvasGradient|CanvasPattern')
  Object strokeStyle;

  String textAlign;

  String textBaseline;

  void addHitRegion([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      _addHitRegion_1(options_1);
      return;
    }
    _addHitRegion_2();
    return;
  }

  @JSName('addHitRegion')
  void _addHitRegion_1(options) native;
  @JSName('addHitRegion')
  void _addHitRegion_2() native;

  void beginPath() native;

  void clearHitRegions() native;

  void clearRect(num x, num y, num width, num height) native;

  void clip([path_OR_winding, String winding]) native;

  @Creates('ImageData|=Object')
  ImageData createImageData(data_OR_imagedata_OR_sw,
      [int sh_OR_sw,
      imageDataColorSettings_OR_sh,
      Map imageDataColorSettings]) {
    if ((data_OR_imagedata_OR_sw is ImageData) &&
        sh_OR_sw == null &&
        imageDataColorSettings_OR_sh == null &&
        imageDataColorSettings == null) {
      var imagedata_1 = convertDartToNative_ImageData(data_OR_imagedata_OR_sw);
      return convertNativeToDart_ImageData(_createImageData_1(imagedata_1));
    }
    if (sh_OR_sw != null &&
        (data_OR_imagedata_OR_sw is int) &&
        imageDataColorSettings_OR_sh == null &&
        imageDataColorSettings == null) {
      return convertNativeToDart_ImageData(
          _createImageData_2(data_OR_imagedata_OR_sw, sh_OR_sw));
    }
    if ((imageDataColorSettings_OR_sh is Map) &&
        sh_OR_sw != null &&
        (data_OR_imagedata_OR_sw is int) &&
        imageDataColorSettings == null) {
      var imageDataColorSettings_1 =
          convertDartToNative_Dictionary(imageDataColorSettings_OR_sh);
      return convertNativeToDart_ImageData(_createImageData_3(
          data_OR_imagedata_OR_sw, sh_OR_sw, imageDataColorSettings_1));
    }
    if ((imageDataColorSettings_OR_sh is int) &&
        sh_OR_sw != null &&
        data_OR_imagedata_OR_sw != null &&
        imageDataColorSettings == null) {
      return convertNativeToDart_ImageData(_createImageData_4(
          data_OR_imagedata_OR_sw, sh_OR_sw, imageDataColorSettings_OR_sh));
    }
    if (imageDataColorSettings != null &&
        (imageDataColorSettings_OR_sh is int) &&
        sh_OR_sw != null &&
        data_OR_imagedata_OR_sw != null) {
      var imageDataColorSettings_1 =
          convertDartToNative_Dictionary(imageDataColorSettings);
      return convertNativeToDart_ImageData(_createImageData_5(
          data_OR_imagedata_OR_sw,
          sh_OR_sw,
          imageDataColorSettings_OR_sh,
          imageDataColorSettings_1));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('createImageData')
  @Creates('ImageData|=Object')
  _createImageData_1(imagedata) native;
  @JSName('createImageData')
  @Creates('ImageData|=Object')
  _createImageData_2(int sw, sh) native;
  @JSName('createImageData')
  @Creates('ImageData|=Object')
  _createImageData_3(int sw, sh, imageDataColorSettings) native;
  @JSName('createImageData')
  @Creates('ImageData|=Object')
  _createImageData_4(data, sw, int sh) native;
  @JSName('createImageData')
  @Creates('ImageData|=Object')
  _createImageData_5(data, sw, int sh, imageDataColorSettings) native;

  CanvasGradient createLinearGradient(num x0, num y0, num x1, num y1) native;

  CanvasPattern createPattern(Object image, String repetitionType) native;

  CanvasGradient createRadialGradient(
      num x0, num y0, num r0, num x1, num y1, num r1) native;

  void drawFocusIfNeeded(element_OR_path, [Element element]) native;

  void fill([path_OR_winding, String winding]) native;

  void fillRect(num x, num y, num width, num height) native;

  Map getContextAttributes() {
    return convertNativeToDart_Dictionary(_getContextAttributes_1());
  }

  @JSName('getContextAttributes')
  _getContextAttributes_1() native;

  @Creates('ImageData|=Object')
  ImageData getImageData(int sx, int sy, int sw, int sh) {
    return convertNativeToDart_ImageData(_getImageData_1(sx, sy, sw, sh));
  }

  @JSName('getImageData')
  @Creates('ImageData|=Object')
  _getImageData_1(sx, sy, sw, sh) native;

  @JSName('getLineDash')
  List<num> _getLineDash() native;

  bool isContextLost() native;

  bool isPointInPath(path_OR_x, num x_OR_y, [winding_OR_y, String winding])
      native;

  bool isPointInStroke(path_OR_x, num x_OR_y, [num y]) native;

  TextMetrics measureText(String text) native;

  void putImageData(ImageData imagedata, int dx, int dy,
      [int dirtyX, int dirtyY, int dirtyWidth, int dirtyHeight]) {
    if (dirtyX == null &&
        dirtyY == null &&
        dirtyWidth == null &&
        dirtyHeight == null) {
      var imagedata_1 = convertDartToNative_ImageData(imagedata);
      _putImageData_1(imagedata_1, dx, dy);
      return;
    }
    if (dirtyHeight != null &&
        dirtyWidth != null &&
        dirtyY != null &&
        dirtyX != null) {
      var imagedata_1 = convertDartToNative_ImageData(imagedata);
      _putImageData_2(
          imagedata_1, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('putImageData')
  void _putImageData_1(imagedata, dx, dy) native;
  @JSName('putImageData')
  void _putImageData_2(
      imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) native;

  void removeHitRegion(String id) native;

  void resetTransform() native;

  void restore() native;

  void rotate(num angle) native;

  void save() native;

  void scale(num x, num y) native;

  void scrollPathIntoView([Path2D path]) native;

  void setTransform(num a, num b, num c, num d, num e, num f) native;

  void stroke([Path2D path]) native;

  void strokeRect(num x, num y, num width, num height) native;

  void strokeText(String text, num x, num y, [num maxWidth]) native;

  void transform(num a, num b, num c, num d, num e, num f) native;

  void translate(num x, num y) native;

  // From CanvasPath

  @JSName('arc')
  void _arc(num x, num y, num radius, num startAngle, num endAngle,
      bool anticlockwise) native;

  void arcTo(num x1, num y1, num x2, num y2, num radius) native;

  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y)
      native;

  void closePath() native;

  void ellipse(num x, num y, num radiusX, num radiusY, num rotation,
      num startAngle, num endAngle, bool anticlockwise) native;

  void lineTo(num x, num y) native;

  void moveTo(num x, num y) native;

  void quadraticCurveTo(num cpx, num cpy, num x, num y) native;

  void rect(num x, num y, num width, num height) native;

  ImageData createImageDataFromImageData(ImageData imagedata) =>
      JS('ImageData', '#.createImageData(#)', this, imagedata);

  /**
   * Sets the color used inside shapes.
   * [r], [g], [b] are 0-255, [a] is 0-1.
   */
  void setFillColorRgb(int r, int g, int b, [num a = 1]) {
    this.fillStyle = 'rgba($r, $g, $b, $a)';
  }

  /**
   * Sets the color used inside shapes.
   * [h] is in degrees, 0-360.
   * [s], [l] are in percent, 0-100.
   * [a] is 0-1.
   */
  void setFillColorHsl(int h, num s, num l, [num a = 1]) {
    this.fillStyle = 'hsla($h, $s%, $l%, $a)';
  }

  /**
   * Sets the color used for stroking shapes.
   * [r], [g], [b] are 0-255, [a] is 0-1.
   */
  void setStrokeColorRgb(int r, int g, int b, [num a = 1]) {
    this.strokeStyle = 'rgba($r, $g, $b, $a)';
  }

  /**
   * Sets the color used for stroking shapes.
   * [h] is in degrees, 0-360.
   * [s], [l] are in percent, 0-100.
   * [a] is 0-1.
   */
  void setStrokeColorHsl(int h, num s, num l, [num a = 1]) {
    this.strokeStyle = 'hsla($h, $s%, $l%, $a)';
  }

  void arc(num x, num y, num radius, num startAngle, num endAngle,
      [bool anticlockwise = false]) {
    // TODO(terry): This should not be needed: dartbug.com/20939.
    JS('void', '#.arc(#, #, #, #, #, #)', this, x, y, radius, startAngle,
        endAngle, anticlockwise);
  }

  CanvasPattern createPatternFromImage(
          ImageElement image, String repetitionType) =>
      JS('CanvasPattern', '#.createPattern(#, #)', this, image, repetitionType);

  /**
   * Draws an image from a CanvasImageSource to an area of this canvas.
   *
   * The image will be drawn to an area of this canvas defined by
   * [destRect]. [sourceRect] defines the region of the source image that is
   * drawn.
   * If [sourceRect] is not provided, then
   * the entire rectangular image from [source] will be drawn to this context.
   *
   * If the image is larger than canvas
   * will allow, the image will be clipped to fit the available space.
   *
   *     CanvasElement canvas = new CanvasElement(width: 600, height: 600);
   *     CanvasRenderingContext2D ctx = canvas.context2D;
   *     ImageElement img = document.query('img');
   *     img.width = 100;
   *     img.height = 100;
   *
   *     // Scale the image to 20x20.
   *     ctx.drawImageToRect(img, new Rectangle(50, 50, 20, 20));
   *
   *     VideoElement video = document.query('video');
   *     video.width = 100;
   *     video.height = 100;
   *     // Take the middle 20x20 pixels from the video and stretch them.
   *     ctx.drawImageToRect(video, new Rectangle(50, 50, 100, 100),
   *         sourceRect: new Rectangle(40, 40, 20, 20));
   *
   *     // Draw the top 100x20 pixels from the otherCanvas.
   *     CanvasElement otherCanvas = document.query('canvas');
   *     ctx.drawImageToRect(otherCanvas, new Rectangle(0, 0, 100, 20),
   *         sourceRect: new Rectangle(0, 0, 100, 20));
   *
   * See also:
   *
   *   * [CanvasImageSource] for more information on what data is retrieved
   * from [source].
   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
   * from the WHATWG.
   */
  void drawImageToRect(CanvasImageSource source, Rectangle destRect,
      {Rectangle sourceRect}) {
    if (sourceRect == null) {
      drawImageScaled(
          source, destRect.left, destRect.top, destRect.width, destRect.height);
    } else {
      drawImageScaledFromSource(
          source,
          sourceRect.left,
          sourceRect.top,
          sourceRect.width,
          sourceRect.height,
          destRect.left,
          destRect.top,
          destRect.width,
          destRect.height);
    }
  }

  /**
   * Draws an image from a CanvasImageSource to this canvas.
   *
   * The entire image from [source] will be drawn to this context with its top
   * left corner at the point ([destX], [destY]). If the image is
   * larger than canvas will allow, the image will be clipped to fit the
   * available space.
   *
   *     CanvasElement canvas = new CanvasElement(width: 600, height: 600);
   *     CanvasRenderingContext2D ctx = canvas.context2D;
   *     ImageElement img = document.query('img');
   *
   *     ctx.drawImage(img, 100, 100);
   *
   *     VideoElement video = document.query('video');
   *     ctx.drawImage(video, 0, 0);
   *
   *     CanvasElement otherCanvas = document.query('canvas');
   *     otherCanvas.width = 100;
   *     otherCanvas.height = 100;
   *     ctx.drawImage(otherCanvas, 590, 590); // will get clipped
   *
   * See also:
   *
   *   * [CanvasImageSource] for more information on what data is retrieved
   * from [source].
   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
   * from the WHATWG.
   */
  @JSName('drawImage')
  void drawImage(CanvasImageSource source, num destX, num destY) native;

  /**
   * Draws an image from a CanvasImageSource to an area of this canvas.
   *
   * The image will be drawn to this context with its top left corner at the
   * point ([destX], [destY]) and will be scaled to be [destWidth] wide and
   * [destHeight] tall.
   *
   * If the image is larger than canvas
   * will allow, the image will be clipped to fit the available space.
   *
   *     CanvasElement canvas = new CanvasElement(width: 600, height: 600);
   *     CanvasRenderingContext2D ctx = canvas.context2D;
   *     ImageElement img = document.query('img');
   *     img.width = 100;
   *     img.height = 100;
   *
   *     // Scale the image to 300x50 at the point (20, 20)
   *     ctx.drawImageScaled(img, 20, 20, 300, 50);
   *
   * See also:
   *
   *   * [CanvasImageSource] for more information on what data is retrieved
   * from [source].
   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
   * from the WHATWG.
   */
  @JSName('drawImage')
  void drawImageScaled(CanvasImageSource source, num destX, num destY,
      num destWidth, num destHeight) native;

  /**
   * Draws an image from a CanvasImageSource to an area of this canvas.
   *
   * The image is a region of [source] that is [sourceWidth] wide and
   * [destHeight] tall with top left corner at ([sourceX], [sourceY]).
   * The image will be drawn to this context with its top left corner at the
   * point ([destX], [destY]) and will be scaled to be [destWidth] wide and
   * [destHeight] tall.
   *
   * If the image is larger than canvas
   * will allow, the image will be clipped to fit the available space.
   *
   *     VideoElement video = document.query('video');
   *     video.width = 100;
   *     video.height = 100;
   *     // Take the middle 20x20 pixels from the video and stretch them.
   *     ctx.drawImageScaledFromSource(video, 40, 40, 20, 20, 50, 50, 100, 100);
   *
   *     // Draw the top 100x20 pixels from the otherCanvas to this one.
   *     CanvasElement otherCanvas = document.query('canvas');
   *     ctx.drawImageScaledFromSource(otherCanvas, 0, 0, 100, 20, 0, 0, 100, 20);
   *
   * See also:
   *
   *   * [CanvasImageSource] for more information on what data is retrieved
   * from [source].
   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
   * from the WHATWG.
   */
  @JSName('drawImage')
  void drawImageScaledFromSource(
      CanvasImageSource source,
      num sourceX,
      num sourceY,
      num sourceWidth,
      num sourceHeight,
      num destX,
      num destY,
      num destWidth,
      num destHeight) native;

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @SupportedBrowser(SupportedBrowser.IE, '11')
  @Unstable()
  // TODO(14316): Firefox has this functionality with mozDashOffset, but it
  // needs to be polyfilled.
  num get lineDashOffset =>
      JS('num', '#.lineDashOffset || #.webkitLineDashOffset', this, this);

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @SupportedBrowser(SupportedBrowser.IE, '11')
  @Unstable()
  // TODO(14316): Firefox has this functionality with mozDashOffset, but it
  // needs to be polyfilled.
  set lineDashOffset(num value) {
    JS(
        'void',
        'typeof #.lineDashOffset != "undefined" ? #.lineDashOffset = # : '
        '#.webkitLineDashOffset = #',
        this,
        this,
        value,
        this,
        value);
  }

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @SupportedBrowser(SupportedBrowser.IE, '11')
  @Unstable()
  List<num> getLineDash() {
    // TODO(14316): Firefox has this functionality with mozDash, but it's a bit
    // different.
    if (JS('bool', '!!#.getLineDash', this)) {
      return JS('List<num>', '#.getLineDash()', this);
    } else if (JS('bool', '!!#.webkitLineDash', this)) {
      return JS('List<num>', '#.webkitLineDash', this);
    }
  }

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @SupportedBrowser(SupportedBrowser.IE, '11')
  @Unstable()
  void setLineDash(List<num> dash) {
    // TODO(14316): Firefox has this functionality with mozDash, but it's a bit
    // different.
    if (JS('bool', '!!#.setLineDash', this)) {
      JS('void', '#.setLineDash(#)', this, dash);
    } else if (JS('bool', '!!#.webkitLineDash', this)) {
      JS('void', '#.webkitLineDash = #', this, dash);
    }
  }

  /**
   * Draws text to the canvas.
   *
   * The text is drawn starting at coordinates ([x], [y]).
   * If [maxWidth] is provided and the [text] is computed to be wider than
   * [maxWidth], then the drawn text is scaled down horizontally to fit.
   *
   * The text uses the current [CanvasRenderingContext2D.font] property for font
   * options, such as typeface and size, and the current
   * [CanvasRenderingContext2D.fillStyle] for style options such as color.
   * The current [CanvasRenderingContext2D.textAlign] and
   * [CanvasRenderingContext2D.textBaseLine] properties are also applied to the
   * drawn text.
   */
  void fillText(String text, num x, num y, [num maxWidth]) {
    if (maxWidth != null) {
      JS('void', '#.fillText(#, #, #, #)', this, text, x, y, maxWidth);
    } else {
      JS('void', '#.fillText(#, #, #)', this, text, x, y);
    }
  }

  /** Deprecated always returns 1.0 */
  @deprecated
  double get backingStorePixelRatio => 1.0;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CharacterData")
class CharacterData extends Node
    implements NonDocumentTypeChildNode, ChildNode {
  // To suppress missing implicit constructor warnings.
  factory CharacterData._() {
    throw new UnsupportedError("Not supported");
  }

  String data;

  final int length;

  void appendData(String data) native;

  void deleteData(int offset, int count) native;

  void insertData(int offset, String data) native;

  void replaceData(int offset, int count, String data) native;

  String substringData(int offset, int count) native;

  // From ChildNode

  void after(Object nodes) native;

  void before(Object nodes) native;

  // From NonDocumentTypeChildNode

  final Element nextElementSibling;

  final Element previousElementSibling;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class ChildNode extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ChildNode._() {
    throw new UnsupportedError("Not supported");
  }

  void after(Object nodes);

  void before(Object nodes);

  void remove();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Client")
class Client extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Client._() {
    throw new UnsupportedError("Not supported");
  }

  final String frameType;

  final String id;

  final String type;

  final String url;

  void postMessage(Object message, [List<Object> transfer]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Clients")
class Clients extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Clients._() {
    throw new UnsupportedError("Not supported");
  }

  Future claim() => promiseToFuture(JS("", "#.claim()", this));

  Future get(String id) => promiseToFuture(JS("", "#.get(#)", this, id));

  Future<List<Client>> matchAll([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture<List<Client>>(
        JS("", "#.matchAll(#)", this, options_dict));
  }

  Future<WindowClient> openWindow(String url) =>
      promiseToFuture<WindowClient>(JS("", "#.openWindow(#)", this, url));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ClipboardEvent")
class ClipboardEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory ClipboardEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory ClipboardEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return ClipboardEvent._create_1(type, eventInitDict_1);
    }
    return ClipboardEvent._create_2(type);
  }
  static ClipboardEvent _create_1(type, eventInitDict) =>
      JS('ClipboardEvent', 'new ClipboardEvent(#,#)', type, eventInitDict);
  static ClipboardEvent _create_2(type) =>
      JS('ClipboardEvent', 'new ClipboardEvent(#)', type);

  final DataTransfer clipboardData;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CloseEvent")
class CloseEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory CloseEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory CloseEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return CloseEvent._create_1(type, eventInitDict_1);
    }
    return CloseEvent._create_2(type);
  }
  static CloseEvent _create_1(type, eventInitDict) =>
      JS('CloseEvent', 'new CloseEvent(#,#)', type, eventInitDict);
  static CloseEvent _create_2(type) =>
      JS('CloseEvent', 'new CloseEvent(#)', type);

  final int code;

  final String reason;

  final bool wasClean;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Comment")
class Comment extends CharacterData {
  factory Comment([String data]) {
    return JS('returns:Comment;depends:none;effects:none;new:true',
        '#.createComment(#)', document, data == null ? "" : data);
  }
  // To suppress missing implicit constructor warnings.
  factory Comment._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Native("CompositionEvent")
class CompositionEvent extends UIEvent {
  factory CompositionEvent(String type,
      {bool canBubble: false,
      bool cancelable: false,
      Window view,
      String data,
      String locale}) {
    if (view == null) {
      view = window;
    }
    CompositionEvent e = document._createEvent("CompositionEvent");

    if (Device.isFirefox) {
      // Firefox requires the locale parameter that isn't supported elsewhere.
      JS('void', '#.initCompositionEvent(#, #, #, #, #, #)', e, type, canBubble,
          cancelable, view, data, locale);
    } else {
      e._initCompositionEvent(type, canBubble, cancelable, view, data);
    }

    return e;
  }

  factory CompositionEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return CompositionEvent._create_1(type, eventInitDict_1);
    }
    return CompositionEvent._create_2(type);
  }
  static CompositionEvent _create_1(type, eventInitDict) =>
      JS('CompositionEvent', 'new CompositionEvent(#,#)', type, eventInitDict);
  static CompositionEvent _create_2(type) =>
      JS('CompositionEvent', 'new CompositionEvent(#)', type);

  final String data;

  @JSName('initCompositionEvent')
  void _initCompositionEvent(String type, bool bubbles, bool cancelable,
      Window view, String data) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME, '26')
@Native("HTMLContentElement")
class ContentElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ContentElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory ContentElement() => document.createElement("content");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ContentElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('content');

  String select;

  @Returns('NodeList|Null')
  @Creates('NodeList')
  List<Node> getDistributedNodes() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CookieStore")
class CookieStore extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CookieStore._() {
    throw new UnsupportedError("Not supported");
  }

  Future getAll([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(JS("", "#.getAll(#)", this, options_dict));
  }

  Future set(String name, String value, [Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(
        JS("", "#.set(#, #, #)", this, name, value, options_dict));
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Coordinates")
class Coordinates extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Coordinates._() {
    throw new UnsupportedError("Not supported");
  }

  final num accuracy;

  final num altitude;

  final num altitudeAccuracy;

  final num heading;

  final num latitude;

  final num longitude;

  final num speed;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Credential")
class Credential extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Credential._() {
    throw new UnsupportedError("Not supported");
  }

  final String id;

  final String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CredentialUserData")
class CredentialUserData extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CredentialUserData._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('iconURL')
  final String iconUrl;

  final String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CredentialsContainer")
class CredentialsContainer extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CredentialsContainer._() {
    throw new UnsupportedError("Not supported");
  }

  Future create([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(JS("", "#.create(#)", this, options_dict));
  }

  Future get([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(JS("", "#.get(#)", this, options_dict));
  }

  Future preventSilentAccess() =>
      promiseToFuture(JS("", "#.preventSilentAccess()", this));

  Future requireUserMediation() =>
      promiseToFuture(JS("", "#.requireUserMediation()", this));

  Future store(Credential credential) =>
      promiseToFuture(JS("", "#.store(#)", this, credential));
}
// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("Crypto")
class Crypto extends Interceptor {
  TypedData getRandomValues(TypedData array) {
    return _getRandomValues(array);
  }

  // To suppress missing implicit constructor warnings.
  factory Crypto._() {
    throw new UnsupportedError("Not supported");
  }

  /// Checks if this type is supported on the current platform.
  static bool get supported =>
      JS('bool', '!!(window.crypto && window.crypto.getRandomValues)');

  final _SubtleCrypto subtle;

  @JSName('getRandomValues')
  @Creates('TypedData')
  @Returns('TypedData|Null')
  TypedData _getRandomValues(TypedData array) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CryptoKey")
class CryptoKey extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CryptoKey._() {
    throw new UnsupportedError("Not supported");
  }

  @Creates('Null')
  final Object algorithm;

  final bool extractable;

  final String type;

  final Object usages;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSS")
class Css extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Css._() {
    throw new UnsupportedError("Not supported");
  }

  static final _Worklet paintWorklet;

  static CssUnitValue Hz(num value) native;

  static CssUnitValue ch(num value) native;

  static CssUnitValue cm(num value) native;

  static CssUnitValue deg(num value) native;

  static CssUnitValue dpcm(num value) native;

  static CssUnitValue dpi(num value) native;

  static CssUnitValue dppx(num value) native;

  static CssUnitValue em(num value) native;

  static String escape(String ident) native;

  static CssUnitValue ex(num value) native;

  static CssUnitValue fr(num value) native;

  static CssUnitValue grad(num value) native;

  @JSName('in')
  static CssUnitValue inch(num value) native;

  static CssUnitValue kHz(num value) native;

  static CssUnitValue mm(num value) native;

  static CssUnitValue ms(num value) native;

  static CssUnitValue number(num value) native;

  static CssUnitValue pc(num value) native;

  static CssUnitValue percent(num value) native;

  static CssUnitValue pt(num value) native;

  static CssUnitValue px(num value) native;

  static CssUnitValue rad(num value) native;

  static void registerProperty(Map descriptor) {
    var descriptor_1 = convertDartToNative_Dictionary(descriptor);
    _registerProperty_1(descriptor_1);
    return;
  }

  @JSName('registerProperty')
  static void _registerProperty_1(descriptor) native;

  static CssUnitValue rem(num value) native;

  static CssUnitValue s(num value) native;

  static bool supports(String property, String value) native;

  @JSName('supports')
  static bool supportsCondition(String conditionText) native;

  static CssUnitValue turn(num value) native;

  static CssUnitValue vh(num value) native;

  static CssUnitValue vmax(num value) native;

  static CssUnitValue vmin(num value) native;

  static CssUnitValue vw(num value) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSCharsetRule")
class CssCharsetRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssCharsetRule._() {
    throw new UnsupportedError("Not supported");
  }

  String encoding;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSConditionRule")
class CssConditionRule extends CssGroupingRule {
  // To suppress missing implicit constructor warnings.
  factory CssConditionRule._() {
    throw new UnsupportedError("Not supported");
  }

  final String conditionText;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSFontFaceRule")
class CssFontFaceRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssFontFaceRule._() {
    throw new UnsupportedError("Not supported");
  }

  final CssStyleDeclaration style;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSGroupingRule")
class CssGroupingRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssGroupingRule._() {
    throw new UnsupportedError("Not supported");
  }

  @Returns('_CssRuleList|Null')
  @Creates('_CssRuleList')
  final List<CssRule> cssRules;

  void deleteRule(int index) native;

  int insertRule(String rule, int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSImageValue")
class CssImageValue extends CssResourceValue {
  // To suppress missing implicit constructor warnings.
  factory CssImageValue._() {
    throw new UnsupportedError("Not supported");
  }

  final num intrinsicHeight;

  final num intrinsicRatio;

  final num intrinsicWidth;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSImportRule")
class CssImportRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssImportRule._() {
    throw new UnsupportedError("Not supported");
  }

  final String href;

  final MediaList media;

  final CssStyleSheet styleSheet;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSKeyframeRule,MozCSSKeyframeRule,WebKitCSSKeyframeRule")
class CssKeyframeRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssKeyframeRule._() {
    throw new UnsupportedError("Not supported");
  }

  String keyText;

  final CssStyleDeclaration style;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSKeyframesRule,MozCSSKeyframesRule,WebKitCSSKeyframesRule")
class CssKeyframesRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssKeyframesRule._() {
    throw new UnsupportedError("Not supported");
  }

  @Returns('_CssRuleList|Null')
  @Creates('_CssRuleList')
  final List<CssRule> cssRules;

  String name;

  CssKeyframeRule __getter__(int index) native;

  void appendRule(String rule) native;

  void deleteRule(String select) native;

  CssKeyframeRule findRule(String select) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSKeywordValue")
class CssKeywordValue extends CssStyleValue {
  // To suppress missing implicit constructor warnings.
  factory CssKeywordValue._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssKeywordValue(String keyword) {
    return CssKeywordValue._create_1(keyword);
  }
  static CssKeywordValue _create_1(keyword) =>
      JS('CssKeywordValue', 'new CSSKeywordValue(#)', keyword);

  String value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSMatrixComponent")
class CssMatrixComponent extends CssTransformComponent {
  // To suppress missing implicit constructor warnings.
  factory CssMatrixComponent._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssMatrixComponent(DomMatrixReadOnly matrix, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return CssMatrixComponent._create_1(matrix, options_1);
    }
    return CssMatrixComponent._create_2(matrix);
  }
  static CssMatrixComponent _create_1(matrix, options) =>
      JS('CssMatrixComponent', 'new CSSMatrixComponent(#,#)', matrix, options);
  static CssMatrixComponent _create_2(matrix) =>
      JS('CssMatrixComponent', 'new CSSMatrixComponent(#)', matrix);

  DomMatrix matrix;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSMediaRule")
class CssMediaRule extends CssConditionRule {
  // To suppress missing implicit constructor warnings.
  factory CssMediaRule._() {
    throw new UnsupportedError("Not supported");
  }

  final MediaList media;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSNamespaceRule")
class CssNamespaceRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssNamespaceRule._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('namespaceURI')
  final String namespaceUri;

  final String prefix;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSNumericValue")
class CssNumericValue extends CssStyleValue {
  // To suppress missing implicit constructor warnings.
  factory CssNumericValue._() {
    throw new UnsupportedError("Not supported");
  }

  CssNumericValue add(CssNumericValue value) native;

  CssNumericValue div(num value) native;

  CssNumericValue mul(num value) native;

  static CssNumericValue parse(String cssText) native;

  CssNumericValue sub(CssNumericValue value) native;

  CssNumericValue to(String unit) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSPageRule")
class CssPageRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssPageRule._() {
    throw new UnsupportedError("Not supported");
  }

  String selectorText;

  final CssStyleDeclaration style;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSPerspective")
class CssPerspective extends CssTransformComponent {
  // To suppress missing implicit constructor warnings.
  factory CssPerspective._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssPerspective(CssNumericValue length) {
    return CssPerspective._create_1(length);
  }
  static CssPerspective _create_1(length) =>
      JS('CssPerspective', 'new CSSPerspective(#)', length);

  CssNumericValue length;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSPositionValue")
class CssPositionValue extends CssStyleValue {
  // To suppress missing implicit constructor warnings.
  factory CssPositionValue._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssPositionValue(CssNumericValue x, CssNumericValue y) {
    return CssPositionValue._create_1(x, y);
  }
  static CssPositionValue _create_1(x, y) =>
      JS('CssPositionValue', 'new CSSPositionValue(#,#)', x, y);

  CssNumericValue x;

  CssNumericValue y;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSResourceValue")
class CssResourceValue extends CssStyleValue {
  // To suppress missing implicit constructor warnings.
  factory CssResourceValue._() {
    throw new UnsupportedError("Not supported");
  }

  final String state;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSRotation")
class CssRotation extends CssTransformComponent {
  // To suppress missing implicit constructor warnings.
  factory CssRotation._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssRotation(angleValue_OR_x, [num y, num z, CssNumericValue angle]) {
    if ((angleValue_OR_x is CssNumericValue) &&
        y == null &&
        z == null &&
        angle == null) {
      return CssRotation._create_1(angleValue_OR_x);
    }
    if ((angle is CssNumericValue) &&
        (z is num) &&
        (y is num) &&
        (angleValue_OR_x is num)) {
      return CssRotation._create_2(angleValue_OR_x, y, z, angle);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static CssRotation _create_1(angleValue_OR_x) =>
      JS('CssRotation', 'new CSSRotation(#)', angleValue_OR_x);
  static CssRotation _create_2(angleValue_OR_x, y, z, angle) => JS(
      'CssRotation', 'new CSSRotation(#,#,#,#)', angleValue_OR_x, y, z, angle);

  CssNumericValue angle;

  num x;

  num y;

  num z;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSRule")
class CssRule extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CssRule._() {
    throw new UnsupportedError("Not supported");
  }

  static const int CHARSET_RULE = 2;

  static const int FONT_FACE_RULE = 5;

  static const int IMPORT_RULE = 3;

  static const int KEYFRAMES_RULE = 7;

  static const int KEYFRAME_RULE = 8;

  static const int MEDIA_RULE = 4;

  static const int NAMESPACE_RULE = 10;

  static const int PAGE_RULE = 6;

  static const int STYLE_RULE = 1;

  static const int SUPPORTS_RULE = 12;

  static const int VIEWPORT_RULE = 15;

  String cssText;

  final CssRule parentRule;

  final CssStyleSheet parentStyleSheet;

  final int type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSScale")
class CssScale extends CssTransformComponent {
  // To suppress missing implicit constructor warnings.
  factory CssScale._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssScale(num x, num y, [num z]) {
    if ((y is num) && (x is num) && z == null) {
      return CssScale._create_1(x, y);
    }
    if ((z is num) && (y is num) && (x is num)) {
      return CssScale._create_2(x, y, z);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static CssScale _create_1(x, y) => JS('CssScale', 'new CSSScale(#,#)', x, y);
  static CssScale _create_2(x, y, z) =>
      JS('CssScale', 'new CSSScale(#,#,#)', x, y, z);

  num x;

  num y;

  num z;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSSkew")
class CssSkew extends CssTransformComponent {
  // To suppress missing implicit constructor warnings.
  factory CssSkew._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssSkew(CssNumericValue ax, CssNumericValue ay) {
    return CssSkew._create_1(ax, ay);
  }
  static CssSkew _create_1(ax, ay) => JS('CssSkew', 'new CSSSkew(#,#)', ax, ay);

  CssNumericValue ax;

  CssNumericValue ay;
}

// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: DO NOT EDIT THIS TEMPLATE FILE.
// The template file was generated by scripts/css_code_generator.py

// Source of CSS properties:
//   CSSPropertyNames.in

@Native("CSSStyleDeclaration,MSStyleCSSProperties,CSS2Properties")
class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase {
  factory CssStyleDeclaration() => new CssStyleDeclaration.css('');

  factory CssStyleDeclaration.css(String css) {
    final style = new DivElement().style;
    style.cssText = css;
    return style;
  }

  /// Returns the value of the property if the provided *CSS* property
  /// name is supported on this element and if the value is set. Otherwise
  /// returns an empty string.
  ///
  /// Please note the property name uses camelCase, not-hyphens.
  String getPropertyValue(String propertyName) {
    var propValue = _getPropertyValueHelper(propertyName);
    return propValue ?? '';
  }

  String _getPropertyValueHelper(String propertyName) {
    return _getPropertyValue(_browserPropertyName(propertyName));
  }

  /**
   * Returns true if the provided *CSS* property name is supported on this
   * element.
   *
   * Please note the property name camelCase, not-hyphens. This
   * method returns true if the property is accessible via an unprefixed _or_
   * prefixed property.
   */
  bool supportsProperty(String propertyName) {
    return _supportsProperty(propertyName) ||
        _supportsProperty(_camelCase("${Device.cssPrefix}$propertyName"));
  }

  bool _supportsProperty(String propertyName) {
    return JS('bool', '# in #', propertyName, this);
  }

  void setProperty(String propertyName, String value, [String priority]) {
    return _setPropertyHelper(
        _browserPropertyName(propertyName), value, priority);
  }

  String _browserPropertyName(String propertyName) {
    String name = _readCache(propertyName);
    if (name is String) return name;
    name = _supportedBrowserPropertyName(propertyName);
    _writeCache(propertyName, name);
    return name;
  }

  String _supportedBrowserPropertyName(String propertyName) {
    if (_supportsProperty(_camelCase(propertyName))) {
      return propertyName;
    }
    var prefixed = "${Device.cssPrefix}$propertyName";
    if (_supportsProperty(prefixed)) {
      return prefixed;
    }
    // May be a CSS variable, just use it as provided.
    return propertyName;
  }

  static final _propertyCache = JS('', '{}');
  static String _readCache(String key) =>
      JS('String|Null', '#[#]', _propertyCache, key);
  static void _writeCache(String key, String value) {
    JS('void', '#[#] = #', _propertyCache, key, value);
  }

  static String _camelCase(String hyphenated) {
    var replacedMs = JS('String', r'#.replace(/^-ms-/, "ms-")', hyphenated);
    return JS(
        'String',
        r'#.replace(/-([\da-z])/ig,'
        r'function(_, letter) { return letter.toUpperCase();})',
        replacedMs);
  }

  void _setPropertyHelper(String propertyName, String value,
      [String priority]) {
    if (value == null) value = '';
    if (priority == null) priority = '';
    JS('void', '#.setProperty(#, #, #)', this, propertyName, value, priority);
  }

  /**
   * Checks to see if CSS Transitions are supported.
   */
  static bool get supportsTransitions {
    return document.body.style.supportsProperty('transition');
  }

  // To suppress missing implicit constructor warnings.
  factory CssStyleDeclaration._() {
    throw new UnsupportedError("Not supported");
  }

  String cssFloat;

  String cssText;

  final int length;

  final CssRule parentRule;

  String getPropertyPriority(String property) native;

  @JSName('getPropertyValue')
  String _getPropertyValue(String property) native;

  String item(int index) native;

  String removeProperty(String property) native;

  /** Gets the value of "background" */
  String get background => this._background;

  /** Sets the value of "background" */
  set background(String value) {
    _background = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('background')
  String _background;

  /** Gets the value of "background-attachment" */
  String get backgroundAttachment => this._backgroundAttachment;

  /** Sets the value of "background-attachment" */
  set backgroundAttachment(String value) {
    _backgroundAttachment = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('backgroundAttachment')
  String _backgroundAttachment;

  /** Gets the value of "background-color" */
  String get backgroundColor => this._backgroundColor;

  /** Sets the value of "background-color" */
  set backgroundColor(String value) {
    _backgroundColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('backgroundColor')
  String _backgroundColor;

  /** Gets the value of "background-image" */
  String get backgroundImage => this._backgroundImage;

  /** Sets the value of "background-image" */
  set backgroundImage(String value) {
    _backgroundImage = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('backgroundImage')
  String _backgroundImage;

  /** Gets the value of "background-position" */
  String get backgroundPosition => this._backgroundPosition;

  /** Sets the value of "background-position" */
  set backgroundPosition(String value) {
    _backgroundPosition = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('backgroundPosition')
  String _backgroundPosition;

  /** Gets the value of "background-repeat" */
  String get backgroundRepeat => this._backgroundRepeat;

  /** Sets the value of "background-repeat" */
  set backgroundRepeat(String value) {
    _backgroundRepeat = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('backgroundRepeat')
  String _backgroundRepeat;

  /** Gets the value of "border" */
  String get border => this._border;

  /** Sets the value of "border" */
  set border(String value) {
    _border = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('border')
  String _border;

  /** Gets the value of "border-bottom" */
  String get borderBottom => this._borderBottom;

  /** Sets the value of "border-bottom" */
  set borderBottom(String value) {
    _borderBottom = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderBottom')
  String _borderBottom;

  /** Gets the value of "border-bottom-color" */
  String get borderBottomColor => this._borderBottomColor;

  /** Sets the value of "border-bottom-color" */
  set borderBottomColor(String value) {
    _borderBottomColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderBottomColor')
  String _borderBottomColor;

  /** Gets the value of "border-bottom-style" */
  String get borderBottomStyle => this._borderBottomStyle;

  /** Sets the value of "border-bottom-style" */
  set borderBottomStyle(String value) {
    _borderBottomStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderBottomStyle')
  String _borderBottomStyle;

  /** Gets the value of "border-bottom-width" */
  String get borderBottomWidth => this._borderBottomWidth;

  /** Sets the value of "border-bottom-width" */
  set borderBottomWidth(String value) {
    _borderBottomWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderBottomWidth')
  String _borderBottomWidth;

  /** Gets the value of "border-collapse" */
  String get borderCollapse => this._borderCollapse;

  /** Sets the value of "border-collapse" */
  set borderCollapse(String value) {
    _borderCollapse = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderCollapse')
  String _borderCollapse;

  /** Gets the value of "border-color" */
  String get borderColor => this._borderColor;

  /** Sets the value of "border-color" */
  set borderColor(String value) {
    _borderColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderColor')
  String _borderColor;

  /** Gets the value of "border-left" */
  String get borderLeft => this._borderLeft;

  /** Sets the value of "border-left" */
  set borderLeft(String value) {
    _borderLeft = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderLeft')
  String _borderLeft;

  /** Gets the value of "border-left-color" */
  String get borderLeftColor => this._borderLeftColor;

  /** Sets the value of "border-left-color" */
  set borderLeftColor(String value) {
    _borderLeftColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderLeftColor')
  String _borderLeftColor;

  /** Gets the value of "border-left-style" */
  String get borderLeftStyle => this._borderLeftStyle;

  /** Sets the value of "border-left-style" */
  set borderLeftStyle(String value) {
    _borderLeftStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderLeftStyle')
  String _borderLeftStyle;

  /** Gets the value of "border-left-width" */
  String get borderLeftWidth => this._borderLeftWidth;

  /** Sets the value of "border-left-width" */
  set borderLeftWidth(String value) {
    _borderLeftWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderLeftWidth')
  String _borderLeftWidth;

  /** Gets the value of "border-right" */
  String get borderRight => this._borderRight;

  /** Sets the value of "border-right" */
  set borderRight(String value) {
    _borderRight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderRight')
  String _borderRight;

  /** Gets the value of "border-right-color" */
  String get borderRightColor => this._borderRightColor;

  /** Sets the value of "border-right-color" */
  set borderRightColor(String value) {
    _borderRightColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderRightColor')
  String _borderRightColor;

  /** Gets the value of "border-right-style" */
  String get borderRightStyle => this._borderRightStyle;

  /** Sets the value of "border-right-style" */
  set borderRightStyle(String value) {
    _borderRightStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderRightStyle')
  String _borderRightStyle;

  /** Gets the value of "border-right-width" */
  String get borderRightWidth => this._borderRightWidth;

  /** Sets the value of "border-right-width" */
  set borderRightWidth(String value) {
    _borderRightWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderRightWidth')
  String _borderRightWidth;

  /** Gets the value of "border-spacing" */
  String get borderSpacing => this._borderSpacing;

  /** Sets the value of "border-spacing" */
  set borderSpacing(String value) {
    _borderSpacing = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderSpacing')
  String _borderSpacing;

  /** Gets the value of "border-style" */
  String get borderStyle => this._borderStyle;

  /** Sets the value of "border-style" */
  set borderStyle(String value) {
    _borderStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderStyle')
  String _borderStyle;

  /** Gets the value of "border-top" */
  String get borderTop => this._borderTop;

  /** Sets the value of "border-top" */
  set borderTop(String value) {
    _borderTop = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderTop')
  String _borderTop;

  /** Gets the value of "border-top-color" */
  String get borderTopColor => this._borderTopColor;

  /** Sets the value of "border-top-color" */
  set borderTopColor(String value) {
    _borderTopColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderTopColor')
  String _borderTopColor;

  /** Gets the value of "border-top-style" */
  String get borderTopStyle => this._borderTopStyle;

  /** Sets the value of "border-top-style" */
  set borderTopStyle(String value) {
    _borderTopStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderTopStyle')
  String _borderTopStyle;

  /** Gets the value of "border-top-width" */
  String get borderTopWidth => this._borderTopWidth;

  /** Sets the value of "border-top-width" */
  set borderTopWidth(String value) {
    _borderTopWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderTopWidth')
  String _borderTopWidth;

  /** Gets the value of "border-width" */
  String get borderWidth => this._borderWidth;

  /** Sets the value of "border-width" */
  set borderWidth(String value) {
    _borderWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderWidth')
  String _borderWidth;

  /** Gets the value of "bottom" */
  String get bottom => this._bottom;

  /** Sets the value of "bottom" */
  set bottom(String value) {
    _bottom = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('bottom')
  String _bottom;

  /** Gets the value of "caption-side" */
  String get captionSide => this._captionSide;

  /** Sets the value of "caption-side" */
  set captionSide(String value) {
    _captionSide = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('captionSide')
  String _captionSide;

  /** Gets the value of "clear" */
  String get clear => this._clear;

  /** Sets the value of "clear" */
  set clear(String value) {
    _clear = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('clear')
  String _clear;

  /** Gets the value of "clip" */
  String get clip => this._clip;

  /** Sets the value of "clip" */
  set clip(String value) {
    _clip = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('clip')
  String _clip;

  /** Gets the value of "color" */
  String get color => this._color;

  /** Sets the value of "color" */
  set color(String value) {
    _color = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('color')
  String _color;

  /** Gets the value of "content" */
  String get content => this._content;

  /** Sets the value of "content" */
  set content(String value) {
    _content = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('content')
  String _content;

  /** Gets the value of "cursor" */
  String get cursor => this._cursor;

  /** Sets the value of "cursor" */
  set cursor(String value) {
    _cursor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('cursor')
  String _cursor;

  /** Gets the value of "direction" */
  String get direction => this._direction;

  /** Sets the value of "direction" */
  set direction(String value) {
    _direction = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('direction')
  String _direction;

  /** Gets the value of "display" */
  String get display => this._display;

  /** Sets the value of "display" */
  set display(String value) {
    _display = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('display')
  String _display;

  /** Gets the value of "empty-cells" */
  String get emptyCells => this._emptyCells;

  /** Sets the value of "empty-cells" */
  set emptyCells(String value) {
    _emptyCells = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('emptyCells')
  String _emptyCells;

  /** Gets the value of "font" */
  String get font => this._font;

  /** Sets the value of "font" */
  set font(String value) {
    _font = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('font')
  String _font;

  /** Gets the value of "font-family" */
  String get fontFamily => this._fontFamily;

  /** Sets the value of "font-family" */
  set fontFamily(String value) {
    _fontFamily = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('fontFamily')
  String _fontFamily;

  /** Gets the value of "font-size" */
  String get fontSize => this._fontSize;

  /** Sets the value of "font-size" */
  set fontSize(String value) {
    _fontSize = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('fontSize')
  String _fontSize;

  /** Gets the value of "font-style" */
  String get fontStyle => this._fontStyle;

  /** Sets the value of "font-style" */
  set fontStyle(String value) {
    _fontStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('fontStyle')
  String _fontStyle;

  /** Gets the value of "font-variant" */
  String get fontVariant => this._fontVariant;

  /** Sets the value of "font-variant" */
  set fontVariant(String value) {
    _fontVariant = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('fontVariant')
  String _fontVariant;

  /** Gets the value of "font-weight" */
  String get fontWeight => this._fontWeight;

  /** Sets the value of "font-weight" */
  set fontWeight(String value) {
    _fontWeight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('fontWeight')
  String _fontWeight;

  /** Gets the value of "height" */
  String get height => this._height;

  /** Sets the value of "height" */
  set height(String value) {
    _height = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('height')
  String _height;

  /** Gets the value of "left" */
  String get left => this._left;

  /** Sets the value of "left" */
  set left(String value) {
    _left = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('left')
  String _left;

  /** Gets the value of "letter-spacing" */
  String get letterSpacing => this._letterSpacing;

  /** Sets the value of "letter-spacing" */
  set letterSpacing(String value) {
    _letterSpacing = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('letterSpacing')
  String _letterSpacing;

  /** Gets the value of "line-height" */
  String get lineHeight => this._lineHeight;

  /** Sets the value of "line-height" */
  set lineHeight(String value) {
    _lineHeight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('lineHeight')
  String _lineHeight;

  /** Gets the value of "list-style" */
  String get listStyle => this._listStyle;

  /** Sets the value of "list-style" */
  set listStyle(String value) {
    _listStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('listStyle')
  String _listStyle;

  /** Gets the value of "list-style-image" */
  String get listStyleImage => this._listStyleImage;

  /** Sets the value of "list-style-image" */
  set listStyleImage(String value) {
    _listStyleImage = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('listStyleImage')
  String _listStyleImage;

  /** Gets the value of "list-style-position" */
  String get listStylePosition => this._listStylePosition;

  /** Sets the value of "list-style-position" */
  set listStylePosition(String value) {
    _listStylePosition = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('listStylePosition')
  String _listStylePosition;

  /** Gets the value of "list-style-type" */
  String get listStyleType => this._listStyleType;

  /** Sets the value of "list-style-type" */
  set listStyleType(String value) {
    _listStyleType = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('listStyleType')
  String _listStyleType;

  /** Gets the value of "margin" */
  String get margin => this._margin;

  /** Sets the value of "margin" */
  set margin(String value) {
    _margin = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('margin')
  String _margin;

  /** Gets the value of "margin-bottom" */
  String get marginBottom => this._marginBottom;

  /** Sets the value of "margin-bottom" */
  set marginBottom(String value) {
    _marginBottom = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('marginBottom')
  String _marginBottom;

  /** Gets the value of "margin-left" */
  String get marginLeft => this._marginLeft;

  /** Sets the value of "margin-left" */
  set marginLeft(String value) {
    _marginLeft = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('marginLeft')
  String _marginLeft;

  /** Gets the value of "margin-right" */
  String get marginRight => this._marginRight;

  /** Sets the value of "margin-right" */
  set marginRight(String value) {
    _marginRight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('marginRight')
  String _marginRight;

  /** Gets the value of "margin-top" */
  String get marginTop => this._marginTop;

  /** Sets the value of "margin-top" */
  set marginTop(String value) {
    _marginTop = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('marginTop')
  String _marginTop;

  /** Gets the value of "max-height" */
  String get maxHeight => this._maxHeight;

  /** Sets the value of "max-height" */
  set maxHeight(String value) {
    _maxHeight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('maxHeight')
  String _maxHeight;

  /** Gets the value of "max-width" */
  String get maxWidth => this._maxWidth;

  /** Sets the value of "max-width" */
  set maxWidth(String value) {
    _maxWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('maxWidth')
  String _maxWidth;

  /** Gets the value of "min-height" */
  String get minHeight => this._minHeight;

  /** Sets the value of "min-height" */
  set minHeight(String value) {
    _minHeight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('minHeight')
  String _minHeight;

  /** Gets the value of "min-width" */
  String get minWidth => this._minWidth;

  /** Sets the value of "min-width" */
  set minWidth(String value) {
    _minWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('minWidth')
  String _minWidth;

  /** Gets the value of "outline" */
  String get outline => this._outline;

  /** Sets the value of "outline" */
  set outline(String value) {
    _outline = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('outline')
  String _outline;

  /** Gets the value of "outline-color" */
  String get outlineColor => this._outlineColor;

  /** Sets the value of "outline-color" */
  set outlineColor(String value) {
    _outlineColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('outlineColor')
  String _outlineColor;

  /** Gets the value of "outline-style" */
  String get outlineStyle => this._outlineStyle;

  /** Sets the value of "outline-style" */
  set outlineStyle(String value) {
    _outlineStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('outlineStyle')
  String _outlineStyle;

  /** Gets the value of "outline-width" */
  String get outlineWidth => this._outlineWidth;

  /** Sets the value of "outline-width" */
  set outlineWidth(String value) {
    _outlineWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('outlineWidth')
  String _outlineWidth;

  /** Gets the value of "overflow" */
  String get overflow => this._overflow;

  /** Sets the value of "overflow" */
  set overflow(String value) {
    _overflow = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('overflow')
  String _overflow;

  /** Gets the value of "padding" */
  String get padding => this._padding;

  /** Sets the value of "padding" */
  set padding(String value) {
    _padding = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('padding')
  String _padding;

  /** Gets the value of "padding-bottom" */
  String get paddingBottom => this._paddingBottom;

  /** Sets the value of "padding-bottom" */
  set paddingBottom(String value) {
    _paddingBottom = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('paddingBottom')
  String _paddingBottom;

  /** Gets the value of "padding-left" */
  String get paddingLeft => this._paddingLeft;

  /** Sets the value of "padding-left" */
  set paddingLeft(String value) {
    _paddingLeft = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('paddingLeft')
  String _paddingLeft;

  /** Gets the value of "padding-right" */
  String get paddingRight => this._paddingRight;

  /** Sets the value of "padding-right" */
  set paddingRight(String value) {
    _paddingRight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('paddingRight')
  String _paddingRight;

  /** Gets the value of "padding-top" */
  String get paddingTop => this._paddingTop;

  /** Sets the value of "padding-top" */
  set paddingTop(String value) {
    _paddingTop = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('paddingTop')
  String _paddingTop;

  /** Gets the value of "page-break-after" */
  String get pageBreakAfter => this._pageBreakAfter;

  /** Sets the value of "page-break-after" */
  set pageBreakAfter(String value) {
    _pageBreakAfter = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('pageBreakAfter')
  String _pageBreakAfter;

  /** Gets the value of "page-break-before" */
  String get pageBreakBefore => this._pageBreakBefore;

  /** Sets the value of "page-break-before" */
  set pageBreakBefore(String value) {
    _pageBreakBefore = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('pageBreakBefore')
  String _pageBreakBefore;

  /** Gets the value of "page-break-inside" */
  String get pageBreakInside => this._pageBreakInside;

  /** Sets the value of "page-break-inside" */
  set pageBreakInside(String value) {
    _pageBreakInside = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('pageBreakInside')
  String _pageBreakInside;

  /** Gets the value of "position" */
  String get position => this._position;

  /** Sets the value of "position" */
  set position(String value) {
    _position = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('position')
  String _position;

  /** Gets the value of "quotes" */
  String get quotes => this._quotes;

  /** Sets the value of "quotes" */
  set quotes(String value) {
    _quotes = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('quotes')
  String _quotes;

  /** Gets the value of "right" */
  String get right => this._right;

  /** Sets the value of "right" */
  set right(String value) {
    _right = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('right')
  String _right;

  /** Gets the value of "table-layout" */
  String get tableLayout => this._tableLayout;

  /** Sets the value of "table-layout" */
  set tableLayout(String value) {
    _tableLayout = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('tableLayout')
  String _tableLayout;

  /** Gets the value of "text-align" */
  String get textAlign => this._textAlign;

  /** Sets the value of "text-align" */
  set textAlign(String value) {
    _textAlign = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('textAlign')
  String _textAlign;

  /** Gets the value of "text-decoration" */
  String get textDecoration => this._textDecoration;

  /** Sets the value of "text-decoration" */
  set textDecoration(String value) {
    _textDecoration = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('textDecoration')
  String _textDecoration;

  /** Gets the value of "text-indent" */
  String get textIndent => this._textIndent;

  /** Sets the value of "text-indent" */
  set textIndent(String value) {
    _textIndent = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('textIndent')
  String _textIndent;

  /** Gets the value of "text-transform" */
  String get textTransform => this._textTransform;

  /** Sets the value of "text-transform" */
  set textTransform(String value) {
    _textTransform = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('textTransform')
  String _textTransform;

  /** Gets the value of "top" */
  String get top => this._top;

  /** Sets the value of "top" */
  set top(String value) {
    _top = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('top')
  String _top;

  /** Gets the value of "unicode-bidi" */
  String get unicodeBidi => this._unicodeBidi;

  /** Sets the value of "unicode-bidi" */
  set unicodeBidi(String value) {
    _unicodeBidi = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('unicodeBidi')
  String _unicodeBidi;

  /** Gets the value of "vertical-align" */
  String get verticalAlign => this._verticalAlign;

  /** Sets the value of "vertical-align" */
  set verticalAlign(String value) {
    _verticalAlign = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('verticalAlign')
  String _verticalAlign;

  /** Gets the value of "visibility" */
  String get visibility => this._visibility;

  /** Sets the value of "visibility" */
  set visibility(String value) {
    _visibility = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('visibility')
  String _visibility;

  /** Gets the value of "white-space" */
  String get whiteSpace => this._whiteSpace;

  /** Sets the value of "white-space" */
  set whiteSpace(String value) {
    _whiteSpace = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('whiteSpace')
  String _whiteSpace;

  /** Gets the value of "width" */
  String get width => this._width;

  /** Sets the value of "width" */
  set width(String value) {
    _width = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('width')
  String _width;

  /** Gets the value of "word-spacing" */
  String get wordSpacing => this._wordSpacing;

  /** Sets the value of "word-spacing" */
  set wordSpacing(String value) {
    _wordSpacing = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('wordSpacing')
  String _wordSpacing;

  /** Gets the value of "z-index" */
  String get zIndex => this._zIndex;

  /** Sets the value of "z-index" */
  set zIndex(String value) {
    _zIndex = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('zIndex')
  String _zIndex;
}

class _CssStyleDeclarationSet extends Object with CssStyleDeclarationBase {
  final Iterable<Element> _elementIterable;
  Iterable<CssStyleDeclaration> _elementCssStyleDeclarationSetIterable;

  _CssStyleDeclarationSet(this._elementIterable) {
    _elementCssStyleDeclarationSetIterable =
        new List.from(_elementIterable).map((e) => e.style);
  }

  String getPropertyValue(String propertyName) =>
      _elementCssStyleDeclarationSetIterable.first
          .getPropertyValue(propertyName);

  void setProperty(String propertyName, String value, [String priority]) {
    _elementCssStyleDeclarationSetIterable
        .forEach((e) => e.setProperty(propertyName, value, priority));
  }

  void _setAll(String propertyName, String value) {
    value = value == null ? '' : value;
    for (Element element in _elementIterable) {
      JS('void', '#.style[#] = #', element, propertyName, value);
    }
  }

  /** Sets the value of "background" */
  set background(String value) {
    _setAll('background', value);
  }

  /** Sets the value of "background-attachment" */
  set backgroundAttachment(String value) {
    _setAll('backgroundAttachment', value);
  }

  /** Sets the value of "background-color" */
  set backgroundColor(String value) {
    _setAll('backgroundColor', value);
  }

  /** Sets the value of "background-image" */
  set backgroundImage(String value) {
    _setAll('backgroundImage', value);
  }

  /** Sets the value of "background-position" */
  set backgroundPosition(String value) {
    _setAll('backgroundPosition', value);
  }

  /** Sets the value of "background-repeat" */
  set backgroundRepeat(String value) {
    _setAll('backgroundRepeat', value);
  }

  /** Sets the value of "border" */
  set border(String value) {
    _setAll('border', value);
  }

  /** Sets the value of "border-bottom" */
  set borderBottom(String value) {
    _setAll('borderBottom', value);
  }

  /** Sets the value of "border-bottom-color" */
  set borderBottomColor(String value) {
    _setAll('borderBottomColor', value);
  }

  /** Sets the value of "border-bottom-style" */
  set borderBottomStyle(String value) {
    _setAll('borderBottomStyle', value);
  }

  /** Sets the value of "border-bottom-width" */
  set borderBottomWidth(String value) {
    _setAll('borderBottomWidth', value);
  }

  /** Sets the value of "border-collapse" */
  set borderCollapse(String value) {
    _setAll('borderCollapse', value);
  }

  /** Sets the value of "border-color" */
  set borderColor(String value) {
    _setAll('borderColor', value);
  }

  /** Sets the value of "border-left" */
  set borderLeft(String value) {
    _setAll('borderLeft', value);
  }

  /** Sets the value of "border-left-color" */
  set borderLeftColor(String value) {
    _setAll('borderLeftColor', value);
  }

  /** Sets the value of "border-left-style" */
  set borderLeftStyle(String value) {
    _setAll('borderLeftStyle', value);
  }

  /** Sets the value of "border-left-width" */
  set borderLeftWidth(String value) {
    _setAll('borderLeftWidth', value);
  }

  /** Sets the value of "border-right" */
  set borderRight(String value) {
    _setAll('borderRight', value);
  }

  /** Sets the value of "border-right-color" */
  set borderRightColor(String value) {
    _setAll('borderRightColor', value);
  }

  /** Sets the value of "border-right-style" */
  set borderRightStyle(String value) {
    _setAll('borderRightStyle', value);
  }

  /** Sets the value of "border-right-width" */
  set borderRightWidth(String value) {
    _setAll('borderRightWidth', value);
  }

  /** Sets the value of "border-spacing" */
  set borderSpacing(String value) {
    _setAll('borderSpacing', value);
  }

  /** Sets the value of "border-style" */
  set borderStyle(String value) {
    _setAll('borderStyle', value);
  }

  /** Sets the value of "border-top" */
  set borderTop(String value) {
    _setAll('borderTop', value);
  }

  /** Sets the value of "border-top-color" */
  set borderTopColor(String value) {
    _setAll('borderTopColor', value);
  }

  /** Sets the value of "border-top-style" */
  set borderTopStyle(String value) {
    _setAll('borderTopStyle', value);
  }

  /** Sets the value of "border-top-width" */
  set borderTopWidth(String value) {
    _setAll('borderTopWidth', value);
  }

  /** Sets the value of "border-width" */
  set borderWidth(String value) {
    _setAll('borderWidth', value);
  }

  /** Sets the value of "bottom" */
  set bottom(String value) {
    _setAll('bottom', value);
  }

  /** Sets the value of "caption-side" */
  set captionSide(String value) {
    _setAll('captionSide', value);
  }

  /** Sets the value of "clear" */
  set clear(String value) {
    _setAll('clear', value);
  }

  /** Sets the value of "clip" */
  set clip(String value) {
    _setAll('clip', value);
  }

  /** Sets the value of "color" */
  set color(String value) {
    _setAll('color', value);
  }

  /** Sets the value of "content" */
  set content(String value) {
    _setAll('content', value);
  }

  /** Sets the value of "cursor" */
  set cursor(String value) {
    _setAll('cursor', value);
  }

  /** Sets the value of "direction" */
  set direction(String value) {
    _setAll('direction', value);
  }

  /** Sets the value of "display" */
  set display(String value) {
    _setAll('display', value);
  }

  /** Sets the value of "empty-cells" */
  set emptyCells(String value) {
    _setAll('emptyCells', value);
  }

  /** Sets the value of "font" */
  set font(String value) {
    _setAll('font', value);
  }

  /** Sets the value of "font-family" */
  set fontFamily(String value) {
    _setAll('fontFamily', value);
  }

  /** Sets the value of "font-size" */
  set fontSize(String value) {
    _setAll('fontSize', value);
  }

  /** Sets the value of "font-style" */
  set fontStyle(String value) {
    _setAll('fontStyle', value);
  }

  /** Sets the value of "font-variant" */
  set fontVariant(String value) {
    _setAll('fontVariant', value);
  }

  /** Sets the value of "font-weight" */
  set fontWeight(String value) {
    _setAll('fontWeight', value);
  }

  /** Sets the value of "height" */
  set height(String value) {
    _setAll('height', value);
  }

  /** Sets the value of "left" */
  set left(String value) {
    _setAll('left', value);
  }

  /** Sets the value of "letter-spacing" */
  set letterSpacing(String value) {
    _setAll('letterSpacing', value);
  }

  /** Sets the value of "line-height" */
  set lineHeight(String value) {
    _setAll('lineHeight', value);
  }

  /** Sets the value of "list-style" */
  set listStyle(String value) {
    _setAll('listStyle', value);
  }

  /** Sets the value of "list-style-image" */
  set listStyleImage(String value) {
    _setAll('listStyleImage', value);
  }

  /** Sets the value of "list-style-position" */
  set listStylePosition(String value) {
    _setAll('listStylePosition', value);
  }

  /** Sets the value of "list-style-type" */
  set listStyleType(String value) {
    _setAll('listStyleType', value);
  }

  /** Sets the value of "margin" */
  set margin(String value) {
    _setAll('margin', value);
  }

  /** Sets the value of "margin-bottom" */
  set marginBottom(String value) {
    _setAll('marginBottom', value);
  }

  /** Sets the value of "margin-left" */
  set marginLeft(String value) {
    _setAll('marginLeft', value);
  }

  /** Sets the value of "margin-right" */
  set marginRight(String value) {
    _setAll('marginRight', value);
  }

  /** Sets the value of "margin-top" */
  set marginTop(String value) {
    _setAll('marginTop', value);
  }

  /** Sets the value of "max-height" */
  set maxHeight(String value) {
    _setAll('maxHeight', value);
  }

  /** Sets the value of "max-width" */
  set maxWidth(String value) {
    _setAll('maxWidth', value);
  }

  /** Sets the value of "min-height" */
  set minHeight(String value) {
    _setAll('minHeight', value);
  }

  /** Sets the value of "min-width" */
  set minWidth(String value) {
    _setAll('minWidth', value);
  }

  /** Sets the value of "outline" */
  set outline(String value) {
    _setAll('outline', value);
  }

  /** Sets the value of "outline-color" */
  set outlineColor(String value) {
    _setAll('outlineColor', value);
  }

  /** Sets the value of "outline-style" */
  set outlineStyle(String value) {
    _setAll('outlineStyle', value);
  }

  /** Sets the value of "outline-width" */
  set outlineWidth(String value) {
    _setAll('outlineWidth', value);
  }

  /** Sets the value of "overflow" */
  set overflow(String value) {
    _setAll('overflow', value);
  }

  /** Sets the value of "padding" */
  set padding(String value) {
    _setAll('padding', value);
  }

  /** Sets the value of "padding-bottom" */
  set paddingBottom(String value) {
    _setAll('paddingBottom', value);
  }

  /** Sets the value of "padding-left" */
  set paddingLeft(String value) {
    _setAll('paddingLeft', value);
  }

  /** Sets the value of "padding-right" */
  set paddingRight(String value) {
    _setAll('paddingRight', value);
  }

  /** Sets the value of "padding-top" */
  set paddingTop(String value) {
    _setAll('paddingTop', value);
  }

  /** Sets the value of "page-break-after" */
  set pageBreakAfter(String value) {
    _setAll('pageBreakAfter', value);
  }

  /** Sets the value of "page-break-before" */
  set pageBreakBefore(String value) {
    _setAll('pageBreakBefore', value);
  }

  /** Sets the value of "page-break-inside" */
  set pageBreakInside(String value) {
    _setAll('pageBreakInside', value);
  }

  /** Sets the value of "position" */
  set position(String value) {
    _setAll('position', value);
  }

  /** Sets the value of "quotes" */
  set quotes(String value) {
    _setAll('quotes', value);
  }

  /** Sets the value of "right" */
  set right(String value) {
    _setAll('right', value);
  }

  /** Sets the value of "table-layout" */
  set tableLayout(String value) {
    _setAll('tableLayout', value);
  }

  /** Sets the value of "text-align" */
  set textAlign(String value) {
    _setAll('textAlign', value);
  }

  /** Sets the value of "text-decoration" */
  set textDecoration(String value) {
    _setAll('textDecoration', value);
  }

  /** Sets the value of "text-indent" */
  set textIndent(String value) {
    _setAll('textIndent', value);
  }

  /** Sets the value of "text-transform" */
  set textTransform(String value) {
    _setAll('textTransform', value);
  }

  /** Sets the value of "top" */
  set top(String value) {
    _setAll('top', value);
  }

  /** Sets the value of "unicode-bidi" */
  set unicodeBidi(String value) {
    _setAll('unicodeBidi', value);
  }

  /** Sets the value of "vertical-align" */
  set verticalAlign(String value) {
    _setAll('verticalAlign', value);
  }

  /** Sets the value of "visibility" */
  set visibility(String value) {
    _setAll('visibility', value);
  }

  /** Sets the value of "white-space" */
  set whiteSpace(String value) {
    _setAll('whiteSpace', value);
  }

  /** Sets the value of "width" */
  set width(String value) {
    _setAll('width', value);
  }

  /** Sets the value of "word-spacing" */
  set wordSpacing(String value) {
    _setAll('wordSpacing', value);
  }

  /** Sets the value of "z-index" */
  set zIndex(String value) {
    _setAll('zIndex', value);
  }

  // Important note: CssStyleDeclarationSet does NOT implement every method
  // available in CssStyleDeclaration. Some of the methods don't make so much
  // sense in terms of having a resonable value to return when you're
  // considering a list of Elements. You will need to manually add any of the
  // items in the MEMBERS set if you want that functionality.
}

abstract class CssStyleDeclarationBase {
  String getPropertyValue(String propertyName);
  void setProperty(String propertyName, String value, [String priority]);

  /** Gets the value of "align-content" */
  String get alignContent => getPropertyValue('align-content');

  /** Sets the value of "align-content" */
  set alignContent(String value) {
    setProperty('align-content', value, '');
  }

  /** Gets the value of "align-items" */
  String get alignItems => getPropertyValue('align-items');

  /** Sets the value of "align-items" */
  set alignItems(String value) {
    setProperty('align-items', value, '');
  }

  /** Gets the value of "align-self" */
  String get alignSelf => getPropertyValue('align-self');

  /** Sets the value of "align-self" */
  set alignSelf(String value) {
    setProperty('align-self', value, '');
  }

  /** Gets the value of "animation" */
  String get animation => getPropertyValue('animation');

  /** Sets the value of "animation" */
  set animation(String value) {
    setProperty('animation', value, '');
  }

  /** Gets the value of "animation-delay" */
  String get animationDelay => getPropertyValue('animation-delay');

  /** Sets the value of "animation-delay" */
  set animationDelay(String value) {
    setProperty('animation-delay', value, '');
  }

  /** Gets the value of "animation-direction" */
  String get animationDirection => getPropertyValue('animation-direction');

  /** Sets the value of "animation-direction" */
  set animationDirection(String value) {
    setProperty('animation-direction', value, '');
  }

  /** Gets the value of "animation-duration" */
  String get animationDuration => getPropertyValue('animation-duration');

  /** Sets the value of "animation-duration" */
  set animationDuration(String value) {
    setProperty('animation-duration', value, '');
  }

  /** Gets the value of "animation-fill-mode" */
  String get animationFillMode => getPropertyValue('animation-fill-mode');

  /** Sets the value of "animation-fill-mode" */
  set animationFillMode(String value) {
    setProperty('animation-fill-mode', value, '');
  }

  /** Gets the value of "animation-iteration-count" */
  String get animationIterationCount =>
      getPropertyValue('animation-iteration-count');

  /** Sets the value of "animation-iteration-count" */
  set animationIterationCount(String value) {
    setProperty('animation-iteration-count', value, '');
  }

  /** Gets the value of "animation-name" */
  String get animationName => getPropertyValue('animation-name');

  /** Sets the value of "animation-name" */
  set animationName(String value) {
    setProperty('animation-name', value, '');
  }

  /** Gets the value of "animation-play-state" */
  String get animationPlayState => getPropertyValue('animation-play-state');

  /** Sets the value of "animation-play-state" */
  set animationPlayState(String value) {
    setProperty('animation-play-state', value, '');
  }

  /** Gets the value of "animation-timing-function" */
  String get animationTimingFunction =>
      getPropertyValue('animation-timing-function');

  /** Sets the value of "animation-timing-function" */
  set animationTimingFunction(String value) {
    setProperty('animation-timing-function', value, '');
  }

  /** Gets the value of "app-region" */
  String get appRegion => getPropertyValue('app-region');

  /** Sets the value of "app-region" */
  set appRegion(String value) {
    setProperty('app-region', value, '');
  }

  /** Gets the value of "appearance" */
  String get appearance => getPropertyValue('appearance');

  /** Sets the value of "appearance" */
  set appearance(String value) {
    setProperty('appearance', value, '');
  }

  /** Gets the value of "aspect-ratio" */
  String get aspectRatio => getPropertyValue('aspect-ratio');

  /** Sets the value of "aspect-ratio" */
  set aspectRatio(String value) {
    setProperty('aspect-ratio', value, '');
  }

  /** Gets the value of "backface-visibility" */
  String get backfaceVisibility => getPropertyValue('backface-visibility');

  /** Sets the value of "backface-visibility" */
  set backfaceVisibility(String value) {
    setProperty('backface-visibility', value, '');
  }

  /** Gets the value of "background" */
  String get background => getPropertyValue('background');

  /** Sets the value of "background" */
  set background(String value) {
    setProperty('background', value, '');
  }

  /** Gets the value of "background-attachment" */
  String get backgroundAttachment => getPropertyValue('background-attachment');

  /** Sets the value of "background-attachment" */
  set backgroundAttachment(String value) {
    setProperty('background-attachment', value, '');
  }

  /** Gets the value of "background-blend-mode" */
  String get backgroundBlendMode => getPropertyValue('background-blend-mode');

  /** Sets the value of "background-blend-mode" */
  set backgroundBlendMode(String value) {
    setProperty('background-blend-mode', value, '');
  }

  /** Gets the value of "background-clip" */
  String get backgroundClip => getPropertyValue('background-clip');

  /** Sets the value of "background-clip" */
  set backgroundClip(String value) {
    setProperty('background-clip', value, '');
  }

  /** Gets the value of "background-color" */
  String get backgroundColor => getPropertyValue('background-color');

  /** Sets the value of "background-color" */
  set backgroundColor(String value) {
    setProperty('background-color', value, '');
  }

  /** Gets the value of "background-composite" */
  String get backgroundComposite => getPropertyValue('background-composite');

  /** Sets the value of "background-composite" */
  set backgroundComposite(String value) {
    setProperty('background-composite', value, '');
  }

  /** Gets the value of "background-image" */
  String get backgroundImage => getPropertyValue('background-image');

  /** Sets the value of "background-image" */
  set backgroundImage(String value) {
    setProperty('background-image', value, '');
  }

  /** Gets the value of "background-origin" */
  String get backgroundOrigin => getPropertyValue('background-origin');

  /** Sets the value of "background-origin" */
  set backgroundOrigin(String value) {
    setProperty('background-origin', value, '');
  }

  /** Gets the value of "background-position" */
  String get backgroundPosition => getPropertyValue('background-position');

  /** Sets the value of "background-position" */
  set backgroundPosition(String value) {
    setProperty('background-position', value, '');
  }

  /** Gets the value of "background-position-x" */
  String get backgroundPositionX => getPropertyValue('background-position-x');

  /** Sets the value of "background-position-x" */
  set backgroundPositionX(String value) {
    setProperty('background-position-x', value, '');
  }

  /** Gets the value of "background-position-y" */
  String get backgroundPositionY => getPropertyValue('background-position-y');

  /** Sets the value of "background-position-y" */
  set backgroundPositionY(String value) {
    setProperty('background-position-y', value, '');
  }

  /** Gets the value of "background-repeat" */
  String get backgroundRepeat => getPropertyValue('background-repeat');

  /** Sets the value of "background-repeat" */
  set backgroundRepeat(String value) {
    setProperty('background-repeat', value, '');
  }

  /** Gets the value of "background-repeat-x" */
  String get backgroundRepeatX => getPropertyValue('background-repeat-x');

  /** Sets the value of "background-repeat-x" */
  set backgroundRepeatX(String value) {
    setProperty('background-repeat-x', value, '');
  }

  /** Gets the value of "background-repeat-y" */
  String get backgroundRepeatY => getPropertyValue('background-repeat-y');

  /** Sets the value of "background-repeat-y" */
  set backgroundRepeatY(String value) {
    setProperty('background-repeat-y', value, '');
  }

  /** Gets the value of "background-size" */
  String get backgroundSize => getPropertyValue('background-size');

  /** Sets the value of "background-size" */
  set backgroundSize(String value) {
    setProperty('background-size', value, '');
  }

  /** Gets the value of "border" */
  String get border => getPropertyValue('border');

  /** Sets the value of "border" */
  set border(String value) {
    setProperty('border', value, '');
  }

  /** Gets the value of "border-after" */
  String get borderAfter => getPropertyValue('border-after');

  /** Sets the value of "border-after" */
  set borderAfter(String value) {
    setProperty('border-after', value, '');
  }

  /** Gets the value of "border-after-color" */
  String get borderAfterColor => getPropertyValue('border-after-color');

  /** Sets the value of "border-after-color" */
  set borderAfterColor(String value) {
    setProperty('border-after-color', value, '');
  }

  /** Gets the value of "border-after-style" */
  String get borderAfterStyle => getPropertyValue('border-after-style');

  /** Sets the value of "border-after-style" */
  set borderAfterStyle(String value) {
    setProperty('border-after-style', value, '');
  }

  /** Gets the value of "border-after-width" */
  String get borderAfterWidth => getPropertyValue('border-after-width');

  /** Sets the value of "border-after-width" */
  set borderAfterWidth(String value) {
    setProperty('border-after-width', value, '');
  }

  /** Gets the value of "border-before" */
  String get borderBefore => getPropertyValue('border-before');

  /** Sets the value of "border-before" */
  set borderBefore(String value) {
    setProperty('border-before', value, '');
  }

  /** Gets the value of "border-before-color" */
  String get borderBeforeColor => getPropertyValue('border-before-color');

  /** Sets the value of "border-before-color" */
  set borderBeforeColor(String value) {
    setProperty('border-before-color', value, '');
  }

  /** Gets the value of "border-before-style" */
  String get borderBeforeStyle => getPropertyValue('border-before-style');

  /** Sets the value of "border-before-style" */
  set borderBeforeStyle(String value) {
    setProperty('border-before-style', value, '');
  }

  /** Gets the value of "border-before-width" */
  String get borderBeforeWidth => getPropertyValue('border-before-width');

  /** Sets the value of "border-before-width" */
  set borderBeforeWidth(String value) {
    setProperty('border-before-width', value, '');
  }

  /** Gets the value of "border-bottom" */
  String get borderBottom => getPropertyValue('border-bottom');

  /** Sets the value of "border-bottom" */
  set borderBottom(String value) {
    setProperty('border-bottom', value, '');
  }

  /** Gets the value of "border-bottom-color" */
  String get borderBottomColor => getPropertyValue('border-bottom-color');

  /** Sets the value of "border-bottom-color" */
  set borderBottomColor(String value) {
    setProperty('border-bottom-color', value, '');
  }

  /** Gets the value of "border-bottom-left-radius" */
  String get borderBottomLeftRadius =>
      getPropertyValue('border-bottom-left-radius');

  /** Sets the value of "border-bottom-left-radius" */
  set borderBottomLeftRadius(String value) {
    setProperty('border-bottom-left-radius', value, '');
  }

  /** Gets the value of "border-bottom-right-radius" */
  String get borderBottomRightRadius =>
      getPropertyValue('border-bottom-right-radius');

  /** Sets the value of "border-bottom-right-radius" */
  set borderBottomRightRadius(String value) {
    setProperty('border-bottom-right-radius', value, '');
  }

  /** Gets the value of "border-bottom-style" */
  String get borderBottomStyle => getPropertyValue('border-bottom-style');

  /** Sets the value of "border-bottom-style" */
  set borderBottomStyle(String value) {
    setProperty('border-bottom-style', value, '');
  }

  /** Gets the value of "border-bottom-width" */
  String get borderBottomWidth => getPropertyValue('border-bottom-width');

  /** Sets the value of "border-bottom-width" */
  set borderBottomWidth(String value) {
    setProperty('border-bottom-width', value, '');
  }

  /** Gets the value of "border-collapse" */
  String get borderCollapse => getPropertyValue('border-collapse');

  /** Sets the value of "border-collapse" */
  set borderCollapse(String value) {
    setProperty('border-collapse', value, '');
  }

  /** Gets the value of "border-color" */
  String get borderColor => getPropertyValue('border-color');

  /** Sets the value of "border-color" */
  set borderColor(String value) {
    setProperty('border-color', value, '');
  }

  /** Gets the value of "border-end" */
  String get borderEnd => getPropertyValue('border-end');

  /** Sets the value of "border-end" */
  set borderEnd(String value) {
    setProperty('border-end', value, '');
  }

  /** Gets the value of "border-end-color" */
  String get borderEndColor => getPropertyValue('border-end-color');

  /** Sets the value of "border-end-color" */
  set borderEndColor(String value) {
    setProperty('border-end-color', value, '');
  }

  /** Gets the value of "border-end-style" */
  String get borderEndStyle => getPropertyValue('border-end-style');

  /** Sets the value of "border-end-style" */
  set borderEndStyle(String value) {
    setProperty('border-end-style', value, '');
  }

  /** Gets the value of "border-end-width" */
  String get borderEndWidth => getPropertyValue('border-end-width');

  /** Sets the value of "border-end-width" */
  set borderEndWidth(String value) {
    setProperty('border-end-width', value, '');
  }

  /** Gets the value of "border-fit" */
  String get borderFit => getPropertyValue('border-fit');

  /** Sets the value of "border-fit" */
  set borderFit(String value) {
    setProperty('border-fit', value, '');
  }

  /** Gets the value of "border-horizontal-spacing" */
  String get borderHorizontalSpacing =>
      getPropertyValue('border-horizontal-spacing');

  /** Sets the value of "border-horizontal-spacing" */
  set borderHorizontalSpacing(String value) {
    setProperty('border-horizontal-spacing', value, '');
  }

  /** Gets the value of "border-image" */
  String get borderImage => getPropertyValue('border-image');

  /** Sets the value of "border-image" */
  set borderImage(String value) {
    setProperty('border-image', value, '');
  }

  /** Gets the value of "border-image-outset" */
  String get borderImageOutset => getPropertyValue('border-image-outset');

  /** Sets the value of "border-image-outset" */
  set borderImageOutset(String value) {
    setProperty('border-image-outset', value, '');
  }

  /** Gets the value of "border-image-repeat" */
  String get borderImageRepeat => getPropertyValue('border-image-repeat');

  /** Sets the value of "border-image-repeat" */
  set borderImageRepeat(String value) {
    setProperty('border-image-repeat', value, '');
  }

  /** Gets the value of "border-image-slice" */
  String get borderImageSlice => getPropertyValue('border-image-slice');

  /** Sets the value of "border-image-slice" */
  set borderImageSlice(String value) {
    setProperty('border-image-slice', value, '');
  }

  /** Gets the value of "border-image-source" */
  String get borderImageSource => getPropertyValue('border-image-source');

  /** Sets the value of "border-image-source" */
  set borderImageSource(String value) {
    setProperty('border-image-source', value, '');
  }

  /** Gets the value of "border-image-width" */
  String get borderImageWidth => getPropertyValue('border-image-width');

  /** Sets the value of "border-image-width" */
  set borderImageWidth(String value) {
    setProperty('border-image-width', value, '');
  }

  /** Gets the value of "border-left" */
  String get borderLeft => getPropertyValue('border-left');

  /** Sets the value of "border-left" */
  set borderLeft(String value) {
    setProperty('border-left', value, '');
  }

  /** Gets the value of "border-left-color" */
  String get borderLeftColor => getPropertyValue('border-left-color');

  /** Sets the value of "border-left-color" */
  set borderLeftColor(String value) {
    setProperty('border-left-color', value, '');
  }

  /** Gets the value of "border-left-style" */
  String get borderLeftStyle => getPropertyValue('border-left-style');

  /** Sets the value of "border-left-style" */
  set borderLeftStyle(String value) {
    setProperty('border-left-style', value, '');
  }

  /** Gets the value of "border-left-width" */
  String get borderLeftWidth => getPropertyValue('border-left-width');

  /** Sets the value of "border-left-width" */
  set borderLeftWidth(String value) {
    setProperty('border-left-width', value, '');
  }

  /** Gets the value of "border-radius" */
  String get borderRadius => getPropertyValue('border-radius');

  /** Sets the value of "border-radius" */
  set borderRadius(String value) {
    setProperty('border-radius', value, '');
  }

  /** Gets the value of "border-right" */
  String get borderRight => getPropertyValue('border-right');

  /** Sets the value of "border-right" */
  set borderRight(String value) {
    setProperty('border-right', value, '');
  }

  /** Gets the value of "border-right-color" */
  String get borderRightColor => getPropertyValue('border-right-color');

  /** Sets the value of "border-right-color" */
  set borderRightColor(String value) {
    setProperty('border-right-color', value, '');
  }

  /** Gets the value of "border-right-style" */
  String get borderRightStyle => getPropertyValue('border-right-style');

  /** Sets the value of "border-right-style" */
  set borderRightStyle(String value) {
    setProperty('border-right-style', value, '');
  }

  /** Gets the value of "border-right-width" */
  String get borderRightWidth => getPropertyValue('border-right-width');

  /** Sets the value of "border-right-width" */
  set borderRightWidth(String value) {
    setProperty('border-right-width', value, '');
  }

  /** Gets the value of "border-spacing" */
  String get borderSpacing => getPropertyValue('border-spacing');

  /** Sets the value of "border-spacing" */
  set borderSpacing(String value) {
    setProperty('border-spacing', value, '');
  }

  /** Gets the value of "border-start" */
  String get borderStart => getPropertyValue('border-start');

  /** Sets the value of "border-start" */
  set borderStart(String value) {
    setProperty('border-start', value, '');
  }

  /** Gets the value of "border-start-color" */
  String get borderStartColor => getPropertyValue('border-start-color');

  /** Sets the value of "border-start-color" */
  set borderStartColor(String value) {
    setProperty('border-start-color', value, '');
  }

  /** Gets the value of "border-start-style" */
  String get borderStartStyle => getPropertyValue('border-start-style');

  /** Sets the value of "border-start-style" */
  set borderStartStyle(String value) {
    setProperty('border-start-style', value, '');
  }

  /** Gets the value of "border-start-width" */
  String get borderStartWidth => getPropertyValue('border-start-width');

  /** Sets the value of "border-start-width" */
  set borderStartWidth(String value) {
    setProperty('border-start-width', value, '');
  }

  /** Gets the value of "border-style" */
  String get borderStyle => getPropertyValue('border-style');

  /** Sets the value of "border-style" */
  set borderStyle(String value) {
    setProperty('border-style', value, '');
  }

  /** Gets the value of "border-top" */
  String get borderTop => getPropertyValue('border-top');

  /** Sets the value of "border-top" */
  set borderTop(String value) {
    setProperty('border-top', value, '');
  }

  /** Gets the value of "border-top-color" */
  String get borderTopColor => getPropertyValue('border-top-color');

  /** Sets the value of "border-top-color" */
  set borderTopColor(String value) {
    setProperty('border-top-color', value, '');
  }

  /** Gets the value of "border-top-left-radius" */
  String get borderTopLeftRadius => getPropertyValue('border-top-left-radius');

  /** Sets the value of "border-top-left-radius" */
  set borderTopLeftRadius(String value) {
    setProperty('border-top-left-radius', value, '');
  }

  /** Gets the value of "border-top-right-radius" */
  String get borderTopRightRadius =>
      getPropertyValue('border-top-right-radius');

  /** Sets the value of "border-top-right-radius" */
  set borderTopRightRadius(String value) {
    setProperty('border-top-right-radius', value, '');
  }

  /** Gets the value of "border-top-style" */
  String get borderTopStyle => getPropertyValue('border-top-style');

  /** Sets the value of "border-top-style" */
  set borderTopStyle(String value) {
    setProperty('border-top-style', value, '');
  }

  /** Gets the value of "border-top-width" */
  String get borderTopWidth => getPropertyValue('border-top-width');

  /** Sets the value of "border-top-width" */
  set borderTopWidth(String value) {
    setProperty('border-top-width', value, '');
  }

  /** Gets the value of "border-vertical-spacing" */
  String get borderVerticalSpacing =>
      getPropertyValue('border-vertical-spacing');

  /** Sets the value of "border-vertical-spacing" */
  set borderVerticalSpacing(String value) {
    setProperty('border-vertical-spacing', value, '');
  }

  /** Gets the value of "border-width" */
  String get borderWidth => getPropertyValue('border-width');

  /** Sets the value of "border-width" */
  set borderWidth(String value) {
    setProperty('border-width', value, '');
  }

  /** Gets the value of "bottom" */
  String get bottom => getPropertyValue('bottom');

  /** Sets the value of "bottom" */
  set bottom(String value) {
    setProperty('bottom', value, '');
  }

  /** Gets the value of "box-align" */
  String get boxAlign => getPropertyValue('box-align');

  /** Sets the value of "box-align" */
  set boxAlign(String value) {
    setProperty('box-align', value, '');
  }

  /** Gets the value of "box-decoration-break" */
  String get boxDecorationBreak => getPropertyValue('box-decoration-break');

  /** Sets the value of "box-decoration-break" */
  set boxDecorationBreak(String value) {
    setProperty('box-decoration-break', value, '');
  }

  /** Gets the value of "box-direction" */
  String get boxDirection => getPropertyValue('box-direction');

  /** Sets the value of "box-direction" */
  set boxDirection(String value) {
    setProperty('box-direction', value, '');
  }

  /** Gets the value of "box-flex" */
  String get boxFlex => getPropertyValue('box-flex');

  /** Sets the value of "box-flex" */
  set boxFlex(String value) {
    setProperty('box-flex', value, '');
  }

  /** Gets the value of "box-flex-group" */
  String get boxFlexGroup => getPropertyValue('box-flex-group');

  /** Sets the value of "box-flex-group" */
  set boxFlexGroup(String value) {
    setProperty('box-flex-group', value, '');
  }

  /** Gets the value of "box-lines" */
  String get boxLines => getPropertyValue('box-lines');

  /** Sets the value of "box-lines" */
  set boxLines(String value) {
    setProperty('box-lines', value, '');
  }

  /** Gets the value of "box-ordinal-group" */
  String get boxOrdinalGroup => getPropertyValue('box-ordinal-group');

  /** Sets the value of "box-ordinal-group" */
  set boxOrdinalGroup(String value) {
    setProperty('box-ordinal-group', value, '');
  }

  /** Gets the value of "box-orient" */
  String get boxOrient => getPropertyValue('box-orient');

  /** Sets the value of "box-orient" */
  set boxOrient(String value) {
    setProperty('box-orient', value, '');
  }

  /** Gets the value of "box-pack" */
  String get boxPack => getPropertyValue('box-pack');

  /** Sets the value of "box-pack" */
  set boxPack(String value) {
    setProperty('box-pack', value, '');
  }

  /** Gets the value of "box-reflect" */
  String get boxReflect => getPropertyValue('box-reflect');

  /** Sets the value of "box-reflect" */
  set boxReflect(String value) {
    setProperty('box-reflect', value, '');
  }

  /** Gets the value of "box-shadow" */
  String get boxShadow => getPropertyValue('box-shadow');

  /** Sets the value of "box-shadow" */
  set boxShadow(String value) {
    setProperty('box-shadow', value, '');
  }

  /** Gets the value of "box-sizing" */
  String get boxSizing => getPropertyValue('box-sizing');

  /** Sets the value of "box-sizing" */
  set boxSizing(String value) {
    setProperty('box-sizing', value, '');
  }

  /** Gets the value of "caption-side" */
  String get captionSide => getPropertyValue('caption-side');

  /** Sets the value of "caption-side" */
  set captionSide(String value) {
    setProperty('caption-side', value, '');
  }

  /** Gets the value of "clear" */
  String get clear => getPropertyValue('clear');

  /** Sets the value of "clear" */
  set clear(String value) {
    setProperty('clear', value, '');
  }

  /** Gets the value of "clip" */
  String get clip => getPropertyValue('clip');

  /** Sets the value of "clip" */
  set clip(String value) {
    setProperty('clip', value, '');
  }

  /** Gets the value of "clip-path" */
  String get clipPath => getPropertyValue('clip-path');

  /** Sets the value of "clip-path" */
  set clipPath(String value) {
    setProperty('clip-path', value, '');
  }

  /** Gets the value of "color" */
  String get color => getPropertyValue('color');

  /** Sets the value of "color" */
  set color(String value) {
    setProperty('color', value, '');
  }

  /** Gets the value of "column-break-after" */
  String get columnBreakAfter => getPropertyValue('column-break-after');

  /** Sets the value of "column-break-after" */
  set columnBreakAfter(String value) {
    setProperty('column-break-after', value, '');
  }

  /** Gets the value of "column-break-before" */
  String get columnBreakBefore => getPropertyValue('column-break-before');

  /** Sets the value of "column-break-before" */
  set columnBreakBefore(String value) {
    setProperty('column-break-before', value, '');
  }

  /** Gets the value of "column-break-inside" */
  String get columnBreakInside => getPropertyValue('column-break-inside');

  /** Sets the value of "column-break-inside" */
  set columnBreakInside(String value) {
    setProperty('column-break-inside', value, '');
  }

  /** Gets the value of "column-count" */
  String get columnCount => getPropertyValue('column-count');

  /** Sets the value of "column-count" */
  set columnCount(String value) {
    setProperty('column-count', value, '');
  }

  /** Gets the value of "column-fill" */
  String get columnFill => getPropertyValue('column-fill');

  /** Sets the value of "column-fill" */
  set columnFill(String value) {
    setProperty('column-fill', value, '');
  }

  /** Gets the value of "column-gap" */
  String get columnGap => getPropertyValue('column-gap');

  /** Sets the value of "column-gap" */
  set columnGap(String value) {
    setProperty('column-gap', value, '');
  }

  /** Gets the value of "column-rule" */
  String get columnRule => getPropertyValue('column-rule');

  /** Sets the value of "column-rule" */
  set columnRule(String value) {
    setProperty('column-rule', value, '');
  }

  /** Gets the value of "column-rule-color" */
  String get columnRuleColor => getPropertyValue('column-rule-color');

  /** Sets the value of "column-rule-color" */
  set columnRuleColor(String value) {
    setProperty('column-rule-color', value, '');
  }

  /** Gets the value of "column-rule-style" */
  String get columnRuleStyle => getPropertyValue('column-rule-style');

  /** Sets the value of "column-rule-style" */
  set columnRuleStyle(String value) {
    setProperty('column-rule-style', value, '');
  }

  /** Gets the value of "column-rule-width" */
  String get columnRuleWidth => getPropertyValue('column-rule-width');

  /** Sets the value of "column-rule-width" */
  set columnRuleWidth(String value) {
    setProperty('column-rule-width', value, '');
  }

  /** Gets the value of "column-span" */
  String get columnSpan => getPropertyValue('column-span');

  /** Sets the value of "column-span" */
  set columnSpan(String value) {
    setProperty('column-span', value, '');
  }

  /** Gets the value of "column-width" */
  String get columnWidth => getPropertyValue('column-width');

  /** Sets the value of "column-width" */
  set columnWidth(String value) {
    setProperty('column-width', value, '');
  }

  /** Gets the value of "columns" */
  String get columns => getPropertyValue('columns');

  /** Sets the value of "columns" */
  set columns(String value) {
    setProperty('columns', value, '');
  }

  /** Gets the value of "content" */
  String get content => getPropertyValue('content');

  /** Sets the value of "content" */
  set content(String value) {
    setProperty('content', value, '');
  }

  /** Gets the value of "counter-increment" */
  String get counterIncrement => getPropertyValue('counter-increment');

  /** Sets the value of "counter-increment" */
  set counterIncrement(String value) {
    setProperty('counter-increment', value, '');
  }

  /** Gets the value of "counter-reset" */
  String get counterReset => getPropertyValue('counter-reset');

  /** Sets the value of "counter-reset" */
  set counterReset(String value) {
    setProperty('counter-reset', value, '');
  }

  /** Gets the value of "cursor" */
  String get cursor => getPropertyValue('cursor');

  /** Sets the value of "cursor" */
  set cursor(String value) {
    setProperty('cursor', value, '');
  }

  /** Gets the value of "direction" */
  String get direction => getPropertyValue('direction');

  /** Sets the value of "direction" */
  set direction(String value) {
    setProperty('direction', value, '');
  }

  /** Gets the value of "display" */
  String get display => getPropertyValue('display');

  /** Sets the value of "display" */
  set display(String value) {
    setProperty('display', value, '');
  }

  /** Gets the value of "empty-cells" */
  String get emptyCells => getPropertyValue('empty-cells');

  /** Sets the value of "empty-cells" */
  set emptyCells(String value) {
    setProperty('empty-cells', value, '');
  }

  /** Gets the value of "filter" */
  String get filter => getPropertyValue('filter');

  /** Sets the value of "filter" */
  set filter(String value) {
    setProperty('filter', value, '');
  }

  /** Gets the value of "flex" */
  String get flex => getPropertyValue('flex');

  /** Sets the value of "flex" */
  set flex(String value) {
    setProperty('flex', value, '');
  }

  /** Gets the value of "flex-basis" */
  String get flexBasis => getPropertyValue('flex-basis');

  /** Sets the value of "flex-basis" */
  set flexBasis(String value) {
    setProperty('flex-basis', value, '');
  }

  /** Gets the value of "flex-direction" */
  String get flexDirection => getPropertyValue('flex-direction');

  /** Sets the value of "flex-direction" */
  set flexDirection(String value) {
    setProperty('flex-direction', value, '');
  }

  /** Gets the value of "flex-flow" */
  String get flexFlow => getPropertyValue('flex-flow');

  /** Sets the value of "flex-flow" */
  set flexFlow(String value) {
    setProperty('flex-flow', value, '');
  }

  /** Gets the value of "flex-grow" */
  String get flexGrow => getPropertyValue('flex-grow');

  /** Sets the value of "flex-grow" */
  set flexGrow(String value) {
    setProperty('flex-grow', value, '');
  }

  /** Gets the value of "flex-shrink" */
  String get flexShrink => getPropertyValue('flex-shrink');

  /** Sets the value of "flex-shrink" */
  set flexShrink(String value) {
    setProperty('flex-shrink', value, '');
  }

  /** Gets the value of "flex-wrap" */
  String get flexWrap => getPropertyValue('flex-wrap');

  /** Sets the value of "flex-wrap" */
  set flexWrap(String value) {
    setProperty('flex-wrap', value, '');
  }

  /** Gets the value of "float" */
  String get float => getPropertyValue('float');

  /** Sets the value of "float" */
  set float(String value) {
    setProperty('float', value, '');
  }

  /** Gets the value of "font" */
  String get font => getPropertyValue('font');

  /** Sets the value of "font" */
  set font(String value) {
    setProperty('font', value, '');
  }

  /** Gets the value of "font-family" */
  String get fontFamily => getPropertyValue('font-family');

  /** Sets the value of "font-family" */
  set fontFamily(String value) {
    setProperty('font-family', value, '');
  }

  /** Gets the value of "font-feature-settings" */
  String get fontFeatureSettings => getPropertyValue('font-feature-settings');

  /** Sets the value of "font-feature-settings" */
  set fontFeatureSettings(String value) {
    setProperty('font-feature-settings', value, '');
  }

  /** Gets the value of "font-kerning" */
  String get fontKerning => getPropertyValue('font-kerning');

  /** Sets the value of "font-kerning" */
  set fontKerning(String value) {
    setProperty('font-kerning', value, '');
  }

  /** Gets the value of "font-size" */
  String get fontSize => getPropertyValue('font-size');

  /** Sets the value of "font-size" */
  set fontSize(String value) {
    setProperty('font-size', value, '');
  }

  /** Gets the value of "font-size-delta" */
  String get fontSizeDelta => getPropertyValue('font-size-delta');

  /** Sets the value of "font-size-delta" */
  set fontSizeDelta(String value) {
    setProperty('font-size-delta', value, '');
  }

  /** Gets the value of "font-smoothing" */
  String get fontSmoothing => getPropertyValue('font-smoothing');

  /** Sets the value of "font-smoothing" */
  set fontSmoothing(String value) {
    setProperty('font-smoothing', value, '');
  }

  /** Gets the value of "font-stretch" */
  String get fontStretch => getPropertyValue('font-stretch');

  /** Sets the value of "font-stretch" */
  set fontStretch(String value) {
    setProperty('font-stretch', value, '');
  }

  /** Gets the value of "font-style" */
  String get fontStyle => getPropertyValue('font-style');

  /** Sets the value of "font-style" */
  set fontStyle(String value) {
    setProperty('font-style', value, '');
  }

  /** Gets the value of "font-variant" */
  String get fontVariant => getPropertyValue('font-variant');

  /** Sets the value of "font-variant" */
  set fontVariant(String value) {
    setProperty('font-variant', value, '');
  }

  /** Gets the value of "font-variant-ligatures" */
  String get fontVariantLigatures => getPropertyValue('font-variant-ligatures');

  /** Sets the value of "font-variant-ligatures" */
  set fontVariantLigatures(String value) {
    setProperty('font-variant-ligatures', value, '');
  }

  /** Gets the value of "font-weight" */
  String get fontWeight => getPropertyValue('font-weight');

  /** Sets the value of "font-weight" */
  set fontWeight(String value) {
    setProperty('font-weight', value, '');
  }

  /** Gets the value of "grid" */
  String get grid => getPropertyValue('grid');

  /** Sets the value of "grid" */
  set grid(String value) {
    setProperty('grid', value, '');
  }

  /** Gets the value of "grid-area" */
  String get gridArea => getPropertyValue('grid-area');

  /** Sets the value of "grid-area" */
  set gridArea(String value) {
    setProperty('grid-area', value, '');
  }

  /** Gets the value of "grid-auto-columns" */
  String get gridAutoColumns => getPropertyValue('grid-auto-columns');

  /** Sets the value of "grid-auto-columns" */
  set gridAutoColumns(String value) {
    setProperty('grid-auto-columns', value, '');
  }

  /** Gets the value of "grid-auto-flow" */
  String get gridAutoFlow => getPropertyValue('grid-auto-flow');

  /** Sets the value of "grid-auto-flow" */
  set gridAutoFlow(String value) {
    setProperty('grid-auto-flow', value, '');
  }

  /** Gets the value of "grid-auto-rows" */
  String get gridAutoRows => getPropertyValue('grid-auto-rows');

  /** Sets the value of "grid-auto-rows" */
  set gridAutoRows(String value) {
    setProperty('grid-auto-rows', value, '');
  }

  /** Gets the value of "grid-column" */
  String get gridColumn => getPropertyValue('grid-column');

  /** Sets the value of "grid-column" */
  set gridColumn(String value) {
    setProperty('grid-column', value, '');
  }

  /** Gets the value of "grid-column-end" */
  String get gridColumnEnd => getPropertyValue('grid-column-end');

  /** Sets the value of "grid-column-end" */
  set gridColumnEnd(String value) {
    setProperty('grid-column-end', value, '');
  }

  /** Gets the value of "grid-column-start" */
  String get gridColumnStart => getPropertyValue('grid-column-start');

  /** Sets the value of "grid-column-start" */
  set gridColumnStart(String value) {
    setProperty('grid-column-start', value, '');
  }

  /** Gets the value of "grid-row" */
  String get gridRow => getPropertyValue('grid-row');

  /** Sets the value of "grid-row" */
  set gridRow(String value) {
    setProperty('grid-row', value, '');
  }

  /** Gets the value of "grid-row-end" */
  String get gridRowEnd => getPropertyValue('grid-row-end');

  /** Sets the value of "grid-row-end" */
  set gridRowEnd(String value) {
    setProperty('grid-row-end', value, '');
  }

  /** Gets the value of "grid-row-start" */
  String get gridRowStart => getPropertyValue('grid-row-start');

  /** Sets the value of "grid-row-start" */
  set gridRowStart(String value) {
    setProperty('grid-row-start', value, '');
  }

  /** Gets the value of "grid-template" */
  String get gridTemplate => getPropertyValue('grid-template');

  /** Sets the value of "grid-template" */
  set gridTemplate(String value) {
    setProperty('grid-template', value, '');
  }

  /** Gets the value of "grid-template-areas" */
  String get gridTemplateAreas => getPropertyValue('grid-template-areas');

  /** Sets the value of "grid-template-areas" */
  set gridTemplateAreas(String value) {
    setProperty('grid-template-areas', value, '');
  }

  /** Gets the value of "grid-template-columns" */
  String get gridTemplateColumns => getPropertyValue('grid-template-columns');

  /** Sets the value of "grid-template-columns" */
  set gridTemplateColumns(String value) {
    setProperty('grid-template-columns', value, '');
  }

  /** Gets the value of "grid-template-rows" */
  String get gridTemplateRows => getPropertyValue('grid-template-rows');

  /** Sets the value of "grid-template-rows" */
  set gridTemplateRows(String value) {
    setProperty('grid-template-rows', value, '');
  }

  /** Gets the value of "height" */
  String get height => getPropertyValue('height');

  /** Sets the value of "height" */
  set height(String value) {
    setProperty('height', value, '');
  }

  /** Gets the value of "highlight" */
  String get highlight => getPropertyValue('highlight');

  /** Sets the value of "highlight" */
  set highlight(String value) {
    setProperty('highlight', value, '');
  }

  /** Gets the value of "hyphenate-character" */
  String get hyphenateCharacter => getPropertyValue('hyphenate-character');

  /** Sets the value of "hyphenate-character" */
  set hyphenateCharacter(String value) {
    setProperty('hyphenate-character', value, '');
  }

  /** Gets the value of "image-rendering" */
  String get imageRendering => getPropertyValue('image-rendering');

  /** Sets the value of "image-rendering" */
  set imageRendering(String value) {
    setProperty('image-rendering', value, '');
  }

  /** Gets the value of "isolation" */
  String get isolation => getPropertyValue('isolation');

  /** Sets the value of "isolation" */
  set isolation(String value) {
    setProperty('isolation', value, '');
  }

  /** Gets the value of "justify-content" */
  String get justifyContent => getPropertyValue('justify-content');

  /** Sets the value of "justify-content" */
  set justifyContent(String value) {
    setProperty('justify-content', value, '');
  }

  /** Gets the value of "justify-self" */
  String get justifySelf => getPropertyValue('justify-self');

  /** Sets the value of "justify-self" */
  set justifySelf(String value) {
    setProperty('justify-self', value, '');
  }

  /** Gets the value of "left" */
  String get left => getPropertyValue('left');

  /** Sets the value of "left" */
  set left(String value) {
    setProperty('left', value, '');
  }

  /** Gets the value of "letter-spacing" */
  String get letterSpacing => getPropertyValue('letter-spacing');

  /** Sets the value of "letter-spacing" */
  set letterSpacing(String value) {
    setProperty('letter-spacing', value, '');
  }

  /** Gets the value of "line-box-contain" */
  String get lineBoxContain => getPropertyValue('line-box-contain');

  /** Sets the value of "line-box-contain" */
  set lineBoxContain(String value) {
    setProperty('line-box-contain', value, '');
  }

  /** Gets the value of "line-break" */
  String get lineBreak => getPropertyValue('line-break');

  /** Sets the value of "line-break" */
  set lineBreak(String value) {
    setProperty('line-break', value, '');
  }

  /** Gets the value of "line-clamp" */
  String get lineClamp => getPropertyValue('line-clamp');

  /** Sets the value of "line-clamp" */
  set lineClamp(String value) {
    setProperty('line-clamp', value, '');
  }

  /** Gets the value of "line-height" */
  String get lineHeight => getPropertyValue('line-height');

  /** Sets the value of "line-height" */
  set lineHeight(String value) {
    setProperty('line-height', value, '');
  }

  /** Gets the value of "list-style" */
  String get listStyle => getPropertyValue('list-style');

  /** Sets the value of "list-style" */
  set listStyle(String value) {
    setProperty('list-style', value, '');
  }

  /** Gets the value of "list-style-image" */
  String get listStyleImage => getPropertyValue('list-style-image');

  /** Sets the value of "list-style-image" */
  set listStyleImage(String value) {
    setProperty('list-style-image', value, '');
  }

  /** Gets the value of "list-style-position" */
  String get listStylePosition => getPropertyValue('list-style-position');

  /** Sets the value of "list-style-position" */
  set listStylePosition(String value) {
    setProperty('list-style-position', value, '');
  }

  /** Gets the value of "list-style-type" */
  String get listStyleType => getPropertyValue('list-style-type');

  /** Sets the value of "list-style-type" */
  set listStyleType(String value) {
    setProperty('list-style-type', value, '');
  }

  /** Gets the value of "locale" */
  String get locale => getPropertyValue('locale');

  /** Sets the value of "locale" */
  set locale(String value) {
    setProperty('locale', value, '');
  }

  /** Gets the value of "logical-height" */
  String get logicalHeight => getPropertyValue('logical-height');

  /** Sets the value of "logical-height" */
  set logicalHeight(String value) {
    setProperty('logical-height', value, '');
  }

  /** Gets the value of "logical-width" */
  String get logicalWidth => getPropertyValue('logical-width');

  /** Sets the value of "logical-width" */
  set logicalWidth(String value) {
    setProperty('logical-width', value, '');
  }

  /** Gets the value of "margin" */
  String get margin => getPropertyValue('margin');

  /** Sets the value of "margin" */
  set margin(String value) {
    setProperty('margin', value, '');
  }

  /** Gets the value of "margin-after" */
  String get marginAfter => getPropertyValue('margin-after');

  /** Sets the value of "margin-after" */
  set marginAfter(String value) {
    setProperty('margin-after', value, '');
  }

  /** Gets the value of "margin-after-collapse" */
  String get marginAfterCollapse => getPropertyValue('margin-after-collapse');

  /** Sets the value of "margin-after-collapse" */
  set marginAfterCollapse(String value) {
    setProperty('margin-after-collapse', value, '');
  }

  /** Gets the value of "margin-before" */
  String get marginBefore => getPropertyValue('margin-before');

  /** Sets the value of "margin-before" */
  set marginBefore(String value) {
    setProperty('margin-before', value, '');
  }

  /** Gets the value of "margin-before-collapse" */
  String get marginBeforeCollapse => getPropertyValue('margin-before-collapse');

  /** Sets the value of "margin-before-collapse" */
  set marginBeforeCollapse(String value) {
    setProperty('margin-before-collapse', value, '');
  }

  /** Gets the value of "margin-bottom" */
  String get marginBottom => getPropertyValue('margin-bottom');

  /** Sets the value of "margin-bottom" */
  set marginBottom(String value) {
    setProperty('margin-bottom', value, '');
  }

  /** Gets the value of "margin-bottom-collapse" */
  String get marginBottomCollapse => getPropertyValue('margin-bottom-collapse');

  /** Sets the value of "margin-bottom-collapse" */
  set marginBottomCollapse(String value) {
    setProperty('margin-bottom-collapse', value, '');
  }

  /** Gets the value of "margin-collapse" */
  String get marginCollapse => getPropertyValue('margin-collapse');

  /** Sets the value of "margin-collapse" */
  set marginCollapse(String value) {
    setProperty('margin-collapse', value, '');
  }

  /** Gets the value of "margin-end" */
  String get marginEnd => getPropertyValue('margin-end');

  /** Sets the value of "margin-end" */
  set marginEnd(String value) {
    setProperty('margin-end', value, '');
  }

  /** Gets the value of "margin-left" */
  String get marginLeft => getPropertyValue('margin-left');

  /** Sets the value of "margin-left" */
  set marginLeft(String value) {
    setProperty('margin-left', value, '');
  }

  /** Gets the value of "margin-right" */
  String get marginRight => getPropertyValue('margin-right');

  /** Sets the value of "margin-right" */
  set marginRight(String value) {
    setProperty('margin-right', value, '');
  }

  /** Gets the value of "margin-start" */
  String get marginStart => getPropertyValue('margin-start');

  /** Sets the value of "margin-start" */
  set marginStart(String value) {
    setProperty('margin-start', value, '');
  }

  /** Gets the value of "margin-top" */
  String get marginTop => getPropertyValue('margin-top');

  /** Sets the value of "margin-top" */
  set marginTop(String value) {
    setProperty('margin-top', value, '');
  }

  /** Gets the value of "margin-top-collapse" */
  String get marginTopCollapse => getPropertyValue('margin-top-collapse');

  /** Sets the value of "margin-top-collapse" */
  set marginTopCollapse(String value) {
    setProperty('margin-top-collapse', value, '');
  }

  /** Gets the value of "mask" */
  String get mask => getPropertyValue('mask');

  /** Sets the value of "mask" */
  set mask(String value) {
    setProperty('mask', value, '');
  }

  /** Gets the value of "mask-box-image" */
  String get maskBoxImage => getPropertyValue('mask-box-image');

  /** Sets the value of "mask-box-image" */
  set maskBoxImage(String value) {
    setProperty('mask-box-image', value, '');
  }

  /** Gets the value of "mask-box-image-outset" */
  String get maskBoxImageOutset => getPropertyValue('mask-box-image-outset');

  /** Sets the value of "mask-box-image-outset" */
  set maskBoxImageOutset(String value) {
    setProperty('mask-box-image-outset', value, '');
  }

  /** Gets the value of "mask-box-image-repeat" */
  String get maskBoxImageRepeat => getPropertyValue('mask-box-image-repeat');

  /** Sets the value of "mask-box-image-repeat" */
  set maskBoxImageRepeat(String value) {
    setProperty('mask-box-image-repeat', value, '');
  }

  /** Gets the value of "mask-box-image-slice" */
  String get maskBoxImageSlice => getPropertyValue('mask-box-image-slice');

  /** Sets the value of "mask-box-image-slice" */
  set maskBoxImageSlice(String value) {
    setProperty('mask-box-image-slice', value, '');
  }

  /** Gets the value of "mask-box-image-source" */
  String get maskBoxImageSource => getPropertyValue('mask-box-image-source');

  /** Sets the value of "mask-box-image-source" */
  set maskBoxImageSource(String value) {
    setProperty('mask-box-image-source', value, '');
  }

  /** Gets the value of "mask-box-image-width" */
  String get maskBoxImageWidth => getPropertyValue('mask-box-image-width');

  /** Sets the value of "mask-box-image-width" */
  set maskBoxImageWidth(String value) {
    setProperty('mask-box-image-width', value, '');
  }

  /** Gets the value of "mask-clip" */
  String get maskClip => getPropertyValue('mask-clip');

  /** Sets the value of "mask-clip" */
  set maskClip(String value) {
    setProperty('mask-clip', value, '');
  }

  /** Gets the value of "mask-composite" */
  String get maskComposite => getPropertyValue('mask-composite');

  /** Sets the value of "mask-composite" */
  set maskComposite(String value) {
    setProperty('mask-composite', value, '');
  }

  /** Gets the value of "mask-image" */
  String get maskImage => getPropertyValue('mask-image');

  /** Sets the value of "mask-image" */
  set maskImage(String value) {
    setProperty('mask-image', value, '');
  }

  /** Gets the value of "mask-origin" */
  String get maskOrigin => getPropertyValue('mask-origin');

  /** Sets the value of "mask-origin" */
  set maskOrigin(String value) {
    setProperty('mask-origin', value, '');
  }

  /** Gets the value of "mask-position" */
  String get maskPosition => getPropertyValue('mask-position');

  /** Sets the value of "mask-position" */
  set maskPosition(String value) {
    setProperty('mask-position', value, '');
  }

  /** Gets the value of "mask-position-x" */
  String get maskPositionX => getPropertyValue('mask-position-x');

  /** Sets the value of "mask-position-x" */
  set maskPositionX(String value) {
    setProperty('mask-position-x', value, '');
  }

  /** Gets the value of "mask-position-y" */
  String get maskPositionY => getPropertyValue('mask-position-y');

  /** Sets the value of "mask-position-y" */
  set maskPositionY(String value) {
    setProperty('mask-position-y', value, '');
  }

  /** Gets the value of "mask-repeat" */
  String get maskRepeat => getPropertyValue('mask-repeat');

  /** Sets the value of "mask-repeat" */
  set maskRepeat(String value) {
    setProperty('mask-repeat', value, '');
  }

  /** Gets the value of "mask-repeat-x" */
  String get maskRepeatX => getPropertyValue('mask-repeat-x');

  /** Sets the value of "mask-repeat-x" */
  set maskRepeatX(String value) {
    setProperty('mask-repeat-x', value, '');
  }

  /** Gets the value of "mask-repeat-y" */
  String get maskRepeatY => getPropertyValue('mask-repeat-y');

  /** Sets the value of "mask-repeat-y" */
  set maskRepeatY(String value) {
    setProperty('mask-repeat-y', value, '');
  }

  /** Gets the value of "mask-size" */
  String get maskSize => getPropertyValue('mask-size');

  /** Sets the value of "mask-size" */
  set maskSize(String value) {
    setProperty('mask-size', value, '');
  }

  /** Gets the value of "mask-source-type" */
  String get maskSourceType => getPropertyValue('mask-source-type');

  /** Sets the value of "mask-source-type" */
  set maskSourceType(String value) {
    setProperty('mask-source-type', value, '');
  }

  /** Gets the value of "max-height" */
  String get maxHeight => getPropertyValue('max-height');

  /** Sets the value of "max-height" */
  set maxHeight(String value) {
    setProperty('max-height', value, '');
  }

  /** Gets the value of "max-logical-height" */
  String get maxLogicalHeight => getPropertyValue('max-logical-height');

  /** Sets the value of "max-logical-height" */
  set maxLogicalHeight(String value) {
    setProperty('max-logical-height', value, '');
  }

  /** Gets the value of "max-logical-width" */
  String get maxLogicalWidth => getPropertyValue('max-logical-width');

  /** Sets the value of "max-logical-width" */
  set maxLogicalWidth(String value) {
    setProperty('max-logical-width', value, '');
  }

  /** Gets the value of "max-width" */
  String get maxWidth => getPropertyValue('max-width');

  /** Sets the value of "max-width" */
  set maxWidth(String value) {
    setProperty('max-width', value, '');
  }

  /** Gets the value of "max-zoom" */
  String get maxZoom => getPropertyValue('max-zoom');

  /** Sets the value of "max-zoom" */
  set maxZoom(String value) {
    setProperty('max-zoom', value, '');
  }

  /** Gets the value of "min-height" */
  String get minHeight => getPropertyValue('min-height');

  /** Sets the value of "min-height" */
  set minHeight(String value) {
    setProperty('min-height', value, '');
  }

  /** Gets the value of "min-logical-height" */
  String get minLogicalHeight => getPropertyValue('min-logical-height');

  /** Sets the value of "min-logical-height" */
  set minLogicalHeight(String value) {
    setProperty('min-logical-height', value, '');
  }

  /** Gets the value of "min-logical-width" */
  String get minLogicalWidth => getPropertyValue('min-logical-width');

  /** Sets the value of "min-logical-width" */
  set minLogicalWidth(String value) {
    setProperty('min-logical-width', value, '');
  }

  /** Gets the value of "min-width" */
  String get minWidth => getPropertyValue('min-width');

  /** Sets the value of "min-width" */
  set minWidth(String value) {
    setProperty('min-width', value, '');
  }

  /** Gets the value of "min-zoom" */
  String get minZoom => getPropertyValue('min-zoom');

  /** Sets the value of "min-zoom" */
  set minZoom(String value) {
    setProperty('min-zoom', value, '');
  }

  /** Gets the value of "mix-blend-mode" */
  String get mixBlendMode => getPropertyValue('mix-blend-mode');

  /** Sets the value of "mix-blend-mode" */
  set mixBlendMode(String value) {
    setProperty('mix-blend-mode', value, '');
  }

  /** Gets the value of "object-fit" */
  String get objectFit => getPropertyValue('object-fit');

  /** Sets the value of "object-fit" */
  set objectFit(String value) {
    setProperty('object-fit', value, '');
  }

  /** Gets the value of "object-position" */
  String get objectPosition => getPropertyValue('object-position');

  /** Sets the value of "object-position" */
  set objectPosition(String value) {
    setProperty('object-position', value, '');
  }

  /** Gets the value of "opacity" */
  String get opacity => getPropertyValue('opacity');

  /** Sets the value of "opacity" */
  set opacity(String value) {
    setProperty('opacity', value, '');
  }

  /** Gets the value of "order" */
  String get order => getPropertyValue('order');

  /** Sets the value of "order" */
  set order(String value) {
    setProperty('order', value, '');
  }

  /** Gets the value of "orientation" */
  String get orientation => getPropertyValue('orientation');

  /** Sets the value of "orientation" */
  set orientation(String value) {
    setProperty('orientation', value, '');
  }

  /** Gets the value of "orphans" */
  String get orphans => getPropertyValue('orphans');

  /** Sets the value of "orphans" */
  set orphans(String value) {
    setProperty('orphans', value, '');
  }

  /** Gets the value of "outline" */
  String get outline => getPropertyValue('outline');

  /** Sets the value of "outline" */
  set outline(String value) {
    setProperty('outline', value, '');
  }

  /** Gets the value of "outline-color" */
  String get outlineColor => getPropertyValue('outline-color');

  /** Sets the value of "outline-color" */
  set outlineColor(String value) {
    setProperty('outline-color', value, '');
  }

  /** Gets the value of "outline-offset" */
  String get outlineOffset => getPropertyValue('outline-offset');

  /** Sets the value of "outline-offset" */
  set outlineOffset(String value) {
    setProperty('outline-offset', value, '');
  }

  /** Gets the value of "outline-style" */
  String get outlineStyle => getPropertyValue('outline-style');

  /** Sets the value of "outline-style" */
  set outlineStyle(String value) {
    setProperty('outline-style', value, '');
  }

  /** Gets the value of "outline-width" */
  String get outlineWidth => getPropertyValue('outline-width');

  /** Sets the value of "outline-width" */
  set outlineWidth(String value) {
    setProperty('outline-width', value, '');
  }

  /** Gets the value of "overflow" */
  String get overflow => getPropertyValue('overflow');

  /** Sets the value of "overflow" */
  set overflow(String value) {
    setProperty('overflow', value, '');
  }

  /** Gets the value of "overflow-wrap" */
  String get overflowWrap => getPropertyValue('overflow-wrap');

  /** Sets the value of "overflow-wrap" */
  set overflowWrap(String value) {
    setProperty('overflow-wrap', value, '');
  }

  /** Gets the value of "overflow-x" */
  String get overflowX => getPropertyValue('overflow-x');

  /** Sets the value of "overflow-x" */
  set overflowX(String value) {
    setProperty('overflow-x', value, '');
  }

  /** Gets the value of "overflow-y" */
  String get overflowY => getPropertyValue('overflow-y');

  /** Sets the value of "overflow-y" */
  set overflowY(String value) {
    setProperty('overflow-y', value, '');
  }

  /** Gets the value of "padding" */
  String get padding => getPropertyValue('padding');

  /** Sets the value of "padding" */
  set padding(String value) {
    setProperty('padding', value, '');
  }

  /** Gets the value of "padding-after" */
  String get paddingAfter => getPropertyValue('padding-after');

  /** Sets the value of "padding-after" */
  set paddingAfter(String value) {
    setProperty('padding-after', value, '');
  }

  /** Gets the value of "padding-before" */
  String get paddingBefore => getPropertyValue('padding-before');

  /** Sets the value of "padding-before" */
  set paddingBefore(String value) {
    setProperty('padding-before', value, '');
  }

  /** Gets the value of "padding-bottom" */
  String get paddingBottom => getPropertyValue('padding-bottom');

  /** Sets the value of "padding-bottom" */
  set paddingBottom(String value) {
    setProperty('padding-bottom', value, '');
  }

  /** Gets the value of "padding-end" */
  String get paddingEnd => getPropertyValue('padding-end');

  /** Sets the value of "padding-end" */
  set paddingEnd(String value) {
    setProperty('padding-end', value, '');
  }

  /** Gets the value of "padding-left" */
  String get paddingLeft => getPropertyValue('padding-left');

  /** Sets the value of "padding-left" */
  set paddingLeft(String value) {
    setProperty('padding-left', value, '');
  }

  /** Gets the value of "padding-right" */
  String get paddingRight => getPropertyValue('padding-right');

  /** Sets the value of "padding-right" */
  set paddingRight(String value) {
    setProperty('padding-right', value, '');
  }

  /** Gets the value of "padding-start" */
  String get paddingStart => getPropertyValue('padding-start');

  /** Sets the value of "padding-start" */
  set paddingStart(String value) {
    setProperty('padding-start', value, '');
  }

  /** Gets the value of "padding-top" */
  String get paddingTop => getPropertyValue('padding-top');

  /** Sets the value of "padding-top" */
  set paddingTop(String value) {
    setProperty('padding-top', value, '');
  }

  /** Gets the value of "page" */
  String get page => getPropertyValue('page');

  /** Sets the value of "page" */
  set page(String value) {
    setProperty('page', value, '');
  }

  /** Gets the value of "page-break-after" */
  String get pageBreakAfter => getPropertyValue('page-break-after');

  /** Sets the value of "page-break-after" */
  set pageBreakAfter(String value) {
    setProperty('page-break-after', value, '');
  }

  /** Gets the value of "page-break-before" */
  String get pageBreakBefore => getPropertyValue('page-break-before');

  /** Sets the value of "page-break-before" */
  set pageBreakBefore(String value) {
    setProperty('page-break-before', value, '');
  }

  /** Gets the value of "page-break-inside" */
  String get pageBreakInside => getPropertyValue('page-break-inside');

  /** Sets the value of "page-break-inside" */
  set pageBreakInside(String value) {
    setProperty('page-break-inside', value, '');
  }

  /** Gets the value of "perspective" */
  String get perspective => getPropertyValue('perspective');

  /** Sets the value of "perspective" */
  set perspective(String value) {
    setProperty('perspective', value, '');
  }

  /** Gets the value of "perspective-origin" */
  String get perspectiveOrigin => getPropertyValue('perspective-origin');

  /** Sets the value of "perspective-origin" */
  set perspectiveOrigin(String value) {
    setProperty('perspective-origin', value, '');
  }

  /** Gets the value of "perspective-origin-x" */
  String get perspectiveOriginX => getPropertyValue('perspective-origin-x');

  /** Sets the value of "perspective-origin-x" */
  set perspectiveOriginX(String value) {
    setProperty('perspective-origin-x', value, '');
  }

  /** Gets the value of "perspective-origin-y" */
  String get perspectiveOriginY => getPropertyValue('perspective-origin-y');

  /** Sets the value of "perspective-origin-y" */
  set perspectiveOriginY(String value) {
    setProperty('perspective-origin-y', value, '');
  }

  /** Gets the value of "pointer-events" */
  String get pointerEvents => getPropertyValue('pointer-events');

  /** Sets the value of "pointer-events" */
  set pointerEvents(String value) {
    setProperty('pointer-events', value, '');
  }

  /** Gets the value of "position" */
  String get position => getPropertyValue('position');

  /** Sets the value of "position" */
  set position(String value) {
    setProperty('position', value, '');
  }

  /** Gets the value of "print-color-adjust" */
  String get printColorAdjust => getPropertyValue('print-color-adjust');

  /** Sets the value of "print-color-adjust" */
  set printColorAdjust(String value) {
    setProperty('print-color-adjust', value, '');
  }

  /** Gets the value of "quotes" */
  String get quotes => getPropertyValue('quotes');

  /** Sets the value of "quotes" */
  set quotes(String value) {
    setProperty('quotes', value, '');
  }

  /** Gets the value of "resize" */
  String get resize => getPropertyValue('resize');

  /** Sets the value of "resize" */
  set resize(String value) {
    setProperty('resize', value, '');
  }

  /** Gets the value of "right" */
  String get right => getPropertyValue('right');

  /** Sets the value of "right" */
  set right(String value) {
    setProperty('right', value, '');
  }

  /** Gets the value of "rtl-ordering" */
  String get rtlOrdering => getPropertyValue('rtl-ordering');

  /** Sets the value of "rtl-ordering" */
  set rtlOrdering(String value) {
    setProperty('rtl-ordering', value, '');
  }

  /** Gets the value of "ruby-position" */
  String get rubyPosition => getPropertyValue('ruby-position');

  /** Sets the value of "ruby-position" */
  set rubyPosition(String value) {
    setProperty('ruby-position', value, '');
  }

  /** Gets the value of "scroll-behavior" */
  String get scrollBehavior => getPropertyValue('scroll-behavior');

  /** Sets the value of "scroll-behavior" */
  set scrollBehavior(String value) {
    setProperty('scroll-behavior', value, '');
  }

  /** Gets the value of "shape-image-threshold" */
  String get shapeImageThreshold => getPropertyValue('shape-image-threshold');

  /** Sets the value of "shape-image-threshold" */
  set shapeImageThreshold(String value) {
    setProperty('shape-image-threshold', value, '');
  }

  /** Gets the value of "shape-margin" */
  String get shapeMargin => getPropertyValue('shape-margin');

  /** Sets the value of "shape-margin" */
  set shapeMargin(String value) {
    setProperty('shape-margin', value, '');
  }

  /** Gets the value of "shape-outside" */
  String get shapeOutside => getPropertyValue('shape-outside');

  /** Sets the value of "shape-outside" */
  set shapeOutside(String value) {
    setProperty('shape-outside', value, '');
  }

  /** Gets the value of "size" */
  String get size => getPropertyValue('size');

  /** Sets the value of "size" */
  set size(String value) {
    setProperty('size', value, '');
  }

  /** Gets the value of "speak" */
  String get speak => getPropertyValue('speak');

  /** Sets the value of "speak" */
  set speak(String value) {
    setProperty('speak', value, '');
  }

  /** Gets the value of "src" */
  String get src => getPropertyValue('src');

  /** Sets the value of "src" */
  set src(String value) {
    setProperty('src', value, '');
  }

  /** Gets the value of "tab-size" */
  String get tabSize => getPropertyValue('tab-size');

  /** Sets the value of "tab-size" */
  set tabSize(String value) {
    setProperty('tab-size', value, '');
  }

  /** Gets the value of "table-layout" */
  String get tableLayout => getPropertyValue('table-layout');

  /** Sets the value of "table-layout" */
  set tableLayout(String value) {
    setProperty('table-layout', value, '');
  }

  /** Gets the value of "tap-highlight-color" */
  String get tapHighlightColor => getPropertyValue('tap-highlight-color');

  /** Sets the value of "tap-highlight-color" */
  set tapHighlightColor(String value) {
    setProperty('tap-highlight-color', value, '');
  }

  /** Gets the value of "text-align" */
  String get textAlign => getPropertyValue('text-align');

  /** Sets the value of "text-align" */
  set textAlign(String value) {
    setProperty('text-align', value, '');
  }

  /** Gets the value of "text-align-last" */
  String get textAlignLast => getPropertyValue('text-align-last');

  /** Sets the value of "text-align-last" */
  set textAlignLast(String value) {
    setProperty('text-align-last', value, '');
  }

  /** Gets the value of "text-combine" */
  String get textCombine => getPropertyValue('text-combine');

  /** Sets the value of "text-combine" */
  set textCombine(String value) {
    setProperty('text-combine', value, '');
  }

  /** Gets the value of "text-decoration" */
  String get textDecoration => getPropertyValue('text-decoration');

  /** Sets the value of "text-decoration" */
  set textDecoration(String value) {
    setProperty('text-decoration', value, '');
  }

  /** Gets the value of "text-decoration-color" */
  String get textDecorationColor => getPropertyValue('text-decoration-color');

  /** Sets the value of "text-decoration-color" */
  set textDecorationColor(String value) {
    setProperty('text-decoration-color', value, '');
  }

  /** Gets the value of "text-decoration-line" */
  String get textDecorationLine => getPropertyValue('text-decoration-line');

  /** Sets the value of "text-decoration-line" */
  set textDecorationLine(String value) {
    setProperty('text-decoration-line', value, '');
  }

  /** Gets the value of "text-decoration-style" */
  String get textDecorationStyle => getPropertyValue('text-decoration-style');

  /** Sets the value of "text-decoration-style" */
  set textDecorationStyle(String value) {
    setProperty('text-decoration-style', value, '');
  }

  /** Gets the value of "text-decorations-in-effect" */
  String get textDecorationsInEffect =>
      getPropertyValue('text-decorations-in-effect');

  /** Sets the value of "text-decorations-in-effect" */
  set textDecorationsInEffect(String value) {
    setProperty('text-decorations-in-effect', value, '');
  }

  /** Gets the value of "text-emphasis" */
  String get textEmphasis => getPropertyValue('text-emphasis');

  /** Sets the value of "text-emphasis" */
  set textEmphasis(String value) {
    setProperty('text-emphasis', value, '');
  }

  /** Gets the value of "text-emphasis-color" */
  String get textEmphasisColor => getPropertyValue('text-emphasis-color');

  /** Sets the value of "text-emphasis-color" */
  set textEmphasisColor(String value) {
    setProperty('text-emphasis-color', value, '');
  }

  /** Gets the value of "text-emphasis-position" */
  String get textEmphasisPosition => getPropertyValue('text-emphasis-position');

  /** Sets the value of "text-emphasis-position" */
  set textEmphasisPosition(String value) {
    setProperty('text-emphasis-position', value, '');
  }

  /** Gets the value of "text-emphasis-style" */
  String get textEmphasisStyle => getPropertyValue('text-emphasis-style');

  /** Sets the value of "text-emphasis-style" */
  set textEmphasisStyle(String value) {
    setProperty('text-emphasis-style', value, '');
  }

  /** Gets the value of "text-fill-color" */
  String get textFillColor => getPropertyValue('text-fill-color');

  /** Sets the value of "text-fill-color" */
  set textFillColor(String value) {
    setProperty('text-fill-color', value, '');
  }

  /** Gets the value of "text-indent" */
  String get textIndent => getPropertyValue('text-indent');

  /** Sets the value of "text-indent" */
  set textIndent(String value) {
    setProperty('text-indent', value, '');
  }

  /** Gets the value of "text-justify" */
  String get textJustify => getPropertyValue('text-justify');

  /** Sets the value of "text-justify" */
  set textJustify(String value) {
    setProperty('text-justify', value, '');
  }

  /** Gets the value of "text-line-through-color" */
  String get textLineThroughColor =>
      getPropertyValue('text-line-through-color');

  /** Sets the value of "text-line-through-color" */
  set textLineThroughColor(String value) {
    setProperty('text-line-through-color', value, '');
  }

  /** Gets the value of "text-line-through-mode" */
  String get textLineThroughMode => getPropertyValue('text-line-through-mode');

  /** Sets the value of "text-line-through-mode" */
  set textLineThroughMode(String value) {
    setProperty('text-line-through-mode', value, '');
  }

  /** Gets the value of "text-line-through-style" */
  String get textLineThroughStyle =>
      getPropertyValue('text-line-through-style');

  /** Sets the value of "text-line-through-style" */
  set textLineThroughStyle(String value) {
    setProperty('text-line-through-style', value, '');
  }

  /** Gets the value of "text-line-through-width" */
  String get textLineThroughWidth =>
      getPropertyValue('text-line-through-width');

  /** Sets the value of "text-line-through-width" */
  set textLineThroughWidth(String value) {
    setProperty('text-line-through-width', value, '');
  }

  /** Gets the value of "text-orientation" */
  String get textOrientation => getPropertyValue('text-orientation');

  /** Sets the value of "text-orientation" */
  set textOrientation(String value) {
    setProperty('text-orientation', value, '');
  }

  /** Gets the value of "text-overflow" */
  String get textOverflow => getPropertyValue('text-overflow');

  /** Sets the value of "text-overflow" */
  set textOverflow(String value) {
    setProperty('text-overflow', value, '');
  }

  /** Gets the value of "text-overline-color" */
  String get textOverlineColor => getPropertyValue('text-overline-color');

  /** Sets the value of "text-overline-color" */
  set textOverlineColor(String value) {
    setProperty('text-overline-color', value, '');
  }

  /** Gets the value of "text-overline-mode" */
  String get textOverlineMode => getPropertyValue('text-overline-mode');

  /** Sets the value of "text-overline-mode" */
  set textOverlineMode(String value) {
    setProperty('text-overline-mode', value, '');
  }

  /** Gets the value of "text-overline-style" */
  String get textOverlineStyle => getPropertyValue('text-overline-style');

  /** Sets the value of "text-overline-style" */
  set textOverlineStyle(String value) {
    setProperty('text-overline-style', value, '');
  }

  /** Gets the value of "text-overline-width" */
  String get textOverlineWidth => getPropertyValue('text-overline-width');

  /** Sets the value of "text-overline-width" */
  set textOverlineWidth(String value) {
    setProperty('text-overline-width', value, '');
  }

  /** Gets the value of "text-rendering" */
  String get textRendering => getPropertyValue('text-rendering');

  /** Sets the value of "text-rendering" */
  set textRendering(String value) {
    setProperty('text-rendering', value, '');
  }

  /** Gets the value of "text-security" */
  String get textSecurity => getPropertyValue('text-security');

  /** Sets the value of "text-security" */
  set textSecurity(String value) {
    setProperty('text-security', value, '');
  }

  /** Gets the value of "text-shadow" */
  String get textShadow => getPropertyValue('text-shadow');

  /** Sets the value of "text-shadow" */
  set textShadow(String value) {
    setProperty('text-shadow', value, '');
  }

  /** Gets the value of "text-stroke" */
  String get textStroke => getPropertyValue('text-stroke');

  /** Sets the value of "text-stroke" */
  set textStroke(String value) {
    setProperty('text-stroke', value, '');
  }

  /** Gets the value of "text-stroke-color" */
  String get textStrokeColor => getPropertyValue('text-stroke-color');

  /** Sets the value of "text-stroke-color" */
  set textStrokeColor(String value) {
    setProperty('text-stroke-color', value, '');
  }

  /** Gets the value of "text-stroke-width" */
  String get textStrokeWidth => getPropertyValue('text-stroke-width');

  /** Sets the value of "text-stroke-width" */
  set textStrokeWidth(String value) {
    setProperty('text-stroke-width', value, '');
  }

  /** Gets the value of "text-transform" */
  String get textTransform => getPropertyValue('text-transform');

  /** Sets the value of "text-transform" */
  set textTransform(String value) {
    setProperty('text-transform', value, '');
  }

  /** Gets the value of "text-underline-color" */
  String get textUnderlineColor => getPropertyValue('text-underline-color');

  /** Sets the value of "text-underline-color" */
  set textUnderlineColor(String value) {
    setProperty('text-underline-color', value, '');
  }

  /** Gets the value of "text-underline-mode" */
  String get textUnderlineMode => getPropertyValue('text-underline-mode');

  /** Sets the value of "text-underline-mode" */
  set textUnderlineMode(String value) {
    setProperty('text-underline-mode', value, '');
  }

  /** Gets the value of "text-underline-position" */
  String get textUnderlinePosition =>
      getPropertyValue('text-underline-position');

  /** Sets the value of "text-underline-position" */
  set textUnderlinePosition(String value) {
    setProperty('text-underline-position', value, '');
  }

  /** Gets the value of "text-underline-style" */
  String get textUnderlineStyle => getPropertyValue('text-underline-style');

  /** Sets the value of "text-underline-style" */
  set textUnderlineStyle(String value) {
    setProperty('text-underline-style', value, '');
  }

  /** Gets the value of "text-underline-width" */
  String get textUnderlineWidth => getPropertyValue('text-underline-width');

  /** Sets the value of "text-underline-width" */
  set textUnderlineWidth(String value) {
    setProperty('text-underline-width', value, '');
  }

  /** Gets the value of "top" */
  String get top => getPropertyValue('top');

  /** Sets the value of "top" */
  set top(String value) {
    setProperty('top', value, '');
  }

  /** Gets the value of "touch-action" */
  String get touchAction => getPropertyValue('touch-action');

  /** Sets the value of "touch-action" */
  set touchAction(String value) {
    setProperty('touch-action', value, '');
  }

  /** Gets the value of "touch-action-delay" */
  String get touchActionDelay => getPropertyValue('touch-action-delay');

  /** Sets the value of "touch-action-delay" */
  set touchActionDelay(String value) {
    setProperty('touch-action-delay', value, '');
  }

  /** Gets the value of "transform" */
  String get transform => getPropertyValue('transform');

  /** Sets the value of "transform" */
  set transform(String value) {
    setProperty('transform', value, '');
  }

  /** Gets the value of "transform-origin" */
  String get transformOrigin => getPropertyValue('transform-origin');

  /** Sets the value of "transform-origin" */
  set transformOrigin(String value) {
    setProperty('transform-origin', value, '');
  }

  /** Gets the value of "transform-origin-x" */
  String get transformOriginX => getPropertyValue('transform-origin-x');

  /** Sets the value of "transform-origin-x" */
  set transformOriginX(String value) {
    setProperty('transform-origin-x', value, '');
  }

  /** Gets the value of "transform-origin-y" */
  String get transformOriginY => getPropertyValue('transform-origin-y');

  /** Sets the value of "transform-origin-y" */
  set transformOriginY(String value) {
    setProperty('transform-origin-y', value, '');
  }

  /** Gets the value of "transform-origin-z" */
  String get transformOriginZ => getPropertyValue('transform-origin-z');

  /** Sets the value of "transform-origin-z" */
  set transformOriginZ(String value) {
    setProperty('transform-origin-z', value, '');
  }

  /** Gets the value of "transform-style" */
  String get transformStyle => getPropertyValue('transform-style');

  /** Sets the value of "transform-style" */
  set transformStyle(String value) {
    setProperty('transform-style', value, '');
  }

  /** Gets the value of "transition" */ @SupportedBrowser(
      SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  String get transition => getPropertyValue('transition');

  /** Sets the value of "transition" */ @SupportedBrowser(
      SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  set transition(String value) {
    setProperty('transition', value, '');
  }

  /** Gets the value of "transition-delay" */
  String get transitionDelay => getPropertyValue('transition-delay');

  /** Sets the value of "transition-delay" */
  set transitionDelay(String value) {
    setProperty('transition-delay', value, '');
  }

  /** Gets the value of "transition-duration" */
  String get transitionDuration => getPropertyValue('transition-duration');

  /** Sets the value of "transition-duration" */
  set transitionDuration(String value) {
    setProperty('transition-duration', value, '');
  }

  /** Gets the value of "transition-property" */
  String get transitionProperty => getPropertyValue('transition-property');

  /** Sets the value of "transition-property" */
  set transitionProperty(String value) {
    setProperty('transition-property', value, '');
  }

  /** Gets the value of "transition-timing-function" */
  String get transitionTimingFunction =>
      getPropertyValue('transition-timing-function');

  /** Sets the value of "transition-timing-function" */
  set transitionTimingFunction(String value) {
    setProperty('transition-timing-function', value, '');
  }

  /** Gets the value of "unicode-bidi" */
  String get unicodeBidi => getPropertyValue('unicode-bidi');

  /** Sets the value of "unicode-bidi" */
  set unicodeBidi(String value) {
    setProperty('unicode-bidi', value, '');
  }

  /** Gets the value of "unicode-range" */
  String get unicodeRange => getPropertyValue('unicode-range');

  /** Sets the value of "unicode-range" */
  set unicodeRange(String value) {
    setProperty('unicode-range', value, '');
  }

  /** Gets the value of "user-drag" */
  String get userDrag => getPropertyValue('user-drag');

  /** Sets the value of "user-drag" */
  set userDrag(String value) {
    setProperty('user-drag', value, '');
  }

  /** Gets the value of "user-modify" */
  String get userModify => getPropertyValue('user-modify');

  /** Sets the value of "user-modify" */
  set userModify(String value) {
    setProperty('user-modify', value, '');
  }

  /** Gets the value of "user-select" */
  String get userSelect => getPropertyValue('user-select');

  /** Sets the value of "user-select" */
  set userSelect(String value) {
    setProperty('user-select', value, '');
  }

  /** Gets the value of "user-zoom" */
  String get userZoom => getPropertyValue('user-zoom');

  /** Sets the value of "user-zoom" */
  set userZoom(String value) {
    setProperty('user-zoom', value, '');
  }

  /** Gets the value of "vertical-align" */
  String get verticalAlign => getPropertyValue('vertical-align');

  /** Sets the value of "vertical-align" */
  set verticalAlign(String value) {
    setProperty('vertical-align', value, '');
  }

  /** Gets the value of "visibility" */
  String get visibility => getPropertyValue('visibility');

  /** Sets the value of "visibility" */
  set visibility(String value) {
    setProperty('visibility', value, '');
  }

  /** Gets the value of "white-space" */
  String get whiteSpace => getPropertyValue('white-space');

  /** Sets the value of "white-space" */
  set whiteSpace(String value) {
    setProperty('white-space', value, '');
  }

  /** Gets the value of "widows" */
  String get widows => getPropertyValue('widows');

  /** Sets the value of "widows" */
  set widows(String value) {
    setProperty('widows', value, '');
  }

  /** Gets the value of "width" */
  String get width => getPropertyValue('width');

  /** Sets the value of "width" */
  set width(String value) {
    setProperty('width', value, '');
  }

  /** Gets the value of "will-change" */
  String get willChange => getPropertyValue('will-change');

  /** Sets the value of "will-change" */
  set willChange(String value) {
    setProperty('will-change', value, '');
  }

  /** Gets the value of "word-break" */
  String get wordBreak => getPropertyValue('word-break');

  /** Sets the value of "word-break" */
  set wordBreak(String value) {
    setProperty('word-break', value, '');
  }

  /** Gets the value of "word-spacing" */
  String get wordSpacing => getPropertyValue('word-spacing');

  /** Sets the value of "word-spacing" */
  set wordSpacing(String value) {
    setProperty('word-spacing', value, '');
  }

  /** Gets the value of "word-wrap" */
  String get wordWrap => getPropertyValue('word-wrap');

  /** Sets the value of "word-wrap" */
  set wordWrap(String value) {
    setProperty('word-wrap', value, '');
  }

  /** Gets the value of "wrap-flow" */
  String get wrapFlow => getPropertyValue('wrap-flow');

  /** Sets the value of "wrap-flow" */
  set wrapFlow(String value) {
    setProperty('wrap-flow', value, '');
  }

  /** Gets the value of "wrap-through" */
  String get wrapThrough => getPropertyValue('wrap-through');

  /** Sets the value of "wrap-through" */
  set wrapThrough(String value) {
    setProperty('wrap-through', value, '');
  }

  /** Gets the value of "writing-mode" */
  String get writingMode => getPropertyValue('writing-mode');

  /** Sets the value of "writing-mode" */
  set writingMode(String value) {
    setProperty('writing-mode', value, '');
  }

  /** Gets the value of "z-index" */
  String get zIndex => getPropertyValue('z-index');

  /** Sets the value of "z-index" */
  set zIndex(String value) {
    setProperty('z-index', value, '');
  }

  /** Gets the value of "zoom" */
  String get zoom => getPropertyValue('zoom');

  /** Sets the value of "zoom" */
  set zoom(String value) {
    setProperty('zoom', value, '');
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSStyleRule")
class CssStyleRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssStyleRule._() {
    throw new UnsupportedError("Not supported");
  }

  String selectorText;

  final CssStyleDeclaration style;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSStyleSheet")
class CssStyleSheet extends StyleSheet {
  // To suppress missing implicit constructor warnings.
  factory CssStyleSheet._() {
    throw new UnsupportedError("Not supported");
  }

  @Returns('_CssRuleList|Null')
  @Creates('_CssRuleList')
  final List<CssRule> cssRules;

  final CssRule ownerRule;

  @Returns('_CssRuleList|Null')
  @Creates('_CssRuleList')
  final List<CssRule> rules;

  int addRule(String selector, String style, [int index]) native;

  void deleteRule(int index) native;

  int insertRule(String rule, [int index]) native;

  void removeRule(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSStyleValue")
class CssStyleValue extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CssStyleValue._() {
    throw new UnsupportedError("Not supported");
  }

  static Object parse(String property, String cssText) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSSupportsRule")
class CssSupportsRule extends CssConditionRule {
  // To suppress missing implicit constructor warnings.
  factory CssSupportsRule._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSTransformComponent")
class CssTransformComponent extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CssTransformComponent._() {
    throw new UnsupportedError("Not supported");
  }

  bool is2D;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSTransformValue")
class CssTransformValue extends CssStyleValue {
  // To suppress missing implicit constructor warnings.
  factory CssTransformValue._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssTransformValue([List<CssTransformComponent> transformComponents]) {
    if (transformComponents == null) {
      return CssTransformValue._create_1();
    }
    if ((transformComponents is List<CssTransformComponent>)) {
      return CssTransformValue._create_2(transformComponents);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static CssTransformValue _create_1() =>
      JS('CssTransformValue', 'new CSSTransformValue()');
  static CssTransformValue _create_2(transformComponents) =>
      JS('CssTransformValue', 'new CSSTransformValue(#)', transformComponents);

  final bool is2D;

  final int length;

  CssTransformComponent componentAtIndex(int index) native;

  DomMatrix toMatrix() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSTranslation")
class CssTranslation extends CssTransformComponent {
  // To suppress missing implicit constructor warnings.
  factory CssTranslation._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssTranslation(CssNumericValue x, CssNumericValue y,
      [CssNumericValue z]) {
    if ((y is CssNumericValue) && (x is CssNumericValue) && z == null) {
      return CssTranslation._create_1(x, y);
    }
    if ((z is CssNumericValue) &&
        (y is CssNumericValue) &&
        (x is CssNumericValue)) {
      return CssTranslation._create_2(x, y, z);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static CssTranslation _create_1(x, y) =>
      JS('CssTranslation', 'new CSSTranslation(#,#)', x, y);
  static CssTranslation _create_2(x, y, z) =>
      JS('CssTranslation', 'new CSSTranslation(#,#,#)', x, y, z);

  CssNumericValue x;

  CssNumericValue y;

  CssNumericValue z;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSUnitValue")
class CssUnitValue extends CssNumericValue {
  // To suppress missing implicit constructor warnings.
  factory CssUnitValue._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssUnitValue(num value, String unit) {
    return CssUnitValue._create_1(value, unit);
  }
  static CssUnitValue _create_1(value, unit) =>
      JS('CssUnitValue', 'new CSSUnitValue(#,#)', value, unit);

  final String type;

  String unit;

  num value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSUnparsedValue")
class CssUnparsedValue extends CssStyleValue {
  // To suppress missing implicit constructor warnings.
  factory CssUnparsedValue._() {
    throw new UnsupportedError("Not supported");
  }

  final int length;

  Object fragmentAtIndex(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSVariableReferenceValue")
class CssVariableReferenceValue extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CssVariableReferenceValue._() {
    throw new UnsupportedError("Not supported");
  }

  final CssUnparsedValue fallback;

  final String variable;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSViewportRule")
class CssViewportRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssViewportRule._() {
    throw new UnsupportedError("Not supported");
  }

  final CssStyleDeclaration style;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSURLImageValue")
class CssurlImageValue extends CssImageValue {
  // To suppress missing implicit constructor warnings.
  factory CssurlImageValue._() {
    throw new UnsupportedError("Not supported");
  }

  factory CssurlImageValue(String url) {
    return CssurlImageValue._create_1(url);
  }
  static CssurlImageValue _create_1(url) =>
      JS('CssurlImageValue', 'new CSSURLImageValue(#)', url);

  final String url;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-custom-element-constructor-generation
@deprecated // experimental
typedef void CustomElementConstructor();
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CustomElementRegistry")
class CustomElementRegistry extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CustomElementRegistry._() {
    throw new UnsupportedError("Not supported");
  }

  void define(String name, Object constructor, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      _define_1(name, constructor, options_1);
      return;
    }
    _define_2(name, constructor);
    return;
  }

  @JSName('define')
  void _define_1(name, constructor, options) native;
  @JSName('define')
  void _define_2(name, constructor) native;

  Object get(String name) native;

  Future whenDefined(String name) =>
      promiseToFuture(JS("", "#.whenDefined(#)", this, name));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Native("CustomEvent")
class CustomEvent extends Event {
  @Creates('Null') // Set from Dart code; does not instantiate a native type.
  var _dartDetail;

  factory CustomEvent(String type,
      {bool canBubble: true, bool cancelable: true, Object detail}) {
    final CustomEvent e = document._createEvent('CustomEvent');

    e._dartDetail = detail;

    // Only try setting the detail if it's one of these types to avoid
    // first-chance exceptions. Can expand this list in the future as needed.
    if (detail is List || detail is Map || detail is String || detail is num) {
      try {
        detail = convertDartToNative_SerializedScriptValue(detail);
        e._initCustomEvent(type, canBubble, cancelable, detail);
      } catch (_) {
        e._initCustomEvent(type, canBubble, cancelable, null);
      }
    } else {
      e._initCustomEvent(type, canBubble, cancelable, null);
    }

    return e;
  }

  get detail {
    if (_dartDetail != null) {
      return _dartDetail;
    }
    return _detail;
  }

  factory CustomEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return CustomEvent._create_1(type, eventInitDict_1);
    }
    return CustomEvent._create_2(type);
  }
  static CustomEvent _create_1(type, eventInitDict) =>
      JS('CustomEvent', 'new CustomEvent(#,#)', type, eventInitDict);
  static CustomEvent _create_2(type) =>
      JS('CustomEvent', 'new CustomEvent(#)', type);

  dynamic get _detail =>
      convertNativeToDart_SerializedScriptValue(this._get__detail);
  @JSName('detail')
  @Creates('Null')
  final dynamic _get__detail;

  @JSName('initCustomEvent')
  void _initCustomEvent(String type,
      [bool bubbles, bool cancelable, Object detail]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLDListElement")
class DListElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory DListElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory DListElement() => JS(
      'returns:DListElement;creates:DListElement;new:true',
      '#.createElement(#)',
      document,
      "dl");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DListElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLDataElement")
class DataElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory DataElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DataElement.created() : super.created();

  String value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("HTMLDataListElement")
class DataListElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory DataListElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory DataListElement() => document.createElement("datalist");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DataListElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('datalist');

  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> options;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DataTransfer")
class DataTransfer extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DataTransfer._() {
    throw new UnsupportedError("Not supported");
  }

  factory DataTransfer() {
    return DataTransfer._create_1();
  }
  static DataTransfer _create_1() => JS('DataTransfer', 'new DataTransfer()');

  String dropEffect;

  String effectAllowed;

  @Returns('FileList|Null')
  @Creates('FileList')
  final List<File> files;

  final DataTransferItemList items;

  final List<String> types;

  void clearData([String format]) native;

  String getData(String format) native;

  void setData(String format, String data) native;

  void setDragImage(Element image, int x, int y) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DataTransferItem")
class DataTransferItem extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DataTransferItem._() {
    throw new UnsupportedError("Not supported");
  }

  final String kind;

  final String type;

  File getAsFile() native;

  @JSName('webkitGetAsEntry')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  Entry getAsEntry() native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DataTransferItemList")
class DataTransferItemList extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DataTransferItemList._() {
    throw new UnsupportedError("Not supported");
  }

  final int length;

  DataTransferItem add(data_OR_file, [String type]) native;

  @JSName('add')
  DataTransferItem addData(String data, String type) native;

  @JSName('add')
  DataTransferItem addFile(File file) native;

  void clear() native;

  DataTransferItem item(int index) native;

  void remove(int index) native;

  DataTransferItem operator [](int index) {
    return JS('DataTransferItem', '#[#]', this, index);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void DatabaseCallback(SqlDatabase database);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void DecodeErrorCallback(DomException error);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void DecodeSuccessCallback(AudioBuffer decodedData);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DedicatedWorkerGlobalScope")
class DedicatedWorkerGlobalScope extends WorkerGlobalScope {
  // To suppress missing implicit constructor warnings.
  factory DedicatedWorkerGlobalScope._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [DedicatedWorkerGlobalScope].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  static const int PERSISTENT = 1;

  static const int TEMPORARY = 0;

  void close() native;

  void postMessage(/*any*/ message, [List<Object> transfer]) {
    if (transfer != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, transfer);
      return;
    }
    var message_1 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_1);
    return;
  }

  @JSName('postMessage')
  void _postMessage_1(message, List<Object> transfer) native;
  @JSName('postMessage')
  void _postMessage_2(message) native;

  @JSName('webkitRequestFileSystem')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void _webkitRequestFileSystem(int type, int size,
      [_FileSystemCallback successCallback,
      _ErrorCallback errorCallback]) native;

  @JSName('webkitRequestFileSystemSync')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  _DOMFileSystemSync requestFileSystemSync(int type, int size) native;

  @JSName('webkitResolveLocalFileSystemSyncURL')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  _EntrySync resolveLocalFileSystemSyncUrl(String url) native;

  @JSName('webkitResolveLocalFileSystemURL')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void _webkitResolveLocalFileSystemUrl(
      String url, _EntryCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  /// Stream of `message` events handled by this [DedicatedWorkerGlobalScope].
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  static DedicatedWorkerGlobalScope get instance {
    return _workerSelf as DedicatedWorkerGlobalScope;
  }
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DeprecatedStorageInfo")
class DeprecatedStorageInfo extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DeprecatedStorageInfo._() {
    throw new UnsupportedError("Not supported");
  }

  static const int PERSISTENT = 1;

  static const int TEMPORARY = 0;

  void queryUsageAndQuota(int storageType,
      [StorageUsageCallback usageCallback,
      StorageErrorCallback errorCallback]) native;

  void requestQuota(int storageType, int newQuotaInBytes,
      [StorageQuotaCallback quotaCallback,
      StorageErrorCallback errorCallback]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DeprecatedStorageQuota")
class DeprecatedStorageQuota extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DeprecatedStorageQuota._() {
    throw new UnsupportedError("Not supported");
  }

  void queryUsageAndQuota(StorageUsageCallback usageCallback,
      [StorageErrorCallback errorCallback]) native;

  void requestQuota(int newQuotaInBytes,
      [StorageQuotaCallback quotaCallback,
      StorageErrorCallback errorCallback]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DeprecationReport")
class DeprecationReport extends ReportBody {
  // To suppress missing implicit constructor warnings.
  factory DeprecationReport._() {
    throw new UnsupportedError("Not supported");
  }

  final int lineNumber;

  final String message;

  final String sourceFile;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("HTMLDetailsElement")
class DetailsElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory DetailsElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory DetailsElement() => document.createElement("details");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DetailsElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('details');

  bool open;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DetectedBarcode")
class DetectedBarcode extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DetectedBarcode._() {
    throw new UnsupportedError("Not supported");
  }

  factory DetectedBarcode() {
    return DetectedBarcode._create_1();
  }
  static DetectedBarcode _create_1() =>
      JS('DetectedBarcode', 'new DetectedBarcode()');

  final Rectangle boundingBox;

  final List cornerPoints;

  final String rawValue;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DetectedFace")
class DetectedFace extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DetectedFace._() {
    throw new UnsupportedError("Not supported");
  }

  factory DetectedFace() {
    return DetectedFace._create_1();
  }
  static DetectedFace _create_1() => JS('DetectedFace', 'new DetectedFace()');

  final Rectangle boundingBox;

  final List landmarks;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DetectedText")
class DetectedText extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DetectedText._() {
    throw new UnsupportedError("Not supported");
  }

  factory DetectedText() {
    return DetectedText._create_1();
  }
  static DetectedText _create_1() => JS('DetectedText', 'new DetectedText()');

  final Rectangle boundingBox;

  final List cornerPoints;

  final String rawValue;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DeviceAcceleration")
class DeviceAcceleration extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DeviceAcceleration._() {
    throw new UnsupportedError("Not supported");
  }

  final num x;

  final num y;

  final num z;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DeviceMotionEvent")
class DeviceMotionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory DeviceMotionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory DeviceMotionEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return DeviceMotionEvent._create_1(type, eventInitDict_1);
    }
    return DeviceMotionEvent._create_2(type);
  }
  static DeviceMotionEvent _create_1(type, eventInitDict) => JS(
      'DeviceMotionEvent', 'new DeviceMotionEvent(#,#)', type, eventInitDict);
  static DeviceMotionEvent _create_2(type) =>
      JS('DeviceMotionEvent', 'new DeviceMotionEvent(#)', type);

  final DeviceAcceleration acceleration;

  final DeviceAcceleration accelerationIncludingGravity;

  final num interval;

  final DeviceRotationRate rotationRate;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DeviceOrientationEvent")
class DeviceOrientationEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory DeviceOrientationEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory DeviceOrientationEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return DeviceOrientationEvent._create_1(type, eventInitDict_1);
    }
    return DeviceOrientationEvent._create_2(type);
  }
  static DeviceOrientationEvent _create_1(type, eventInitDict) => JS(
      'DeviceOrientationEvent',
      'new DeviceOrientationEvent(#,#)',
      type,
      eventInitDict);
  static DeviceOrientationEvent _create_2(type) =>
      JS('DeviceOrientationEvent', 'new DeviceOrientationEvent(#)', type);

  final bool absolute;

  final num alpha;

  final num beta;

  final num gamma;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DeviceRotationRate")
class DeviceRotationRate extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DeviceRotationRate._() {
    throw new UnsupportedError("Not supported");
  }

  final num alpha;

  final num beta;

  final num gamma;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("HTMLDialogElement")
class DialogElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory DialogElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DialogElement.created() : super.created();

  bool open;

  String returnValue;

  void close([String returnValue]) native;

  void show() native;

  void showModal() native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DirectoryEntry")
class DirectoryEntry extends Entry {
  /**
   * Create a new directory with the specified `path`. If `exclusive` is true,
   * the returned Future will complete with an error if a directory already
   * exists with the specified `path`.
   */
  Future<Entry> createDirectory(String path, {bool exclusive: false}) {
    return _getDirectory(path,
        options: {'create': true, 'exclusive': exclusive});
  }

  DirectoryReader createReader() {
    DirectoryReader reader = _createReader();
    applyExtension('DirectoryReader', reader);
    return reader;
  }

  /**
   * Retrieve an already existing directory entry. The returned future will
   * result in an error if a directory at `path` does not exist or if the item
   * at `path` is not a directory.
   */
  Future<Entry> getDirectory(String path) {
    return _getDirectory(path);
  }

  /**
   * Create a new file with the specified `path`. If `exclusive` is true,
   * the returned Future will complete with an error if a file already
   * exists at the specified `path`.
   */
  Future<Entry> createFile(String path, {bool exclusive: false}) {
    return _getFile(path, options: {'create': true, 'exclusive': exclusive});
  }

  /**
   * Retrieve an already existing file entry. The returned future will
   * result in an error if a file at `path` does not exist or if the item at
   * `path` is not a file.
   */
  Future<Entry> getFile(String path) {
    return _getFile(path);
  }

  // To suppress missing implicit constructor warnings.
  factory DirectoryEntry._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('createReader')
  DirectoryReader _createReader() native;

  void __getDirectory(String path,
      [Map options,
      _EntryCallback successCallback,
      _ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getDirectory_1(path, options_1, successCallback, errorCallback);
      return;
    }
    if (successCallback != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getDirectory_2(path, options_1, successCallback);
      return;
    }
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getDirectory_3(path, options_1);
      return;
    }
    __getDirectory_4(path);
    return;
  }

  @JSName('getDirectory')
  void __getDirectory_1(path, options, _EntryCallback successCallback,
      _ErrorCallback errorCallback) native;
  @JSName('getDirectory')
  void __getDirectory_2(path, options, _EntryCallback successCallback) native;
  @JSName('getDirectory')
  void __getDirectory_3(path, options) native;
  @JSName('getDirectory')
  void __getDirectory_4(path) native;

  @JSName('getDirectory')
  Future<Entry> _getDirectory(String path, {Map options}) {
    var completer = new Completer<Entry>();
    __getDirectory(path, options, (value) {
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  void __getFile(String path,
      [Map options,
      _EntryCallback successCallback,
      _ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getFile_1(path, options_1, successCallback, errorCallback);
      return;
    }
    if (successCallback != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getFile_2(path, options_1, successCallback);
      return;
    }
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getFile_3(path, options_1);
      return;
    }
    __getFile_4(path);
    return;
  }

  @JSName('getFile')
  void __getFile_1(path, options, _EntryCallback successCallback,
      _ErrorCallback errorCallback) native;
  @JSName('getFile')
  void __getFile_2(path, options, _EntryCallback successCallback) native;
  @JSName('getFile')
  void __getFile_3(path, options) native;
  @JSName('getFile')
  void __getFile_4(path) native;

  @JSName('getFile')
  Future<Entry> _getFile(String path, {Map options}) {
    var completer = new Completer<Entry>();
    __getFile(path, options, (value) {
      applyExtension('FileEntry', value);
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('removeRecursively')
  void _removeRecursively(VoidCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  @JSName('removeRecursively')
  Future removeRecursively() {
    var completer = new Completer();
    _removeRecursively(() {
      completer.complete();
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DirectoryReader")
class DirectoryReader extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DirectoryReader._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('readEntries')
  void _readEntries(_EntriesCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  Future<List<Entry>> readEntries() {
    var completer = new Completer<List<Entry>>();
    _readEntries((value) {
      completer.complete(new List<Entry>.from(value));
    }, (error) {
      completer.completeError(error);
    });

    return completer.future;
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * A generic container for content on an HTML page;
 * corresponds to the &lt;div&gt; tag.
 *
 * The [DivElement] is a generic container and does not have any semantic
 * significance. It is functionally similar to [SpanElement].
 *
 * The [DivElement] is a block-level element, as opposed to [SpanElement],
 * which is an inline-level element.
 *
 * Example usage:
 *
 *     DivElement div = new DivElement();
 *     div.text = 'Here's my new DivElem
 *     document.body.elements.add(elem);
 *
 * See also:
 *
 * * [HTML `<div>` element](http://www.w3.org/TR/html-markup/div.html) from W3C.
 * * [Block-level element](http://www.w3.org/TR/CSS2/visuren.html#block-boxes) from W3C.
 * * [Inline-level element](http://www.w3.org/TR/CSS2/visuren.html#inline-boxes) from W3C.
 */
@Native("HTMLDivElement")
class DivElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory DivElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory DivElement() => JS('returns:DivElement;creates:DivElement;new:true',
      '#.createElement(#)', document, "div");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DivElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * The base class for all documents.
 *
 * Each web page loaded in the browser has its own [Document] object, which is
 * typically an [HtmlDocument].
 *
 * If you aren't comfortable with DOM concepts, see the Dart tutorial
 * [Target 2: Connect Dart & HTML](http://www.dartlang.org/docs/tutorials/connect-dart-html/).
 */
@Native("Document")
class Document extends Node {
  // To suppress missing implicit constructor warnings.
  factory Document._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> pointerLockChangeEvent =
      const EventStreamProvider<Event>('pointerlockchange');

  static const EventStreamProvider<Event> pointerLockErrorEvent =
      const EventStreamProvider<Event>('pointerlockerror');

  /**
   * Static factory designed to expose `readystatechange` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> readyStateChangeEvent =
      const EventStreamProvider<Event>('readystatechange');

  /**
   * Static factory designed to expose `securitypolicyviolation` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<SecurityPolicyViolationEvent>
      securityPolicyViolationEvent =
      const EventStreamProvider<SecurityPolicyViolationEvent>(
          'securitypolicyviolation');

  /**
   * Static factory designed to expose `selectionchange` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> selectionChangeEvent =
      const EventStreamProvider<Event>('selectionchange');

  factory Document() {
    return Document._create_1();
  }
  static Document _create_1() => JS('Document', 'new Document()');

  final String addressSpace;

  @JSName('body')
  HtmlElement _body;

  final String contentType;

  String cookie;

  final ScriptElement currentScript;

  WindowBase get window => _convertNativeToDart_Window(this._get_window);
  @JSName('defaultView')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  @Creates('Window|=Object|Null')
  @Returns('Window|=Object|Null')
  final dynamic _get_window;

  final Element documentElement;

  final String domain;

  final bool fullscreenEnabled;

  @JSName('head')
  final HeadElement _head;

  final bool hidden;

  final DomImplementation implementation;

  @JSName('lastModified')
  final String _lastModified;

  final String origin;

  @JSName('preferredStylesheetSet')
  final String _preferredStylesheetSet;

  final String readyState;

  @JSName('referrer')
  final String _referrer;

  final SvgSvgElement rootElement;

  Element rootScroller;

  final Element scrollingElement;

  @JSName('selectedStylesheetSet')
  String _selectedStylesheetSet;

  final String suborigin;

  final DocumentTimeline timeline;

  @JSName('title')
  String _title;

  @JSName('visibilityState')
  final String _visibilityState;

  @JSName('webkitFullscreenElement')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final Element _webkitFullscreenElement;

  @JSName('webkitFullscreenEnabled')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final bool _webkitFullscreenEnabled;

  @JSName('webkitHidden')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final bool _webkitHidden;

  @JSName('webkitVisibilityState')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final String _webkitVisibilityState;

  Node adoptNode(Node node) native;

  @JSName('caretRangeFromPoint')
  Range _caretRangeFromPoint(int x, int y) native;

  DocumentFragment createDocumentFragment() native;

  @JSName('createElement')
  Element _createElement(String localName_OR_tagName,
      [options_OR_typeExtension]) native;

  @JSName('createElementNS')
  Element _createElementNS(String namespaceURI, String qualifiedName,
      [options_OR_typeExtension]) native;

  @JSName('createEvent')
  Event _createEvent(String eventType) native;

  Range createRange() native;

  @JSName('createTextNode')
  Text _createTextNode(String data) native;

  Touch _createTouch(Window view, EventTarget target, int identifier, num pageX,
      num pageY, num screenX, num screenY,
      [num radiusX, num radiusY, num rotationAngle, num force]) {
    if (force != null) {
      var target_1 = _convertDartToNative_EventTarget(target);
      return _createTouch_1(view, target_1, identifier, pageX, pageY, screenX,
          screenY, radiusX, radiusY, rotationAngle, force);
    }
    if (rotationAngle != null) {
      var target_1 = _convertDartToNative_EventTarget(target);
      return _createTouch_2(view, target_1, identifier, pageX, pageY, screenX,
          screenY, radiusX, radiusY, rotationAngle);
    }
    if (radiusY != null) {
      var target_1 = _convertDartToNative_EventTarget(target);
      return _createTouch_3(view, target_1, identifier, pageX, pageY, screenX,
          screenY, radiusX, radiusY);
    }
    if (radiusX != null) {
      var target_1 = _convertDartToNative_EventTarget(target);
      return _createTouch_4(
          view, target_1, identifier, pageX, pageY, screenX, screenY, radiusX);
    }
    var target_1 = _convertDartToNative_EventTarget(target);
    return _createTouch_5(
        view, target_1, identifier, pageX, pageY, screenX, screenY);
  }

  @JSName('createTouch')
  Touch _createTouch_1(Window view, target, identifier, pageX, pageY, screenX,
      screenY, radiusX, radiusY, rotationAngle, force) native;
  @JSName('createTouch')
  Touch _createTouch_2(Window view, target, identifier, pageX, pageY, screenX,
      screenY, radiusX, radiusY, rotationAngle) native;
  @JSName('createTouch')
  Touch _createTouch_3(Window view, target, identifier, pageX, pageY, screenX,
      screenY, radiusX, radiusY) native;
  @JSName('createTouch')
  Touch _createTouch_4(Window view, target, identifier, pageX, pageY, screenX,
      screenY, radiusX) native;
  @JSName('createTouch')
  Touch _createTouch_5(
      Window view, target, identifier, pageX, pageY, screenX, screenY) native;

  @JSName('createTouchList')
  TouchList _createTouchList(Touch touches) native;

  bool execCommand(String commandId, [bool showUI, String value]) native;

  void exitFullscreen() native;

  void exitPointerLock() native;

  List<Animation> getAnimations() native;

  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByClassName(String classNames) native;

  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByName(String elementName) native;

  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByTagName(String localName) native;

  Node importNode(Node node, [bool deep]) native;

  bool queryCommandEnabled(String commandId) native;

  bool queryCommandIndeterm(String commandId) native;

  bool queryCommandState(String commandId) native;

  bool queryCommandSupported(String commandId) native;

  String queryCommandValue(String commandId) native;

  Function registerElement2(String type, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _registerElement2_1(type, options_1);
    }
    return _registerElement2_2(type);
  }

  @JSName('registerElement')
  Function _registerElement2_1(type, options) native;
  @JSName('registerElement')
  Function _registerElement2_2(type) native;

  @JSName('webkitExitFullscreen')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void _webkitExitFullscreen() native;

  // From NonElementParentNode

  Element getElementById(String elementId) native;

  // From DocumentOrShadowRoot

  final Element activeElement;

  final Element fullscreenElement;

  final Element pointerLockElement;

  @JSName('styleSheets')
  @Returns('_StyleSheetList|Null')
  @Creates('_StyleSheetList')
  final List<StyleSheet> _styleSheets;

  @JSName('elementFromPoint')
  Element _elementFromPoint(int x, int y) native;

  List<Element> elementsFromPoint(int x, int y) native;

  // From FontFaceSource

  final FontFaceSet fonts;

  // From ParentNode

  @JSName('childElementCount')
  final int _childElementCount;

  @JSName('children')
  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> _children;

  @JSName('firstElementChild')
  final Element _firstElementChild;

  @JSName('lastElementChild')
  final Element _lastElementChild;

  /**
   * Finds the first descendant element of this document that matches the
   * specified group of selectors.
   *
   * Unless your webpage contains multiple documents, the top-level
   * [querySelector]
   * method behaves the same as this method, so you should use it instead to
   * save typing a few characters.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var element1 = document.querySelector('.className');
   *     var element2 = document.querySelector('#id');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  Element querySelector(String selectors) native;

  @JSName('querySelectorAll')
  @Creates('NodeList')
  @Returns('NodeList')
  List<Node> _querySelectorAll(String selectors) native;

  /// Stream of `abort` events handled by this [Document].
  Stream<Event> get onAbort => Element.abortEvent.forTarget(this);

  /// Stream of `beforecopy` events handled by this [Document].
  Stream<Event> get onBeforeCopy => Element.beforeCopyEvent.forTarget(this);

  /// Stream of `beforecut` events handled by this [Document].
  Stream<Event> get onBeforeCut => Element.beforeCutEvent.forTarget(this);

  /// Stream of `beforepaste` events handled by this [Document].
  Stream<Event> get onBeforePaste => Element.beforePasteEvent.forTarget(this);

  /// Stream of `blur` events handled by this [Document].
  Stream<Event> get onBlur => Element.blurEvent.forTarget(this);

  Stream<Event> get onCanPlay => Element.canPlayEvent.forTarget(this);

  Stream<Event> get onCanPlayThrough =>
      Element.canPlayThroughEvent.forTarget(this);

  /// Stream of `change` events handled by this [Document].
  Stream<Event> get onChange => Element.changeEvent.forTarget(this);

  /// Stream of `click` events handled by this [Document].
  Stream<MouseEvent> get onClick => Element.clickEvent.forTarget(this);

  /// Stream of `contextmenu` events handled by this [Document].
  Stream<MouseEvent> get onContextMenu =>
      Element.contextMenuEvent.forTarget(this);

  /// Stream of `copy` events handled by this [Document].
  Stream<ClipboardEvent> get onCopy => Element.copyEvent.forTarget(this);

  /// Stream of `cut` events handled by this [Document].
  Stream<ClipboardEvent> get onCut => Element.cutEvent.forTarget(this);

  /// Stream of `doubleclick` events handled by this [Document].
  Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);

  /// Stream of `drag` events handled by this [Document].
  Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);

  /// Stream of `dragend` events handled by this [Document].
  Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);

  /// Stream of `dragenter` events handled by this [Document].
  Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);

  /// Stream of `dragleave` events handled by this [Document].
  Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);

  /// Stream of `dragover` events handled by this [Document].
  Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);

  /// Stream of `dragstart` events handled by this [Document].
  Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);

  /// Stream of `drop` events handled by this [Document].
  Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);

  Stream<Event> get onDurationChange =>
      Element.durationChangeEvent.forTarget(this);

  Stream<Event> get onEmptied => Element.emptiedEvent.forTarget(this);

  Stream<Event> get onEnded => Element.endedEvent.forTarget(this);

  /// Stream of `error` events handled by this [Document].
  Stream<Event> get onError => Element.errorEvent.forTarget(this);

  /// Stream of `focus` events handled by this [Document].
  Stream<Event> get onFocus => Element.focusEvent.forTarget(this);

  /// Stream of `input` events handled by this [Document].
  Stream<Event> get onInput => Element.inputEvent.forTarget(this);

  /// Stream of `invalid` events handled by this [Document].
  Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);

  /// Stream of `keydown` events handled by this [Document].
  Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);

  /// Stream of `keypress` events handled by this [Document].
  Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);

  /// Stream of `keyup` events handled by this [Document].
  Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);

  /// Stream of `load` events handled by this [Document].
  Stream<Event> get onLoad => Element.loadEvent.forTarget(this);

  Stream<Event> get onLoadedData => Element.loadedDataEvent.forTarget(this);

  Stream<Event> get onLoadedMetadata =>
      Element.loadedMetadataEvent.forTarget(this);

  /// Stream of `mousedown` events handled by this [Document].
  Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);

  /// Stream of `mouseenter` events handled by this [Document].
  Stream<MouseEvent> get onMouseEnter =>
      Element.mouseEnterEvent.forTarget(this);

  /// Stream of `mouseleave` events handled by this [Document].
  Stream<MouseEvent> get onMouseLeave =>
      Element.mouseLeaveEvent.forTarget(this);

  /// Stream of `mousemove` events handled by this [Document].
  Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);

  /// Stream of `mouseout` events handled by this [Document].
  Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);

  /// Stream of `mouseover` events handled by this [Document].
  Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);

  /// Stream of `mouseup` events handled by this [Document].
  Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);

  /// Stream of `mousewheel` events handled by this [Document].
  Stream<WheelEvent> get onMouseWheel =>
      Element.mouseWheelEvent.forTarget(this);

  /// Stream of `paste` events handled by this [Document].
  Stream<ClipboardEvent> get onPaste => Element.pasteEvent.forTarget(this);

  Stream<Event> get onPause => Element.pauseEvent.forTarget(this);

  Stream<Event> get onPlay => Element.playEvent.forTarget(this);

  Stream<Event> get onPlaying => Element.playingEvent.forTarget(this);

  Stream<Event> get onPointerLockChange =>
      pointerLockChangeEvent.forTarget(this);

  Stream<Event> get onPointerLockError => pointerLockErrorEvent.forTarget(this);

  Stream<Event> get onRateChange => Element.rateChangeEvent.forTarget(this);

  /// Stream of `readystatechange` events handled by this [Document].
  Stream<Event> get onReadyStateChange => readyStateChangeEvent.forTarget(this);

  /// Stream of `reset` events handled by this [Document].
  Stream<Event> get onReset => Element.resetEvent.forTarget(this);

  Stream<Event> get onResize => Element.resizeEvent.forTarget(this);

  /// Stream of `scroll` events handled by this [Document].
  Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);

  /// Stream of `search` events handled by this [Document].
  Stream<Event> get onSearch => Element.searchEvent.forTarget(this);

  /// Stream of `securitypolicyviolation` events handled by this [Document].
  Stream<SecurityPolicyViolationEvent> get onSecurityPolicyViolation =>
      securityPolicyViolationEvent.forTarget(this);

  Stream<Event> get onSeeked => Element.seekedEvent.forTarget(this);

  Stream<Event> get onSeeking => Element.seekingEvent.forTarget(this);

  /// Stream of `select` events handled by this [Document].
  Stream<Event> get onSelect => Element.selectEvent.forTarget(this);

  /// Stream of `selectionchange` events handled by this [Document].
  Stream<Event> get onSelectionChange => selectionChangeEvent.forTarget(this);

  /// Stream of `selectstart` events handled by this [Document].
  Stream<Event> get onSelectStart => Element.selectStartEvent.forTarget(this);

  Stream<Event> get onStalled => Element.stalledEvent.forTarget(this);

  /// Stream of `submit` events handled by this [Document].
  Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);

  Stream<Event> get onSuspend => Element.suspendEvent.forTarget(this);

  Stream<Event> get onTimeUpdate => Element.timeUpdateEvent.forTarget(this);

  /// Stream of `touchcancel` events handled by this [Document].
  Stream<TouchEvent> get onTouchCancel =>
      Element.touchCancelEvent.forTarget(this);

  /// Stream of `touchend` events handled by this [Document].
  Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);

  /// Stream of `touchmove` events handled by this [Document].
  Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);

  /// Stream of `touchstart` events handled by this [Document].
  Stream<TouchEvent> get onTouchStart =>
      Element.touchStartEvent.forTarget(this);

  Stream<Event> get onVolumeChange => Element.volumeChangeEvent.forTarget(this);

  Stream<Event> get onWaiting => Element.waitingEvent.forTarget(this);

  /// Stream of `fullscreenchange` events handled by this [Document].
  Stream<Event> get onFullscreenChange =>
      Element.fullscreenChangeEvent.forTarget(this);

  /// Stream of `fullscreenerror` events handled by this [Document].
  Stream<Event> get onFullscreenError =>
      Element.fullscreenErrorEvent.forTarget(this);

  /**
   * Finds all descendant elements of this document that match the specified
   * group of selectors.
   *
   * Unless your webpage contains multiple documents, the top-level
   * [querySelectorAll]
   * method behaves the same as this method, so you should use it instead to
   * save typing a few characters.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = document.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  ElementList<T> querySelectorAll<T extends Element>(String selectors) =>
      new _FrozenElementList<T>._wrap(_querySelectorAll(selectors));

  /// Checks if [registerElement] is supported on the current platform.
  bool get supportsRegisterElement {
    return JS('bool', '("registerElement" in #)', this);
  }

  /// *Deprecated*: use [supportsRegisterElement] instead.
  @deprecated
  bool get supportsRegister => supportsRegisterElement;

  void registerElement(String tag, Type customElementClass,
      {String extendsTag}) {
    registerElement2(
        tag, {'prototype': customElementClass, 'extends': extendsTag});
  }

  @ForceInline() // Almost all call sites have one argument.
  Element createElement(String tagName, [String typeExtension]) {
    return (typeExtension == null)
        ? _createElement_2(tagName)
        : _createElement(tagName, typeExtension);
  }

  // The two-argument version of this is automatically generated, but we need to
  // omit the typeExtension if it's null on Firefox or we get an is="null" attribute.
  _createElement_2(String tagName) =>
      JS('Element', '#.createElement(#)', this, tagName);

  // The three-argument version of this is automatically generated, but we need to
  // omit the typeExtension if it's null on Firefox or we get an is="null" attribute.
  _createElementNS_2(String namespaceURI, String qualifiedName) => JS(
      'Element', '#.createElementNS(#, #)', this, namespaceURI, qualifiedName);

  Element createElementNS(String namespaceURI, String qualifiedName,
      [String typeExtension]) {
    return (typeExtension == null)
        ? _createElementNS_2(namespaceURI, qualifiedName)
        : _createElementNS(namespaceURI, qualifiedName, typeExtension);
  }

  NodeIterator _createNodeIterator(Node root,
          [int whatToShow, NodeFilter filter]) =>
      JS('NodeIterator', '#.createNodeIterator(#, #, #, false)', this, root,
          whatToShow, filter);

  TreeWalker _createTreeWalker(Node root,
          [int whatToShow, NodeFilter filter]) =>
      JS('TreeWalker', '#.createTreeWalker(#, #, #, false)', this, root,
          whatToShow, filter);

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  String get visibilityState => JS(
      'String',
      '(#.visibilityState || #.mozVisibilityState || #.msVisibilityState ||'
      '#.webkitVisibilityState)',
      this,
      this,
      this,
      this);
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DocumentFragment")
class DocumentFragment extends Node
    implements NonElementParentNode, ParentNode {
  factory DocumentFragment() => document.createDocumentFragment();

  factory DocumentFragment.html(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    return document.body.createFragment(html,
        validator: validator, treeSanitizer: treeSanitizer);
  }

  factory DocumentFragment.svg(String svgContent,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    return new svg.SvgSvgElement().createFragment(svgContent,
        validator: validator, treeSanitizer: treeSanitizer);
  }

  HtmlCollection get _children =>
      throw new UnimplementedError('Use _docChildren instead');

  // Native field is used only by Dart code so does not lead to instantiation
  // of native classes
  @Creates('Null')
  List<Element> _docChildren;

  List<Element> get children {
    if (_docChildren == null) {
      _docChildren = new FilteredElementList(this);
    }
    return _docChildren;
  }

  set children(List<Element> value) {
    // Copy list first since we don't want liveness during iteration.
    var copy = value.toList();
    var children = this.children;
    children.clear();
    children.addAll(copy);
  }

  /**
   * Finds all descendant elements of this document fragment that match the
   * specified group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = document.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  ElementList<T> querySelectorAll<T extends Element>(String selectors) =>
      new _FrozenElementList<T>._wrap(_querySelectorAll(selectors));

  String get innerHtml {
    final e = new DivElement();
    e.append(this.clone(true));
    return e.innerHtml;
  }

  set innerHtml(String value) {
    this.setInnerHtml(value);
  }

  void setInnerHtml(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    this.nodes.clear();
    append(document.body.createFragment(html,
        validator: validator, treeSanitizer: treeSanitizer));
  }

  /**
   * Adds the specified text as a text node after the last child of this
   * document fragment.
   */
  void appendText(String text) {
    this.append(new Text(text));
  }

  /**
   * Parses the specified text as HTML and adds the resulting node after the
   * last child of this document fragment.
   */
  void appendHtml(String text,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    this.append(new DocumentFragment.html(text,
        validator: validator, treeSanitizer: treeSanitizer));
  }

  // To suppress missing implicit constructor warnings.
  factory DocumentFragment._() {
    throw new UnsupportedError("Not supported");
  }

  // From NonElementParentNode

  Element getElementById(String elementId) native;

  // From ParentNode

  @JSName('childElementCount')
  final int _childElementCount;

  @JSName('firstElementChild')
  final Element _firstElementChild;

  @JSName('lastElementChild')
  final Element _lastElementChild;

  /**
   * Finds the first descendant element of this document fragment that matches
   * the specified group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var element1 = fragment.querySelector('.className');
   *     var element2 = fragment.querySelector('#id');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  Element querySelector(String selectors) native;

  @JSName('querySelectorAll')
  @Creates('NodeList')
  @Returns('NodeList')
  List<Node> _querySelectorAll(String selectors) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DocumentOrShadowRoot")
class DocumentOrShadowRoot extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DocumentOrShadowRoot._() {
    throw new UnsupportedError("Not supported");
  }

  final Element activeElement;

  final Element fullscreenElement;

  final Element pointerLockElement;

  @Returns('_StyleSheetList|Null')
  @Creates('_StyleSheetList')
  final List<StyleSheet> styleSheets;

  Element elementFromPoint(int x, int y) native;

  List<Element> elementsFromPoint(int x, int y) native;

  Selection getSelection() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DocumentTimeline")
class DocumentTimeline extends AnimationTimeline {
  // To suppress missing implicit constructor warnings.
  factory DocumentTimeline._() {
    throw new UnsupportedError("Not supported");
  }

  factory DocumentTimeline([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return DocumentTimeline._create_1(options_1);
    }
    return DocumentTimeline._create_2();
  }
  static DocumentTimeline _create_1(options) =>
      JS('DocumentTimeline', 'new DocumentTimeline(#)', options);
  static DocumentTimeline _create_2() =>
      JS('DocumentTimeline', 'new DocumentTimeline()');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMError")
class DomError extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomError._() {
    throw new UnsupportedError("Not supported");
  }

  factory DomError(String name, [String message]) {
    if (message != null) {
      return DomError._create_1(name, message);
    }
    return DomError._create_2(name);
  }
  static DomError _create_1(name, message) =>
      JS('DomError', 'new DOMError(#,#)', name, message);
  static DomError _create_2(name) => JS('DomError', 'new DOMError(#)', name);

  final String message;

  final String name;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("DOMException")
class DomException extends Interceptor {
  static const String INDEX_SIZE = 'IndexSizeError';
  static const String HIERARCHY_REQUEST = 'HierarchyRequestError';
  static const String WRONG_DOCUMENT = 'WrongDocumentError';
  static const String INVALID_CHARACTER = 'InvalidCharacterError';
  static const String NO_MODIFICATION_ALLOWED = 'NoModificationAllowedError';
  static const String NOT_FOUND = 'NotFoundError';
  static const String NOT_SUPPORTED = 'NotSupportedError';
  static const String INVALID_STATE = 'InvalidStateError';
  static const String SYNTAX = 'SyntaxError';
  static const String INVALID_MODIFICATION = 'InvalidModificationError';
  static const String NAMESPACE = 'NamespaceError';
  static const String INVALID_ACCESS = 'InvalidAccessError';
  static const String TYPE_MISMATCH = 'TypeMismatchError';
  static const String SECURITY = 'SecurityError';
  static const String NETWORK = 'NetworkError';
  static const String ABORT = 'AbortError';
  static const String URL_MISMATCH = 'URLMismatchError';
  static const String QUOTA_EXCEEDED = 'QuotaExceededError';
  static const String TIMEOUT = 'TimeoutError';
  static const String INVALID_NODE_TYPE = 'InvalidNodeTypeError';
  static const String DATA_CLONE = 'DataCloneError';
  // Is TypeError class derived from DomException but name is 'TypeError'
  static const String TYPE_ERROR = 'TypeError';

  String get name {
    var errorName = JS('String', '#.name', this);
    // Although Safari nightly has updated the name to SecurityError, Safari 5
    // and 6 still return SECURITY_ERR.
    if (Device.isWebKit && errorName == 'SECURITY_ERR') return 'SecurityError';
    // Chrome release still uses old string, remove this line when Chrome stable
    // also prints out SyntaxError.
    if (Device.isWebKit && errorName == 'SYNTAX_ERR') return 'SyntaxError';
    return errorName;
  }

  // To suppress missing implicit constructor warnings.
  factory DomException._() {
    throw new UnsupportedError("Not supported");
  }

  final String message;

  String toString() => JS('String', 'String(#)', this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMImplementation")
class DomImplementation extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomImplementation._() {
    throw new UnsupportedError("Not supported");
  }

  XmlDocument createDocument(
      String namespaceURI, String qualifiedName, _DocumentType doctype) native;

  _DocumentType createDocumentType(
      String qualifiedName, String publicId, String systemId) native;

  @JSName('createHTMLDocument')
  HtmlDocument createHtmlDocument([String title]) native;

  bool hasFeature() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Iterator")
class DomIterator extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomIterator._() {
    throw new UnsupportedError("Not supported");
  }

  Object next([Object value]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMMatrix")
class DomMatrix extends DomMatrixReadOnly {
  // To suppress missing implicit constructor warnings.
  factory DomMatrix._() {
    throw new UnsupportedError("Not supported");
  }

  factory DomMatrix([Object init]) {
    if (init != null) {
      return DomMatrix._create_1(init);
    }
    return DomMatrix._create_2();
  }
  static DomMatrix _create_1(init) => JS('DomMatrix', 'new DOMMatrix(#)', init);
  static DomMatrix _create_2() => JS('DomMatrix', 'new DOMMatrix()');

  // Shadowing definition.
  num get a => JS("num", "#.a", this);

  set a(num value) {
    JS("void", "#.a = #", this, value);
  }

  // Shadowing definition.
  num get b => JS("num", "#.b", this);

  set b(num value) {
    JS("void", "#.b = #", this, value);
  }

  // Shadowing definition.
  num get c => JS("num", "#.c", this);

  set c(num value) {
    JS("void", "#.c = #", this, value);
  }

  // Shadowing definition.
  num get d => JS("num", "#.d", this);

  set d(num value) {
    JS("void", "#.d = #", this, value);
  }

  // Shadowing definition.
  num get e => JS("num", "#.e", this);

  set e(num value) {
    JS("void", "#.e = #", this, value);
  }

  // Shadowing definition.
  num get f => JS("num", "#.f", this);

  set f(num value) {
    JS("void", "#.f = #", this, value);
  }

  // Shadowing definition.
  num get m11 => JS("num", "#.m11", this);

  set m11(num value) {
    JS("void", "#.m11 = #", this, value);
  }

  // Shadowing definition.
  num get m12 => JS("num", "#.m12", this);

  set m12(num value) {
    JS("void", "#.m12 = #", this, value);
  }

  // Shadowing definition.
  num get m13 => JS("num", "#.m13", this);

  set m13(num value) {
    JS("void", "#.m13 = #", this, value);
  }

  // Shadowing definition.
  num get m14 => JS("num", "#.m14", this);

  set m14(num value) {
    JS("void", "#.m14 = #", this, value);
  }

  // Shadowing definition.
  num get m21 => JS("num", "#.m21", this);

  set m21(num value) {
    JS("void", "#.m21 = #", this, value);
  }

  // Shadowing definition.
  num get m22 => JS("num", "#.m22", this);

  set m22(num value) {
    JS("void", "#.m22 = #", this, value);
  }

  // Shadowing definition.
  num get m23 => JS("num", "#.m23", this);

  set m23(num value) {
    JS("void", "#.m23 = #", this, value);
  }

  // Shadowing definition.
  num get m24 => JS("num", "#.m24", this);

  set m24(num value) {
    JS("void", "#.m24 = #", this, value);
  }

  // Shadowing definition.
  num get m31 => JS("num", "#.m31", this);

  set m31(num value) {
    JS("void", "#.m31 = #", this, value);
  }

  // Shadowing definition.
  num get m32 => JS("num", "#.m32", this);

  set m32(num value) {
    JS("void", "#.m32 = #", this, value);
  }

  // Shadowing definition.
  num get m33 => JS("num", "#.m33", this);

  set m33(num value) {
    JS("void", "#.m33 = #", this, value);
  }

  // Shadowing definition.
  num get m34 => JS("num", "#.m34", this);

  set m34(num value) {
    JS("void", "#.m34 = #", this, value);
  }

  // Shadowing definition.
  num get m41 => JS("num", "#.m41", this);

  set m41(num value) {
    JS("void", "#.m41 = #", this, value);
  }

  // Shadowing definition.
  num get m42 => JS("num", "#.m42", this);

  set m42(num value) {
    JS("void", "#.m42 = #", this, value);
  }

  // Shadowing definition.
  num get m43 => JS("num", "#.m43", this);

  set m43(num value) {
    JS("void", "#.m43 = #", this, value);
  }

  // Shadowing definition.
  num get m44 => JS("num", "#.m44", this);

  set m44(num value) {
    JS("void", "#.m44 = #", this, value);
  }

  static DomMatrix fromFloat32Array(Float32List array32) native;

  static DomMatrix fromFloat64Array(Float64List array64) native;

  static DomMatrix fromMatrix([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _fromMatrix_1(other_1);
    }
    return _fromMatrix_2();
  }

  @JSName('fromMatrix')
  static DomMatrix _fromMatrix_1(other) native;
  @JSName('fromMatrix')
  static DomMatrix _fromMatrix_2() native;

  DomMatrix invertSelf() native;

  DomMatrix multiplySelf([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _multiplySelf_1(other_1);
    }
    return _multiplySelf_2();
  }

  @JSName('multiplySelf')
  DomMatrix _multiplySelf_1(other) native;
  @JSName('multiplySelf')
  DomMatrix _multiplySelf_2() native;

  DomMatrix preMultiplySelf([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _preMultiplySelf_1(other_1);
    }
    return _preMultiplySelf_2();
  }

  @JSName('preMultiplySelf')
  DomMatrix _preMultiplySelf_1(other) native;
  @JSName('preMultiplySelf')
  DomMatrix _preMultiplySelf_2() native;

  DomMatrix rotateAxisAngleSelf([num x, num y, num z, num angle]) native;

  DomMatrix rotateFromVectorSelf([num x, num y]) native;

  DomMatrix rotateSelf([num rotX, num rotY, num rotZ]) native;

  DomMatrix scale3dSelf([num scale, num originX, num originY, num originZ])
      native;

  DomMatrix scaleSelf(
      [num scaleX,
      num scaleY,
      num scaleZ,
      num originX,
      num originY,
      num originZ]) native;

  DomMatrix setMatrixValue(String transformList) native;

  DomMatrix skewXSelf([num sx]) native;

  DomMatrix skewYSelf([num sy]) native;

  DomMatrix translateSelf([num tx, num ty, num tz]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMMatrixReadOnly")
class DomMatrixReadOnly extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomMatrixReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  factory DomMatrixReadOnly([Object init]) {
    if (init != null) {
      return DomMatrixReadOnly._create_1(init);
    }
    return DomMatrixReadOnly._create_2();
  }
  static DomMatrixReadOnly _create_1(init) =>
      JS('DomMatrixReadOnly', 'new DOMMatrixReadOnly(#)', init);
  static DomMatrixReadOnly _create_2() =>
      JS('DomMatrixReadOnly', 'new DOMMatrixReadOnly()');

  num get a => JS("num", "#.a", this);

  num get b => JS("num", "#.b", this);

  num get c => JS("num", "#.c", this);

  num get d => JS("num", "#.d", this);

  num get e => JS("num", "#.e", this);

  num get f => JS("num", "#.f", this);

  bool get is2D => JS("bool", "#.is2D", this);

  bool get isIdentity => JS("bool", "#.isIdentity", this);

  num get m11 => JS("num", "#.m11", this);

  num get m12 => JS("num", "#.m12", this);

  num get m13 => JS("num", "#.m13", this);

  num get m14 => JS("num", "#.m14", this);

  num get m21 => JS("num", "#.m21", this);

  num get m22 => JS("num", "#.m22", this);

  num get m23 => JS("num", "#.m23", this);

  num get m24 => JS("num", "#.m24", this);

  num get m31 => JS("num", "#.m31", this);

  num get m32 => JS("num", "#.m32", this);

  num get m33 => JS("num", "#.m33", this);

  num get m34 => JS("num", "#.m34", this);

  num get m41 => JS("num", "#.m41", this);

  num get m42 => JS("num", "#.m42", this);

  num get m43 => JS("num", "#.m43", this);

  num get m44 => JS("num", "#.m44", this);

  DomMatrix flipX() native;

  DomMatrix flipY() native;

  static DomMatrixReadOnly fromFloat32Array(Float32List array32) native;

  static DomMatrixReadOnly fromFloat64Array(Float64List array64) native;

  static DomMatrixReadOnly fromMatrix([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _fromMatrix_1(other_1);
    }
    return _fromMatrix_2();
  }

  @JSName('fromMatrix')
  static DomMatrixReadOnly _fromMatrix_1(other) native;
  @JSName('fromMatrix')
  static DomMatrixReadOnly _fromMatrix_2() native;

  DomMatrix inverse() native;

  DomMatrix multiply([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _multiply_1(other_1);
    }
    return _multiply_2();
  }

  @JSName('multiply')
  DomMatrix _multiply_1(other) native;
  @JSName('multiply')
  DomMatrix _multiply_2() native;

  DomMatrix rotate([num rotX, num rotY, num rotZ]) native;

  DomMatrix rotateAxisAngle([num x, num y, num z, num angle]) native;

  DomMatrix rotateFromVector([num x, num y]) native;

  DomMatrix scale(
      [num scaleX,
      num scaleY,
      num scaleZ,
      num originX,
      num originY,
      num originZ]) native;

  DomMatrix scale3d([num scale, num originX, num originY, num originZ]) native;

  DomMatrix skewX([num sx]) native;

  DomMatrix skewY([num sy]) native;

  Float32List toFloat32Array() native;

  Float64List toFloat64Array() native;

  DomPoint transformPoint([Map point]) {
    if (point != null) {
      var point_1 = convertDartToNative_Dictionary(point);
      return _transformPoint_1(point_1);
    }
    return _transformPoint_2();
  }

  @JSName('transformPoint')
  DomPoint _transformPoint_1(point) native;
  @JSName('transformPoint')
  DomPoint _transformPoint_2() native;

  DomMatrix translate([num tx, num ty, num tz]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMParser")
class DomParser extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomParser._() {
    throw new UnsupportedError("Not supported");
  }

  factory DomParser() {
    return DomParser._create_1();
  }
  static DomParser _create_1() => JS('DomParser', 'new DOMParser()');

  Document parseFromString(String str, String type) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMPoint")
class DomPoint extends DomPointReadOnly {
  // To suppress missing implicit constructor warnings.
  factory DomPoint._() {
    throw new UnsupportedError("Not supported");
  }

  factory DomPoint([num x, num y, num z, num w]) {
    if (w != null) {
      return DomPoint._create_1(x, y, z, w);
    }
    if (z != null) {
      return DomPoint._create_2(x, y, z);
    }
    if (y != null) {
      return DomPoint._create_3(x, y);
    }
    if (x != null) {
      return DomPoint._create_4(x);
    }
    return DomPoint._create_5();
  }
  static DomPoint _create_1(x, y, z, w) =>
      JS('DomPoint', 'new DOMPoint(#,#,#,#)', x, y, z, w);
  static DomPoint _create_2(x, y, z) =>
      JS('DomPoint', 'new DOMPoint(#,#,#)', x, y, z);
  static DomPoint _create_3(x, y) => JS('DomPoint', 'new DOMPoint(#,#)', x, y);
  static DomPoint _create_4(x) => JS('DomPoint', 'new DOMPoint(#)', x);
  static DomPoint _create_5() => JS('DomPoint', 'new DOMPoint()');

  /// Checks if this type is supported on the current platform.
  static bool get supported =>
      JS('bool', '!!(window.DOMPoint) || !!(window.WebKitPoint)');

  // Shadowing definition.
  num get w => JS("num", "#.w", this);

  set w(num value) {
    JS("void", "#.w = #", this, value);
  }

  // Shadowing definition.
  num get x => JS("num", "#.x", this);

  set x(num value) {
    JS("void", "#.x = #", this, value);
  }

  // Shadowing definition.
  num get y => JS("num", "#.y", this);

  set y(num value) {
    JS("void", "#.y = #", this, value);
  }

  // Shadowing definition.
  num get z => JS("num", "#.z", this);

  set z(num value) {
    JS("void", "#.z = #", this, value);
  }

  static DomPoint fromPoint([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _fromPoint_1(other_1);
    }
    return _fromPoint_2();
  }

  @JSName('fromPoint')
  static DomPoint _fromPoint_1(other) native;
  @JSName('fromPoint')
  static DomPoint _fromPoint_2() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMPointReadOnly")
class DomPointReadOnly extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomPointReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  factory DomPointReadOnly([num x, num y, num z, num w]) {
    if (w != null) {
      return DomPointReadOnly._create_1(x, y, z, w);
    }
    if (z != null) {
      return DomPointReadOnly._create_2(x, y, z);
    }
    if (y != null) {
      return DomPointReadOnly._create_3(x, y);
    }
    if (x != null) {
      return DomPointReadOnly._create_4(x);
    }
    return DomPointReadOnly._create_5();
  }
  static DomPointReadOnly _create_1(x, y, z, w) =>
      JS('DomPointReadOnly', 'new DOMPointReadOnly(#,#,#,#)', x, y, z, w);
  static DomPointReadOnly _create_2(x, y, z) =>
      JS('DomPointReadOnly', 'new DOMPointReadOnly(#,#,#)', x, y, z);
  static DomPointReadOnly _create_3(x, y) =>
      JS('DomPointReadOnly', 'new DOMPointReadOnly(#,#)', x, y);
  static DomPointReadOnly _create_4(x) =>
      JS('DomPointReadOnly', 'new DOMPointReadOnly(#)', x);
  static DomPointReadOnly _create_5() =>
      JS('DomPointReadOnly', 'new DOMPointReadOnly()');

  num get w => JS("num", "#.w", this);

  num get x => JS("num", "#.x", this);

  num get y => JS("num", "#.y", this);

  num get z => JS("num", "#.z", this);

  static DomPointReadOnly fromPoint([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _fromPoint_1(other_1);
    }
    return _fromPoint_2();
  }

  @JSName('fromPoint')
  static DomPointReadOnly _fromPoint_1(other) native;
  @JSName('fromPoint')
  static DomPointReadOnly _fromPoint_2() native;

  DomPoint matrixTransform([Map matrix]) {
    if (matrix != null) {
      var matrix_1 = convertDartToNative_Dictionary(matrix);
      return _matrixTransform_1(matrix_1);
    }
    return _matrixTransform_2();
  }

  @JSName('matrixTransform')
  DomPoint _matrixTransform_1(matrix) native;
  @JSName('matrixTransform')
  DomPoint _matrixTransform_2() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMQuad")
class DomQuad extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomQuad._() {
    throw new UnsupportedError("Not supported");
  }

  factory DomQuad([Map p1, Map p2, Map p3, Map p4]) {
    if (p4 != null) {
      var p1_1 = convertDartToNative_Dictionary(p1);
      var p2_2 = convertDartToNative_Dictionary(p2);
      var p3_3 = convertDartToNative_Dictionary(p3);
      var p4_4 = convertDartToNative_Dictionary(p4);
      return DomQuad._create_1(p1_1, p2_2, p3_3, p4_4);
    }
    if (p3 != null) {
      var p1_1 = convertDartToNative_Dictionary(p1);
      var p2_2 = convertDartToNative_Dictionary(p2);
      var p3_3 = convertDartToNative_Dictionary(p3);
      return DomQuad._create_2(p1_1, p2_2, p3_3);
    }
    if (p2 != null) {
      var p1_1 = convertDartToNative_Dictionary(p1);
      var p2_2 = convertDartToNative_Dictionary(p2);
      return DomQuad._create_3(p1_1, p2_2);
    }
    if (p1 != null) {
      var p1_1 = convertDartToNative_Dictionary(p1);
      return DomQuad._create_4(p1_1);
    }
    return DomQuad._create_5();
  }
  static DomQuad _create_1(p1, p2, p3, p4) =>
      JS('DomQuad', 'new DOMQuad(#,#,#,#)', p1, p2, p3, p4);
  static DomQuad _create_2(p1, p2, p3) =>
      JS('DomQuad', 'new DOMQuad(#,#,#)', p1, p2, p3);
  static DomQuad _create_3(p1, p2) => JS('DomQuad', 'new DOMQuad(#,#)', p1, p2);
  static DomQuad _create_4(p1) => JS('DomQuad', 'new DOMQuad(#)', p1);
  static DomQuad _create_5() => JS('DomQuad', 'new DOMQuad()');

  final DomPoint p1;

  final DomPoint p2;

  final DomPoint p3;

  final DomPoint p4;

  static DomQuad fromQuad([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _fromQuad_1(other_1);
    }
    return _fromQuad_2();
  }

  @JSName('fromQuad')
  static DomQuad _fromQuad_1(other) native;
  @JSName('fromQuad')
  static DomQuad _fromQuad_2() native;

  static DomQuad fromRect([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _fromRect_1(other_1);
    }
    return _fromRect_2();
  }

  @JSName('fromRect')
  static DomQuad _fromRect_1(other) native;
  @JSName('fromRect')
  static DomQuad _fromRect_2() native;

  Rectangle getBounds() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ClientRectList,DOMRectList")
class DomRectList extends Interceptor
    with ListMixin<Rectangle>, ImmutableListMixin<Rectangle>
    implements List<Rectangle>, JavaScriptIndexingBehavior<Rectangle> {
  // To suppress missing implicit constructor warnings.
  factory DomRectList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  Rectangle operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Rectangle", "#[#]", this, index);
  }

  void operator []=(int index, Rectangle value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Rectangle> mixins.
  // Rectangle is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Rectangle get first {
    if (this.length > 0) {
      return JS('Rectangle', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Rectangle get last {
    int len = this.length;
    if (len > 0) {
      return JS('Rectangle', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Rectangle get single {
    int len = this.length;
    if (len == 1) {
      return JS('Rectangle', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Rectangle elementAt(int index) => this[index];
  // -- end List<Rectangle> mixins.

  Rectangle item(int index) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMRectReadOnly")
class DomRectReadOnly extends Interceptor implements Rectangle {
  // NOTE! All code below should be common with RectangleBase.
  String toString() {
    return 'Rectangle ($left, $top) $width x $height';
  }

  bool operator ==(other) {
    if (other is! Rectangle) return false;
    return left == other.left &&
        top == other.top &&
        width == other.width &&
        height == other.height;
  }

  int get hashCode => _JenkinsSmiHash.hash4(
      left.hashCode, top.hashCode, width.hashCode, height.hashCode);

  /**
   * Computes the intersection of `this` and [other].
   *
   * The intersection of two axis-aligned rectangles, if any, is always another
   * axis-aligned rectangle.
   *
   * Returns the intersection of this and `other`, or null if they don't
   * intersect.
   */
  Rectangle intersection(Rectangle other) {
    var x0 = max(left, other.left);
    var x1 = min(left + width, other.left + other.width);

    if (x0 <= x1) {
      var y0 = max(top, other.top);
      var y1 = min(top + height, other.top + other.height);

      if (y0 <= y1) {
        return new Rectangle(x0, y0, x1 - x0, y1 - y0);
      }
    }
    return null;
  }

  /**
   * Returns true if `this` intersects [other].
   */
  bool intersects(Rectangle<num> other) {
    return (left <= other.left + other.width &&
        other.left <= left + width &&
        top <= other.top + other.height &&
        other.top <= top + height);
  }

  /**
   * Returns a new rectangle which completely contains `this` and [other].
   */
  Rectangle boundingBox(Rectangle other) {
    var right = max(this.left + this.width, other.left + other.width);
    var bottom = max(this.top + this.height, other.top + other.height);

    var left = min(this.left, other.left);
    var top = min(this.top, other.top);

    return new Rectangle(left, top, right - left, bottom - top);
  }

  /**
   * Tests whether `this` entirely contains [another].
   */
  bool containsRectangle(Rectangle<num> another) {
    return left <= another.left &&
        left + width >= another.left + another.width &&
        top <= another.top &&
        top + height >= another.top + another.height;
  }

  /**
   * Tests whether [another] is inside or along the edges of `this`.
   */
  bool containsPoint(Point<num> another) {
    return another.x >= left &&
        another.x <= left + width &&
        another.y >= top &&
        another.y <= top + height;
  }

  Point get topLeft => new Point(this.left, this.top);
  Point get topRight => new Point(this.left + this.width, this.top);
  Point get bottomRight =>
      new Point(this.left + this.width, this.top + this.height);
  Point get bottomLeft => new Point(this.left, this.top + this.height);

  // To suppress missing implicit constructor warnings.
  factory DomRectReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  factory DomRectReadOnly([num x, num y, num width, num height]) {
    if (height != null) {
      return DomRectReadOnly._create_1(x, y, width, height);
    }
    if (width != null) {
      return DomRectReadOnly._create_2(x, y, width);
    }
    if (y != null) {
      return DomRectReadOnly._create_3(x, y);
    }
    if (x != null) {
      return DomRectReadOnly._create_4(x);
    }
    return DomRectReadOnly._create_5();
  }
  static DomRectReadOnly _create_1(x, y, width, height) => JS(
      'DomRectReadOnly', 'new DOMRectReadOnly(#,#,#,#)', x, y, width, height);
  static DomRectReadOnly _create_2(x, y, width) =>
      JS('DomRectReadOnly', 'new DOMRectReadOnly(#,#,#)', x, y, width);
  static DomRectReadOnly _create_3(x, y) =>
      JS('DomRectReadOnly', 'new DOMRectReadOnly(#,#)', x, y);
  static DomRectReadOnly _create_4(x) =>
      JS('DomRectReadOnly', 'new DOMRectReadOnly(#)', x);
  static DomRectReadOnly _create_5() =>
      JS('DomRectReadOnly', 'new DOMRectReadOnly()');

  num get bottom => JS("num", "#.bottom", this);

  num get height => JS("num", "#.height", this);

  num get left => JS("num", "#.left", this);

  num get right => JS("num", "#.right", this);

  num get top => JS("num", "#.top", this);

  num get width => JS("num", "#.width", this);

  num get x => JS("num", "#.x", this);

  num get y => JS("num", "#.y", this);

  static DomRectReadOnly fromRect([Map other]) {
    if (other != null) {
      var other_1 = convertDartToNative_Dictionary(other);
      return _fromRect_1(other_1);
    }
    return _fromRect_2();
  }

  @JSName('fromRect')
  static DomRectReadOnly _fromRect_1(other) native;
  @JSName('fromRect')
  static DomRectReadOnly _fromRect_2() native;
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMStringList")
class DomStringList extends Interceptor
    with ListMixin<String>, ImmutableListMixin<String>
    implements JavaScriptIndexingBehavior<String>, List<String> {
  // To suppress missing implicit constructor warnings.
  factory DomStringList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  String operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("String", "#[#]", this, index);
  }

  void operator []=(int index, String value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<String> mixins.
  // String is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  String get first {
    if (this.length > 0) {
      return JS('String', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  String get last {
    int len = this.length;
    if (len > 0) {
      return JS('String', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  String get single {
    int len = this.length;
    if (len == 1) {
      return JS('String', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  String elementAt(int index) => this[index];
  // -- end List<String> mixins.

  String item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMStringMap")
class DomStringMap extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomStringMap._() {
    throw new UnsupportedError("Not supported");
  }

  void __delete__(String name) native;

  void __setter__(String name, String value) native;

  String item(String name) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DOMTokenList")
class DomTokenList extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomTokenList._() {
    throw new UnsupportedError("Not supported");
  }

  final int length;

  String value;

  void add(String tokens) native;

  bool contains(String token) native;

  String item(int index) native;

  void remove(String tokens) native;

  void replace(String token, String newToken) native;

  bool supports(String token) native;

  bool toggle(String token, [bool force]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

class _ChildrenElementList extends ListBase<Element>
    implements NodeListWrapper {
  // Raw Element.
  final Element _element;
  final HtmlCollection _childElements;

  _ChildrenElementList._wrap(Element element)
      : _childElements = element._children,
        _element = element;

  bool contains(Object element) => _childElements.contains(element);

  bool get isEmpty {
    return _element._firstElementChild == null;
  }

  int get length {
    return _childElements.length;
  }

  Element operator [](int index) {
    return _childElements[index];
  }

  void operator []=(int index, Element value) {
    _element._replaceChild(value, _childElements[index]);
  }

  set length(int newLength) {
    // TODO(jacobr): remove children when length is reduced.
    throw new UnsupportedError('Cannot resize element lists');
  }

  Element add(Element value) {
    _element.append(value);
    return value;
  }

  Iterator<Element> get iterator => toList().iterator;

  void addAll(Iterable<Element> iterable) {
    if (iterable is _ChildNodeListLazy) {
      iterable = new List.from(iterable);
    }

    for (Element element in iterable) {
      _element.append(element);
    }
  }

  void sort([int compare(Element a, Element b)]) {
    throw new UnsupportedError('Cannot sort element lists');
  }

  void shuffle([Random random]) {
    throw new UnsupportedError('Cannot shuffle element lists');
  }

  void removeWhere(bool test(Element element)) {
    _filter(test, false);
  }

  void retainWhere(bool test(Element element)) {
    _filter(test, true);
  }

  void _filter(bool test(Element element), bool retainMatching) {
    var removed;
    if (retainMatching) {
      removed = _element.children.where((e) => !test(e));
    } else {
      removed = _element.children.where(test);
    }
    for (var e in removed) e.remove();
  }

  void fillRange(int start, int end, [Element fillValue]) {
    throw new UnimplementedError();
  }

  void replaceRange(int start, int end, Iterable<Element> iterable) {
    throw new UnimplementedError();
  }

  void removeRange(int start, int end) {
    throw new UnimplementedError();
  }

  void setRange(int start, int end, Iterable<Element> iterable,
      [int skipCount = 0]) {
    throw new UnimplementedError();
  }

  bool remove(Object object) {
    if (object is Element) {
      Element element = object;
      if (identical(element.parentNode, _element)) {
        _element._removeChild(element);
        return true;
      }
    }
    return false;
  }

  void insert(int index, Element element) {
    if (index < 0 || index > length) {
      throw new RangeError.range(index, 0, length);
    }
    if (index == length) {
      _element.append(element);
    } else {
      _element.insertBefore(element, this[index]);
    }
  }

  void setAll(int index, Iterable<Element> iterable) {
    throw new UnimplementedError();
  }

  void clear() {
    _element._clearChildren();
  }

  Element removeAt(int index) {
    final result = this[index];
    if (result != null) {
      _element._removeChild(result);
    }
    return result;
  }

  Element removeLast() {
    final result = this.last;
    if (result != null) {
      _element._removeChild(result);
    }
    return result;
  }

  Element get first {
    Element result = _element._firstElementChild;
    if (result == null) throw new StateError("No elements");
    return result;
  }

  Element get last {
    Element result = _element._lastElementChild;
    if (result == null) throw new StateError("No elements");
    return result;
  }

  Element get single {
    if (length > 1) throw new StateError("More than one element");
    return first;
  }

  List<Node> get rawList => _childElements;
}

/**
 * An immutable list containing HTML elements. This list contains some
 * additional methods when compared to regular lists for ease of CSS
 * manipulation on a group of elements.
 */
abstract class ElementList<T extends Element> extends ListBase<T> {
  /**
   * The union of all CSS classes applied to the elements in this list.
   *
   * This set makes it easy to add, remove or toggle (add if not present, remove
   * if present) the classes applied to a collection of elements.
   *
   *     htmlList.classes.add('selected');
   *     htmlList.classes.toggle('isOnline');
   *     htmlList.classes.remove('selected');
   */
  CssClassSet get classes;

  /** Replace the classes with `value` for every element in this list. */
  set classes(Iterable<String> value);

  /**
   * Access the union of all [CssStyleDeclaration]s that are associated with an
   * [ElementList].
   *
   * Grouping the style objects all together provides easy editing of specific
   * properties of a collection of elements. Setting a specific property value
   * will set that property in all [Element]s in the [ElementList]. Getting a
   * specific property value will return the value of the property of the first
   * element in the [ElementList].
   */
  CssStyleDeclarationBase get style;

  /**
   * Access dimensions and position of the Elements in this list.
   *
   * Setting the height or width properties will set the height or width
   * property for all elements in the list. This returns a rectangle with the
   * dimensions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Getting the height or width returns the height or width of the
   * first Element in this list.
   *
   * Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not.
   */
  CssRect get contentEdge;

  /**
   * Access dimensions and position of the first Element's content + padding box
   * in this list.
   *
   * This returns a rectangle with the dimensions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's `innerHeight` value for an element. This
   * is also a rectangle equalling the dimensions of clientHeight and
   * clientWidth.
   */
  CssRect get paddingEdge;

  /**
   * Access dimensions and position of the first Element's content + padding +
   * border box in this list.
   *
   * This returns a rectangle with the dimensions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's `outerHeight` value for an element.
   */
  CssRect get borderEdge;

  /**
   * Access dimensions and position of the first Element's content + padding +
   * border + margin box in this list.
   *
   * This returns a rectangle with the dimensions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's `outerHeight` value for an element.
   */
  CssRect get marginEdge;

  /// Stream of `abort` events handled by this [Element].
  ElementStream<Event> get onAbort;

  /// Stream of `beforecopy` events handled by this [Element].
  ElementStream<Event> get onBeforeCopy;

  /// Stream of `beforecut` events handled by this [Element].
  ElementStream<Event> get onBeforeCut;

  /// Stream of `beforepaste` events handled by this [Element].
  ElementStream<Event> get onBeforePaste;

  /// Stream of `blur` events handled by this [Element].
  ElementStream<Event> get onBlur;

  ElementStream<Event> get onCanPlay;

  ElementStream<Event> get onCanPlayThrough;

  /// Stream of `change` events handled by this [Element].
  ElementStream<Event> get onChange;

  /// Stream of `click` events handled by this [Element].
  ElementStream<MouseEvent> get onClick;

  /// Stream of `contextmenu` events handled by this [Element].
  ElementStream<MouseEvent> get onContextMenu;

  /// Stream of `copy` events handled by this [Element].
  ElementStream<ClipboardEvent> get onCopy;

  /// Stream of `cut` events handled by this [Element].
  ElementStream<ClipboardEvent> get onCut;

  /// Stream of `doubleclick` events handled by this [Element].
  ElementStream<Event> get onDoubleClick;

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDrag;

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragEnd;

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragEnter;

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragLeave;

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragOver;

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragStart;

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDrop;

  ElementStream<Event> get onDurationChange;

  ElementStream<Event> get onEmptied;

  ElementStream<Event> get onEnded;

  /// Stream of `error` events handled by this [Element].
  ElementStream<Event> get onError;

  /// Stream of `focus` events handled by this [Element].
  ElementStream<Event> get onFocus;

  /// Stream of `input` events handled by this [Element].
  ElementStream<Event> get onInput;

  /// Stream of `invalid` events handled by this [Element].
  ElementStream<Event> get onInvalid;

  /// Stream of `keydown` events handled by this [Element].
  ElementStream<KeyboardEvent> get onKeyDown;

  /// Stream of `keypress` events handled by this [Element].
  ElementStream<KeyboardEvent> get onKeyPress;

  /// Stream of `keyup` events handled by this [Element].
  ElementStream<KeyboardEvent> get onKeyUp;

  /// Stream of `load` events handled by this [Element].
  ElementStream<Event> get onLoad;

  ElementStream<Event> get onLoadedData;

  ElementStream<Event> get onLoadedMetadata;

  /// Stream of `mousedown` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseDown;

  /// Stream of `mouseenter` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseEnter;

  /// Stream of `mouseleave` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseLeave;

  /// Stream of `mousemove` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseMove;

  /// Stream of `mouseout` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseOut;

  /// Stream of `mouseover` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseOver;

  /// Stream of `mouseup` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseUp;

  /// Stream of `mousewheel` events handled by this [Element].
  ElementStream<WheelEvent> get onMouseWheel;

  /// Stream of `paste` events handled by this [Element].
  ElementStream<ClipboardEvent> get onPaste;

  ElementStream<Event> get onPause;

  ElementStream<Event> get onPlay;

  ElementStream<Event> get onPlaying;

  ElementStream<Event> get onRateChange;

  /// Stream of `reset` events handled by this [Element].
  ElementStream<Event> get onReset;

  ElementStream<Event> get onResize;

  /// Stream of `scroll` events handled by this [Element].
  ElementStream<Event> get onScroll;

  /// Stream of `search` events handled by this [Element].
  ElementStream<Event> get onSearch;

  ElementStream<Event> get onSeeked;

  ElementStream<Event> get onSeeking;

  /// Stream of `select` events handled by this [Element].
  ElementStream<Event> get onSelect;

  /// Stream of `selectstart` events handled by this [Element].
  ElementStream<Event> get onSelectStart;

  ElementStream<Event> get onStalled;

  /// Stream of `submit` events handled by this [Element].
  ElementStream<Event> get onSubmit;

  ElementStream<Event> get onSuspend;

  ElementStream<Event> get onTimeUpdate;

  /// Stream of `touchcancel` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchCancel;

  /// Stream of `touchend` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchEnd;

  /// Stream of `touchenter` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchEnter;

  /// Stream of `touchleave` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchLeave;

  /// Stream of `touchmove` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchMove;

  /// Stream of `touchstart` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchStart;

  /// Stream of `transitionend` events handled by this [Element].
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd;

  ElementStream<Event> get onVolumeChange;

  ElementStream<Event> get onWaiting;

  /// Stream of `fullscreenchange` events handled by this [Element].
  ElementStream<Event> get onFullscreenChange;

  /// Stream of `fullscreenerror` events handled by this [Element].
  ElementStream<Event> get onFullscreenError;

  ElementStream<WheelEvent> get onWheel;
}

// Wrapper over an immutable NodeList to make it implement ElementList.
//
// Clients are {`Document`, `DocumentFragment`}.`querySelectorAll` which are
// declared to return `ElementList`.  This provides all the static analysis
// benefit so there is no need for this class have a constrained type parameter.
//
class _FrozenElementList<E extends Element> extends ListBase<E>
    implements ElementList<E>, NodeListWrapper {
  final List<Node> _nodeList;

  _FrozenElementList._wrap(this._nodeList) {
    assert(this._nodeList.every((element) => element is E),
        "Query expects only HTML elements of type $E but found ${this._nodeList.firstWhere((e) => e is! E)}");
  }

  int get length => _nodeList.length;

  E operator [](int index) => _nodeList[index];

  void operator []=(int index, E value) {
    throw new UnsupportedError('Cannot modify list');
  }

  set length(int newLength) {
    throw new UnsupportedError('Cannot modify list');
  }

  void sort([Comparator<E> compare]) {
    throw new UnsupportedError('Cannot sort list');
  }

  void shuffle([Random random]) {
    throw new UnsupportedError('Cannot shuffle list');
  }

  E get first => _nodeList.first;

  E get last => _nodeList.last;

  E get single => _nodeList.single;

  CssClassSet get classes => new _MultiElementCssClassSet(this);

  CssStyleDeclarationBase get style => new _CssStyleDeclarationSet(this);

  set classes(Iterable<String> value) {
    // TODO(sra): This might be faster for Sets:
    //
    //     new _MultiElementCssClassSet(this).writeClasses(value)
    //
    // as the code below converts the Iterable[value] to a string multiple
    // times.  Maybe compute the string and set className here.
    forEach((e) => e.classes = value);
  }

  CssRect get contentEdge => new _ContentCssListRect(this);

  CssRect get paddingEdge => this.first.paddingEdge;

  CssRect get borderEdge => this.first.borderEdge;

  CssRect get marginEdge => this.first.marginEdge;

  List<Node> get rawList => _nodeList;

  /// Stream of `abort` events handled by this [Element].
  ElementStream<Event> get onAbort => Element.abortEvent._forElementList(this);

  /// Stream of `beforecopy` events handled by this [Element].
  ElementStream<Event> get onBeforeCopy =>
      Element.beforeCopyEvent._forElementList(this);

  /// Stream of `beforecut` events handled by this [Element].
  ElementStream<Event> get onBeforeCut =>
      Element.beforeCutEvent._forElementList(this);

  /// Stream of `beforepaste` events handled by this [Element].
  ElementStream<Event> get onBeforePaste =>
      Element.beforePasteEvent._forElementList(this);

  /// Stream of `blur` events handled by this [Element].
  ElementStream<Event> get onBlur => Element.blurEvent._forElementList(this);

  ElementStream<Event> get onCanPlay =>
      Element.canPlayEvent._forElementList(this);

  ElementStream<Event> get onCanPlayThrough =>
      Element.canPlayThroughEvent._forElementList(this);

  /// Stream of `change` events handled by this [Element].
  ElementStream<Event> get onChange =>
      Element.changeEvent._forElementList(this);

  /// Stream of `click` events handled by this [Element].
  ElementStream<MouseEvent> get onClick =>
      Element.clickEvent._forElementList(this);

  /// Stream of `contextmenu` events handled by this [Element].
  ElementStream<MouseEvent> get onContextMenu =>
      Element.contextMenuEvent._forElementList(this);

  /// Stream of `copy` events handled by this [Element].
  ElementStream<ClipboardEvent> get onCopy =>
      Element.copyEvent._forElementList(this);

  /// Stream of `cut` events handled by this [Element].
  ElementStream<ClipboardEvent> get onCut =>
      Element.cutEvent._forElementList(this);

  /// Stream of `doubleclick` events handled by this [Element].
  ElementStream<Event> get onDoubleClick =>
      Element.doubleClickEvent._forElementList(this);

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDrag =>
      Element.dragEvent._forElementList(this);

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragEnd =>
      Element.dragEndEvent._forElementList(this);

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragEnter =>
      Element.dragEnterEvent._forElementList(this);

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragLeave =>
      Element.dragLeaveEvent._forElementList(this);

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragOver =>
      Element.dragOverEvent._forElementList(this);

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragStart =>
      Element.dragStartEvent._forElementList(this);

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDrop =>
      Element.dropEvent._forElementList(this);

  ElementStream<Event> get onDurationChange =>
      Element.durationChangeEvent._forElementList(this);

  ElementStream<Event> get onEmptied =>
      Element.emptiedEvent._forElementList(this);

  ElementStream<Event> get onEnded => Element.endedEvent._forElementList(this);

  /// Stream of `error` events handled by this [Element].
  ElementStream<Event> get onError => Element.errorEvent._forElementList(this);

  /// Stream of `focus` events handled by this [Element].
  ElementStream<Event> get onFocus => Element.focusEvent._forElementList(this);

  /// Stream of `input` events handled by this [Element].
  ElementStream<Event> get onInput => Element.inputEvent._forElementList(this);

  /// Stream of `invalid` events handled by this [Element].
  ElementStream<Event> get onInvalid =>
      Element.invalidEvent._forElementList(this);

  /// Stream of `keydown` events handled by this [Element].
  ElementStream<KeyboardEvent> get onKeyDown =>
      Element.keyDownEvent._forElementList(this);

  /// Stream of `keypress` events handled by this [Element].
  ElementStream<KeyboardEvent> get onKeyPress =>
      Element.keyPressEvent._forElementList(this);

  /// Stream of `keyup` events handled by this [Element].
  ElementStream<KeyboardEvent> get onKeyUp =>
      Element.keyUpEvent._forElementList(this);

  /// Stream of `load` events handled by this [Element].
  ElementStream<Event> get onLoad => Element.loadEvent._forElementList(this);

  ElementStream<Event> get onLoadedData =>
      Element.loadedDataEvent._forElementList(this);

  ElementStream<Event> get onLoadedMetadata =>
      Element.loadedMetadataEvent._forElementList(this);

  /// Stream of `mousedown` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseDown =>
      Element.mouseDownEvent._forElementList(this);

  /// Stream of `mouseenter` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseEnter =>
      Element.mouseEnterEvent._forElementList(this);

  /// Stream of `mouseleave` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseLeave =>
      Element.mouseLeaveEvent._forElementList(this);

  /// Stream of `mousemove` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseMove =>
      Element.mouseMoveEvent._forElementList(this);

  /// Stream of `mouseout` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseOut =>
      Element.mouseOutEvent._forElementList(this);

  /// Stream of `mouseover` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseOver =>
      Element.mouseOverEvent._forElementList(this);

  /// Stream of `mouseup` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseUp =>
      Element.mouseUpEvent._forElementList(this);

  /// Stream of `mousewheel` events handled by this [Element].
  ElementStream<WheelEvent> get onMouseWheel =>
      Element.mouseWheelEvent._forElementList(this);

  /// Stream of `paste` events handled by this [Element].
  ElementStream<ClipboardEvent> get onPaste =>
      Element.pasteEvent._forElementList(this);

  ElementStream<Event> get onPause => Element.pauseEvent._forElementList(this);

  ElementStream<Event> get onPlay => Element.playEvent._forElementList(this);

  ElementStream<Event> get onPlaying =>
      Element.playingEvent._forElementList(this);

  ElementStream<Event> get onRateChange =>
      Element.rateChangeEvent._forElementList(this);

  /// Stream of `reset` events handled by this [Element].
  ElementStream<Event> get onReset => Element.resetEvent._forElementList(this);

  ElementStream<Event> get onResize =>
      Element.resizeEvent._forElementList(this);

  /// Stream of `scroll` events handled by this [Element].
  ElementStream<Event> get onScroll =>
      Element.scrollEvent._forElementList(this);

  /// Stream of `search` events handled by this [Element].
  ElementStream<Event> get onSearch =>
      Element.searchEvent._forElementList(this);

  ElementStream<Event> get onSeeked =>
      Element.seekedEvent._forElementList(this);

  ElementStream<Event> get onSeeking =>
      Element.seekingEvent._forElementList(this);

  /// Stream of `select` events handled by this [Element].
  ElementStream<Event> get onSelect =>
      Element.selectEvent._forElementList(this);

  /// Stream of `selectstart` events handled by this [Element].
  ElementStream<Event> get onSelectStart =>
      Element.selectStartEvent._forElementList(this);

  ElementStream<Event> get onStalled =>
      Element.stalledEvent._forElementList(this);

  /// Stream of `submit` events handled by this [Element].
  ElementStream<Event> get onSubmit =>
      Element.submitEvent._forElementList(this);

  ElementStream<Event> get onSuspend =>
      Element.suspendEvent._forElementList(this);

  ElementStream<Event> get onTimeUpdate =>
      Element.timeUpdateEvent._forElementList(this);

  /// Stream of `touchcancel` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchCancel =>
      Element.touchCancelEvent._forElementList(this);

  /// Stream of `touchend` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchEnd =>
      Element.touchEndEvent._forElementList(this);

  /// Stream of `touchenter` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchEnter =>
      Element.touchEnterEvent._forElementList(this);

  /// Stream of `touchleave` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchLeave =>
      Element.touchLeaveEvent._forElementList(this);

  /// Stream of `touchmove` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchMove =>
      Element.touchMoveEvent._forElementList(this);

  /// Stream of `touchstart` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchStart =>
      Element.touchStartEvent._forElementList(this);

  /// Stream of `transitionend` events handled by this [Element].
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd =>
      Element.transitionEndEvent._forElementList(this);

  ElementStream<Event> get onVolumeChange =>
      Element.volumeChangeEvent._forElementList(this);

  ElementStream<Event> get onWaiting =>
      Element.waitingEvent._forElementList(this);

  /// Stream of `fullscreenchange` events handled by this [Element].
  ElementStream<Event> get onFullscreenChange =>
      Element.fullscreenChangeEvent._forElementList(this);

  /// Stream of `fullscreenerror` events handled by this [Element].
  ElementStream<Event> get onFullscreenError =>
      Element.fullscreenErrorEvent._forElementList(this);

  ElementStream<WheelEvent> get onWheel =>
      Element.wheelEvent._forElementList(this);
}

/**
 * An abstract class, which all HTML elements extend.
 */
@Native("Element")
class Element extends Node
    implements
        NonDocumentTypeChildNode,
        GlobalEventHandlers,
        ParentNode,
        ChildNode {
  /**
   * Creates an HTML element from a valid fragment of HTML.
   *
   *     var element = new Element.html('<div class="foo">content</div>');
   *
   * The HTML fragment should contain only one single root element, any
   * leading or trailing text nodes will be removed.
   *
   * The HTML fragment is parsed as if it occurred within the context of a
   * `<body>` tag, this means that special elements such as `<caption>` which
   * must be parsed within the scope of a `<table>` element will be dropped. Use
   * [createFragment] to parse contextual HTML fragments.
   *
   * Unless a validator is provided this will perform the default validation
   * and remove all scriptable elements and attributes.
   *
   * See also:
   *
   * * [NodeValidator]
   *
   */
  factory Element.html(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    var fragment = document.body.createFragment(html,
        validator: validator, treeSanitizer: treeSanitizer);

    return fragment.nodes.where((e) => e is Element).single;
  }

  /**
   * Custom element creation constructor.
   *
   * This constructor is used by the DOM when a custom element has been
   * created. It can only be invoked by subclasses of Element from
   * that classes created constructor.
   *
   *     class CustomElement extends Element {
   *       factory CustomElement() => new Element.tag('x-custom');
   *
   *       CustomElement.created() : super.created() {
   *          // Perform any element initialization.
   *       }
   *     }
   *     document.registerElement('x-custom', CustomElement);
   */
  Element.created() : super._created();

  /**
   * Creates the HTML element specified by the tag name.
   *
   * This is similar to [Document.createElement].
   * [tag] should be a valid HTML tag name. If [tag] is an unknown tag then
   * this will create an [UnknownElement].
   *
   *     var divElement = new Element.tag('div');
   *     print(divElement is DivElement); // 'true'
   *     var myElement = new Element.tag('unknownTag');
   *     print(myElement is UnknownElement); // 'true'
   *
   * For standard elements it is better to use the element type constructors:
   *
   *     var element = new DivElement();
   *
   * It is better to use e.g `new CanvasElement()` because the type of the
   * expression is `CanvasElement`, whereas the type of `Element.tag` is the
   * less specific `Element`.
   *
   * See also:
   *
   * * [isTagSupported]
   */
  factory Element.tag(String tag, [String typeExtention]) =>
      _ElementFactoryProvider.createElement_tag(tag, typeExtention);

  /// Creates a new `<a>` element.
  ///
  /// This is equivalent to calling `new Element.tag('a')`.
  factory Element.a() => new AnchorElement();

  /// Creates a new `<article>` element.
  ///
  /// This is equivalent to calling `new Element.tag('article')`.
  factory Element.article() => new Element.tag('article');

  /// Creates a new `<aside>` element.
  ///
  /// This is equivalent to calling `new Element.tag('aside')`.
  factory Element.aside() => new Element.tag('aside');

  /// Creates a new `<audio>` element.
  ///
  /// This is equivalent to calling `new Element.tag('audio')`.
  factory Element.audio() => new Element.tag('audio');

  /// Creates a new `<br>` element.
  ///
  /// This is equivalent to calling `new Element.tag('br')`.
  factory Element.br() => new BRElement();

  /// Creates a new `<canvas>` element.
  ///
  /// This is equivalent to calling `new Element.tag('canvas')`.
  factory Element.canvas() => new CanvasElement();

  /// Creates a new `<div>` element.
  ///
  /// This is equivalent to calling `new Element.tag('div')`.
  factory Element.div() => new DivElement();

  /// Creates a new `<footer>` element.
  ///
  /// This is equivalent to calling `new Element.tag('footer')`.
  factory Element.footer() => new Element.tag('footer');

  /// Creates a new `<header>` element.
  ///
  /// This is equivalent to calling `new Element.tag('header')`.
  factory Element.header() => new Element.tag('header');

  /// Creates a new `<hr>` element.
  ///
  /// This is equivalent to calling `new Element.tag('hr')`.
  factory Element.hr() => new Element.tag('hr');

  /// Creates a new `<iframe>` element.
  ///
  /// This is equivalent to calling `new Element.tag('iframe')`.
  factory Element.iframe() => new Element.tag('iframe');

  /// Creates a new `<img>` element.
  ///
  /// This is equivalent to calling `new Element.tag('img')`.
  factory Element.img() => new Element.tag('img');

  /// Creates a new `<li>` element.
  ///
  /// This is equivalent to calling `new Element.tag('li')`.
  factory Element.li() => new Element.tag('li');

  /// Creates a new `<nav>` element.
  ///
  /// This is equivalent to calling `new Element.tag('nav')`.
  factory Element.nav() => new Element.tag('nav');

  /// Creates a new `<ol>` element.
  ///
  /// This is equivalent to calling `new Element.tag('ol')`.
  factory Element.ol() => new Element.tag('ol');

  /// Creates a new `<option>` element.
  ///
  /// This is equivalent to calling `new Element.tag('option')`.
  factory Element.option() => new Element.tag('option');

  /// Creates a new `<p>` element.
  ///
  /// This is equivalent to calling `new Element.tag('p')`.
  factory Element.p() => new Element.tag('p');

  /// Creates a new `<pre>` element.
  ///
  /// This is equivalent to calling `new Element.tag('pre')`.
  factory Element.pre() => new Element.tag('pre');

  /// Creates a new `<section>` element.
  ///
  /// This is equivalent to calling `new Element.tag('section')`.
  factory Element.section() => new Element.tag('section');

  /// Creates a new `<select>` element.
  ///
  /// This is equivalent to calling `new Element.tag('select')`.
  factory Element.select() => new Element.tag('select');

  /// Creates a new `<span>` element.
  ///
  /// This is equivalent to calling `new Element.tag('span')`.
  factory Element.span() => new Element.tag('span');

  /// Creates a new `<svg>` element.
  ///
  /// This is equivalent to calling `new Element.tag('svg')`.
  factory Element.svg() => new Element.tag('svg');

  /// Creates a new `<table>` element.
  ///
  /// This is equivalent to calling `new Element.tag('table')`.
  factory Element.table() => new Element.tag('table');

  /// Creates a new `<td>` element.
  ///
  /// This is equivalent to calling `new Element.tag('td')`.
  factory Element.td() => new Element.tag('td');

  /// Creates a new `<textarea>` element.
  ///
  /// This is equivalent to calling `new Element.tag('textarea')`.
  factory Element.textarea() => new Element.tag('textarea');

  /// Creates a new `<th>` element.
  ///
  /// This is equivalent to calling `new Element.tag('th')`.
  factory Element.th() => new Element.tag('th');

  /// Creates a new `<tr>` element.
  ///
  /// This is equivalent to calling `new Element.tag('tr')`.
  factory Element.tr() => new Element.tag('tr');

  /// Creates a new `<ul>` element.
  ///
  /// This is equivalent to calling `new Element.tag('ul')`.
  factory Element.ul() => new Element.tag('ul');

  /// Creates a new `<video>` element.
  ///
  /// This is equivalent to calling `new Element.tag('video')`.
  factory Element.video() => new Element.tag('video');

  /**
   * All attributes on this element.
   *
   * Any modifications to the attribute map will automatically be applied to
   * this element.
   *
   * This only includes attributes which are not in a namespace
   * (such as 'xlink:href'), additional attributes can be accessed via
   * [getNamespacedAttributes].
   */
  Map<String, String> get attributes => new _ElementAttributeMap(this);

  set attributes(Map<String, String> value) {
    Map<String, String> attributes = this.attributes;
    attributes.clear();
    for (String key in value.keys) {
      attributes[key] = value[key];
    }
  }

  /**
   * List of the direct children of this element.
   *
   * This collection can be used to add and remove elements from the document.
   *
   *     var item = new DivElement();
   *     item.text = 'Something';
   *     document.body.children.add(item) // Item is now displayed on the page.
   *     for (var element in document.body.children) {
   *       element.style.background = 'red'; // Turns every child of body red.
   *     }
   */
  List<Element> get children => new _ChildrenElementList._wrap(this);

  set children(List<Element> value) {
    // Copy list first since we don't want liveness during iteration.
    var copy = value.toList();
    var children = this.children;
    children.clear();
    children.addAll(copy);
  }

  /**
   * Finds all descendent elements of this element that match the specified
   * group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = element.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  ElementList<T> querySelectorAll<T extends Element>(String selectors) =>
      new _FrozenElementList<T>._wrap(_querySelectorAll(selectors));

  /**
   * The set of CSS classes applied to this element.
   *
   * This set makes it easy to add, remove or toggle the classes applied to
   * this element.
   *
   *     element.classes.add('selected');
   *     element.classes.toggle('isOnline');
   *     element.classes.remove('selected');
   */
  CssClassSet get classes => new _ElementCssClassSet(this);

  set classes(Iterable<String> value) {
    // TODO(sra): Do this without reading the classes in clear() and addAll(),
    // or writing the classes in clear().
    CssClassSet classSet = classes;
    classSet.clear();
    classSet.addAll(value);
  }

  /**
   * Allows access to all custom data attributes (data-*) set on this element.
   *
   * The keys for the map must follow these rules:
   *
   * * The name must not begin with 'xml'.
   * * The name cannot contain a semi-colon (';').
   * * The name cannot contain any capital letters.
   *
   * Any keys from markup will be converted to camel-cased keys in the map.
   *
   * For example, HTML specified as:
   *
   *     <div data-my-random-value='value'></div>
   *
   * Would be accessed in Dart as:
   *
   *     var value = element.dataset['myRandomValue'];
   *
   * See also:
   *
   * * [Custom data
   *   attributes](http://dev.w3.org/html5/spec-preview/global-attributes.html#custom-data-attribute)
   */
  Map<String, String> get dataset => new _DataAttributeMap(attributes);

  set dataset(Map<String, String> value) {
    final data = this.dataset;
    data.clear();
    for (String key in value.keys) {
      data[key] = value[key];
    }
  }

  /**
   * Gets a map for manipulating the attributes of a particular namespace.
   *
   * This is primarily useful for SVG attributes such as xref:link.
   */
  Map<String, String> getNamespacedAttributes(String namespace) {
    return new _NamespacedAttributeMap(this, namespace);
  }

  /**
   * The set of all CSS values applied to this element, including inherited
   * and default values.
   *
   * The computedStyle contains values that are inherited from other
   * sources, such as parent elements or stylesheets. This differs from the
   * [style] property, which contains only the values specified directly on this
   * element.
   *
   * PseudoElement can be values such as `::after`, `::before`, `::marker`,
   * `::line-marker`.
   *
   * See also:
   *
   * * [CSS Inheritance and Cascade](http://docs.webplatform.org/wiki/tutorials/inheritance_and_cascade)
   * * [Pseudo-elements](http://docs.webplatform.org/wiki/css/selectors/pseudo-elements)
   */
  CssStyleDeclaration getComputedStyle([String pseudoElement]) {
    if (pseudoElement == null) {
      pseudoElement = '';
    }
    // TODO(jacobr): last param should be null, see b/5045788
    return window._getComputedStyle(this, pseudoElement);
  }

  /**
   * Gets the position of this element relative to the client area of the page.
   */
  Rectangle get client =>
      new Rectangle(clientLeft, clientTop, clientWidth, clientHeight);

  /**
   * Gets the offset of this element relative to its offsetParent.
   */
  Rectangle get offset =>
      new Rectangle(offsetLeft, offsetTop, offsetWidth, offsetHeight);

  /**
   * Adds the specified text after the last child of this element.
   */
  void appendText(String text) {
    this.append(new Text(text));
  }

  /**
   * Parses the specified text as HTML and adds the resulting node after the
   * last child of this element.
   */
  void appendHtml(String text,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    this.insertAdjacentHtml('beforeend', text,
        validator: validator, treeSanitizer: treeSanitizer);
  }

  /**
   * Checks to see if the tag name is supported by the current platform.
   *
   * The tag should be a valid HTML tag name.
   */
  static bool isTagSupported(String tag) {
    var e = _ElementFactoryProvider.createElement_tag(tag, null);
    return e is Element && !(e is UnknownElement);
  }

  /**
   * Called by the DOM when this element has been inserted into the live
   * document.
   *
   * More information can be found in the
   * [Custom Elements](http://w3c.github.io/webcomponents/spec/custom/#dfn-attached-callback)
   * draft specification.
   */
  void attached() {
    // For the deprecation period, call the old callback.
    enteredView();
  }

  /**
   * Called by the DOM when this element has been removed from the live
   * document.
   *
   * More information can be found in the
   * [Custom Elements](http://w3c.github.io/webcomponents/spec/custom/#dfn-detached-callback)
   * draft specification.
   */
  void detached() {
    // For the deprecation period, call the old callback.
    leftView();
  }

  /** *Deprecated*: override [attached] instead. */
  @deprecated
  void enteredView() {}

  List<Rectangle> getClientRects() {
    var value = _getClientRects();

    // If no prototype we need one for the world to hookup to the proper Dart class.
    var jsProto = JS('', '#.prototype', value);
    if (jsProto == null) {
      JS('', '#.prototype = Object.create(null)', value);
    }

    applyExtension('DOMRectList', value);

    return value;
  }

  /** *Deprecated*: override [detached] instead. */
  @deprecated
  void leftView() {}

  /**
   * Creates a new AnimationEffect object whose target element is the object
   * on which the method is called, and calls the play() method of the
   * AnimationTimeline object of the document timeline of the node document
   * of the element, passing the newly created AnimationEffect as the argument
   * to the method. Returns an Animation for the effect.
   *
   * Examples
   *
   *     var animation = elem.animate([{"opacity": 75}, {"opacity": 0}], 200);
   *
   *     var animation = elem.animate([
   *       {"transform": "translate(100px, -100%)"},
   *       {"transform" : "translate(400px, 500px)"}
   *     ], 1500);
   *
   * The [frames] parameter is an Iterable<Map>, where the
   * map entries specify CSS animation effects. The
   * [timing] paramter can be a double, representing the number of milliseconds
   * for the transition, or a Map with fields corresponding to those
   * of the [Timing] object.
  **/
  @SupportedBrowser(SupportedBrowser.CHROME, '36')
  Animation animate(Iterable<Map<String, dynamic>> frames, [timing]) {
    if (frames is! Iterable || !(frames.every((x) => x is Map))) {
      throw new ArgumentError("The frames parameter should be a List of Maps "
          "with frame information");
    }
    var convertedFrames;
    if (frames is Iterable) {
      convertedFrames = frames.map(convertDartToNative_Dictionary).toList();
    } else {
      convertedFrames = frames;
    }
    var convertedTiming =
        timing is Map ? convertDartToNative_Dictionary(timing) : timing;
    return convertedTiming == null
        ? _animate(convertedFrames)
        : _animate(convertedFrames, convertedTiming);
  }

  @JSName('animate')
  Animation _animate(Object effect, [timing]) native;
  /**
   * Called by the DOM whenever an attribute on this has been changed.
   */
  void attributeChanged(String name, String oldValue, String newValue) {}

  @Returns('String')
  // Non-null for Elements.
  String get localName => JS('String', '#', _localName);

  /**
   * A URI that identifies the XML namespace of this element.
   *
   * `null` if no namespace URI is specified.
   *
   * ## Other resources
   *
   * * [Node.namespaceURI](http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname)
   *   from W3C.
   */
  String get namespaceUri => _namespaceUri;

  /**
   * The string representation of this element.
   *
   * This is equivalent to reading the [localName] property.
   */
  String toString() => localName;

  /**
   * Scrolls this element into view.
   *
   * Only one of of the alignment options may be specified at a time.
   *
   * If no options are specified then this will attempt to scroll the minimum
   * amount needed to bring the element into view.
   *
   * Note that alignCenter is currently only supported on WebKit platforms. If
   * alignCenter is specified but not supported then this will fall back to
   * alignTop.
   *
   * See also:
   *
   * * [scrollIntoView](http://docs.webplatform.org/wiki/dom/methods/scrollIntoView)
   * * [scrollIntoViewIfNeeded](http://docs.webplatform.org/wiki/dom/methods/scrollIntoViewIfNeeded)
   */
  void scrollIntoView([ScrollAlignment alignment]) {
    var hasScrollIntoViewIfNeeded = true;
    hasScrollIntoViewIfNeeded =
        JS('bool', '!!(#.scrollIntoViewIfNeeded)', this);
    if (alignment == ScrollAlignment.TOP) {
      this._scrollIntoView(true);
    } else if (alignment == ScrollAlignment.BOTTOM) {
      this._scrollIntoView(false);
    } else if (hasScrollIntoViewIfNeeded) {
      if (alignment == ScrollAlignment.CENTER) {
        this._scrollIntoViewIfNeeded(true);
      } else {
        this._scrollIntoViewIfNeeded();
      }
    } else {
      this._scrollIntoView();
    }
  }

  /**
   * Static factory designed to expose `mousewheel` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<WheelEvent> mouseWheelEvent =
      const _CustomEventStreamProvider<WheelEvent>(
          Element._determineMouseWheelEventType);

  static String _determineMouseWheelEventType(EventTarget e) => 'wheel';

  /**
   * Static factory designed to expose `transitionend` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<TransitionEvent> transitionEndEvent =
      const _CustomEventStreamProvider<TransitionEvent>(
          Element._determineTransitionEventType);

  static String _determineTransitionEventType(EventTarget e) {
    // Unfortunately the normal 'ontransitionend' style checks don't work here.
    if (Device.isWebKit) {
      return 'webkitTransitionEnd';
    } else if (Device.isOpera) {
      return 'oTransitionEnd';
    }
    return 'transitionend';
  }

  /**
   * Inserts text into the DOM at the specified location.
   *
   * To see the possible values for [where], read the doc for
   * [insertAdjacentHtml].
   *
   * See also:
   *
   * * [insertAdjacentHtml]
   */
  void insertAdjacentText(String where, String text) {
    if (JS('bool', '!!#.insertAdjacentText', this)) {
      _insertAdjacentText(where, text);
    } else {
      _insertAdjacentNode(where, new Text(text));
    }
  }

  @JSName('insertAdjacentText')
  void _insertAdjacentText(String where, String text) native;

  /**
   * Parses text as an HTML fragment and inserts it into the DOM at the
   * specified location.
   *
   * The [where] parameter indicates where to insert the HTML fragment:
   *
   * * 'beforeBegin': Immediately before this element.
   * * 'afterBegin': As the first child of this element.
   * * 'beforeEnd': As the last child of this element.
   * * 'afterEnd': Immediately after this element.
   *
   *     var html = '<div class="something">content</div>';
   *     // Inserts as the first child
   *     document.body.insertAdjacentHtml('afterBegin', html);
   *     var createdElement = document.body.children[0];
   *     print(createdElement.classes[0]); // Prints 'something'
   *
   * See also:
   *
   * * [insertAdjacentText]
   * * [insertAdjacentElement]
   */
  void insertAdjacentHtml(String where, String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (treeSanitizer is _TrustedHtmlTreeSanitizer) {
      _insertAdjacentHtml(where, html);
    } else {
      _insertAdjacentNode(
          where,
          createFragment(html,
              validator: validator, treeSanitizer: treeSanitizer));
    }
  }

  @JSName('insertAdjacentHTML')
  void _insertAdjacentHtml(String where, String text) native;

  /**
   * Inserts [element] into the DOM at the specified location.
   *
   * To see the possible values for [where], read the doc for
   * [insertAdjacentHtml].
   *
   * See also:
   *
   * * [insertAdjacentHtml]
   */
  Element insertAdjacentElement(String where, Element element) {
    if (JS('bool', '!!#.insertAdjacentElement', this)) {
      _insertAdjacentElement(where, element);
    } else {
      _insertAdjacentNode(where, element);
    }
    return element;
  }

  @JSName('insertAdjacentElement')
  void _insertAdjacentElement(String where, Element element) native;

  void _insertAdjacentNode(String where, Node node) {
    switch (where.toLowerCase()) {
      case 'beforebegin':
        this.parentNode.insertBefore(node, this);
        break;
      case 'afterbegin':
        var first = this.nodes.length > 0 ? this.nodes[0] : null;
        this.insertBefore(node, first);
        break;
      case 'beforeend':
        this.append(node);
        break;
      case 'afterend':
        this.parentNode.insertBefore(node, this.nextNode);
        break;
      default:
        throw new ArgumentError("Invalid position ${where}");
    }
  }

  /**
   * Checks if this element matches the CSS selectors.
   */
  bool matches(String selectors) {
    if (JS('bool', '!!#.matches', this)) {
      return JS('bool', '#.matches(#)', this, selectors);
    } else if (JS('bool', '!!#.webkitMatchesSelector', this)) {
      return JS('bool', '#.webkitMatchesSelector(#)', this, selectors);
    } else if (JS('bool', '!!#.mozMatchesSelector', this)) {
      return JS('bool', '#.mozMatchesSelector(#)', this, selectors);
    } else if (JS('bool', '!!#.msMatchesSelector', this)) {
      return JS('bool', '#.msMatchesSelector(#)', this, selectors);
    } else if (JS('bool', '!!#.oMatchesSelector', this)) {
      return JS('bool', '#.oMatchesSelector(#)', this, selectors);
    } else {
      throw new UnsupportedError("Not supported on this platform");
    }
  }

  /** Checks if this element or any of its parents match the CSS selectors. */
  bool matchesWithAncestors(String selectors) {
    var elem = this;
    do {
      if (elem.matches(selectors)) return true;
      elem = elem.parent;
    } while (elem != null);
    return false;
  }

  /**
   * Creates a new shadow root for this shadow host.
   *
   * ## Other resources
   *
   * * [Shadow DOM 101](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
   *   from HTML5Rocks.
   * * [Shadow DOM specification](http://www.w3.org/TR/shadow-dom/) from W3C.
   */
  @SupportedBrowser(SupportedBrowser.CHROME, '25')
  ShadowRoot createShadowRoot() {
    return JS(
        'ShadowRoot',
        '(#.createShadowRoot || #.webkitCreateShadowRoot).call(#)',
        this,
        this,
        this);
  }

  /**
   * The shadow root of this shadow host.
   *
   * ## Other resources
   *
   * * [Shadow DOM 101](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
   *   from HTML5Rocks.
   * * [Shadow DOM specification](http://www.w3.org/TR/shadow-dom/)
   *   from W3C.
   */
  @SupportedBrowser(SupportedBrowser.CHROME, '25')
  ShadowRoot get shadowRoot =>
      JS('ShadowRoot|Null', '#.shadowRoot || #.webkitShadowRoot', this, this);

  /**
   * Access this element's content position.
   *
   * This returns a rectangle with the dimensions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not.
   *
   * _Important_ _note_: use of this method _will_ perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  CssRect get contentEdge => new _ContentCssRect(this);

  /**
   * Access the dimensions and position of this element's content + padding box.
   *
   * This returns a rectangle with the dimensions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's
   * [innerHeight](http://api.jquery.com/innerHeight/) value for an element.
   * This is also a rectangle equalling the dimensions of clientHeight and
   * clientWidth.
   *
   * _Important_ _note_: use of this method _will_ perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  CssRect get paddingEdge => new _PaddingCssRect(this);

  /**
   * Access the dimensions and position of this element's content + padding +
   * border box.
   *
   * This returns a rectangle with the dimensions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's
   * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
   *
   * _Important_ _note_: use of this method _will_ perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  CssRect get borderEdge => new _BorderCssRect(this);

  /**
   * Access the dimensions and position of this element's content + padding +
   * border + margin box.
   *
   * This returns a rectangle with the dimensions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's
   * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
   *
   * _Important_ _note_: use of this method will perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  CssRect get marginEdge => new _MarginCssRect(this);

  /**
   * Provides the coordinates of the element relative to the top of the
   * document.
   *
   * This method is the Dart equivalent to jQuery's
   * [offset](http://api.jquery.com/offset/) method.
   */
  Point get documentOffset => offsetTo(document.documentElement);

  /**
   * Provides the offset of this element's [borderEdge] relative to the
   * specified [parent].
   *
   * This is the Dart equivalent of jQuery's
   * [position](http://api.jquery.com/position/) method. Unlike jQuery's
   * position, however, [parent] can be any parent element of `this`,
   * rather than only `this`'s immediate [offsetParent]. If the specified
   * element is _not_ an offset parent or transitive offset parent to this
   * element, an [ArgumentError] is thrown.
   */
  Point offsetTo(Element parent) {
    return Element._offsetToHelper(this, parent);
  }

  static Point _offsetToHelper(Element current, Element parent) {
    // We're hopping from _offsetParent_ to offsetParent (not just parent), so
    // offsetParent, "tops out" at BODY. But people could conceivably pass in
    // the document.documentElement and I want it to return an absolute offset,
    // so we have the special case checking for HTML.
    bool sameAsParent = identical(current, parent);
    bool foundAsParent = sameAsParent || parent.tagName == 'HTML';
    if (current == null || sameAsParent) {
      if (foundAsParent) return new Point(0, 0);
      throw new ArgumentError("Specified element is not a transitive offset "
          "parent of this element.");
    }
    Element parentOffset = current.offsetParent;
    Point p = Element._offsetToHelper(parentOffset, parent);
    return new Point(p.x + current.offsetLeft, p.y + current.offsetTop);
  }

  static HtmlDocument _parseDocument;
  static Range _parseRange;
  static NodeValidatorBuilder _defaultValidator;
  static _ValidatingTreeSanitizer _defaultSanitizer;

  /**
   * Create a DocumentFragment from the HTML fragment and ensure that it follows
   * the sanitization rules specified by the validator or treeSanitizer.
   *
   * If the default validation behavior is too restrictive then a new
   * NodeValidator should be created, either extending or wrapping a default
   * validator and overriding the validation APIs.
   *
   * The treeSanitizer is used to walk the generated node tree and sanitize it.
   * A custom treeSanitizer can also be provided to perform special validation
   * rules but since the API is more complex to implement this is discouraged.
   *
   * The returned tree is guaranteed to only contain nodes and attributes which
   * are allowed by the provided validator.
   *
   * See also:
   *
   * * [NodeValidator]
   * * [NodeTreeSanitizer]
   */
  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (treeSanitizer == null) {
      if (validator == null) {
        if (_defaultValidator == null) {
          _defaultValidator = new NodeValidatorBuilder.common();
        }
        validator = _defaultValidator;
      }
      if (_defaultSanitizer == null) {
        _defaultSanitizer = new _ValidatingTreeSanitizer(validator);
      } else {
        _defaultSanitizer.validator = validator;
      }
      treeSanitizer = _defaultSanitizer;
    } else if (validator != null) {
      throw new ArgumentError(
          'validator can only be passed if treeSanitizer is null');
    }

    if (_parseDocument == null) {
      _parseDocument = document.implementation.createHtmlDocument('');
      _parseRange = _parseDocument.createRange();

      // Workaround for Safari bug. Was also previously Chrome bug 229142
      // - URIs are not resolved in new doc.
      BaseElement base = _parseDocument.createElement('base');
      base.href = document.baseUri;
      _parseDocument.head.append(base);
    }

    // TODO(terry): Fixes Chromium 50 change no body after createHtmlDocument()
    if (_parseDocument.body == null) {
      _parseDocument.body = _parseDocument.createElement("body");
    }

    var contextElement;
    if (this is BodyElement) {
      contextElement = _parseDocument.body;
    } else {
      contextElement = _parseDocument.createElement(tagName);
      _parseDocument.body.append(contextElement);
    }
    var fragment;
    if (Range.supportsCreateContextualFragment &&
        _canBeUsedToCreateContextualFragment) {
      _parseRange.selectNodeContents(contextElement);
      fragment = _parseRange.createContextualFragment(html);
    } else {
      contextElement._innerHtml = html;

      fragment = _parseDocument.createDocumentFragment();
      while (contextElement.firstChild != null) {
        fragment.append(contextElement.firstChild);
      }
    }
    if (contextElement != _parseDocument.body) {
      contextElement.remove();
    }

    treeSanitizer.sanitizeTree(fragment);
    // Copy the fragment over to the main document (fix for 14184)
    document.adoptNode(fragment);

    return fragment;
  }

  /** Test if createContextualFragment is supported for this element type */
  bool get _canBeUsedToCreateContextualFragment =>
      !_cannotBeUsedToCreateContextualFragment;

  /** Test if createContextualFragment is NOT supported for this element type */
  bool get _cannotBeUsedToCreateContextualFragment =>
      _tagsForWhichCreateContextualFragmentIsNotSupported.contains(tagName);

  /**
   * A hard-coded list of the tag names for which createContextualFragment
   * isn't supported.
   */
  static const _tagsForWhichCreateContextualFragmentIsNotSupported = const [
    'HEAD',
    'AREA',
    'BASE',
    'BASEFONT',
    'BR',
    'COL',
    'COLGROUP',
    'EMBED',
    'FRAME',
    'FRAMESET',
    'HR',
    'IMAGE',
    'IMG',
    'INPUT',
    'ISINDEX',
    'LINK',
    'META',
    'PARAM',
    'SOURCE',
    'STYLE',
    'TITLE',
    'WBR'
  ];

  /**
   * Parses the HTML fragment and sets it as the contents of this element.
   *
   * This uses the default sanitization behavior to sanitize the HTML fragment,
   * use [setInnerHtml] to override the default behavior.
   */
  set innerHtml(String html) {
    this.setInnerHtml(html);
  }

  /**
   * Parses the HTML fragment and sets it as the contents of this element.
   * This ensures that the generated content follows the sanitization rules
   * specified by the validator or treeSanitizer.
   *
   * If the default validation behavior is too restrictive then a new
   * NodeValidator should be created, either extending or wrapping a default
   * validator and overriding the validation APIs.
   *
   * The treeSanitizer is used to walk the generated node tree and sanitize it.
   * A custom treeSanitizer can also be provided to perform special validation
   * rules but since the API is more complex to implement this is discouraged.
   *
   * The resulting tree is guaranteed to only contain nodes and attributes which
   * are allowed by the provided validator.
   *
   * See also:
   *
   * * [NodeValidator]
   * * [NodeTreeSanitizer]
   */
  void setInnerHtml(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    text = null;
    if (treeSanitizer is _TrustedHtmlTreeSanitizer) {
      _innerHtml = html;
    } else {
      append(createFragment(html,
          validator: validator, treeSanitizer: treeSanitizer));
    }
  }

  String get innerHtml => _innerHtml;

  /**
   * This is an ease-of-use accessor for event streams which should only be
   * used when an explicit accessor is not available.
   */
  ElementEvents get on => new ElementEvents(this);

  /**
   * Verify if any of the attributes that we use in the sanitizer look unexpected,
   * possibly indicating DOM clobbering attacks.
   *
   * Those attributes are: attributes, lastChild, children, previousNode and tagName.
   */
  static bool _hasCorruptedAttributes(Element element) {
    return JS(
        'bool',
        r'''
       (function(element) {
         if (!(element.attributes instanceof NamedNodeMap)) {
	   return true;
	 }
	 var childNodes = element.childNodes;
	 if (element.lastChild &&
	     element.lastChild !== childNodes[childNodes.length -1]) {
	   return true;
	 }
	 if (element.children) { // On Safari, children can apparently be null.
  	   if (!((element.children instanceof HTMLCollection) ||
               (element.children instanceof NodeList))) {
	     return true;
	   }
	 }
         var length = 0;
         if (element.children) {
           length = element.children.length;
         }
         for (var i = 0; i < length; i++) {
           var child = element.children[i];
           // On IE it seems like we sometimes don't see the clobbered attribute,
           // perhaps as a result of an over-optimization. Also use another route
           // to check of attributes, children, or lastChild are clobbered. It may
           // seem silly to check children as we rely on children to do this iteration,
           // but it seems possible that the access to children might see the real thing,
           // allowing us to check for clobbering that may show up in other accesses.
           if (child["id"] == 'attributes' || child["name"] == 'attributes' ||
               child["id"] == 'lastChild'  || child["name"] == 'lastChild' ||
               child["id"] == 'children' || child["name"] == 'children') {
             return true;
           }
         }
	 return false;
          })(#)''',
        element);
  }

  /// A secondary check for corruption, needed on IE
  static bool _hasCorruptedAttributesAdditionalCheck(Element element) {
    return JS('bool', r'!(#.attributes instanceof NamedNodeMap)', element);
  }

  static String _safeTagName(element) {
    String result = 'element tag unavailable';
    try {
      if (element.tagName is String) {
        result = element.tagName;
      }
    } catch (e) {}
    return result;
  }

  final Element offsetParent;

  int get offsetHeight => JS('num', '#.offsetHeight', this).round();

  int get offsetLeft => JS('num', '#.offsetLeft', this).round();

  int get offsetTop => JS('num', '#.offsetTop', this).round();

  int get offsetWidth => JS('num', '#.offsetWidth', this).round();

  int get scrollHeight => JS('num', '#.scrollHeight', this).round();
  int get scrollLeft => JS('num', '#.scrollLeft', this).round();

  set scrollLeft(int value) {
    JS("void", "#.scrollLeft = #", this, value.round());
  }

  int get scrollTop => JS('num', '#.scrollTop', this).round();

  set scrollTop(int value) {
    JS("void", "#.scrollTop = #", this, value.round());
  }

  int get scrollWidth => JS('num', '#.scrollWidth', this).round();

  // To suppress missing implicit constructor warnings.
  factory Element._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `abort` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> abortEvent =
      const EventStreamProvider<Event>('abort');

  /**
   * Static factory designed to expose `beforecopy` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> beforeCopyEvent =
      const EventStreamProvider<Event>('beforecopy');

  /**
   * Static factory designed to expose `beforecut` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> beforeCutEvent =
      const EventStreamProvider<Event>('beforecut');

  /**
   * Static factory designed to expose `beforepaste` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> beforePasteEvent =
      const EventStreamProvider<Event>('beforepaste');

  /**
   * Static factory designed to expose `blur` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> blurEvent =
      const EventStreamProvider<Event>('blur');

  static const EventStreamProvider<Event> canPlayEvent =
      const EventStreamProvider<Event>('canplay');

  static const EventStreamProvider<Event> canPlayThroughEvent =
      const EventStreamProvider<Event>('canplaythrough');

  /**
   * Static factory designed to expose `change` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  /**
   * Static factory designed to expose `click` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MouseEvent> clickEvent =
      const EventStreamProvider<MouseEvent>('click');

  /**
   * Static factory designed to expose `contextmenu` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MouseEvent> contextMenuEvent =
      const EventStreamProvider<MouseEvent>('contextmenu');

  /**
   * Static factory designed to expose `copy` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ClipboardEvent> copyEvent =
      const EventStreamProvider<ClipboardEvent>('copy');

  /**
   * Static factory designed to expose `cut` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ClipboardEvent> cutEvent =
      const EventStreamProvider<ClipboardEvent>('cut');

  /**
   * Static factory designed to expose `doubleclick` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> doubleClickEvent =
      const EventStreamProvider<Event>('dblclick');

  /**
   * A stream of `drag` events fired when an element is currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  static const EventStreamProvider<MouseEvent> dragEvent =
      const EventStreamProvider<MouseEvent>('drag');

  /**
   * A stream of `dragend` events fired when an element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  static const EventStreamProvider<MouseEvent> dragEndEvent =
      const EventStreamProvider<MouseEvent>('dragend');

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over an element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  static const EventStreamProvider<MouseEvent> dragEnterEvent =
      const EventStreamProvider<MouseEvent>('dragenter');

  /**
   * A stream of `dragleave` events fired when an object being dragged over an
   * element leaves the element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  static const EventStreamProvider<MouseEvent> dragLeaveEvent =
      const EventStreamProvider<MouseEvent>('dragleave');

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over an element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  static const EventStreamProvider<MouseEvent> dragOverEvent =
      const EventStreamProvider<MouseEvent>('dragover');

  /**
   * A stream of `dragstart` events for a dragged element whose drag has begun.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  static const EventStreamProvider<MouseEvent> dragStartEvent =
      const EventStreamProvider<MouseEvent>('dragstart');

  /**
   * A stream of `drop` events fired when a dragged object is dropped on an
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  static const EventStreamProvider<MouseEvent> dropEvent =
      const EventStreamProvider<MouseEvent>('drop');

  static const EventStreamProvider<Event> durationChangeEvent =
      const EventStreamProvider<Event>('durationchange');

  static const EventStreamProvider<Event> emptiedEvent =
      const EventStreamProvider<Event>('emptied');

  static const EventStreamProvider<Event> endedEvent =
      const EventStreamProvider<Event>('ended');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `focus` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> focusEvent =
      const EventStreamProvider<Event>('focus');

  /**
   * Static factory designed to expose `input` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> inputEvent =
      const EventStreamProvider<Event>('input');

  /**
   * Static factory designed to expose `invalid` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> invalidEvent =
      const EventStreamProvider<Event>('invalid');

  /**
   * Static factory designed to expose `keydown` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<KeyboardEvent> keyDownEvent =
      const EventStreamProvider<KeyboardEvent>('keydown');

  /**
   * Static factory designed to expose `keypress` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<KeyboardEvent> keyPressEvent =
      const EventStreamProvider<KeyboardEvent>('keypress');

  /**
   * Static factory designed to expose `keyup` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<KeyboardEvent> keyUpEvent =
      const EventStreamProvider<KeyboardEvent>('keyup');

  /**
   * Static factory designed to expose `load` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> loadEvent =
      const EventStreamProvider<Event>('load');

  static const EventStreamProvider<Event> loadedDataEvent =
      const EventStreamProvider<Event>('loadeddata');

  static const EventStreamProvider<Event> loadedMetadataEvent =
      const EventStreamProvider<Event>('loadedmetadata');

  /**
   * Static factory designed to expose `mousedown` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MouseEvent> mouseDownEvent =
      const EventStreamProvider<MouseEvent>('mousedown');

  /**
   * Static factory designed to expose `mouseenter` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MouseEvent> mouseEnterEvent =
      const EventStreamProvider<MouseEvent>('mouseenter');

  /**
   * Static factory designed to expose `mouseleave` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MouseEvent> mouseLeaveEvent =
      const EventStreamProvider<MouseEvent>('mouseleave');

  /**
   * Static factory designed to expose `mousemove` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MouseEvent> mouseMoveEvent =
      const EventStreamProvider<MouseEvent>('mousemove');

  /**
   * Static factory designed to expose `mouseout` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MouseEvent> mouseOutEvent =
      const EventStreamProvider<MouseEvent>('mouseout');

  /**
   * Static factory designed to expose `mouseover` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MouseEvent> mouseOverEvent =
      const EventStreamProvider<MouseEvent>('mouseover');

  /**
   * Static factory designed to expose `mouseup` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MouseEvent> mouseUpEvent =
      const EventStreamProvider<MouseEvent>('mouseup');

  /**
   * Static factory designed to expose `paste` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ClipboardEvent> pasteEvent =
      const EventStreamProvider<ClipboardEvent>('paste');

  static const EventStreamProvider<Event> pauseEvent =
      const EventStreamProvider<Event>('pause');

  static const EventStreamProvider<Event> playEvent =
      const EventStreamProvider<Event>('play');

  static const EventStreamProvider<Event> playingEvent =
      const EventStreamProvider<Event>('playing');

  static const EventStreamProvider<Event> rateChangeEvent =
      const EventStreamProvider<Event>('ratechange');

  /**
   * Static factory designed to expose `reset` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> resetEvent =
      const EventStreamProvider<Event>('reset');

  static const EventStreamProvider<Event> resizeEvent =
      const EventStreamProvider<Event>('resize');

  /**
   * Static factory designed to expose `scroll` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> scrollEvent =
      const EventStreamProvider<Event>('scroll');

  /**
   * Static factory designed to expose `search` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> searchEvent =
      const EventStreamProvider<Event>('search');

  static const EventStreamProvider<Event> seekedEvent =
      const EventStreamProvider<Event>('seeked');

  static const EventStreamProvider<Event> seekingEvent =
      const EventStreamProvider<Event>('seeking');

  /**
   * Static factory designed to expose `select` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> selectEvent =
      const EventStreamProvider<Event>('select');

  /**
   * Static factory designed to expose `selectstart` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> selectStartEvent =
      const EventStreamProvider<Event>('selectstart');

  static const EventStreamProvider<Event> stalledEvent =
      const EventStreamProvider<Event>('stalled');

  /**
   * Static factory designed to expose `submit` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> submitEvent =
      const EventStreamProvider<Event>('submit');

  static const EventStreamProvider<Event> suspendEvent =
      const EventStreamProvider<Event>('suspend');

  static const EventStreamProvider<Event> timeUpdateEvent =
      const EventStreamProvider<Event>('timeupdate');

  /**
   * Static factory designed to expose `touchcancel` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<TouchEvent> touchCancelEvent =
      const EventStreamProvider<TouchEvent>('touchcancel');

  /**
   * Static factory designed to expose `touchend` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<TouchEvent> touchEndEvent =
      const EventStreamProvider<TouchEvent>('touchend');

  /**
   * Static factory designed to expose `touchenter` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<TouchEvent> touchEnterEvent =
      const EventStreamProvider<TouchEvent>('touchenter');

  /**
   * Static factory designed to expose `touchleave` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<TouchEvent> touchLeaveEvent =
      const EventStreamProvider<TouchEvent>('touchleave');

  /**
   * Static factory designed to expose `touchmove` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<TouchEvent> touchMoveEvent =
      const EventStreamProvider<TouchEvent>('touchmove');

  /**
   * Static factory designed to expose `touchstart` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<TouchEvent> touchStartEvent =
      const EventStreamProvider<TouchEvent>('touchstart');

  static const EventStreamProvider<Event> volumeChangeEvent =
      const EventStreamProvider<Event>('volumechange');

  static const EventStreamProvider<Event> waitingEvent =
      const EventStreamProvider<Event>('waiting');

  /**
   * Static factory designed to expose `fullscreenchange` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  static const EventStreamProvider<Event> fullscreenChangeEvent =
      const EventStreamProvider<Event>('webkitfullscreenchange');

  /**
   * Static factory designed to expose `fullscreenerror` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  static const EventStreamProvider<Event> fullscreenErrorEvent =
      const EventStreamProvider<Event>('webkitfullscreenerror');

  static const EventStreamProvider<WheelEvent> wheelEvent =
      const EventStreamProvider<WheelEvent>('wheel');

  String contentEditable;

  String dir;

  /**
   * Indicates whether the element can be dragged and dropped.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  bool draggable;

  /**
   * Indicates whether the element is not relevant to the page's current state.
   *
   * ## Other resources
   *
   * * [Hidden attribute
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#the-hidden-attribute)
   *   from WHATWG.
   */
  bool hidden;

  bool inert;

  String inputMode;

  // Using property as subclass shadows.
  bool get isContentEditable => JS("bool", "#.isContentEditable", this);

  String lang;

  bool spellcheck;

  final CssStyleDeclaration style;

  int tabIndex;

  String title;

  /**
   * Specifies whether this element's text content changes when the page is
   * localized.
   *
   * ## Other resources
   *
   * * [The translate
   *   attribute](https://html.spec.whatwg.org/multipage/dom.html#the-translate-attribute)
   *   from WHATWG.
   */
  bool translate;

  void blur() native;

  void click() native;

  void focus() native;

  final AccessibleNode accessibleNode;

  final SlotElement assignedSlot;

  @JSName('attributes')
  final _NamedNodeMap _attributes;

  String className;

  final int clientHeight;

  final int clientLeft;

  final int clientTop;

  final int clientWidth;

  final String computedName;

  final String computedRole;

  String id;

  @JSName('innerHTML')
  String _innerHtml;

  @JSName('localName')
  final String _localName;

  @JSName('namespaceURI')
  final String _namespaceUri;

  // Using property as subclass shadows.
  String get outerHtml => JS("String", "#.outerHTML", this);

  @JSName('scrollHeight')
  final int _scrollHeight;

  @JSName('scrollLeft')
  num _scrollLeft;

  @JSName('scrollTop')
  num _scrollTop;

  @JSName('scrollWidth')
  final int _scrollWidth;

  String slot;

  final StylePropertyMap styleMap;

  final String tagName;

  ShadowRoot attachShadow(Map shadowRootInitDict) {
    var shadowRootInitDict_1 =
        convertDartToNative_Dictionary(shadowRootInitDict);
    return _attachShadow_1(shadowRootInitDict_1);
  }

  @JSName('attachShadow')
  ShadowRoot _attachShadow_1(shadowRootInitDict) native;

  Element closest(String selectors) native;

  List<Animation> getAnimations() native;

  String getAttribute(String name) native;

  String getAttributeNS(String namespaceURI, String localName) native;

  List<String> getAttributeNames() native;

  /**
   * Returns the smallest bounding rectangle that encompasses this element's
   * padding, scrollbar, and border.
   *
   * ## Other resources
   *
   * * [Element.getBoundingClientRect](https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect)
   *   from MDN.
   * * [The getBoundingClientRect()
   *   method](http://www.w3.org/TR/cssom-view/#the-getclientrects()-and-getboundingclientrect()-methods)
   *   from W3C.
   */
  @Creates('_DomRect')
  @Returns('_DomRect|Null')
  Rectangle getBoundingClientRect() native;

  @JSName('getClientRects')
  /**
   * Returns a list of bounding rectangles for each box associated with this
   * element.
   *
   * ## Other resources
   *
   * * [Element.getClientRects](https://developer.mozilla.org/en-US/docs/Web/API/Element.getClientRects)
   *   from MDN.
   * * [The getClientRects()
   *   method](http://www.w3.org/TR/cssom-view/#the-getclientrects()-and-getboundingclientrect()-methods)
   *   from W3C.
   */
  @Creates('DomRectList')
  @Returns('DomRectList|Null')
  List<Rectangle> _getClientRects() native;

  /**
   * Returns a list of shadow DOM insertion points to which this element is
   * distributed.
   *
   * ## Other resources
   *
   * * [Shadow DOM
   *   specification](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html)
   *   from W3C.
   */
  @Returns('NodeList|Null')
  @Creates('NodeList')
  List<Node> getDestinationInsertionPoints() native;

  /**
   * Returns a list of nodes with the given class name inside this element.
   *
   * ## Other resources
   *
   * * [getElementsByClassName](https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName)
   *   from MDN.
   * * [DOM specification](http://www.w3.org/TR/domcore/) from W3C.
   */
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByClassName(String classNames) native;

  @JSName('getElementsByTagName')
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> _getElementsByTagName(String localName) native;

  @JSName('hasAttribute')
  bool _hasAttribute(String name) native;

  @JSName('hasAttributeNS')
  bool _hasAttributeNS(String namespaceURI, String localName) native;

  bool hasPointerCapture(int pointerId) native;

  void releasePointerCapture(int pointerId) native;

  @JSName('removeAttribute')
  void _removeAttribute(String name) native;

  @JSName('removeAttributeNS')
  void _removeAttributeNS(String namespaceURI, String localName) native;

  void requestPointerLock() native;

  void scroll([options_OR_x, num y]) {
    if (options_OR_x == null && y == null) {
      _scroll_1();
      return;
    }
    if ((options_OR_x is Map) && y == null) {
      var options_1 = convertDartToNative_Dictionary(options_OR_x);
      _scroll_2(options_1);
      return;
    }
    if (y != null && (options_OR_x is num)) {
      _scroll_3(options_OR_x, y);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('scroll')
  void _scroll_1() native;
  @JSName('scroll')
  void _scroll_2(options) native;
  @JSName('scroll')
  void _scroll_3(num x, y) native;

  void scrollBy([options_OR_x, num y]) {
    if (options_OR_x == null && y == null) {
      _scrollBy_1();
      return;
    }
    if ((options_OR_x is Map) && y == null) {
      var options_1 = convertDartToNative_Dictionary(options_OR_x);
      _scrollBy_2(options_1);
      return;
    }
    if (y != null && (options_OR_x is num)) {
      _scrollBy_3(options_OR_x, y);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('scrollBy')
  void _scrollBy_1() native;
  @JSName('scrollBy')
  void _scrollBy_2(options) native;
  @JSName('scrollBy')
  void _scrollBy_3(num x, y) native;

  @JSName('scrollIntoView')
  void _scrollIntoView([Object arg]) native;

  @JSName('scrollIntoViewIfNeeded')
  void _scrollIntoViewIfNeeded([bool centerIfNeeded]) native;

  void scrollTo([options_OR_x, num y]) {
    if (options_OR_x == null && y == null) {
      _scrollTo_1();
      return;
    }
    if ((options_OR_x is Map) && y == null) {
      var options_1 = convertDartToNative_Dictionary(options_OR_x);
      _scrollTo_2(options_1);
      return;
    }
    if (y != null && (options_OR_x is num)) {
      _scrollTo_3(options_OR_x, y);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('scrollTo')
  void _scrollTo_1() native;
  @JSName('scrollTo')
  void _scrollTo_2(options) native;
  @JSName('scrollTo')
  void _scrollTo_3(num x, y) native;

  void setApplyScroll(ScrollStateCallback scrollStateCallback,
      String nativeScrollBehavior) native;

  void setAttribute(String name, String value) native;

  void setAttributeNS(String namespaceURI, String name, String value) native;

  void setDistributeScroll(ScrollStateCallback scrollStateCallback,
      String nativeScrollBehavior) native;

  void setPointerCapture(int pointerId) native;

  @JSName('webkitRequestFullscreen')
  /**
   * Displays this element fullscreen.
   *
   * ## Other resources
   *
   * * [Using the fullscreen
   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
   *   tutorial from WebPlatform.org.
   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void requestFullscreen() native;

  // From ChildNode

  void after(Object nodes) native;

  void before(Object nodes) native;

  // From NonDocumentTypeChildNode

  final Element nextElementSibling;

  final Element previousElementSibling;

  // From ParentNode

  @JSName('childElementCount')
  final int _childElementCount;

  @JSName('children')
  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> _children;

  @JSName('firstElementChild')
  final Element _firstElementChild;

  @JSName('lastElementChild')
  final Element _lastElementChild;

  /**
   * Finds the first descendant element of this element that matches the
   * specified group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     // Gets the first descendant with the class 'classname'
   *     var element = element.querySelector('.className');
   *     // Gets the element with id 'id'
   *     var element = element.querySelector('#id');
   *     // Gets the first descendant [ImageElement]
   *     var img = element.querySelector('img');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  Element querySelector(String selectors) native;

  @JSName('querySelectorAll')
  @Creates('NodeList')
  @Returns('NodeList')
  List<Node> _querySelectorAll(String selectors) native;

  /// Stream of `abort` events handled by this [Element].
  ElementStream<Event> get onAbort => abortEvent.forElement(this);

  /// Stream of `beforecopy` events handled by this [Element].
  ElementStream<Event> get onBeforeCopy => beforeCopyEvent.forElement(this);

  /// Stream of `beforecut` events handled by this [Element].
  ElementStream<Event> get onBeforeCut => beforeCutEvent.forElement(this);

  /// Stream of `beforepaste` events handled by this [Element].
  ElementStream<Event> get onBeforePaste => beforePasteEvent.forElement(this);

  /// Stream of `blur` events handled by this [Element].
  ElementStream<Event> get onBlur => blurEvent.forElement(this);

  ElementStream<Event> get onCanPlay => canPlayEvent.forElement(this);

  ElementStream<Event> get onCanPlayThrough =>
      canPlayThroughEvent.forElement(this);

  /// Stream of `change` events handled by this [Element].
  ElementStream<Event> get onChange => changeEvent.forElement(this);

  /// Stream of `click` events handled by this [Element].
  ElementStream<MouseEvent> get onClick => clickEvent.forElement(this);

  /// Stream of `contextmenu` events handled by this [Element].
  ElementStream<MouseEvent> get onContextMenu =>
      contextMenuEvent.forElement(this);

  /// Stream of `copy` events handled by this [Element].
  ElementStream<ClipboardEvent> get onCopy => copyEvent.forElement(this);

  /// Stream of `cut` events handled by this [Element].
  ElementStream<ClipboardEvent> get onCut => cutEvent.forElement(this);

  /// Stream of `doubleclick` events handled by this [Element].
  ElementStream<Event> get onDoubleClick => doubleClickEvent.forElement(this);

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDrag => dragEvent.forElement(this);

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragEnd => dragEndEvent.forElement(this);

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragEnter => dragEnterEvent.forElement(this);

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragLeave => dragLeaveEvent.forElement(this);

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragOver => dragOverEvent.forElement(this);

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDragStart => dragStartEvent.forElement(this);

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  ElementStream<MouseEvent> get onDrop => dropEvent.forElement(this);

  ElementStream<Event> get onDurationChange =>
      durationChangeEvent.forElement(this);

  ElementStream<Event> get onEmptied => emptiedEvent.forElement(this);

  ElementStream<Event> get onEnded => endedEvent.forElement(this);

  /// Stream of `error` events handled by this [Element].
  ElementStream<Event> get onError => errorEvent.forElement(this);

  /// Stream of `focus` events handled by this [Element].
  ElementStream<Event> get onFocus => focusEvent.forElement(this);

  /// Stream of `input` events handled by this [Element].
  ElementStream<Event> get onInput => inputEvent.forElement(this);

  /// Stream of `invalid` events handled by this [Element].
  ElementStream<Event> get onInvalid => invalidEvent.forElement(this);

  /// Stream of `keydown` events handled by this [Element].
  ElementStream<KeyboardEvent> get onKeyDown => keyDownEvent.forElement(this);

  /// Stream of `keypress` events handled by this [Element].
  ElementStream<KeyboardEvent> get onKeyPress => keyPressEvent.forElement(this);

  /// Stream of `keyup` events handled by this [Element].
  ElementStream<KeyboardEvent> get onKeyUp => keyUpEvent.forElement(this);

  /// Stream of `load` events handled by this [Element].
  ElementStream<Event> get onLoad => loadEvent.forElement(this);

  ElementStream<Event> get onLoadedData => loadedDataEvent.forElement(this);

  ElementStream<Event> get onLoadedMetadata =>
      loadedMetadataEvent.forElement(this);

  /// Stream of `mousedown` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseDown => mouseDownEvent.forElement(this);

  /// Stream of `mouseenter` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseEnter =>
      mouseEnterEvent.forElement(this);

  /// Stream of `mouseleave` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseLeave =>
      mouseLeaveEvent.forElement(this);

  /// Stream of `mousemove` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseMove => mouseMoveEvent.forElement(this);

  /// Stream of `mouseout` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseOut => mouseOutEvent.forElement(this);

  /// Stream of `mouseover` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseOver => mouseOverEvent.forElement(this);

  /// Stream of `mouseup` events handled by this [Element].
  ElementStream<MouseEvent> get onMouseUp => mouseUpEvent.forElement(this);

  /// Stream of `mousewheel` events handled by this [Element].
  ElementStream<WheelEvent> get onMouseWheel =>
      mouseWheelEvent.forElement(this);

  /// Stream of `paste` events handled by this [Element].
  ElementStream<ClipboardEvent> get onPaste => pasteEvent.forElement(this);

  ElementStream<Event> get onPause => pauseEvent.forElement(this);

  ElementStream<Event> get onPlay => playEvent.forElement(this);

  ElementStream<Event> get onPlaying => playingEvent.forElement(this);

  ElementStream<Event> get onRateChange => rateChangeEvent.forElement(this);

  /// Stream of `reset` events handled by this [Element].
  ElementStream<Event> get onReset => resetEvent.forElement(this);

  ElementStream<Event> get onResize => resizeEvent.forElement(this);

  /// Stream of `scroll` events handled by this [Element].
  ElementStream<Event> get onScroll => scrollEvent.forElement(this);

  /// Stream of `search` events handled by this [Element].
  ElementStream<Event> get onSearch => searchEvent.forElement(this);

  ElementStream<Event> get onSeeked => seekedEvent.forElement(this);

  ElementStream<Event> get onSeeking => seekingEvent.forElement(this);

  /// Stream of `select` events handled by this [Element].
  ElementStream<Event> get onSelect => selectEvent.forElement(this);

  /// Stream of `selectstart` events handled by this [Element].
  ElementStream<Event> get onSelectStart => selectStartEvent.forElement(this);

  ElementStream<Event> get onStalled => stalledEvent.forElement(this);

  /// Stream of `submit` events handled by this [Element].
  ElementStream<Event> get onSubmit => submitEvent.forElement(this);

  ElementStream<Event> get onSuspend => suspendEvent.forElement(this);

  ElementStream<Event> get onTimeUpdate => timeUpdateEvent.forElement(this);

  /// Stream of `touchcancel` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchCancel =>
      touchCancelEvent.forElement(this);

  /// Stream of `touchend` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchEnd => touchEndEvent.forElement(this);

  /// Stream of `touchenter` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchEnter =>
      touchEnterEvent.forElement(this);

  /// Stream of `touchleave` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchLeave =>
      touchLeaveEvent.forElement(this);

  /// Stream of `touchmove` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchMove => touchMoveEvent.forElement(this);

  /// Stream of `touchstart` events handled by this [Element].
  ElementStream<TouchEvent> get onTouchStart =>
      touchStartEvent.forElement(this);

  /// Stream of `transitionend` events handled by this [Element].
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd =>
      transitionEndEvent.forElement(this);

  ElementStream<Event> get onVolumeChange => volumeChangeEvent.forElement(this);

  ElementStream<Event> get onWaiting => waitingEvent.forElement(this);

  /// Stream of `fullscreenchange` events handled by this [Element].
  ElementStream<Event> get onFullscreenChange =>
      fullscreenChangeEvent.forElement(this);

  /// Stream of `fullscreenerror` events handled by this [Element].
  ElementStream<Event> get onFullscreenError =>
      fullscreenErrorEvent.forElement(this);

  ElementStream<WheelEvent> get onWheel => wheelEvent.forElement(this);
}

class _ElementFactoryProvider {
  // Optimization to improve performance until the dart2js compiler inlines this
  // method.
  static dynamic createElement_tag(String tag, String typeExtension) {
    // Firefox may return a JS function for some types (Embed, Object).
    if (typeExtension != null) {
      return JS('Element|=Object', 'document.createElement(#, #)', tag,
          typeExtension);
    }
    // Should be able to eliminate this and just call the two-arg version above
    // with null typeExtension, but Chrome treats the tag as case-sensitive if
    // typeExtension is null.
    // https://code.google.com/p/chromium/issues/detail?id=282467
    return JS('Element|=Object', 'document.createElement(#)', tag);
  }
}

/**
 * Options for Element.scrollIntoView.
 */
class ScrollAlignment {
  final _value;
  const ScrollAlignment._internal(this._value);
  toString() => 'ScrollAlignment.$_value';

  /// Attempt to align the element to the top of the scrollable area.
  static const TOP = const ScrollAlignment._internal('TOP');

  /// Attempt to center the element in the scrollable area.
  static const CENTER = const ScrollAlignment._internal('CENTER');

  /// Attempt to align the element to the bottom of the scrollable area.
  static const BOTTOM = const ScrollAlignment._internal('BOTTOM');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
@Native("HTMLEmbedElement")
class EmbedElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory EmbedElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory EmbedElement() => document.createElement("embed");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  EmbedElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('embed');

  String height;

  String name;

  String src;

  String type;

  String width;

  Node __getter__(String name) native;

  void __setter__(String name, Node value) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _EntriesCallback(List entries);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Entry")
class Entry extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Entry._() {
    throw new UnsupportedError("Not supported");
  }

  final FileSystem filesystem;

  final String fullPath;

  final bool isDirectory;

  final bool isFile;

  final String name;

  @JSName('copyTo')
  void _copyTo(DirectoryEntry parent,
      [String name,
      _EntryCallback successCallback,
      _ErrorCallback errorCallback]) native;

  @JSName('copyTo')
  Future<Entry> copyTo(DirectoryEntry parent, {String name}) {
    var completer = new Completer<Entry>();
    _copyTo(parent, name, (value) {
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('getMetadata')
  void _getMetadata(MetadataCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  @JSName('getMetadata')
  Future<Metadata> getMetadata() {
    var completer = new Completer<Metadata>();
    _getMetadata((value) {
      applyExtension('Metadata', value);
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('getParent')
  void _getParent(
      [_EntryCallback successCallback, _ErrorCallback errorCallback]) native;

  @JSName('getParent')
  Future<Entry> getParent() {
    var completer = new Completer<Entry>();
    _getParent((value) {
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('moveTo')
  void _moveTo(DirectoryEntry parent,
      [String name,
      _EntryCallback successCallback,
      _ErrorCallback errorCallback]) native;

  @JSName('moveTo')
  Future<Entry> moveTo(DirectoryEntry parent, {String name}) {
    var completer = new Completer<Entry>();
    _moveTo(parent, name, (value) {
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('remove')
  void _remove(VoidCallback successCallback, [_ErrorCallback errorCallback])
      native;

  @JSName('remove')
  Future remove() {
    var completer = new Completer();
    _remove(() {
      completer.complete();
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('toURL')
  String toUrl() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _EntryCallback(Entry entry);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _ErrorCallback(DomException error);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("ErrorEvent")
class ErrorEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory ErrorEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory ErrorEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return ErrorEvent._create_1(type, eventInitDict_1);
    }
    return ErrorEvent._create_2(type);
  }
  static ErrorEvent _create_1(type, eventInitDict) =>
      JS('ErrorEvent', 'new ErrorEvent(#,#)', type, eventInitDict);
  static ErrorEvent _create_2(type) =>
      JS('ErrorEvent', 'new ErrorEvent(#)', type);

  final int colno;

  @Creates('Null')
  final Object error;

  final String filename;

  final int lineno;

  final String message;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Native("Event,InputEvent")
class Event extends Interceptor {
  // In JS, canBubble and cancelable are technically required parameters to
  // init*Event. In practice, though, if they aren't provided they simply
  // default to false (since that's Boolean(undefined)).
  //
  // Contrary to JS, we default canBubble and cancelable to true, since that's
  // what people want most of the time anyway.
  factory Event(String type, {bool canBubble: true, bool cancelable: true}) {
    return new Event.eventType('Event', type,
        canBubble: canBubble, cancelable: cancelable);
  }

  /**
   * Creates a new Event object of the specified type.
   *
   * This is analogous to document.createEvent.
   * Normally events should be created via their constructors, if available.
   *
   *     var e = new Event.type('MouseEvent', 'mousedown', true, true);
   */
  factory Event.eventType(String type, String name,
      {bool canBubble: true, bool cancelable: true}) {
    final Event e = document._createEvent(type);
    e._initEvent(name, canBubble, cancelable);
    return e;
  }

  /** The CSS selector involved with event delegation. */
  String _selector;

  /**
   * A pointer to the element whose CSS selector matched within which an event
   * was fired. If this Event was not associated with any Event delegation,
   * accessing this value will throw an [UnsupportedError].
   */
  Element get matchingTarget {
    if (_selector == null) {
      throw new UnsupportedError('Cannot call matchingTarget if this Event did'
          ' not arise as a result of event delegation.');
    }
    Element currentTarget = this.currentTarget;
    Element target = this.target;
    var matchedTarget;
    do {
      if (target.matches(_selector)) return target;
      target = target.parent;
    } while (target != null && target != currentTarget.parent);
    throw new StateError('No selector matched for populating matchedTarget.');
  }

  List<EventTarget> get path =>
      JS('bool', '!!#.composedPath', this) ? composedPath() : [];

  factory Event._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return Event._create_1(type, eventInitDict_1);
    }
    return Event._create_2(type);
  }
  static Event _create_1(type, eventInitDict) =>
      JS('Event', 'new Event(#,#)', type, eventInitDict);
  static Event _create_2(type) => JS('Event', 'new Event(#)', type);

  /**
   * This event is being handled by the event target.
   *
   * ## Other resources
   *
   * * [Target phase](http://www.w3.org/TR/DOM-Level-3-Events/#target-phase)
   *   from W3C.
   */
  static const int AT_TARGET = 2;

  /**
   * This event is bubbling up through the target's ancestors.
   *
   * ## Other resources
   *
   * * [Bubble phase](http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
   *   from W3C.
   */
  static const int BUBBLING_PHASE = 3;

  /**
   * This event is propagating through the target's ancestors, starting from the
   * document.
   *
   * ## Other resources
   *
   * * [Bubble phase](http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
   *   from W3C.
   */
  static const int CAPTURING_PHASE = 1;

  final bool bubbles;

  final bool cancelable;

  final bool composed;

  EventTarget get currentTarget =>
      _convertNativeToDart_EventTarget(this._get_currentTarget);
  @JSName('currentTarget')
  @Creates('Null')
  @Returns('EventTarget|=Object')
  final dynamic _get_currentTarget;

  final bool defaultPrevented;

  final int eventPhase;

  final bool isTrusted;

  EventTarget get target => _convertNativeToDart_EventTarget(this._get_target);
  @JSName('target')
  @Creates('Node')
  @Returns('EventTarget|=Object')
  final dynamic _get_target;

  final num timeStamp;

  final String type;

  List<EventTarget> composedPath() native;

  @JSName('initEvent')
  void _initEvent(String type, [bool bubbles, bool cancelable]) native;

  void preventDefault() native;

  void stopImmediatePropagation() native;

  void stopPropagation() native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("EventSource")
class EventSource extends EventTarget {
  factory EventSource(String url, {withCredentials: false}) {
    var parsedOptions = {
      'withCredentials': withCredentials,
    };
    return EventSource._factoryEventSource(url, parsedOptions);
  }
  // To suppress missing implicit constructor warnings.
  factory EventSource._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [EventSource].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [EventSource].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `open` events to event
   * handlers that are not necessarily instances of [EventSource].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> openEvent =
      const EventStreamProvider<Event>('open');

  static EventSource _factoryEventSource(String url,
      [Map eventSourceInitDict]) {
    if (eventSourceInitDict != null) {
      var eventSourceInitDict_1 =
          convertDartToNative_Dictionary(eventSourceInitDict);
      return EventSource._create_1(url, eventSourceInitDict_1);
    }
    return EventSource._create_2(url);
  }

  static EventSource _create_1(url, eventSourceInitDict) =>
      JS('EventSource', 'new EventSource(#,#)', url, eventSourceInitDict);
  static EventSource _create_2(url) =>
      JS('EventSource', 'new EventSource(#)', url);

  static const int CLOSED = 2;

  static const int CONNECTING = 0;

  static const int OPEN = 1;

  final int readyState;

  final String url;

  final bool withCredentials;

  void close() native;

  /// Stream of `error` events handled by this [EventSource].
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [EventSource].
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `open` events handled by this [EventSource].
  Stream<Event> get onOpen => openEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Base class that supports listening for and dispatching browser events.
 *
 * Normally events are accessed via the Stream getter:
 *
 *     element.onMouseOver.listen((e) => print('Mouse over!'));
 *
 * To access bubbling events which are declared on one element, but may bubble
 * up to another element type (common for MediaElement events):
 *
 *     MediaElement.pauseEvent.forTarget(document.body).listen(...);
 *
 * To useCapture on events:
 *
 *     Element.keyDownEvent.forTarget(element, useCapture: true).listen(...);
 *
 * Custom events can be declared as:
 *
 *     class DataGenerator {
 *       static EventStreamProvider<Event> dataEvent =
 *           new EventStreamProvider('data');
 *     }
 *
 * Then listeners should access the event with:
 *
 *     DataGenerator.dataEvent.forTarget(element).listen(...);
 *
 * Custom events can also be accessed as:
 *
 *     element.on['some_event'].listen(...);
 *
 * This approach is generally discouraged as it loses the event typing and
 * some DOM events may have multiple platform-dependent event names under the
 * covers. By using the standard Stream getters you will get the platform
 * specific event name automatically.
 */
class Events {
  /* Raw event target. */
  final EventTarget _ptr;

  Events(this._ptr);

  Stream<Event> operator [](String type) {
    return new _EventStream(_ptr, type, false);
  }
}

class ElementEvents extends Events {
  static final webkitEvents = {
    'animationend': 'webkitAnimationEnd',
    'animationiteration': 'webkitAnimationIteration',
    'animationstart': 'webkitAnimationStart',
    'fullscreenchange': 'webkitfullscreenchange',
    'fullscreenerror': 'webkitfullscreenerror',
    'keyadded': 'webkitkeyadded',
    'keyerror': 'webkitkeyerror',
    'keymessage': 'webkitkeymessage',
    'needkey': 'webkitneedkey',
    'pointerlockchange': 'webkitpointerlockchange',
    'pointerlockerror': 'webkitpointerlockerror',
    'resourcetimingbufferfull': 'webkitresourcetimingbufferfull',
    'transitionend': 'webkitTransitionEnd',
    'speechchange': 'webkitSpeechChange'
  };

  ElementEvents(Element ptr) : super(ptr);

  Stream<Event> operator [](String type) {
    if (webkitEvents.keys.contains(type.toLowerCase())) {
      if (Device.isWebKit) {
        return new _ElementEventStreamImpl(
            _ptr, webkitEvents[type.toLowerCase()], false);
      }
    }
    return new _ElementEventStreamImpl(_ptr, type, false);
  }
}

/**
 * Base class for all browser objects that support events.
 *
 * Use the [on] property to add, and remove events
 * for compile-time type checks and a more concise API.
 */
@Native("EventTarget")
class EventTarget extends Interceptor {
  // Custom element created callback.
  EventTarget._created();

  /**
   * This is an ease-of-use accessor for event streams which should only be
   * used when an explicit accessor is not available.
   */
  Events get on => new Events(this);

  void addEventListener(String type, EventListener listener,
      [bool useCapture]) {
    // TODO(leafp): This check is avoid a bug in our dispatch code when
    // listener is null.  The browser treats this call as a no-op in this
    // case, so it's fine to short-circuit it, but we should not have to.
    if (listener != null) {
      _addEventListener(type, listener, useCapture);
    }
  }

  void removeEventListener(String type, EventListener listener,
      [bool useCapture]) {
    // TODO(leafp): This check is avoid a bug in our dispatch code when
    // listener is null.  The browser treats this call as a no-op in this
    // case, so it's fine to short-circuit it, but we should not have to.
    if (listener != null) {
      _removeEventListener(type, listener, useCapture);
    }
  }

  // To suppress missing implicit constructor warnings.
  factory EventTarget._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('addEventListener')
  void _addEventListener(String type, EventListener listener, [bool options])
      native;

  bool dispatchEvent(Event event) native;

  @JSName('removeEventListener')
  void _removeEventListener(String type, EventListener listener, [bool options])
      native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ExtendableEvent")
class ExtendableEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory ExtendableEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory ExtendableEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return ExtendableEvent._create_1(type, eventInitDict_1);
    }
    return ExtendableEvent._create_2(type);
  }
  static ExtendableEvent _create_1(type, eventInitDict) =>
      JS('ExtendableEvent', 'new ExtendableEvent(#,#)', type, eventInitDict);
  static ExtendableEvent _create_2(type) =>
      JS('ExtendableEvent', 'new ExtendableEvent(#)', type);

  void waitUntil(Future f) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ExtendableMessageEvent")
class ExtendableMessageEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory ExtendableMessageEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final Object data;

  final String lastEventId;

  final String origin;

  final List<MessagePort> ports;

  @Creates('Client|ServiceWorker|MessagePort')
  @Returns('Client|ServiceWorker|MessagePort|Null')
  final Object source;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("External")
class External extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory External._() {
    throw new UnsupportedError("Not supported");
  }

  void AddSearchProvider() native;

  void IsSearchProviderInstalled() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FaceDetector")
class FaceDetector extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory FaceDetector._() {
    throw new UnsupportedError("Not supported");
  }

  factory FaceDetector([Map faceDetectorOptions]) {
    if (faceDetectorOptions != null) {
      var faceDetectorOptions_1 =
          convertDartToNative_Dictionary(faceDetectorOptions);
      return FaceDetector._create_1(faceDetectorOptions_1);
    }
    return FaceDetector._create_2();
  }
  static FaceDetector _create_1(faceDetectorOptions) =>
      JS('FaceDetector', 'new FaceDetector(#)', faceDetectorOptions);
  static FaceDetector _create_2() => JS('FaceDetector', 'new FaceDetector()');

  Future<List<DetectedFace>> detect(/*ImageBitmapSource*/ image) =>
      promiseToFuture<List<DetectedFace>>(JS("", "#.detect(#)", this, image));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FederatedCredential")
class FederatedCredential extends Credential implements CredentialUserData {
  // To suppress missing implicit constructor warnings.
  factory FederatedCredential._() {
    throw new UnsupportedError("Not supported");
  }

  factory FederatedCredential(Map data) {
    var data_1 = convertDartToNative_Dictionary(data);
    return FederatedCredential._create_1(data_1);
  }
  static FederatedCredential _create_1(data) =>
      JS('FederatedCredential', 'new FederatedCredential(#)', data);

  final String protocol;

  final String provider;

  // From CredentialUserData

  @JSName('iconURL')
  final String iconUrl;

  final String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FetchEvent")
class FetchEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory FetchEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory FetchEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return FetchEvent._create_1(type, eventInitDict_1);
  }
  static FetchEvent _create_1(type, eventInitDict) =>
      JS('FetchEvent', 'new FetchEvent(#,#)', type, eventInitDict);

  final String clientId;

  final bool isReload;

  Future get preloadResponse =>
      promiseToFuture(JS("", "#.preloadResponse", this));

  final _Request request;

  void respondWith(Future r) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("HTMLFieldSetElement")
class FieldSetElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory FieldSetElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory FieldSetElement() => JS(
      'returns:FieldSetElement;creates:FieldSetElement;new:true',
      '#.createElement(#)',
      document,
      "fieldset");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  FieldSetElement.created() : super.created();

  bool disabled;

  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> elements;

  final FormElement form;

  String name;

  final String type;

  final String validationMessage;

  final ValidityState validity;

  final bool willValidate;

  bool checkValidity() native;

  bool reportValidity() native;

  void setCustomValidity(String error) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("File")
class File extends Blob {
  // To suppress missing implicit constructor warnings.
  factory File._() {
    throw new UnsupportedError("Not supported");
  }

  factory File(List<Object> fileBits, String fileName, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return File._create_1(fileBits, fileName, options_1);
    }
    return File._create_2(fileBits, fileName);
  }
  static File _create_1(fileBits, fileName, options) =>
      JS('File', 'new File(#,#,#)', fileBits, fileName, options);
  static File _create_2(fileBits, fileName) =>
      JS('File', 'new File(#,#)', fileBits, fileName);

  final int lastModified;

  DateTime get lastModifiedDate =>
      convertNativeToDart_DateTime(this._get_lastModifiedDate);
  @JSName('lastModifiedDate')
  @Creates('Null')
  final dynamic _get_lastModifiedDate;

  final String name;

  @JSName('webkitRelativePath')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final String relativePath;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _FileCallback(File file);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FileEntry")
class FileEntry extends Entry {
  // To suppress missing implicit constructor warnings.
  factory FileEntry._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('createWriter')
  void _createWriter(_FileWriterCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  @JSName('createWriter')
  Future<FileWriter> createWriter() {
    var completer = new Completer<FileWriter>();
    _createWriter((value) {
      applyExtension('FileWriter', value);
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('file')
  void _file(_FileCallback successCallback, [_ErrorCallback errorCallback])
      native;

  @JSName('file')
  Future<File> file() {
    var completer = new Completer<File>();
    _file((value) {
      applyExtension('File', value);
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FileList")
class FileList extends Interceptor
    with ListMixin<File>, ImmutableListMixin<File>
    implements List<File>, JavaScriptIndexingBehavior<File> {
  // To suppress missing implicit constructor warnings.
  factory FileList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  File operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("File", "#[#]", this, index);
  }

  void operator []=(int index, File value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<File> mixins.
  // File is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  File get first {
    if (this.length > 0) {
      return JS('File', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  File get last {
    int len = this.length;
    if (len > 0) {
      return JS('File', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  File get single {
    int len = this.length;
    if (len == 1) {
      return JS('File', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  File elementAt(int index) => this[index];
  // -- end List<File> mixins.

  File item(int index) native;
}
// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FileReader")
class FileReader extends EventTarget {
  Object get result {
    var res = JS('Null|String|NativeByteBuffer', '#.result', this);
    if (res is ByteBuffer) {
      return new Uint8List.view(res);
    }
    return res;
  }

  // To suppress missing implicit constructor warnings.
  factory FileReader._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `abort` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> abortEvent =
      const EventStreamProvider<ProgressEvent>('abort');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> errorEvent =
      const EventStreamProvider<ProgressEvent>('error');

  /**
   * Static factory designed to expose `load` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> loadEvent =
      const EventStreamProvider<ProgressEvent>('load');

  /**
   * Static factory designed to expose `loadend` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> loadEndEvent =
      const EventStreamProvider<ProgressEvent>('loadend');

  /**
   * Static factory designed to expose `loadstart` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> loadStartEvent =
      const EventStreamProvider<ProgressEvent>('loadstart');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> progressEvent =
      const EventStreamProvider<ProgressEvent>('progress');

  factory FileReader() {
    return FileReader._create_1();
  }
  static FileReader _create_1() => JS('FileReader', 'new FileReader()');

  static const int DONE = 2;

  static const int EMPTY = 0;

  static const int LOADING = 1;

  final DomException error;

  final int readyState;

  void abort() native;

  void readAsArrayBuffer(Blob blob) native;

  @JSName('readAsDataURL')
  void readAsDataUrl(Blob blob) native;

  void readAsText(Blob blob, [String label]) native;

  /// Stream of `abort` events handled by this [FileReader].
  Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);

  /// Stream of `error` events handled by this [FileReader].
  Stream<ProgressEvent> get onError => errorEvent.forTarget(this);

  /// Stream of `load` events handled by this [FileReader].
  Stream<ProgressEvent> get onLoad => loadEvent.forTarget(this);

  /// Stream of `loadend` events handled by this [FileReader].
  Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);

  /// Stream of `loadstart` events handled by this [FileReader].
  Stream<ProgressEvent> get onLoadStart => loadStartEvent.forTarget(this);

  /// Stream of `progress` events handled by this [FileReader].
  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("DOMFileSystem")
class FileSystem extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory FileSystem._() {
    throw new UnsupportedError("Not supported");
  }

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.webkitRequestFileSystem)');

  final String name;

  final DirectoryEntry root;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _FileSystemCallback(FileSystem fileSystem);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FileWriter")
class FileWriter extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory FileWriter._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `abort` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> abortEvent =
      const EventStreamProvider<ProgressEvent>('abort');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> progressEvent =
      const EventStreamProvider<ProgressEvent>('progress');

  /**
   * Static factory designed to expose `write` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> writeEvent =
      const EventStreamProvider<ProgressEvent>('write');

  /**
   * Static factory designed to expose `writeend` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> writeEndEvent =
      const EventStreamProvider<ProgressEvent>('writeend');

  /**
   * Static factory designed to expose `writestart` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> writeStartEvent =
      const EventStreamProvider<ProgressEvent>('writestart');

  static const int DONE = 2;

  static const int INIT = 0;

  static const int WRITING = 1;

  final DomException error;

  final int length;

  final int position;

  final int readyState;

  void abort() native;

  void seek(int position) native;

  void truncate(int size) native;

  void write(Blob data) native;

  /// Stream of `abort` events handled by this [FileWriter].
  Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);

  /// Stream of `error` events handled by this [FileWriter].
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `progress` events handled by this [FileWriter].
  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);

  /// Stream of `write` events handled by this [FileWriter].
  Stream<ProgressEvent> get onWrite => writeEvent.forTarget(this);

  /// Stream of `writeend` events handled by this [FileWriter].
  Stream<ProgressEvent> get onWriteEnd => writeEndEvent.forTarget(this);

  /// Stream of `writestart` events handled by this [FileWriter].
  Stream<ProgressEvent> get onWriteStart => writeStartEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _FileWriterCallback(FileWriter fileWriter);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FocusEvent")
class FocusEvent extends UIEvent {
  // To suppress missing implicit constructor warnings.
  factory FocusEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory FocusEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return FocusEvent._create_1(type, eventInitDict_1);
    }
    return FocusEvent._create_2(type);
  }
  static FocusEvent _create_1(type, eventInitDict) =>
      JS('FocusEvent', 'new FocusEvent(#,#)', type, eventInitDict);
  static FocusEvent _create_2(type) =>
      JS('FocusEvent', 'new FocusEvent(#)', type);

  EventTarget get relatedTarget =>
      _convertNativeToDart_EventTarget(this._get_relatedTarget);
  @JSName('relatedTarget')
  @Creates('Null')
  final dynamic _get_relatedTarget;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FontFace")
class FontFace extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory FontFace._() {
    throw new UnsupportedError("Not supported");
  }

  factory FontFace(String family, Object source, [Map descriptors]) {
    if (descriptors != null) {
      var descriptors_1 = convertDartToNative_Dictionary(descriptors);
      return FontFace._create_1(family, source, descriptors_1);
    }
    return FontFace._create_2(family, source);
  }
  static FontFace _create_1(family, source, descriptors) =>
      JS('FontFace', 'new FontFace(#,#,#)', family, source, descriptors);
  static FontFace _create_2(family, source) =>
      JS('FontFace', 'new FontFace(#,#)', family, source);

  String display;

  String family;

  String featureSettings;

  Future<FontFace> get loaded =>
      promiseToFuture<FontFace>(JS("", "#.loaded", this));

  final String status;

  String stretch;

  String style;

  String unicodeRange;

  String variant;

  String weight;

  Future<FontFace> load() =>
      promiseToFuture<FontFace>(JS("", "#.load()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FontFaceSet")
class FontFaceSet extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory FontFaceSet._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<FontFaceSetLoadEvent> loadingEvent =
      const EventStreamProvider<FontFaceSetLoadEvent>('loading');

  static const EventStreamProvider<FontFaceSetLoadEvent> loadingDoneEvent =
      const EventStreamProvider<FontFaceSetLoadEvent>('loadingdone');

  static const EventStreamProvider<FontFaceSetLoadEvent> loadingErrorEvent =
      const EventStreamProvider<FontFaceSetLoadEvent>('loadingerror');

  final String status;

  FontFaceSet add(FontFace arg) native;

  bool check(String font, [String text]) native;

  void clear() native;

  bool delete(FontFace arg) native;

  void forEach(FontFaceSetForEachCallback callback, [Object thisArg]) native;

  bool has(FontFace arg) native;

  Stream<FontFaceSetLoadEvent> get onLoading => loadingEvent.forTarget(this);

  Stream<FontFaceSetLoadEvent> get onLoadingDone =>
      loadingDoneEvent.forTarget(this);

  Stream<FontFaceSetLoadEvent> get onLoadingError =>
      loadingErrorEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FontFaceSetLoadEvent")
class FontFaceSetLoadEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory FontFaceSetLoadEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory FontFaceSetLoadEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return FontFaceSetLoadEvent._create_1(type, eventInitDict_1);
    }
    return FontFaceSetLoadEvent._create_2(type);
  }
  static FontFaceSetLoadEvent _create_1(type, eventInitDict) => JS(
      'FontFaceSetLoadEvent',
      'new FontFaceSetLoadEvent(#,#)',
      type,
      eventInitDict);
  static FontFaceSetLoadEvent _create_2(type) =>
      JS('FontFaceSetLoadEvent', 'new FontFaceSetLoadEvent(#)', type);

  final List<FontFace> fontfaces;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FontFaceSource")
class FontFaceSource extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory FontFaceSource._() {
    throw new UnsupportedError("Not supported");
  }

  final FontFaceSet fonts;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ForeignFetchEvent")
class ForeignFetchEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory ForeignFetchEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory ForeignFetchEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return ForeignFetchEvent._create_1(type, eventInitDict_1);
  }
  static ForeignFetchEvent _create_1(type, eventInitDict) => JS(
      'ForeignFetchEvent', 'new ForeignFetchEvent(#,#)', type, eventInitDict);

  final String origin;

  final _Request request;

  void respondWith(Future r) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("FormData")
class FormData extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory FormData._() {
    throw new UnsupportedError("Not supported");
  }

  factory FormData([FormElement form]) {
    if (form != null) {
      return FormData._create_1(form);
    }
    return FormData._create_2();
  }
  static FormData _create_1(form) => JS('FormData', 'new FormData(#)', form);
  static FormData _create_2() => JS('FormData', 'new FormData()');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.FormData)');

  void append(String name, String value) native;

  @JSName('append')
  void appendBlob(String name, Blob value, [String filename]) native;

  void delete(String name) native;

  Object get(String name) native;

  List<Object> getAll(String name) native;

  bool has(String name) native;

  void set(String name, value, [String filename]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLFormElement")
class FormElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory FormElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory FormElement() => JS(
      'returns:FormElement;creates:FormElement;new:true',
      '#.createElement(#)',
      document,
      "form");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  FormElement.created() : super.created();

  String acceptCharset;

  String action;

  String autocomplete;

  String encoding;

  String enctype;

  final int length;

  String method;

  String name;

  bool noValidate;

  String target;

  Object __getter__(String name) native;

  bool checkValidity() native;

  Element item(int index) native;

  bool reportValidity() native;

  void requestAutocomplete(Map details) {
    var details_1 = convertDartToNative_Dictionary(details);
    _requestAutocomplete_1(details_1);
    return;
  }

  @JSName('requestAutocomplete')
  void _requestAutocomplete_1(details) native;

  void reset() native;

  void submit() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void FrameRequestCallback(num highResTime);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void FunctionStringCallback(String data);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Gamepad")
class Gamepad extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Gamepad._() {
    throw new UnsupportedError("Not supported");
  }

  final List<num> axes;

  @Creates('JSExtendableArray|GamepadButton')
  @Returns('JSExtendableArray')
  final List<GamepadButton> buttons;

  final bool connected;

  final int displayId;

  final String hand;

  final String id;

  final int index;

  final String mapping;

  final GamepadPose pose;

  final int timestamp;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("GamepadButton")
class GamepadButton extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory GamepadButton._() {
    throw new UnsupportedError("Not supported");
  }

  final bool pressed;

  final bool touched;

  final num value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("GamepadEvent")
class GamepadEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory GamepadEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory GamepadEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return GamepadEvent._create_1(type, eventInitDict_1);
    }
    return GamepadEvent._create_2(type);
  }
  static GamepadEvent _create_1(type, eventInitDict) =>
      JS('GamepadEvent', 'new GamepadEvent(#,#)', type, eventInitDict);
  static GamepadEvent _create_2(type) =>
      JS('GamepadEvent', 'new GamepadEvent(#)', type);

  final Gamepad gamepad;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("GamepadPose")
class GamepadPose extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory GamepadPose._() {
    throw new UnsupportedError("Not supported");
  }

  final Float32List angularAcceleration;

  final Float32List angularVelocity;

  final bool hasOrientation;

  final bool hasPosition;

  final Float32List linearAcceleration;

  final Float32List linearVelocity;

  final Float32List orientation;

  final Float32List position;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("Geolocation")
class Geolocation extends Interceptor {
  Future<Geoposition> getCurrentPosition(
      {bool enableHighAccuracy, Duration timeout, Duration maximumAge}) {
    var options = {};
    if (enableHighAccuracy != null) {
      options['enableHighAccuracy'] = enableHighAccuracy;
    }
    if (timeout != null) {
      options['timeout'] = timeout.inMilliseconds;
    }
    if (maximumAge != null) {
      options['maximumAge'] = maximumAge.inMilliseconds;
    }
    var completer = new Completer<Geoposition>();
    try {
      _getCurrentPosition((position) {
        completer.complete(_ensurePosition(position));
      }, (error) {
        completer.completeError(error);
      }, options);
    } catch (e, stacktrace) {
      completer.completeError(e, stacktrace);
    }
    return completer.future;
  }

  Stream<Geoposition> watchPosition(
      {bool enableHighAccuracy, Duration timeout, Duration maximumAge}) {
    var options = {};
    if (enableHighAccuracy != null) {
      options['enableHighAccuracy'] = enableHighAccuracy;
    }
    if (timeout != null) {
      options['timeout'] = timeout.inMilliseconds;
    }
    if (maximumAge != null) {
      options['maximumAge'] = maximumAge.inMilliseconds;
    }

    int watchId;
    // TODO(jacobr): it seems like a bug that we have to specifiy the static
    // type here for controller.stream to have the right type.
    // dartbug.com/26278
    StreamController<Geoposition> controller;
    controller = new StreamController<Geoposition>(
        sync: true,
        onListen: () {
          assert(watchId == null);
          watchId = _watchPosition((position) {
            controller.add(_ensurePosition(position));
          }, (error) {
            controller.addError(error);
          }, options);
        },
        onCancel: () {
          assert(watchId != null);
          _clearWatch(watchId);
        });

    return controller.stream;
  }

  Geoposition _ensurePosition(domPosition) {
    try {
      // Firefox may throw on this.
      if (domPosition is Geoposition) {
        return domPosition;
      }
    } catch (e) {}
    return new _GeopositionWrapper(domPosition);
  }

  // To suppress missing implicit constructor warnings.
  factory Geolocation._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('clearWatch')
  void _clearWatch(int watchID) native;

  void _getCurrentPosition(_PositionCallback successCallback,
      [_PositionErrorCallback errorCallback, Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      _getCurrentPosition_1(successCallback, errorCallback, options_1);
      return;
    }
    if (errorCallback != null) {
      _getCurrentPosition_2(successCallback, errorCallback);
      return;
    }
    _getCurrentPosition_3(successCallback);
    return;
  }

  @JSName('getCurrentPosition')
  void _getCurrentPosition_1(_PositionCallback successCallback,
      _PositionErrorCallback errorCallback, options) native;
  @JSName('getCurrentPosition')
  void _getCurrentPosition_2(_PositionCallback successCallback,
      _PositionErrorCallback errorCallback) native;
  @JSName('getCurrentPosition')
  void _getCurrentPosition_3(_PositionCallback successCallback) native;

  int _watchPosition(_PositionCallback successCallback,
      [_PositionErrorCallback errorCallback, Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _watchPosition_1(successCallback, errorCallback, options_1);
    }
    if (errorCallback != null) {
      return _watchPosition_2(successCallback, errorCallback);
    }
    return _watchPosition_3(successCallback);
  }

  @JSName('watchPosition')
  int _watchPosition_1(_PositionCallback successCallback,
      _PositionErrorCallback errorCallback, options) native;
  @JSName('watchPosition')
  int _watchPosition_2(_PositionCallback successCallback,
      _PositionErrorCallback errorCallback) native;
  @JSName('watchPosition')
  int _watchPosition_3(_PositionCallback successCallback) native;
}

/**
 * Wrapper for Firefox- it returns an object which we cannot map correctly.
 * Basically Firefox was returning a [xpconnect wrapped nsIDOMGeoPosition] but
 * which has further oddities.
 */
class _GeopositionWrapper implements Geoposition {
  var _ptr;
  _GeopositionWrapper(this._ptr);

  Coordinates get coords => JS('Coordinates', '#.coords', _ptr);
  int get timestamp => JS('int', '#.timestamp', _ptr);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Position")
class Geoposition extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Geoposition._() {
    throw new UnsupportedError("Not supported");
  }

  final Coordinates coords;

  final int timestamp;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// We implement EventTarget and have stubs for its methods because it's tricky to
// convince the scripts to make our instance methods abstract, and the bodies that
// get generated require `this` to be an EventTarget.
abstract class GlobalEventHandlers implements EventTarget {
  void addEventListener(String type, dynamic listener(Event event),
      [bool useCapture]);
  bool dispatchEvent(Event event);
  void removeEventListener(String type, dynamic listener(Event event),
      [bool useCapture]);
  Events get on;

  // To suppress missing implicit constructor warnings.
  factory GlobalEventHandlers._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> abortEvent =
      const EventStreamProvider<Event>('abort');

  static const EventStreamProvider<Event> blurEvent =
      const EventStreamProvider<Event>('blur');

  static const EventStreamProvider<Event> canPlayEvent =
      const EventStreamProvider<Event>('canplay');

  static const EventStreamProvider<Event> canPlayThroughEvent =
      const EventStreamProvider<Event>('canplaythrough');

  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  static const EventStreamProvider<MouseEvent> clickEvent =
      const EventStreamProvider<MouseEvent>('click');

  static const EventStreamProvider<MouseEvent> contextMenuEvent =
      const EventStreamProvider<MouseEvent>('contextmenu');

  static const EventStreamProvider<Event> doubleClickEvent =
      const EventStreamProvider<Event>('dblclick');

  static const EventStreamProvider<MouseEvent> dragEvent =
      const EventStreamProvider<MouseEvent>('drag');

  static const EventStreamProvider<MouseEvent> dragEndEvent =
      const EventStreamProvider<MouseEvent>('dragend');

  static const EventStreamProvider<MouseEvent> dragEnterEvent =
      const EventStreamProvider<MouseEvent>('dragenter');

  static const EventStreamProvider<MouseEvent> dragLeaveEvent =
      const EventStreamProvider<MouseEvent>('dragleave');

  static const EventStreamProvider<MouseEvent> dragOverEvent =
      const EventStreamProvider<MouseEvent>('dragover');

  static const EventStreamProvider<MouseEvent> dragStartEvent =
      const EventStreamProvider<MouseEvent>('dragstart');

  static const EventStreamProvider<MouseEvent> dropEvent =
      const EventStreamProvider<MouseEvent>('drop');

  static const EventStreamProvider<Event> durationChangeEvent =
      const EventStreamProvider<Event>('durationchange');

  static const EventStreamProvider<Event> emptiedEvent =
      const EventStreamProvider<Event>('emptied');

  static const EventStreamProvider<Event> endedEvent =
      const EventStreamProvider<Event>('ended');

  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  static const EventStreamProvider<Event> focusEvent =
      const EventStreamProvider<Event>('focus');

  static const EventStreamProvider<Event> inputEvent =
      const EventStreamProvider<Event>('input');

  static const EventStreamProvider<Event> invalidEvent =
      const EventStreamProvider<Event>('invalid');

  static const EventStreamProvider<KeyboardEvent> keyDownEvent =
      const EventStreamProvider<KeyboardEvent>('keydown');

  static const EventStreamProvider<KeyboardEvent> keyPressEvent =
      const EventStreamProvider<KeyboardEvent>('keypress');

  static const EventStreamProvider<KeyboardEvent> keyUpEvent =
      const EventStreamProvider<KeyboardEvent>('keyup');

  static const EventStreamProvider<Event> loadEvent =
      const EventStreamProvider<Event>('load');

  static const EventStreamProvider<Event> loadedDataEvent =
      const EventStreamProvider<Event>('loadeddata');

  static const EventStreamProvider<Event> loadedMetadataEvent =
      const EventStreamProvider<Event>('loadedmetadata');

  static const EventStreamProvider<MouseEvent> mouseDownEvent =
      const EventStreamProvider<MouseEvent>('mousedown');

  static const EventStreamProvider<MouseEvent> mouseEnterEvent =
      const EventStreamProvider<MouseEvent>('mouseenter');

  static const EventStreamProvider<MouseEvent> mouseLeaveEvent =
      const EventStreamProvider<MouseEvent>('mouseleave');

  static const EventStreamProvider<MouseEvent> mouseMoveEvent =
      const EventStreamProvider<MouseEvent>('mousemove');

  static const EventStreamProvider<MouseEvent> mouseOutEvent =
      const EventStreamProvider<MouseEvent>('mouseout');

  static const EventStreamProvider<MouseEvent> mouseOverEvent =
      const EventStreamProvider<MouseEvent>('mouseover');

  static const EventStreamProvider<MouseEvent> mouseUpEvent =
      const EventStreamProvider<MouseEvent>('mouseup');

  static const EventStreamProvider<WheelEvent> mouseWheelEvent =
      const EventStreamProvider<WheelEvent>('mousewheel');

  static const EventStreamProvider<Event> pauseEvent =
      const EventStreamProvider<Event>('pause');

  static const EventStreamProvider<Event> playEvent =
      const EventStreamProvider<Event>('play');

  static const EventStreamProvider<Event> playingEvent =
      const EventStreamProvider<Event>('playing');

  static const EventStreamProvider<Event> rateChangeEvent =
      const EventStreamProvider<Event>('ratechange');

  static const EventStreamProvider<Event> resetEvent =
      const EventStreamProvider<Event>('reset');

  static const EventStreamProvider<Event> resizeEvent =
      const EventStreamProvider<Event>('resize');

  static const EventStreamProvider<Event> scrollEvent =
      const EventStreamProvider<Event>('scroll');

  static const EventStreamProvider<Event> seekedEvent =
      const EventStreamProvider<Event>('seeked');

  static const EventStreamProvider<Event> seekingEvent =
      const EventStreamProvider<Event>('seeking');

  static const EventStreamProvider<Event> selectEvent =
      const EventStreamProvider<Event>('select');

  static const EventStreamProvider<Event> stalledEvent =
      const EventStreamProvider<Event>('stalled');

  static const EventStreamProvider<Event> submitEvent =
      const EventStreamProvider<Event>('submit');

  static const EventStreamProvider<Event> suspendEvent =
      const EventStreamProvider<Event>('suspend');

  static const EventStreamProvider<Event> timeUpdateEvent =
      const EventStreamProvider<Event>('timeupdate');

  static const EventStreamProvider<TouchEvent> touchCancelEvent =
      const EventStreamProvider<TouchEvent>('touchcancel');

  static const EventStreamProvider<TouchEvent> touchEndEvent =
      const EventStreamProvider<TouchEvent>('touchend');

  static const EventStreamProvider<TouchEvent> touchMoveEvent =
      const EventStreamProvider<TouchEvent>('touchmove');

  static const EventStreamProvider<TouchEvent> touchStartEvent =
      const EventStreamProvider<TouchEvent>('touchstart');

  static const EventStreamProvider<Event> volumeChangeEvent =
      const EventStreamProvider<Event>('volumechange');

  static const EventStreamProvider<Event> waitingEvent =
      const EventStreamProvider<Event>('waiting');

  static const EventStreamProvider<WheelEvent> wheelEvent =
      const EventStreamProvider<WheelEvent>('wheel');

  Stream<Event> get onAbort => abortEvent.forTarget(this);

  Stream<Event> get onBlur => blurEvent.forTarget(this);

  Stream<Event> get onCanPlay => canPlayEvent.forTarget(this);

  Stream<Event> get onCanPlayThrough => canPlayThroughEvent.forTarget(this);

  Stream<Event> get onChange => changeEvent.forTarget(this);

  Stream<MouseEvent> get onClick => clickEvent.forTarget(this);

  Stream<MouseEvent> get onContextMenu => contextMenuEvent.forTarget(this);

  Stream<Event> get onDoubleClick => doubleClickEvent.forTarget(this);

  Stream<MouseEvent> get onDrag => dragEvent.forTarget(this);

  Stream<MouseEvent> get onDragEnd => dragEndEvent.forTarget(this);

  Stream<MouseEvent> get onDragEnter => dragEnterEvent.forTarget(this);

  Stream<MouseEvent> get onDragLeave => dragLeaveEvent.forTarget(this);

  Stream<MouseEvent> get onDragOver => dragOverEvent.forTarget(this);

  Stream<MouseEvent> get onDragStart => dragStartEvent.forTarget(this);

  Stream<MouseEvent> get onDrop => dropEvent.forTarget(this);

  Stream<Event> get onDurationChange => durationChangeEvent.forTarget(this);

  Stream<Event> get onEmptied => emptiedEvent.forTarget(this);

  Stream<Event> get onEnded => endedEvent.forTarget(this);

  Stream<Event> get onError => errorEvent.forTarget(this);

  Stream<Event> get onFocus => focusEvent.forTarget(this);

  Stream<Event> get onInput => inputEvent.forTarget(this);

  Stream<Event> get onInvalid => invalidEvent.forTarget(this);

  Stream<KeyboardEvent> get onKeyDown => keyDownEvent.forTarget(this);

  Stream<KeyboardEvent> get onKeyPress => keyPressEvent.forTarget(this);

  Stream<KeyboardEvent> get onKeyUp => keyUpEvent.forTarget(this);

  Stream<Event> get onLoad => loadEvent.forTarget(this);

  Stream<Event> get onLoadedData => loadedDataEvent.forTarget(this);

  Stream<Event> get onLoadedMetadata => loadedMetadataEvent.forTarget(this);

  Stream<MouseEvent> get onMouseDown => mouseDownEvent.forTarget(this);

  Stream<MouseEvent> get onMouseEnter => mouseEnterEvent.forTarget(this);

  Stream<MouseEvent> get onMouseLeave => mouseLeaveEvent.forTarget(this);

  Stream<MouseEvent> get onMouseMove => mouseMoveEvent.forTarget(this);

  Stream<MouseEvent> get onMouseOut => mouseOutEvent.forTarget(this);

  Stream<MouseEvent> get onMouseOver => mouseOverEvent.forTarget(this);

  Stream<MouseEvent> get onMouseUp => mouseUpEvent.forTarget(this);

  Stream<WheelEvent> get onMouseWheel => mouseWheelEvent.forTarget(this);

  Stream<Event> get onPause => pauseEvent.forTarget(this);

  Stream<Event> get onPlay => playEvent.forTarget(this);

  Stream<Event> get onPlaying => playingEvent.forTarget(this);

  Stream<Event> get onRateChange => rateChangeEvent.forTarget(this);

  Stream<Event> get onReset => resetEvent.forTarget(this);

  Stream<Event> get onResize => resizeEvent.forTarget(this);

  Stream<Event> get onScroll => scrollEvent.forTarget(this);

  Stream<Event> get onSeeked => seekedEvent.forTarget(this);

  Stream<Event> get onSeeking => seekingEvent.forTarget(this);

  Stream<Event> get onSelect => selectEvent.forTarget(this);

  Stream<Event> get onStalled => stalledEvent.forTarget(this);

  Stream<Event> get onSubmit => submitEvent.forTarget(this);

  Stream<Event> get onSuspend => suspendEvent.forTarget(this);

  Stream<Event> get onTimeUpdate => timeUpdateEvent.forTarget(this);

  Stream<TouchEvent> get onTouchCancel => touchCancelEvent.forTarget(this);

  Stream<TouchEvent> get onTouchEnd => touchEndEvent.forTarget(this);

  Stream<TouchEvent> get onTouchMove => touchMoveEvent.forTarget(this);

  Stream<TouchEvent> get onTouchStart => touchStartEvent.forTarget(this);

  Stream<Event> get onVolumeChange => volumeChangeEvent.forTarget(this);

  Stream<Event> get onWaiting => waitingEvent.forTarget(this);

  Stream<WheelEvent> get onWheel => wheelEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Gyroscope")
class Gyroscope extends Sensor {
  // To suppress missing implicit constructor warnings.
  factory Gyroscope._() {
    throw new UnsupportedError("Not supported");
  }

  factory Gyroscope([Map sensorOptions]) {
    if (sensorOptions != null) {
      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
      return Gyroscope._create_1(sensorOptions_1);
    }
    return Gyroscope._create_2();
  }
  static Gyroscope _create_1(sensorOptions) =>
      JS('Gyroscope', 'new Gyroscope(#)', sensorOptions);
  static Gyroscope _create_2() => JS('Gyroscope', 'new Gyroscope()');

  final num x;

  final num y;

  final num z;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * An `<hr>` tag.
 */
@Native("HTMLHRElement")
class HRElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory HRElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory HRElement() => JS('returns:HRElement;creates:HRElement;new:true',
      '#.createElement(#)', document, "hr");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HRElement.created() : super.created();

  String color;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
@Native("HashChangeEvent")
class HashChangeEvent extends Event {
  factory HashChangeEvent(String type,
      {bool canBubble: true,
      bool cancelable: true,
      String oldUrl,
      String newUrl}) {
    var options = {
      'canBubble': canBubble,
      'cancelable': cancelable,
      'oldURL': oldUrl,
      'newURL': newUrl,
    };
    return JS('HashChangeEvent', 'new HashChangeEvent(#, #)', type,
        convertDartToNative_Dictionary(options));
  }

  factory HashChangeEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return HashChangeEvent._create_1(type, eventInitDict_1);
    }
    return HashChangeEvent._create_2(type);
  }
  static HashChangeEvent _create_1(type, eventInitDict) =>
      JS('HashChangeEvent', 'new HashChangeEvent(#,#)', type, eventInitDict);
  static HashChangeEvent _create_2(type) =>
      JS('HashChangeEvent', 'new HashChangeEvent(#)', type);

  /// Checks if this type is supported on the current platform.
  static bool get supported => Device.isEventTypeSupported('HashChangeEvent');

  @JSName('newURL')
  final String newUrl;

  @JSName('oldURL')
  final String oldUrl;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLHeadElement")
class HeadElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory HeadElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory HeadElement() => JS(
      'returns:HeadElement;creates:HeadElement;new:true',
      '#.createElement(#)',
      document,
      "head");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HeadElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Headers")
class Headers extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Headers._() {
    throw new UnsupportedError("Not supported");
  }

  factory Headers([Object init]) {
    if (init != null) {
      return Headers._create_1(init);
    }
    return Headers._create_2();
  }
  static Headers _create_1(init) => JS('Headers', 'new Headers(#)', init);
  static Headers _create_2() => JS('Headers', 'new Headers()');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLHeadingElement")
class HeadingElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory HeadingElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory HeadingElement.h1() => JS(
      'returns:HeadingElement;creates:HeadingElement;new:true',
      '#.createElement(#)',
      document,
      "h1");

  factory HeadingElement.h2() => JS(
      'returns:HeadingElement;creates:HeadingElement;new:true',
      '#.createElement(#)',
      document,
      "h2");

  factory HeadingElement.h3() => JS(
      'returns:HeadingElement;creates:HeadingElement;new:true',
      '#.createElement(#)',
      document,
      "h3");

  factory HeadingElement.h4() => JS(
      'returns:HeadingElement;creates:HeadingElement;new:true',
      '#.createElement(#)',
      document,
      "h4");

  factory HeadingElement.h5() => JS(
      'returns:HeadingElement;creates:HeadingElement;new:true',
      '#.createElement(#)',
      document,
      "h5");

  factory HeadingElement.h6() => JS(
      'returns:HeadingElement;creates:HeadingElement;new:true',
      '#.createElement(#)',
      document,
      "h6");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HeadingElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("History")
class History extends Interceptor implements HistoryBase {
  /**
   * Checks if the State APIs are supported on the current platform.
   *
   * See also:
   *
   * * [pushState]
   * * [replaceState]
   * * [state]
   */
  static bool get supportsState => JS('bool', '!!window.history.pushState');
  // To suppress missing implicit constructor warnings.
  factory History._() {
    throw new UnsupportedError("Not supported");
  }

  final int length;

  String scrollRestoration;

  dynamic get state =>
      convertNativeToDart_SerializedScriptValue(this._get_state);
  @JSName('state')
  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final dynamic _get_state;

  void back() native;

  void forward() native;

  void go([int delta]) native;

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void pushState(/*SerializedScriptValue*/ data, String title, String url) {
    var data_1 = convertDartToNative_SerializedScriptValue(data);
    _pushState_1(data_1, title, url);
    return;
  }

  @JSName('pushState')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void _pushState_1(data, title, url) native;

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void replaceState(/*SerializedScriptValue*/ data, String title, String url) {
    var data_1 = convertDartToNative_SerializedScriptValue(data);
    _replaceState_1(data_1, title, url);
    return;
  }

  @JSName('replaceState')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void _replaceState_1(data, title, url) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLCollection")
class HtmlCollection extends Interceptor
    with ListMixin<Node>, ImmutableListMixin<Node>
    implements JavaScriptIndexingBehavior<Node>, List<Node> {
  // To suppress missing implicit constructor warnings.
  factory HtmlCollection._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  Node operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Node", "#[#]", this, index);
  }

  void operator []=(int index, Node value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Node> mixins.
  // Node is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Node get first {
    if (this.length > 0) {
      return JS('Node', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Node get last {
    int len = this.length;
    if (len > 0) {
      return JS('Node', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Node get single {
    int len = this.length;
    if (len == 1) {
      return JS('Node', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Node elementAt(int index) => this[index];
  // -- end List<Node> mixins.

  Node item(int index) native;

  Object namedItem(String name) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Native("HTMLDocument")
class HtmlDocument extends Document {
  // To suppress missing implicit constructor warnings.
  factory HtmlDocument._() {
    throw new UnsupportedError("Not supported");
  }

  BodyElement body;

  /// UNSTABLE: Chrome-only - create a Range from the given point.
  @Unstable()
  Range caretRangeFromPoint(int x, int y) {
    return _caretRangeFromPoint(x, y);
  }

  Element elementFromPoint(int x, int y) {
    return _elementFromPoint(x, y);
  }

  HeadElement get head => _head;

  String get lastModified => _lastModified;

  String get preferredStylesheetSet => _preferredStylesheetSet;

  String get referrer => _referrer;

  String get selectedStylesheetSet => _selectedStylesheetSet;
  set selectedStylesheetSet(String value) {
    _selectedStylesheetSet = value;
  }

  List<StyleSheet> get styleSheets => _styleSheets;

  String get title => _title;

  set title(String value) {
    _title = value;
  }

  /**
   * Returns page to standard layout.
   *
   * Has no effect if the page is not in fullscreen mode.
   *
   * ## Other resources
   *
   * * [Using the fullscreen
   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
   *   from WebPlatform.org.
   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void exitFullscreen() {
    _webkitExitFullscreen();
  }

  /**
   * Register a custom subclass of Element to be instantiatable by the DOM.
   *
   * This is necessary to allow the construction of any custom elements.
   *
   * The class being registered must either subclass HtmlElement or SvgElement.
   * If they subclass these directly then they can be used as:
   *
   *     class FooElement extends HtmlElement{
   *        void created() {
   *          print('FooElement created!');
   *        }
   *     }
   *
   *     main() {
   *       document.registerElement('x-foo', FooElement);
   *       var myFoo = new Element.tag('x-foo');
   *       // prints 'FooElement created!' to the console.
   *     }
   *
   * The custom element can also be instantiated via HTML using the syntax
   * `<x-foo></x-foo>`
   *
   * Other elements can be subclassed as well:
   *
   *     class BarElement extends InputElement{
   *        void created() {
   *          print('BarElement created!');
   *        }
   *     }
   *
   *     main() {
   *       document.registerElement('x-bar', BarElement);
   *       var myBar = new Element.tag('input', 'x-bar');
   *       // prints 'BarElement created!' to the console.
   *     }
   *
   * This custom element can also be instantiated via HTML using the syntax
   * `<input is="x-bar"></input>`
   *
   */
  Function registerElement2(String tag, [Map options]) {
    return _registerCustomElement(JS('', 'window'), this, tag, options);
  }

  /** *Deprecated*: use [registerElement] instead. */
  @deprecated
  void register(String tag, Type customElementClass, {String extendsTag}) {
    return registerElement(tag, customElementClass, extendsTag: extendsTag);
  }

  /**
   * Static factory designed to expose `visibilitychange` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  static const EventStreamProvider<Event> visibilityChangeEvent =
      const _CustomEventStreamProvider<Event>(
          _determineVisibilityChangeEventType);

  static String _determineVisibilityChangeEventType(EventTarget e) {
    if (JS('bool', '(typeof #.hidden !== "undefined")', e)) {
      // Opera 12.10 and Firefox 18 and later support
      return 'visibilitychange';
    } else if (JS('bool', '(typeof #.mozHidden !== "undefined")', e)) {
      return 'mozvisibilitychange';
    } else if (JS('bool', '(typeof #.msHidden !== "undefined")', e)) {
      return 'msvisibilitychange';
    } else if (JS('bool', '(typeof #.webkitHidden !== "undefined")', e)) {
      return 'webkitvisibilitychange';
    }
    return 'visibilitychange';
  }

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  Stream<Event> get onVisibilityChange => visibilityChangeEvent.forTarget(this);

  /// Creates an element upgrader which can be used to change the Dart wrapper
  /// type for elements.
  ///
  /// The type specified must be a subclass of HtmlElement, when an element is
  /// upgraded then the created constructor will be invoked on that element.
  ///
  /// If the type is not a direct subclass of HtmlElement then the extendsTag
  /// parameter must be provided.
  ElementUpgrader createElementUpgrader(Type type, {String extendsTag}) {
    return new _JSElementUpgrader(this, type, extendsTag);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLFormControlsCollection")
class HtmlFormControlsCollection extends HtmlCollection {
  // To suppress missing implicit constructor warnings.
  factory HtmlFormControlsCollection._() {
    throw new UnsupportedError("Not supported");
  }

  Node item(int index) native;

  Object namedItem(String name) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLHtmlElement")
class HtmlHtmlElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory HtmlHtmlElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory HtmlHtmlElement() => JS(
      'returns:HtmlHtmlElement;creates:HtmlHtmlElement;new:true',
      '#.createElement(#)',
      document,
      "html");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HtmlHtmlElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLHyperlinkElementUtils")
class HtmlHyperlinkElementUtils extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory HtmlHyperlinkElementUtils._() {
    throw new UnsupportedError("Not supported");
  }

  String hash;

  String host;

  String hostname;

  String href;

  final String origin;

  String password;

  String pathname;

  String port;

  String protocol;

  String search;

  String username;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLOptionsCollection")
class HtmlOptionsCollection extends HtmlCollection {
  // To suppress missing implicit constructor warnings.
  factory HtmlOptionsCollection._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('item')
  Element _item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
  * A client-side XHR request for getting data from a URL,
  * formally known as XMLHttpRequest.
  *
  * HttpRequest can be used to obtain data from HTTP and FTP protocols,
  * and is useful for AJAX-style page updates.
  *
  * The simplest way to get the contents of a text file, such as a
  * JSON-formatted file, is with [getString].
  * For example, the following code gets the contents of a JSON file
  * and prints its length:
  *
  *     var path = 'myData.json';
  *     HttpRequest.getString(path)
  *         .then((String fileContents) {
  *           print(fileContents.length);
  *         })
  *         .catchError((Error error) {
  *           print(error.toString());
  *         });
  *
  * ## Fetching data from other servers
  *
  * For security reasons, browsers impose restrictions on requests
  * made by embedded apps.
  * With the default behavior of this class,
  * the code making the request must be served from the same origin
  * (domain name, port, and application layer protocol)
  * as the requested resource.
  * In the example above, the myData.json file must be co-located with the
  * app that uses it.
  * You might be able to
  * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#a-note-on-cors-and-httprequest)
  * by using CORS headers or JSONP.
  *
  * ## Other resources
  *
  * * [Fetch Data Dynamically](https://www.dartlang.org/docs/tutorials/fetchdata/),
  * a tutorial from _A Game of Darts_,
  * shows two different ways to use HttpRequest to get a JSON file.
  * * [Get Input from a Form](https://www.dartlang.org/docs/tutorials/forms/),
  * another tutorial from _A Game of Darts_,
  * shows using HttpRequest with a custom server.
  * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
  * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
  * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
 */
@Native("XMLHttpRequest")
class HttpRequest extends HttpRequestEventTarget {
  /**
   * Creates a GET request for the specified [url].
   *
   * The server response must be a `text/` mime type for this request to
   * succeed.
   *
   * This is similar to [request] but specialized for HTTP GET requests which
   * return text content.
   *
   * To add query parameters, append them to the [url] following a `?`,
   * joining each key to its value with `=` and separating key-value pairs with
   * `&`.
   *
   *     var name = Uri.encodeQueryComponent('John');
   *     var id = Uri.encodeQueryComponent('42');
   *     HttpRequest.getString('users.json?name=$name&id=$id')
   *       .then((HttpRequest resp) {
   *         // Do something with the response.
   *     });
   *
   * See also:
   *
   * * [request]
   */
  static Future<String> getString(String url,
      {bool withCredentials, void onProgress(ProgressEvent e)}) {
    return request(url,
            withCredentials: withCredentials, onProgress: onProgress)
        .then((HttpRequest xhr) => xhr.responseText);
  }

  /**
   * Makes a server POST request with the specified data encoded as form data.
   *
   * This is roughly the POST equivalent of getString. This method is similar
   * to sending a FormData object with broader browser support but limited to
   * String values.
   *
   * If [data] is supplied, the key/value pairs are URI encoded with
   * [Uri.encodeQueryComponent] and converted into an HTTP query string.
   *
   * Unless otherwise specified, this method appends the following header:
   *
   *     Content-Type: application/x-www-form-urlencoded; charset=UTF-8
   *
   * Here's an example of using this method:
   *
   *     var data = { 'firstName' : 'John', 'lastName' : 'Doe' };
   *     HttpRequest.postFormData('/send', data).then((HttpRequest resp) {
   *       // Do something with the response.
   *     });
   *
   * See also:
   *
   * * [request]
   */
  static Future<HttpRequest> postFormData(String url, Map<String, String> data,
      {bool withCredentials,
      String responseType,
      Map<String, String> requestHeaders,
      void onProgress(ProgressEvent e)}) {
    var parts = [];
    data.forEach((key, value) {
      parts.add('${Uri.encodeQueryComponent(key)}='
          '${Uri.encodeQueryComponent(value)}');
    });
    var formData = parts.join('&');

    if (requestHeaders == null) {
      requestHeaders = <String, String>{};
    }
    requestHeaders.putIfAbsent('Content-Type',
        () => 'application/x-www-form-urlencoded; charset=UTF-8');

    return request(url,
        method: 'POST',
        withCredentials: withCredentials,
        responseType: responseType,
        requestHeaders: requestHeaders,
        sendData: formData,
        onProgress: onProgress);
  }

  /**
   * Creates and sends a URL request for the specified [url].
   *
   * By default `request` will perform an HTTP GET request, but a different
   * method (`POST`, `PUT`, `DELETE`, etc) can be used by specifying the
   * [method] parameter. (See also [HttpRequest.postFormData] for `POST` 
   * requests only.
   *
   * The Future is completed when the response is available.
   *
   * If specified, `sendData` will send data in the form of a [ByteBuffer],
   * [Blob], [Document], [String], or [FormData] along with the HttpRequest.
   *
   * If specified, [responseType] sets the desired response format for the
   * request. By default it is [String], but can also be 'arraybuffer', 'blob', 
   * 'document', 'json', or 'text'. See also [HttpRequest.responseType] 
   * for more information.
   *
   * The [withCredentials] parameter specified that credentials such as a cookie
   * (already) set in the header or
   * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2)
   * should be specified for the request. Details to keep in mind when using
   * credentials:
   *
   * * Using credentials is only useful for cross-origin requests.
   * * The `Access-Control-Allow-Origin` header of `url` cannot contain a wildcard (*).
   * * The `Access-Control-Allow-Credentials` header of `url` must be set to true.
   * * If `Access-Control-Expose-Headers` has not been set to true, only a subset of all the response headers will be returned when calling [getAllRequestHeaders].
   *
   * The following is equivalent to the [getString] sample above:
   *
   *     var name = Uri.encodeQueryComponent('John');
   *     var id = Uri.encodeQueryComponent('42');
   *     HttpRequest.request('users.json?name=$name&id=$id')
   *       .then((HttpRequest resp) {
   *         // Do something with the response.
   *     });
   *
   * Here's an example of submitting an entire form with [FormData].
   *
   *     var myForm = querySelector('form#myForm');
   *     var data = new FormData(myForm);
   *     HttpRequest.request('/submit', method: 'POST', sendData: data)
   *       .then((HttpRequest resp) {
   *         // Do something with the response.
   *     });
   *
   * Note that requests for file:// URIs are only supported by Chrome extensions
   * with appropriate permissions in their manifest. Requests to file:// URIs
   * will also never fail- the Future will always complete successfully, even
   * when the file cannot be found.
   *
   * See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access_authentication).
   */
  static Future<HttpRequest> request(String url,
      {String method,
      bool withCredentials,
      String responseType,
      String mimeType,
      Map<String, String> requestHeaders,
      sendData,
      void onProgress(ProgressEvent e)}) {
    var completer = new Completer<HttpRequest>();

    var xhr = new HttpRequest();
    if (method == null) {
      method = 'GET';
    }
    xhr.open(method, url, async: true);

    if (withCredentials != null) {
      xhr.withCredentials = withCredentials;
    }

    if (responseType != null) {
      xhr.responseType = responseType;
    }

    if (mimeType != null) {
      xhr.overrideMimeType(mimeType);
    }

    if (requestHeaders != null) {
      requestHeaders.forEach((header, value) {
        xhr.setRequestHeader(header, value);
      });
    }

    if (onProgress != null) {
      xhr.onProgress.listen(onProgress);
    }

    xhr.onLoad.listen((e) {
      var accepted = xhr.status >= 200 && xhr.status < 300;
      var fileUri = xhr.status == 0; // file:// URIs have status of 0.
      var notModified = xhr.status == 304;
      // Redirect status is specified up to 307, but others have been used in
      // practice. Notably Google Drive uses 308 Resume Incomplete for
      // resumable uploads, and it's also been used as a redirect. The
      // redirect case will be handled by the browser before it gets to us,
      // so if we see it we should pass it through to the user.
      var unknownRedirect = xhr.status > 307 && xhr.status < 400;

      if (accepted || fileUri || notModified || unknownRedirect) {
        completer.complete(xhr);
      } else {
        completer.completeError(e);
      }
    });

    xhr.onError.listen(completer.completeError);

    if (sendData != null) {
      xhr.send(sendData);
    } else {
      xhr.send();
    }

    return completer.future;
  }

  /**
   * Checks to see if the Progress event is supported on the current platform.
   */
  static bool get supportsProgressEvent {
    var xhr = new HttpRequest();
    return JS('bool', '("onprogress" in #)', xhr);
  }

  /**
   * Checks to see if the current platform supports making cross origin
   * requests.
   *
   * Note that even if cross origin requests are supported, they still may fail
   * if the destination server does not support CORS requests.
   */
  static bool get supportsCrossOrigin {
    var xhr = new HttpRequest();
    return JS('bool', '("withCredentials" in #)', xhr);
  }

  /**
   * Checks to see if the LoadEnd event is supported on the current platform.
   */
  static bool get supportsLoadEndEvent {
    var xhr = new HttpRequest();
    return JS('bool', '("onloadend" in #)', xhr);
  }

  /**
   * Checks to see if the overrideMimeType method is supported on the current
   * platform.
   */
  static bool get supportsOverrideMimeType {
    var xhr = new HttpRequest();
    return JS('bool', '("overrideMimeType" in #)', xhr);
  }

  /**
   * Makes a cross-origin request to the specified URL.
   *
   * This API provides a subset of [request] which works on IE9. If IE9
   * cross-origin support is not required then [request] should be used instead.
   */
  static Future<String> requestCrossOrigin(String url,
      {String method, String sendData}) {
    if (supportsCrossOrigin) {
      return request(url, method: method, sendData: sendData).then((xhr) {
        return xhr.responseText;
      });
    }
    var completer = new Completer<String>();
    if (method == null) {
      method = 'GET';
    }
    var xhr = JS('var', 'new XDomainRequest()');
    JS('', '#.open(#, #)', xhr, method, url);
    JS(
        '',
        '#.onload = #',
        xhr,
        convertDartClosureToJS((e) {
          var response = JS('String', '#.responseText', xhr);
          completer.complete(response);
        }, 1));
    JS(
        '',
        '#.onerror = #',
        xhr,
        convertDartClosureToJS((e) {
          completer.completeError(e);
        }, 1));

    // IE9 RTM - XDomainRequest issued requests may abort if all event handlers
    // not specified
    // http://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified
    JS('', '#.onprogress = {}', xhr);
    JS('', '#.ontimeout = {}', xhr);
    JS('', '#.timeout = Number.MAX_VALUE', xhr);

    if (sendData != null) {
      JS('', '#.send(#)', xhr, sendData);
    } else {
      JS('', '#.send()', xhr);
    }

    return completer.future;
  }

  /**
   * Returns all response headers as a key-value map.
   *
   * Multiple values for the same header key can be combined into one,
   * separated by a comma and a space.
   *
   * See: http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method
   */
  Map<String, String> get responseHeaders {
    // from Closure's goog.net.Xhrio.getResponseHeaders.
    var headers = <String, String>{};
    var headersString = this.getAllResponseHeaders();
    if (headersString == null) {
      return headers;
    }
    var headersList = headersString.split('\r\n');
    for (var header in headersList) {
      if (header.isEmpty) {
        continue;
      }

      var splitIdx = header.indexOf(': ');
      if (splitIdx == -1) {
        continue;
      }
      var key = header.substring(0, splitIdx).toLowerCase();
      var value = header.substring(splitIdx + 2);
      if (headers.containsKey(key)) {
        headers[key] = '${headers[key]}, $value';
      } else {
        headers[key] = value;
      }
    }
    return headers;
  }

  /**
   * Specify the desired `url`, and `method` to use in making the request.
   *
   * By default the request is done asyncronously, with no user or password
   * authentication information. If `async` is false, the request will be send
   * synchronously.
   *
   * Calling `open` again on a currently active request is equivalent to
   * calling `abort`.
   *
   * Note: Most simple HTTP requests can be accomplished using the [getString],
   * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
   * `open` method is intended only for more complex HTTP requests where
   * finer-grained control is needed.
   */
  void open(String method, String url,
      {bool async, String user, String password}) native;

  // To suppress missing implicit constructor warnings.
  factory HttpRequest._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `readystatechange` events to event
   * handlers that are not necessarily instances of [HttpRequest].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> readyStateChangeEvent =
      const EventStreamProvider<Event>('readystatechange');

  /**
   * General constructor for any type of request (GET, POST, etc).
   *
   * This call is used in conjunction with [open]:
   *
   *     var request = new HttpRequest();
   *     request.open('GET', 'http://dartlang.org');
   *     request.onLoad.listen((event) => print(
   *         'Request complete ${event.target.reponseText}'));
   *     request.send();
   *
   * is the (more verbose) equivalent of
   *
   *     HttpRequest.getString('http://dartlang.org').then(
   *         (result) => print('Request complete: $result'));
   */
  factory HttpRequest() {
    return HttpRequest._create_1();
  }
  static HttpRequest _create_1() => JS('HttpRequest', 'new XMLHttpRequest()');

  static const int DONE = 4;

  static const int HEADERS_RECEIVED = 2;

  static const int LOADING = 3;

  static const int OPENED = 1;

  static const int UNSENT = 0;

  /**
   * Indicator of the current state of the request:
   *
   * <table>
   *   <tr>
   *     <td>Value</td>
   *     <td>State</td>
   *     <td>Meaning</td>
   *   </tr>
   *   <tr>
   *     <td>0</td>
   *     <td>unsent</td>
   *     <td><code>open()</code> has not yet been called</td>
   *   </tr>
   *   <tr>
   *     <td>1</td>
   *     <td>opened</td>
   *     <td><code>send()</code> has not yet been called</td>
   *   </tr>
   *   <tr>
   *     <td>2</td>
   *     <td>headers received</td>
   *     <td><code>sent()</code> has been called; response headers and <code>status</code> are available</td>
   *   </tr>
   *   <tr>
   *     <td>3</td> <td>loading</td> <td><code>responseText</code> holds some data</td>
   *   </tr>
   *   <tr>
   *     <td>4</td> <td>done</td> <td>request is complete</td>
   *   </tr>
   * </table>
   */
  final int readyState;

  /**
   * The data received as a reponse from the request.
   *
   * The data could be in the
   * form of a [String], [ByteBuffer], [Document], [Blob], or json (also a
   * [String]). `null` indicates request failure.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  dynamic get response => _convertNativeToDart_XHR_Response(this._get_response);
  @JSName('response')
  /**
   * The data received as a reponse from the request.
   *
   * The data could be in the
   * form of a [String], [ByteBuffer], [Document], [Blob], or json (also a
   * [String]). `null` indicates request failure.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Creates(
      'NativeByteBuffer|Blob|Document|=Object|JSExtendableArray|String|num')
  final dynamic _get_response;

  /**
   * The response in String form or empty String on failure.
   */
  final String responseText;

  /**
   * [String] telling the server the desired response format.
   *
   * Default is `String`.
   * Other options are one of 'arraybuffer', 'blob', 'document', 'json',
   * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
   * `responseType` is set while performing a synchronous request.
   *
   * See also: [MDN
   * responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype)
   */
  String responseType;

  @JSName('responseURL')
  final String responseUrl;

  @JSName('responseXML')
  /**
   * The request response, or null on failure.
   *
   * The response is processed as
   * `text/xml` stream, unless responseType = 'document' and the request is
   * synchronous.
   */
  final Document responseXml;

  /**
   * The HTTP result code from the request (200, 404, etc).
   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
   */
  final int status;

  /**
   * The request response string (such as \"200 OK\").
   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
   */
  final String statusText;

  /**
   * Length of time in milliseconds before a request is automatically
   * terminated.
   *
   * When the time has passed, a [TimeoutEvent] is dispatched.
   *
   * If [timeout] is set to 0, then the request will not time out.
   *
   * ## Other resources
   *
   * * [XMLHttpRequest.timeout](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-timeout)
   *   from MDN.
   * * [The timeout attribute](http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
   *   from W3C.
   */
  int timeout;

  /**
   * [EventTarget] that can hold listeners to track the progress of the request.
   * The events fired will be members of [HttpRequestUploadEvents].
   */
  @Unstable()
  final HttpRequestUpload upload;

  /**
   * True if cross-site requests should use credentials such as cookies
   * or authorization headers; false otherwise.
   *
   * This value is ignored for same-site requests.
   */
  bool withCredentials;

  /**
   * Stop the current request.
   *
   * The request can only be stopped if readyState is `HEADERS_RECEIVED` or
   * `LOADING`. If this method is not in the process of being sent, the method
   * has no effect.
   */
  void abort() native;

  /**
   * Retrieve all the response headers from a request.
   *
   * `null` if no headers have been received. For multipart requests,
   * `getAllResponseHeaders` will return the response headers for the current
   * part of the request.
   *
   * See also [HTTP response
   * headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)
   * for a list of common response headers.
   */
  @Unstable()
  String getAllResponseHeaders() native;

  /**
   * Return the response header named `header`, or null if not found.
   *
   * See also [HTTP response
   * headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)
   * for a list of common response headers.
   */
  @Unstable()
  String getResponseHeader(String name) native;

  /**
   * Specify a particular MIME type (such as `text/xml`) desired for the
   * response.
   *
   * This value must be set before the request has been sent. See also the list
   * of [IANA Official MIME types](https://www.iana.org/assignments/media-types/media-types.xhtml)
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void overrideMimeType(String mime) native;

  /**
   * Send the request with any given `data`.
   *
   * Note: Most simple HTTP requests can be accomplished using the [getString],
   * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
   * `send` method is intended only for more complex HTTP requests where
   * finer-grained control is needed.
   *
   * ## Other resources
   *
   * * [XMLHttpRequest.send](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
   *   from MDN.
   */
  void send([body_OR_data]) native;

  /**
   * Sets the value of an HTTP request header.
   *
   * This method should be called after the request is opened, but before
   * the request is sent.
   *
   * Multiple calls with the same header will combine all their values into a
   * single header.
   *
   * ## Other resources
   *
   * * [XMLHttpRequest.setRequestHeader](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#setRequestHeader())
   *   from MDN.
   * * [The setRequestHeader()
   *   method](http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method)
   *   from W3C.
   */
  void setRequestHeader(String name, String value) native;

  /// Stream of `readystatechange` events handled by this [HttpRequest].
/**
   * Event listeners to be notified every time the [HttpRequest]
   * object's `readyState` changes values.
   */
  Stream<Event> get onReadyStateChange => readyStateChangeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("XMLHttpRequestEventTarget")
class HttpRequestEventTarget extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory HttpRequestEventTarget._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `abort` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> abortEvent =
      const EventStreamProvider<ProgressEvent>('abort');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> errorEvent =
      const EventStreamProvider<ProgressEvent>('error');

  /**
   * Static factory designed to expose `load` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> loadEvent =
      const EventStreamProvider<ProgressEvent>('load');

  /**
   * Static factory designed to expose `loadend` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> loadEndEvent =
      const EventStreamProvider<ProgressEvent>('loadend');

  /**
   * Static factory designed to expose `loadstart` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> loadStartEvent =
      const EventStreamProvider<ProgressEvent>('loadstart');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> progressEvent =
      const EventStreamProvider<ProgressEvent>('progress');

  /**
   * Static factory designed to expose `timeout` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<ProgressEvent> timeoutEvent =
      const EventStreamProvider<ProgressEvent>('timeout');

  /// Stream of `abort` events handled by this [HttpRequestEventTarget].
  Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);

  /// Stream of `error` events handled by this [HttpRequestEventTarget].
  Stream<ProgressEvent> get onError => errorEvent.forTarget(this);

  /// Stream of `load` events handled by this [HttpRequestEventTarget].
  Stream<ProgressEvent> get onLoad => loadEvent.forTarget(this);

  /// Stream of `loadend` events handled by this [HttpRequestEventTarget].
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);

  /// Stream of `loadstart` events handled by this [HttpRequestEventTarget].
  Stream<ProgressEvent> get onLoadStart => loadStartEvent.forTarget(this);

  /// Stream of `progress` events handled by this [HttpRequestEventTarget].
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);

  /// Stream of `timeout` events handled by this [HttpRequestEventTarget].
  Stream<ProgressEvent> get onTimeout => timeoutEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("XMLHttpRequestUpload")
class HttpRequestUpload extends HttpRequestEventTarget {
  // To suppress missing implicit constructor warnings.
  factory HttpRequestUpload._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLIFrameElement")
class IFrameElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory IFrameElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory IFrameElement() => JS(
      'returns:IFrameElement;creates:IFrameElement;new:true',
      '#.createElement(#)',
      document,
      "iframe");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  IFrameElement.created() : super.created();

  String allow;

  bool allowFullscreen;

  bool allowPaymentRequest;

  WindowBase get contentWindow =>
      _convertNativeToDart_Window(this._get_contentWindow);
  @JSName('contentWindow')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_contentWindow;

  String csp;

  String height;

  String name;

  String referrerPolicy;

  final DomTokenList sandbox;

  String src;

  String srcdoc;

  String width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("IdleDeadline")
class IdleDeadline extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory IdleDeadline._() {
    throw new UnsupportedError("Not supported");
  }

  final bool didTimeout;

  double timeRemaining() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void IdleRequestCallback(IdleDeadline deadline);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ImageBitmap")
class ImageBitmap extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ImageBitmap._() {
    throw new UnsupportedError("Not supported");
  }

  final int height;

  final int width;

  void close() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ImageBitmapRenderingContext")
class ImageBitmapRenderingContext extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ImageBitmapRenderingContext._() {
    throw new UnsupportedError("Not supported");
  }

  final CanvasElement canvas;

  void transferFromImageBitmap(ImageBitmap bitmap) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ImageCapture")
class ImageCapture extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ImageCapture._() {
    throw new UnsupportedError("Not supported");
  }

  factory ImageCapture(MediaStreamTrack track) {
    return ImageCapture._create_1(track);
  }
  static ImageCapture _create_1(track) =>
      JS('ImageCapture', 'new ImageCapture(#)', track);

  final MediaStreamTrack track;

  Future<PhotoCapabilities> getPhotoCapabilities() =>
      promiseToFuture<PhotoCapabilities>(
          JS("", "#.getPhotoCapabilities()", this));

  Future<Map<String, dynamic>> getPhotoSettings() =>
      promiseToFutureAsMap(JS("", "#.getPhotoSettings()", this));

  Future<ImageBitmap> grabFrame() =>
      promiseToFuture<ImageBitmap>(JS("", "#.grabFrame()", this));

  Future setOptions(Map photoSettings) {
    var photoSettings_dict = convertDartToNative_Dictionary(photoSettings);
    return promiseToFuture(JS("", "#.setOptions(#)", this, photoSettings_dict));
  }

  Future<Blob> takePhoto([Map photoSettings]) {
    var photoSettings_dict = null;
    if (photoSettings != null) {
      photoSettings_dict = convertDartToNative_Dictionary(photoSettings);
    }
    return promiseToFuture<Blob>(
        JS("", "#.takePhoto(#)", this, photoSettings_dict));
  }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ImageData")
class ImageData extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ImageData._() {
    throw new UnsupportedError("Not supported");
  }

  factory ImageData(data_OR_sw, int sh_OR_sw, [int sh]) {
    if ((sh_OR_sw is int) && (data_OR_sw is int) && sh == null) {
      return ImageData._create_1(data_OR_sw, sh_OR_sw);
    }
    if ((sh_OR_sw is int) && (data_OR_sw is Uint8ClampedList) && sh == null) {
      return ImageData._create_2(data_OR_sw, sh_OR_sw);
    }
    if ((sh is int) && (sh_OR_sw is int) && (data_OR_sw is Uint8ClampedList)) {
      return ImageData._create_3(data_OR_sw, sh_OR_sw, sh);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static ImageData _create_1(data_OR_sw, sh_OR_sw) =>
      JS('ImageData', 'new ImageData(#,#)', data_OR_sw, sh_OR_sw);
  static ImageData _create_2(data_OR_sw, sh_OR_sw) =>
      JS('ImageData', 'new ImageData(#,#)', data_OR_sw, sh_OR_sw);
  static ImageData _create_3(data_OR_sw, sh_OR_sw, sh) =>
      JS('ImageData', 'new ImageData(#,#,#)', data_OR_sw, sh_OR_sw, sh);

  @Creates('NativeUint8ClampedList')
  @Returns('NativeUint8ClampedList')
  final Uint8ClampedList data;

  final int height;

  final int width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLImageElement")
class ImageElement extends HtmlElement implements CanvasImageSource {
  // To suppress missing implicit constructor warnings.
  factory ImageElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory ImageElement({String src, int width, int height}) {
    ImageElement e = JS('returns:ImageElement;creates:ImageElement;new:true',
        '#.createElement(#)', document, "img");
    if (src != null) e.src = src;
    if (width != null) e.width = width;
    if (height != null) e.height = height;
    return e;
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ImageElement.created() : super.created();

  String alt;

  String async;

  final bool complete;

  String crossOrigin;

  final String currentSrc;

  int height;

  bool isMap;

  final int naturalHeight;

  final int naturalWidth;

  String referrerPolicy;

  String sizes;

  String src;

  String srcset;

  String useMap;

  int width;

  Future decode() => promiseToFuture(JS("", "#.decode()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("InputDeviceCapabilities")
class InputDeviceCapabilities extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory InputDeviceCapabilities._() {
    throw new UnsupportedError("Not supported");
  }

  factory InputDeviceCapabilities([Map deviceInitDict]) {
    if (deviceInitDict != null) {
      var deviceInitDict_1 = convertDartToNative_Dictionary(deviceInitDict);
      return InputDeviceCapabilities._create_1(deviceInitDict_1);
    }
    return InputDeviceCapabilities._create_2();
  }
  static InputDeviceCapabilities _create_1(deviceInitDict) => JS(
      'InputDeviceCapabilities',
      'new InputDeviceCapabilities(#)',
      deviceInitDict);
  static InputDeviceCapabilities _create_2() =>
      JS('InputDeviceCapabilities', 'new InputDeviceCapabilities()');

  final bool firesTouchEvents;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLInputElement")
class InputElement extends HtmlElement
    implements
        HiddenInputElement,
        SearchInputElement,
        TextInputElement,
        UrlInputElement,
        TelephoneInputElement,
        EmailInputElement,
        PasswordInputElement,
        DateInputElement,
        MonthInputElement,
        WeekInputElement,
        TimeInputElement,
        LocalDateTimeInputElement,
        NumberInputElement,
        RangeInputElement,
        CheckboxInputElement,
        RadioButtonInputElement,
        FileUploadInputElement,
        SubmitButtonInputElement,
        ImageButtonInputElement,
        ResetButtonInputElement,
        ButtonInputElement {
  factory InputElement({String type}) {
    InputElement e = document.createElement("input");
    if (type != null) {
      try {
        // IE throws an exception for unknown types.
        e.type = type;
      } catch (_) {}
    }
    return e;
  }

  // To suppress missing implicit constructor warnings.
  factory InputElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  InputElement.created() : super.created();

  String accept;

  String alt;

  String autocapitalize;

  String autocomplete;

  bool autofocus;

  String capture;

  bool checked;

  bool defaultChecked;

  String defaultValue;

  String dirName;

  bool disabled;

  @Returns('FileList|Null')
  @Creates('FileList')
  List<File> files;

  final FormElement form;

  String formAction;

  String formEnctype;

  String formMethod;

  bool formNoValidate;

  String formTarget;

  int height;

  bool incremental;

  bool indeterminate;

  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> labels;

  final HtmlElement list;

  String max;

  int maxLength;

  String min;

  int minLength;

  bool multiple;

  String name;

  String pattern;

  String placeholder;

  bool readOnly;

  bool required;

  String selectionDirection;

  int selectionEnd;

  int selectionStart;

  int size;

  String src;

  String step;

  String type;

  final String validationMessage;

  final ValidityState validity;

  String value;

  DateTime get valueAsDate =>
      convertNativeToDart_DateTime(this._get_valueAsDate);
  @JSName('valueAsDate')
  @Creates('Null')
  final dynamic _get_valueAsDate;

  set valueAsDate(DateTime value) {
    this._set_valueAsDate = convertDartToNative_DateTime(value);
  }

  set _set_valueAsDate(/*dynamic*/ value) {
    JS("void", "#.valueAsDate = #", this, value);
  }

  num valueAsNumber;

  @JSName('webkitEntries')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final List<Entry> entries;

  @JSName('webkitdirectory')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  bool directory;

  int width;

  final bool willValidate;

  bool checkValidity() native;

  bool reportValidity() native;

  void select() native;

  void setCustomValidity(String error) native;

  void setRangeText(String replacement,
      {int start, int end, String selectionMode}) native;

  void setSelectionRange(int start, int end, [String direction]) native;

  void stepDown([int n]) native;

  void stepUp([int n]) native;
}

// Interfaces representing the InputElement APIs which are supported
// for the various types of InputElement. From:
// http://www.w3.org/html/wg/drafts/html/master/forms.html#the-input-element.

/**
 * Exposes the functionality common between all InputElement types.
 */
abstract class InputElementBase implements Element {
  bool autofocus;

  bool disabled;

  bool incremental;

  bool indeterminate;

  List<Node> get labels;

  String name;

  String get validationMessage;

  ValidityState get validity;

  String value;

  bool get willValidate;

  bool checkValidity();

  void setCustomValidity(String error);
}

/**
 * Hidden input which is not intended to be seen or edited by the user.
 */
abstract class HiddenInputElement implements InputElementBase {
  factory HiddenInputElement() => new InputElement(type: 'hidden');
}

/**
 * Base interface for all inputs which involve text editing.
 */
abstract class TextInputElementBase implements InputElementBase {
  String autocomplete;

  int maxLength;

  String pattern;

  String placeholder;

  bool readOnly;

  bool required;

  int size;

  void select();

  String selectionDirection;

  int selectionEnd;

  int selectionStart;

  void setSelectionRange(int start, int end, [String direction]);
}

/**
 * Similar to [TextInputElement], but on platforms where search is styled
 * differently this will get the search style.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class SearchInputElement implements TextInputElementBase {
  factory SearchInputElement() => new InputElement(type: 'search');

  String dirName;

  Element get list;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'search')).type == 'search';
  }
}

/**
 * A basic text input editor control.
 */
abstract class TextInputElement implements TextInputElementBase {
  factory TextInputElement() => new InputElement(type: 'text');

  String dirName;

  Element get list;
}

/**
 * A control for editing an absolute URL.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class UrlInputElement implements TextInputElementBase {
  factory UrlInputElement() => new InputElement(type: 'url');

  Element get list;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'url')).type == 'url';
  }
}

/**
 * Represents a control for editing a telephone number.
 *
 * This provides a single line of text with minimal formatting help since
 * there is a wide variety of telephone numbers.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class TelephoneInputElement implements TextInputElementBase {
  factory TelephoneInputElement() => new InputElement(type: 'tel');

  Element get list;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'tel')).type == 'tel';
  }
}

/**
 * An e-mail address or list of e-mail addresses.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class EmailInputElement implements TextInputElementBase {
  factory EmailInputElement() => new InputElement(type: 'email');

  String autocomplete;

  bool autofocus;

  Element get list;

  int maxLength;

  bool multiple;

  String pattern;

  String placeholder;

  bool readOnly;

  bool required;

  int size;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'email')).type == 'email';
  }
}

/**
 * Text with no line breaks (sensitive information).
 */
abstract class PasswordInputElement implements TextInputElementBase {
  factory PasswordInputElement() => new InputElement(type: 'password');
}

/**
 * Base interface for all input element types which involve ranges.
 */
abstract class RangeInputElementBase implements InputElementBase {
  Element get list;

  String max;

  String min;

  String step;

  num valueAsNumber;

  void stepDown([int n]);

  void stepUp([int n]);
}

/**
 * A date (year, month, day) with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
abstract class DateInputElement implements RangeInputElementBase {
  factory DateInputElement() => new InputElement(type: 'date');

  DateTime valueAsDate;

  bool readOnly;

  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'date')).type == 'date';
  }
}

/**
 * A date consisting of a year and a month with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
abstract class MonthInputElement implements RangeInputElementBase {
  factory MonthInputElement() => new InputElement(type: 'month');

  DateTime valueAsDate;

  bool readOnly;

  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'month')).type == 'month';
  }
}

/**
 * A date consisting of a week-year number and a week number with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
abstract class WeekInputElement implements RangeInputElementBase {
  factory WeekInputElement() => new InputElement(type: 'week');

  DateTime valueAsDate;

  bool readOnly;

  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'week')).type == 'week';
  }
}

/**
 * A time (hour, minute, seconds, fractional seconds) with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
abstract class TimeInputElement implements RangeInputElementBase {
  factory TimeInputElement() => new InputElement(type: 'time');

  DateTime valueAsDate;

  bool readOnly;

  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'time')).type == 'time';
  }
}

/**
 * A date and time (year, month, day, hour, minute, second, fraction of a
 * second) with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
abstract class LocalDateTimeInputElement implements RangeInputElementBase {
  factory LocalDateTimeInputElement() =>
      new InputElement(type: 'datetime-local');

  bool readOnly;

  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'datetime-local')).type == 'datetime-local';
  }
}

/**
 * A numeric editor control.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE)
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class NumberInputElement implements RangeInputElementBase {
  factory NumberInputElement() => new InputElement(type: 'number');

  String placeholder;

  bool readOnly;

  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'number')).type == 'number';
  }
}

/**
 * Similar to [NumberInputElement] but the browser may provide more optimal
 * styling (such as a slider control).
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE, '10')
abstract class RangeInputElement implements RangeInputElementBase {
  factory RangeInputElement() => new InputElement(type: 'range');

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'range')).type == 'range';
  }
}

/**
 * A boolean editor control.
 *
 * Note that if [indeterminate] is set then this control is in a third
 * indeterminate state.
 */
abstract class CheckboxInputElement implements InputElementBase {
  factory CheckboxInputElement() => new InputElement(type: 'checkbox');

  bool checked;

  bool required;
}

/**
 * A control that when used with other [ReadioButtonInputElement] controls
 * forms a radio button group in which only one control can be checked at a
 * time.
 *
 * Radio buttons are considered to be in the same radio button group if:
 *
 * * They are all of type 'radio'.
 * * They all have either the same [FormElement] owner, or no owner.
 * * Their name attributes contain the same name.
 */
abstract class RadioButtonInputElement implements InputElementBase {
  factory RadioButtonInputElement() => new InputElement(type: 'radio');

  bool checked;

  bool required;
}

/**
 * A control for picking files from the user's computer.
 */
abstract class FileUploadInputElement implements InputElementBase {
  factory FileUploadInputElement() => new InputElement(type: 'file');

  String accept;

  bool multiple;

  bool required;

  List<File> files;
}

/**
 * A button, which when clicked, submits the form.
 */
abstract class SubmitButtonInputElement implements InputElementBase {
  factory SubmitButtonInputElement() => new InputElement(type: 'submit');

  String formAction;

  String formEnctype;

  String formMethod;

  bool formNoValidate;

  String formTarget;
}

/**
 * Either an image which the user can select a coordinate to or a form
 * submit button.
 */
abstract class ImageButtonInputElement implements InputElementBase {
  factory ImageButtonInputElement() => new InputElement(type: 'image');

  String alt;

  String formAction;

  String formEnctype;

  String formMethod;

  bool formNoValidate;

  String formTarget;

  int height;

  String src;

  int width;
}

/**
 * A button, which when clicked, resets the form.
 */
abstract class ResetButtonInputElement implements InputElementBase {
  factory ResetButtonInputElement() => new InputElement(type: 'reset');
}

/**
 * A button, with no default behavior.
 */
abstract class ButtonInputElement implements InputElementBase {
  factory ButtonInputElement() => new InputElement(type: 'button');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("InstallEvent")
class InstallEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory InstallEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory InstallEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return InstallEvent._create_1(type, eventInitDict_1);
    }
    return InstallEvent._create_2(type);
  }
  static InstallEvent _create_1(type, eventInitDict) =>
      JS('InstallEvent', 'new InstallEvent(#,#)', type, eventInitDict);
  static InstallEvent _create_2(type) =>
      JS('InstallEvent', 'new InstallEvent(#)', type);

  void registerForeignFetch(Map options) {
    var options_1 = convertDartToNative_Dictionary(options);
    _registerForeignFetch_1(options_1);
    return;
  }

  @JSName('registerForeignFetch')
  void _registerForeignFetch_1(options) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("IntersectionObserver")
class IntersectionObserver extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory IntersectionObserver._() {
    throw new UnsupportedError("Not supported");
  }

  factory IntersectionObserver(IntersectionObserverCallback callback,
      [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return IntersectionObserver._create_1(callback, options_1);
    }
    return IntersectionObserver._create_2(callback);
  }
  static IntersectionObserver _create_1(callback, options) => JS(
      'IntersectionObserver',
      'new IntersectionObserver(#,#)',
      callback,
      options);
  static IntersectionObserver _create_2(callback) =>
      JS('IntersectionObserver', 'new IntersectionObserver(#)', callback);

  final Element root;

  final String rootMargin;

  final List<num> thresholds;

  void disconnect() native;

  void observe(Element target) native;

  List<IntersectionObserverEntry> takeRecords() native;

  void unobserve(Element target) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void IntersectionObserverCallback(
    List entries, IntersectionObserver observer);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("IntersectionObserverEntry")
class IntersectionObserverEntry extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory IntersectionObserverEntry._() {
    throw new UnsupportedError("Not supported");
  }

  final DomRectReadOnly boundingClientRect;

  final num intersectionRatio;

  final DomRectReadOnly intersectionRect;

  final bool isIntersecting;

  final DomRectReadOnly rootBounds;

  final Element target;

  final num time;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("InterventionReport")
class InterventionReport extends ReportBody {
  // To suppress missing implicit constructor warnings.
  factory InterventionReport._() {
    throw new UnsupportedError("Not supported");
  }

  final int lineNumber;

  final String message;

  final String sourceFile;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * An event that describes user interaction with the keyboard.
 *
 * The [type] of the event identifies what kind of interaction occurred.
 *
 * See also:
 *
 * * [KeyboardEvent](https://developer.mozilla.org/en/DOM/KeyboardEvent) at MDN.
 */
@Native("KeyboardEvent")
class KeyboardEvent extends UIEvent {
  /**
   * Programmatically create a KeyboardEvent.
   *
   * Due to browser differences, keyCode, charCode, or keyIdentifier values
   * cannot be specified in this base level constructor. This constructor
   * enables the user to programmatically create and dispatch a [KeyboardEvent],
   * but it will not contain any particular key content. For programmatically
   * creating keyboard events with specific key value contents, see the custom
   * Event [KeyEvent].
   */
  factory KeyboardEvent(String type,
      {Window view,
      bool canBubble: true,
      bool cancelable: true,
      int location,
      int keyLocation, // Legacy alias for location
      bool ctrlKey: false,
      bool altKey: false,
      bool shiftKey: false,
      bool metaKey: false}) {
    if (view == null) {
      view = window;
    }
    location ??= keyLocation ?? 1;
    KeyboardEvent e = document._createEvent("KeyboardEvent");
    e._initKeyboardEvent(type, canBubble, cancelable, view, "", location,
        ctrlKey, altKey, shiftKey, metaKey);
    return e;
  }

  void _initKeyboardEvent(
      String type,
      bool canBubble,
      bool cancelable,
      Window view,
      String keyIdentifier,
      int location,
      bool ctrlKey,
      bool altKey,
      bool shiftKey,
      bool metaKey) {
    if (JS('bool', 'typeof(#.initKeyEvent) == "function"', this)) {
      // initKeyEvent is only in Firefox (instead of initKeyboardEvent). It has
      // a slightly different signature, and allows you to specify keyCode and
      // charCode as the last two arguments, but we just set them as the default
      // since they can't be specified in other browsers.
      JS('void', '#.initKeyEvent(#, #, #, #, #, #, #, #, 0, 0)', this, type,
          canBubble, cancelable, view, ctrlKey, altKey, shiftKey, metaKey);
    } else {
      // initKeyboardEvent is for all other browsers.
      JS(
          'void',
          '#.initKeyboardEvent(#, #, #, #, #, #, #, #, #, #)',
          this,
          type,
          canBubble,
          cancelable,
          view,
          keyIdentifier,
          location,
          ctrlKey,
          altKey,
          shiftKey,
          metaKey);
    }
  }

  final int keyCode;

  final int charCode;

  int get which => _which;

  factory KeyboardEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return KeyboardEvent._create_1(type, eventInitDict_1);
    }
    return KeyboardEvent._create_2(type);
  }
  static KeyboardEvent _create_1(type, eventInitDict) =>
      JS('KeyboardEvent', 'new KeyboardEvent(#,#)', type, eventInitDict);
  static KeyboardEvent _create_2(type) =>
      JS('KeyboardEvent', 'new KeyboardEvent(#)', type);

  static const int DOM_KEY_LOCATION_LEFT = 0x01;

  static const int DOM_KEY_LOCATION_NUMPAD = 0x03;

  static const int DOM_KEY_LOCATION_RIGHT = 0x02;

  static const int DOM_KEY_LOCATION_STANDARD = 0x00;

  final bool altKey;

  @JSName('charCode')
  final int _charCode;

  final String code;

  final bool ctrlKey;

  final bool isComposing;

  final String key;

  @JSName('keyCode')
  final int _keyCode;

  final int location;

  final bool metaKey;

  final bool repeat;

  final bool shiftKey;

  bool getModifierState(String keyArg) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("KeyframeEffect")
class KeyframeEffect extends KeyframeEffectReadOnly {
  // To suppress missing implicit constructor warnings.
  factory KeyframeEffect._() {
    throw new UnsupportedError("Not supported");
  }

  factory KeyframeEffect(Element target, Object effect, [Object options]) {
    if (options != null) {
      return KeyframeEffect._create_1(target, effect, options);
    }
    return KeyframeEffect._create_2(target, effect);
  }
  static KeyframeEffect _create_1(target, effect, options) => JS(
      'KeyframeEffect', 'new KeyframeEffect(#,#,#)', target, effect, options);
  static KeyframeEffect _create_2(target, effect) =>
      JS('KeyframeEffect', 'new KeyframeEffect(#,#)', target, effect);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("KeyframeEffectReadOnly")
class KeyframeEffectReadOnly extends AnimationEffectReadOnly {
  // To suppress missing implicit constructor warnings.
  factory KeyframeEffectReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  factory KeyframeEffectReadOnly(Element target, Object effect,
      [Object options]) {
    if (options != null) {
      return KeyframeEffectReadOnly._create_1(target, effect, options);
    }
    return KeyframeEffectReadOnly._create_2(target, effect);
  }
  static KeyframeEffectReadOnly _create_1(target, effect, options) => JS(
      'KeyframeEffectReadOnly',
      'new KeyframeEffectReadOnly(#,#,#)',
      target,
      effect,
      options);
  static KeyframeEffectReadOnly _create_2(target, effect) => JS(
      'KeyframeEffectReadOnly',
      'new KeyframeEffectReadOnly(#,#)',
      target,
      effect);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLLIElement")
class LIElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory LIElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory LIElement() => JS('returns:LIElement;creates:LIElement;new:true',
      '#.createElement(#)', document, "li");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  LIElement.created() : super.created();

  int value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLLabelElement")
class LabelElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory LabelElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory LabelElement() => JS(
      'returns:LabelElement;creates:LabelElement;new:true',
      '#.createElement(#)',
      document,
      "label");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  LabelElement.created() : super.created();

  final HtmlElement control;

  final FormElement form;

  String htmlFor;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLLegendElement")
class LegendElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory LegendElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory LegendElement() => JS(
      'returns:LegendElement;creates:LegendElement;new:true',
      '#.createElement(#)',
      document,
      "legend");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  LegendElement.created() : super.created();

  final FormElement form;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("LinearAccelerationSensor")
class LinearAccelerationSensor extends Accelerometer {
  // To suppress missing implicit constructor warnings.
  factory LinearAccelerationSensor._() {
    throw new UnsupportedError("Not supported");
  }

  factory LinearAccelerationSensor([Map sensorOptions]) {
    if (sensorOptions != null) {
      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
      return LinearAccelerationSensor._create_1(sensorOptions_1);
    }
    return LinearAccelerationSensor._create_2();
  }
  static LinearAccelerationSensor _create_1(sensorOptions) => JS(
      'LinearAccelerationSensor',
      'new LinearAccelerationSensor(#)',
      sensorOptions);
  static LinearAccelerationSensor _create_2() =>
      JS('LinearAccelerationSensor', 'new LinearAccelerationSensor()');
}
// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLLinkElement")
class LinkElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory LinkElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory LinkElement() => JS(
      'returns:LinkElement;creates:LinkElement;new:true',
      '#.createElement(#)',
      document,
      "link");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  LinkElement.created() : super.created();

  String as;

  String crossOrigin;

  bool disabled;

  String href;

  String hreflang;

  final Document import;

  String integrity;

  String media;

  String referrerPolicy;

  String rel;

  final DomTokenList relList;

  String scope;

  final StyleSheet sheet;

  final DomTokenList sizes;

  String type;

  /// Checks if HTML imports are supported on the current platform.
  bool get supportsImport {
    return JS('bool', '("import" in #)', this);
  }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Location")
class Location extends Interceptor implements LocationBase {
  // To suppress missing implicit constructor warnings.
  factory Location._() {
    throw new UnsupportedError("Not supported");
  }

  @Returns('DomStringList|Null')
  @Creates('DomStringList')
  final List<String> ancestorOrigins;

  String hash;

  String host;

  String hostname;

  String href;

  String pathname;

  String port;

  String protocol;

  String search;

  TrustedUrl trustedHref;

  void assign([String url]) native;

  void reload() native;

  void replace(String url) native;

  String get origin {
    if (JS('bool', '("origin" in #)', this)) {
      return JS('String', '#.origin', this);
    }
    return '${this.protocol}//${this.host}';
  }

  String toString() => JS('String', 'String(#)', this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Magnetometer")
class Magnetometer extends Sensor {
  // To suppress missing implicit constructor warnings.
  factory Magnetometer._() {
    throw new UnsupportedError("Not supported");
  }

  factory Magnetometer([Map sensorOptions]) {
    if (sensorOptions != null) {
      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
      return Magnetometer._create_1(sensorOptions_1);
    }
    return Magnetometer._create_2();
  }
  static Magnetometer _create_1(sensorOptions) =>
      JS('Magnetometer', 'new Magnetometer(#)', sensorOptions);
  static Magnetometer _create_2() => JS('Magnetometer', 'new Magnetometer()');

  final num x;

  final num y;

  final num z;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLMapElement")
class MapElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MapElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory MapElement() => JS('returns:MapElement;creates:MapElement;new:true',
      '#.createElement(#)', document, "map");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MapElement.created() : super.created();

  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> areas;

  String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaCapabilities")
class MediaCapabilities extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaCapabilities._() {
    throw new UnsupportedError("Not supported");
  }

  Future<MediaCapabilitiesInfo> decodingInfo(Map configuration) {
    var configuration_dict = convertDartToNative_Dictionary(configuration);
    return promiseToFuture<MediaCapabilitiesInfo>(
        JS("", "#.decodingInfo(#)", this, configuration_dict));
  }

  Future<MediaCapabilitiesInfo> encodingInfo(Map configuration) {
    var configuration_dict = convertDartToNative_Dictionary(configuration);
    return promiseToFuture<MediaCapabilitiesInfo>(
        JS("", "#.encodingInfo(#)", this, configuration_dict));
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaCapabilitiesInfo")
class MediaCapabilitiesInfo extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaCapabilitiesInfo._() {
    throw new UnsupportedError("Not supported");
  }

  final bool powerEfficient;

  final bool smooth;

  final bool supported;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaDeviceInfo")
class MediaDeviceInfo extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaDeviceInfo._() {
    throw new UnsupportedError("Not supported");
  }

  final String deviceId;

  final String groupId;

  final String kind;

  final String label;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaDevices")
class MediaDevices extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaDevices._() {
    throw new UnsupportedError("Not supported");
  }

  Future<List<MediaDeviceInfo>> enumerateDevices() =>
      promiseToFuture<List<MediaDeviceInfo>>(
          JS("", "#.enumerateDevices()", this));

  Map getSupportedConstraints() {
    return convertNativeToDart_Dictionary(_getSupportedConstraints_1());
  }

  @JSName('getSupportedConstraints')
  _getSupportedConstraints_1() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("HTMLMediaElement")
class MediaElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MediaElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MediaElement.created() : super.created();

  static const int HAVE_CURRENT_DATA = 2;

  static const int HAVE_ENOUGH_DATA = 4;

  static const int HAVE_FUTURE_DATA = 3;

  static const int HAVE_METADATA = 1;

  static const int HAVE_NOTHING = 0;

  static const int NETWORK_EMPTY = 0;

  static const int NETWORK_IDLE = 1;

  static const int NETWORK_LOADING = 2;

  static const int NETWORK_NO_SOURCE = 3;

  final AudioTrackList audioTracks;

  bool autoplay;

  final TimeRanges buffered;

  bool controls;

  final DomTokenList controlsList;

  String crossOrigin;

  final String currentSrc;

  num currentTime;

  bool defaultMuted;

  num defaultPlaybackRate;

  bool disableRemotePlayback;

  final num duration;

  final bool ended;

  final MediaError error;

  bool loop;

  final MediaKeys mediaKeys;

  bool muted;

  final int networkState;

  final bool paused;

  num playbackRate;

  final TimeRanges played;

  String preload;

  final int readyState;

  final RemotePlayback remote;

  final TimeRanges seekable;

  final bool seeking;

  final String sinkId;

  String src;

  MediaStream srcObject;

  final TextTrackList textTracks;

  final VideoTrackList videoTracks;

  num volume;

  @JSName('webkitAudioDecodedByteCount')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final int audioDecodedByteCount;

  @JSName('webkitVideoDecodedByteCount')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final int videoDecodedByteCount;

  TextTrack addTextTrack(String kind, [String label, String language]) native;

  @Unstable()
  String canPlayType(String type, [String keySystem]) native;

  MediaStream captureStream() native;

  void load() native;

  void pause() native;

  Future play() => promiseToFuture(JS("", "#.play()", this));

  Future setMediaKeys(MediaKeys mediaKeys) =>
      promiseToFuture(JS("", "#.setMediaKeys(#)", this, mediaKeys));

  Future setSinkId(String sinkId) =>
      promiseToFuture(JS("", "#.setSinkId(#)", this, sinkId));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaEncryptedEvent")
class MediaEncryptedEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaEncryptedEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory MediaEncryptedEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MediaEncryptedEvent._create_1(type, eventInitDict_1);
    }
    return MediaEncryptedEvent._create_2(type);
  }
  static MediaEncryptedEvent _create_1(type, eventInitDict) => JS(
      'MediaEncryptedEvent',
      'new MediaEncryptedEvent(#,#)',
      type,
      eventInitDict);
  static MediaEncryptedEvent _create_2(type) =>
      JS('MediaEncryptedEvent', 'new MediaEncryptedEvent(#)', type);

  final ByteBuffer initData;

  final String initDataType;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("MediaError")
class MediaError extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaError._() {
    throw new UnsupportedError("Not supported");
  }

  static const int MEDIA_ERR_ABORTED = 1;

  static const int MEDIA_ERR_DECODE = 3;

  static const int MEDIA_ERR_NETWORK = 2;

  static const int MEDIA_ERR_SRC_NOT_SUPPORTED = 4;

  final int code;

  final String message;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaKeyMessageEvent")
class MediaKeyMessageEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyMessageEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory MediaKeyMessageEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return MediaKeyMessageEvent._create_1(type, eventInitDict_1);
  }
  static MediaKeyMessageEvent _create_1(type, eventInitDict) => JS(
      'MediaKeyMessageEvent',
      'new MediaKeyMessageEvent(#,#)',
      type,
      eventInitDict);

  final ByteBuffer message;

  final String messageType;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaKeySession")
class MediaKeySession extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaKeySession._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  Future<void> get closed => promiseToFuture<void>(JS("", "#.closed", this));

  final num expiration;

  final MediaKeyStatusMap keyStatuses;

  final String sessionId;

  Future close() => promiseToFuture(JS("", "#.close()", this));

  Future generateRequest(String initDataType, /*BufferSource*/ initData) =>
      promiseToFuture(
          JS("", "#.generateRequest(#, #)", this, initDataType, initData));

  Future load(String sessionId) =>
      promiseToFuture(JS("", "#.load(#)", this, sessionId));

  Future remove() => promiseToFuture(JS("", "#.remove()", this));

  @JSName('update')
  Future _update(/*BufferSource*/ response) native;

  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaKeyStatusMap")
class MediaKeyStatusMap extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyStatusMap._() {
    throw new UnsupportedError("Not supported");
  }

  final int size;

  Object get(/*BufferSource*/ keyId) native;

  bool has(/*BufferSource*/ keyId) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaKeySystemAccess")
class MediaKeySystemAccess extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaKeySystemAccess._() {
    throw new UnsupportedError("Not supported");
  }

  final String keySystem;

  Future createMediaKeys() =>
      promiseToFuture(JS("", "#.createMediaKeys()", this));

  Map getConfiguration() {
    return convertNativeToDart_Dictionary(_getConfiguration_1());
  }

  @JSName('getConfiguration')
  _getConfiguration_1() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaKeys")
class MediaKeys extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaKeys._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('createSession')
  MediaKeySession _createSession([String sessionType]) native;

  Future getStatusForPolicy(MediaKeysPolicy policy) =>
      promiseToFuture(JS("", "#.getStatusForPolicy(#)", this, policy));

  Future setServerCertificate(/*BufferSource*/ serverCertificate) =>
      promiseToFuture(
          JS("", "#.setServerCertificate(#)", this, serverCertificate));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaKeysPolicy")
class MediaKeysPolicy extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaKeysPolicy._() {
    throw new UnsupportedError("Not supported");
  }

  factory MediaKeysPolicy(Map init) {
    var init_1 = convertDartToNative_Dictionary(init);
    return MediaKeysPolicy._create_1(init_1);
  }
  static MediaKeysPolicy _create_1(init) =>
      JS('MediaKeysPolicy', 'new MediaKeysPolicy(#)', init);

  final String minHdcpVersion;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("MediaList")
class MediaList extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaList._() {
    throw new UnsupportedError("Not supported");
  }

  final int length;

  String mediaText;

  void appendMedium(String medium) native;

  void deleteMedium(String medium) native;

  String item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaMetadata")
class MediaMetadata extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaMetadata._() {
    throw new UnsupportedError("Not supported");
  }

  factory MediaMetadata([Map metadata]) {
    if (metadata != null) {
      var metadata_1 = convertDartToNative_Dictionary(metadata);
      return MediaMetadata._create_1(metadata_1);
    }
    return MediaMetadata._create_2();
  }
  static MediaMetadata _create_1(metadata) =>
      JS('MediaMetadata', 'new MediaMetadata(#)', metadata);
  static MediaMetadata _create_2() =>
      JS('MediaMetadata', 'new MediaMetadata()');

  String album;

  String artist;

  List artwork;

  String title;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("MediaQueryList")
class MediaQueryList extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaQueryList._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  final bool matches;

  final String media;

  void addListener(EventListener listener) native;

  void removeListener(EventListener listener) native;

  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaQueryListEvent")
class MediaQueryListEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaQueryListEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory MediaQueryListEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MediaQueryListEvent._create_1(type, eventInitDict_1);
    }
    return MediaQueryListEvent._create_2(type);
  }
  static MediaQueryListEvent _create_1(type, eventInitDict) => JS(
      'MediaQueryListEvent',
      'new MediaQueryListEvent(#,#)',
      type,
      eventInitDict);
  static MediaQueryListEvent _create_2(type) =>
      JS('MediaQueryListEvent', 'new MediaQueryListEvent(#)', type);

  final bool matches;

  final String media;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaRecorder")
class MediaRecorder extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaRecorder._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  static const EventStreamProvider<Event> pauseEvent =
      const EventStreamProvider<Event>('pause');

  factory MediaRecorder(MediaStream stream, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return MediaRecorder._create_1(stream, options_1);
    }
    return MediaRecorder._create_2(stream);
  }
  static MediaRecorder _create_1(stream, options) =>
      JS('MediaRecorder', 'new MediaRecorder(#,#)', stream, options);
  static MediaRecorder _create_2(stream) =>
      JS('MediaRecorder', 'new MediaRecorder(#)', stream);

  final int audioBitsPerSecond;

  final String mimeType;

  final String state;

  final MediaStream stream;

  final int videoBitsPerSecond;

  static bool isTypeSupported(String type) native;

  void pause() native;

  void requestData() native;

  void resume() native;

  void start([int timeslice]) native;

  void stop() native;

  Stream<Event> get onError => errorEvent.forTarget(this);

  Stream<Event> get onPause => pauseEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaSession")
class MediaSession extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaSession._() {
    throw new UnsupportedError("Not supported");
  }

  MediaMetadata metadata;

  String playbackState;

  void setActionHandler(String action, MediaSessionActionHandler handler)
      native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void MediaSessionActionHandler();
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MediaSettingsRange")
class MediaSettingsRange extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaSettingsRange._() {
    throw new UnsupportedError("Not supported");
  }

  final num max;

  final num min;

  final num step;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE, '11')
@Native("MediaSource")
class MediaSource extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaSource._() {
    throw new UnsupportedError("Not supported");
  }

  factory MediaSource() {
    return MediaSource._create_1();
  }
  static MediaSource _create_1() => JS('MediaSource', 'new MediaSource()');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.MediaSource)');

  final SourceBufferList activeSourceBuffers;

  num duration;

  final String readyState;

  final SourceBufferList sourceBuffers;

  SourceBuffer addSourceBuffer(String type) native;

  void clearLiveSeekableRange() native;

  void endOfStream([String error]) native;

  static bool isTypeSupported(String type) native;

  void removeSourceBuffer(SourceBuffer buffer) native;

  void setLiveSeekableRange(num start, num end) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("MediaStream")
class MediaStream extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaStream._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `addtrack` events to event
   * handlers that are not necessarily instances of [MediaStream].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> addTrackEvent =
      const EventStreamProvider<Event>('addtrack');

  /**
   * Static factory designed to expose `removetrack` events to event
   * handlers that are not necessarily instances of [MediaStream].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> removeTrackEvent =
      const EventStreamProvider<Event>('removetrack');

  factory MediaStream([stream_OR_tracks]) {
    if (stream_OR_tracks == null) {
      return MediaStream._create_1();
    }
    if ((stream_OR_tracks is MediaStream)) {
      return MediaStream._create_2(stream_OR_tracks);
    }
    if ((stream_OR_tracks is List<MediaStreamTrack>)) {
      return MediaStream._create_3(stream_OR_tracks);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static MediaStream _create_1() => JS('MediaStream', 'new MediaStream()');
  static MediaStream _create_2(stream_OR_tracks) =>
      JS('MediaStream', 'new MediaStream(#)', stream_OR_tracks);
  static MediaStream _create_3(stream_OR_tracks) =>
      JS('MediaStream', 'new MediaStream(#)', stream_OR_tracks);

  final bool active;

  final String id;

  void addTrack(MediaStreamTrack track) native;

  MediaStream clone() native;

  @Creates('JSExtendableArray|MediaStreamTrack')
  @Returns('JSExtendableArray')
  List<MediaStreamTrack> getAudioTracks() native;

  MediaStreamTrack getTrackById(String trackId) native;

  List<MediaStreamTrack> getTracks() native;

  @Creates('JSExtendableArray|MediaStreamTrack')
  @Returns('JSExtendableArray')
  List<MediaStreamTrack> getVideoTracks() native;

  void removeTrack(MediaStreamTrack track) native;

  /// Stream of `addtrack` events handled by this [MediaStream].
  Stream<Event> get onAddTrack => addTrackEvent.forTarget(this);

  /// Stream of `removetrack` events handled by this [MediaStream].
  Stream<Event> get onRemoveTrack => removeTrackEvent.forTarget(this);

  /**
   * Checks if the MediaStream APIs are supported on the current platform.
   *
   * See also:
   *
   * * [Navigator.getUserMedia]
   */
  static bool get supported => JS(
      'bool',
      '''!!(#.getUserMedia || #.webkitGetUserMedia ||
        #.mozGetUserMedia || #.msGetUserMedia)''',
      window.navigator,
      window.navigator,
      window.navigator,
      window.navigator);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("MediaStreamEvent")
class MediaStreamEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaStreamEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory MediaStreamEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MediaStreamEvent._create_1(type, eventInitDict_1);
    }
    return MediaStreamEvent._create_2(type);
  }
  static MediaStreamEvent _create_1(type, eventInitDict) =>
      JS('MediaStreamEvent', 'new MediaStreamEvent(#,#)', type, eventInitDict);
  static MediaStreamEvent _create_2(type) =>
      JS('MediaStreamEvent', 'new MediaStreamEvent(#)', type);

  /// Checks if this type is supported on the current platform.
  static bool get supported => Device.isEventTypeSupported('MediaStreamEvent');

  final MediaStream stream;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("MediaStreamTrack")
class MediaStreamTrack extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaStreamTrack._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `ended` events to event
   * handlers that are not necessarily instances of [MediaStreamTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> endedEvent =
      const EventStreamProvider<Event>('ended');

  /**
   * Static factory designed to expose `mute` events to event
   * handlers that are not necessarily instances of [MediaStreamTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> muteEvent =
      const EventStreamProvider<Event>('mute');

  /**
   * Static factory designed to expose `unmute` events to event
   * handlers that are not necessarily instances of [MediaStreamTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> unmuteEvent =
      const EventStreamProvider<Event>('unmute');

  String contentHint;

  bool enabled;

  final String id;

  final String kind;

  final String label;

  final bool muted;

  final String readyState;

  Future applyConstraints([Map constraints]) {
    var constraints_dict = null;
    if (constraints != null) {
      constraints_dict = convertDartToNative_Dictionary(constraints);
    }
    return promiseToFuture(
        JS("", "#.applyConstraints(#)", this, constraints_dict));
  }

  MediaStreamTrack clone() native;

  Map getCapabilities() {
    return convertNativeToDart_Dictionary(_getCapabilities_1());
  }

  @JSName('getCapabilities')
  _getCapabilities_1() native;

  Map getConstraints() {
    return convertNativeToDart_Dictionary(_getConstraints_1());
  }

  @JSName('getConstraints')
  _getConstraints_1() native;

  Map getSettings() {
    return convertNativeToDart_Dictionary(_getSettings_1());
  }

  @JSName('getSettings')
  _getSettings_1() native;

  void stop() native;

  /// Stream of `ended` events handled by this [MediaStreamTrack].
  Stream<Event> get onEnded => endedEvent.forTarget(this);

  /// Stream of `mute` events handled by this [MediaStreamTrack].
  Stream<Event> get onMute => muteEvent.forTarget(this);

  /// Stream of `unmute` events handled by this [MediaStreamTrack].
  Stream<Event> get onUnmute => unmuteEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("MediaStreamTrackEvent")
class MediaStreamTrackEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaStreamTrackEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory MediaStreamTrackEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return MediaStreamTrackEvent._create_1(type, eventInitDict_1);
  }
  static MediaStreamTrackEvent _create_1(type, eventInitDict) => JS(
      'MediaStreamTrackEvent',
      'new MediaStreamTrackEvent(#,#)',
      type,
      eventInitDict);

  /// Checks if this type is supported on the current platform.
  static bool get supported =>
      Device.isEventTypeSupported('MediaStreamTrackEvent');

  final MediaStreamTrack track;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MemoryInfo")
class MemoryInfo extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MemoryInfo._() {
    throw new UnsupportedError("Not supported");
  }

  final int jsHeapSizeLimit;

  final int totalJSHeapSize;

  final int usedJSHeapSize;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * An HTML <menu> element.
 *
 * A <menu> element represents an unordered list of menu commands.
 *
 * See also:
 *
 *  * [Menu Element](https://developer.mozilla.org/en-US/docs/HTML/Element/menu) from MDN.
 *  * [Menu Element](http://www.w3.org/TR/html5/the-menu-element.html#the-menu-element) from the W3C.
 */
@Native("HTMLMenuElement")
class MenuElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MenuElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory MenuElement() => JS(
      'returns:MenuElement;creates:MenuElement;new:true',
      '#.createElement(#)',
      document,
      "menu");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MenuElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void MessageCallback(Map message);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("MessageChannel")
class MessageChannel extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MessageChannel._() {
    throw new UnsupportedError("Not supported");
  }

  factory MessageChannel() {
    return MessageChannel._create_1();
  }
  static MessageChannel _create_1() =>
      JS('MessageChannel', 'new MessageChannel()');

  final MessagePort port1;

  final MessagePort port2;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Native("MessageEvent")
class MessageEvent extends Event {
  factory MessageEvent(String type,
      {bool canBubble: false,
      bool cancelable: false,
      Object data,
      String origin,
      String lastEventId,
      Window source,
      List<MessagePort> messagePorts: const []}) {
    if (source == null) {
      source = window;
    }
    if (!Device.isIE) {
      // TODO: This if check should be removed once IE
      // implements the constructor.
      return JS(
          'MessageEvent',
          'new MessageEvent(#, {bubbles: #, cancelable: #, data: #, origin: #, lastEventId: #, source: #, ports: #})',
          type,
          canBubble,
          cancelable,
          data,
          origin,
          lastEventId,
          source,
          messagePorts);
    }
    MessageEvent event = document._createEvent("MessageEvent");
    event._initMessageEvent(type, canBubble, cancelable, data, origin,
        lastEventId, source, messagePorts);
    return event;
  }

  // TODO(alanknight): This really should be generated by the
  // _OutputConversion in the systemnative.py script, but that doesn't
  // use those conversions right now, so do this as a one-off.
  dynamic get data => convertNativeToDart_SerializedScriptValue(this._get_data);

  @JSName('data')
  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final dynamic _get_data;

  factory MessageEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MessageEvent._create_1(type, eventInitDict_1);
    }
    return MessageEvent._create_2(type);
  }
  static MessageEvent _create_1(type, eventInitDict) =>
      JS('MessageEvent', 'new MessageEvent(#,#)', type, eventInitDict);
  static MessageEvent _create_2(type) =>
      JS('MessageEvent', 'new MessageEvent(#)', type);

  @Unstable()
  final String lastEventId;

  final String origin;

  EventTarget get source => _convertNativeToDart_EventTarget(this._get_source);
  @JSName('source')
  @Creates('Null')
  @Returns('EventTarget|=Object')
  final dynamic _get_source;

  final String suborigin;

  void _initMessageEvent(
      String typeArg,
      bool canBubbleArg,
      bool cancelableArg,
      Object dataArg,
      String originArg,
      String lastEventIdArg,
      EventTarget sourceArg,
      List<MessagePort> portsArg) {
    var sourceArg_1 = _convertDartToNative_EventTarget(sourceArg);
    _initMessageEvent_1(typeArg, canBubbleArg, cancelableArg, dataArg,
        originArg, lastEventIdArg, sourceArg_1, portsArg);
    return;
  }

  @JSName('initMessageEvent')
  void _initMessageEvent_1(typeArg, canBubbleArg, cancelableArg, dataArg,
      originArg, lastEventIdArg, sourceArg, List<MessagePort> portsArg) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Unstable()
@Native("MessagePort")
class MessagePort extends EventTarget {
  void addEventListener(String type, EventListener listener,
      [bool useCapture]) {
    // Messages posted to ports are initially paused, allowing listeners to be
    // setup, start() needs to be explicitly invoked to begin handling messages.
    if (type == 'message') {
      _start();
    }

    super.addEventListener(type, listener, useCapture);
  }

  // To suppress missing implicit constructor warnings.
  factory MessagePort._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [MessagePort].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  void close() native;

  void postMessage(/*any*/ message, [List<Object> transfer]) {
    if (transfer != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, transfer);
      return;
    }
    var message_1 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_1);
    return;
  }

  @JSName('postMessage')
  void _postMessage_1(message, List<Object> transfer) native;
  @JSName('postMessage')
  void _postMessage_2(message) native;

  @JSName('start')
  void _start() native;

  /// Stream of `message` events handled by this [MessagePort].
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLMetaElement")
class MetaElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MetaElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory MetaElement() => JS(
      'returns:MetaElement;creates:MetaElement;new:true',
      '#.createElement(#)',
      document,
      "meta");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MetaElement.created() : super.created();

  String content;

  String httpEquiv;

  String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Metadata")
class Metadata extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Metadata._() {
    throw new UnsupportedError("Not supported");
  }

  DateTime get modificationTime =>
      convertNativeToDart_DateTime(this._get_modificationTime);
  @JSName('modificationTime')
  @Creates('Null')
  final dynamic _get_modificationTime;

  final int size;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void MetadataCallback(Metadata metadata);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
@Native("HTMLMeterElement")
class MeterElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MeterElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory MeterElement() => document.createElement("meter");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MeterElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('meter');

  num high;

  @Unstable()
  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> labels;

  num low;

  num max;

  num min;

  num optimum;

  num value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MIDIAccess")
class MidiAccess extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MidiAccess._() {
    throw new UnsupportedError("Not supported");
  }

  final MidiInputMap inputs;

  final MidiOutputMap outputs;

  final bool sysexEnabled;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MIDIConnectionEvent")
class MidiConnectionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MidiConnectionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory MidiConnectionEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MidiConnectionEvent._create_1(type, eventInitDict_1);
    }
    return MidiConnectionEvent._create_2(type);
  }
  static MidiConnectionEvent _create_1(type, eventInitDict) => JS(
      'MidiConnectionEvent',
      'new MIDIConnectionEvent(#,#)',
      type,
      eventInitDict);
  static MidiConnectionEvent _create_2(type) =>
      JS('MidiConnectionEvent', 'new MIDIConnectionEvent(#)', type);

  final MidiPort port;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MIDIInput")
class MidiInput extends MidiPort {
  // To suppress missing implicit constructor warnings.
  factory MidiInput._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `midimessage` events to event
   * handlers that are not necessarily instances of [MidiInput].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MidiMessageEvent> midiMessageEvent =
      const EventStreamProvider<MidiMessageEvent>('midimessage');

  /// Stream of `midimessage` events handled by this [MidiInput].
  Stream<MidiMessageEvent> get onMidiMessage =>
      midiMessageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MIDIInputMap")
class MidiInputMap extends Interceptor with MapMixin<String, dynamic> {
  // To suppress missing implicit constructor warnings.
  factory MidiInputMap._() {
    throw new UnsupportedError("Not supported");
  }

  Map _getItem(String key) =>
      convertNativeToDart_Dictionary(JS('', '#.get(#)', this, key));

  void addAll(Map<String, dynamic> other) {
    throw new UnsupportedError("Not supported");
  }

  bool containsValue(dynamic value) => values.any((e) => e == value);

  bool containsKey(dynamic key) => _getItem(key) != null;

  Map operator [](dynamic key) => _getItem(key);

  void forEach(void f(String key, dynamic value)) {
    var entries = JS('', '#.entries()', this);
    while (true) {
      var entry = JS('', '#.next()', entries);
      if (JS('bool', '#.done', entry)) return;
      f(JS('String', '#.value[0]', entry),
          convertNativeToDart_Dictionary(JS('', '#.value[1]', entry)));
    }
  }

  Iterable<String> get keys {
    final keys = <String>[];
    forEach((k, v) => keys.add(k));
    return keys;
  }

  Iterable<Map> get values {
    final values = <Map>[];
    forEach((k, v) => values.add(v));
    return values;
  }

  int get length => JS('int', '#.size', this);

  bool get isEmpty => length == 0;

  bool get isNotEmpty => !isEmpty;

  void operator []=(String key, dynamic value) {
    throw new UnsupportedError("Not supported");
  }

  dynamic putIfAbsent(String key, dynamic ifAbsent()) {
    throw new UnsupportedError("Not supported");
  }

  String remove(dynamic key) {
    throw new UnsupportedError("Not supported");
  }

  void clear() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MIDIMessageEvent")
class MidiMessageEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MidiMessageEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory MidiMessageEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MidiMessageEvent._create_1(type, eventInitDict_1);
    }
    return MidiMessageEvent._create_2(type);
  }
  static MidiMessageEvent _create_1(type, eventInitDict) =>
      JS('MidiMessageEvent', 'new MIDIMessageEvent(#,#)', type, eventInitDict);
  static MidiMessageEvent _create_2(type) =>
      JS('MidiMessageEvent', 'new MIDIMessageEvent(#)', type);

  final Uint8List data;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MIDIOutput")
class MidiOutput extends MidiPort {
  // To suppress missing implicit constructor warnings.
  factory MidiOutput._() {
    throw new UnsupportedError("Not supported");
  }

  void send(Uint8List data, [num timestamp]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MIDIOutputMap")
class MidiOutputMap extends Interceptor with MapMixin<String, dynamic> {
  // To suppress missing implicit constructor warnings.
  factory MidiOutputMap._() {
    throw new UnsupportedError("Not supported");
  }

  Map _getItem(String key) =>
      convertNativeToDart_Dictionary(JS('', '#.get(#)', this, key));

  void addAll(Map<String, dynamic> other) {
    throw new UnsupportedError("Not supported");
  }

  bool containsValue(dynamic value) => values.any((e) => e == value);

  bool containsKey(dynamic key) => _getItem(key) != null;

  Map operator [](dynamic key) => _getItem(key);

  void forEach(void f(String key, dynamic value)) {
    var entries = JS('', '#.entries()', this);
    while (true) {
      var entry = JS('', '#.next()', entries);
      if (JS('bool', '#.done', entry)) return;
      f(JS('String', '#.value[0]', entry),
          convertNativeToDart_Dictionary(JS('', '#.value[1]', entry)));
    }
  }

  Iterable<String> get keys {
    final keys = <String>[];
    forEach((k, v) => keys.add(k));
    return keys;
  }

  Iterable<Map> get values {
    final values = <Map>[];
    forEach((k, v) => values.add(v));
    return values;
  }

  int get length => JS('int', '#.size', this);

  bool get isEmpty => length == 0;

  bool get isNotEmpty => !isEmpty;

  void operator []=(String key, dynamic value) {
    throw new UnsupportedError("Not supported");
  }

  dynamic putIfAbsent(String key, dynamic ifAbsent()) {
    throw new UnsupportedError("Not supported");
  }

  String remove(dynamic key) {
    throw new UnsupportedError("Not supported");
  }

  void clear() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MIDIPort")
class MidiPort extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MidiPort._() {
    throw new UnsupportedError("Not supported");
  }

  final String connection;

  final String id;

  final String manufacturer;

  final String name;

  final String state;

  final String type;

  final String version;

  Future close() => promiseToFuture(JS("", "#.close()", this));

  Future open() => promiseToFuture(JS("", "#.open()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MimeType")
class MimeType extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MimeType._() {
    throw new UnsupportedError("Not supported");
  }

  final String description;

  final Plugin enabledPlugin;

  final String suffixes;

  final String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MimeTypeArray")
class MimeTypeArray extends Interceptor
    with ListMixin<MimeType>, ImmutableListMixin<MimeType>
    implements List<MimeType>, JavaScriptIndexingBehavior<MimeType> {
  // To suppress missing implicit constructor warnings.
  factory MimeTypeArray._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  MimeType operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("MimeType", "#[#]", this, index);
  }

  void operator []=(int index, MimeType value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<MimeType> mixins.
  // MimeType is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  MimeType get first {
    if (this.length > 0) {
      return JS('MimeType', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  MimeType get last {
    int len = this.length;
    if (len > 0) {
      return JS('MimeType', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  MimeType get single {
    int len = this.length;
    if (len == 1) {
      return JS('MimeType', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  MimeType elementAt(int index) => this[index];
  // -- end List<MimeType> mixins.

  MimeType item(int index) native;

  MimeType namedItem(String name) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("HTMLModElement")
class ModElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ModElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ModElement.created() : super.created();

  String cite;

  String dateTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void MojoWatchCallback(int result);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MouseEvent,DragEvent")
class MouseEvent extends UIEvent {
  factory MouseEvent(String type,
      {Window view,
      int detail: 0,
      int screenX: 0,
      int screenY: 0,
      int clientX: 0,
      int clientY: 0,
      int button: 0,
      bool canBubble: true,
      bool cancelable: true,
      bool ctrlKey: false,
      bool altKey: false,
      bool shiftKey: false,
      bool metaKey: false,
      EventTarget relatedTarget}) {
    if (view == null) {
      view = window;
    }
    MouseEvent event = document._createEvent('MouseEvent');
    event._initMouseEvent(
        type,
        canBubble,
        cancelable,
        view,
        detail,
        screenX,
        screenY,
        clientX,
        clientY,
        ctrlKey,
        altKey,
        shiftKey,
        metaKey,
        button,
        relatedTarget);
    return event;
  }

  factory MouseEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MouseEvent._create_1(type, eventInitDict_1);
    }
    return MouseEvent._create_2(type);
  }
  static MouseEvent _create_1(type, eventInitDict) =>
      JS('MouseEvent', 'new MouseEvent(#,#)', type, eventInitDict);
  static MouseEvent _create_2(type) =>
      JS('MouseEvent', 'new MouseEvent(#)', type);

  final bool altKey;

  final int button;

  final int buttons;

  @JSName('clientX')
  final num _clientX;

  @JSName('clientY')
  final num _clientY;

  final bool ctrlKey;

  /**
   * The nonstandard way to access the element that the mouse comes
   * from in the case of a `mouseover` event.
   *
   * This member is deprecated and not cross-browser compatible; use
   * relatedTarget to get the same information in the standard way.
   */
  @deprecated
  final Node fromElement;

  @JSName('layerX')
  final int _layerX;

  @JSName('layerY')
  final int _layerY;

  final bool metaKey;

  @JSName('movementX')
  final int _movementX;

  @JSName('movementY')
  final int _movementY;

  @JSName('pageX')
  final num _pageX;

  @JSName('pageY')
  final num _pageY;

  final String region;

  EventTarget get relatedTarget =>
      _convertNativeToDart_EventTarget(this._get_relatedTarget);
  @JSName('relatedTarget')
  @Creates('Node')
  @Returns('EventTarget|=Object')
  final dynamic _get_relatedTarget;

  @JSName('screenX')
  final num _screenX;

  @JSName('screenY')
  final num _screenY;

  final bool shiftKey;

  /**
   * The nonstandard way to access the element that the mouse goes
   * to in the case of a `mouseout` event.
   *
   * This member is deprecated and not cross-browser compatible; use
   * relatedTarget to get the same information in the standard way.
   */
  @deprecated
  final Node toElement;

  bool getModifierState(String keyArg) native;

  void _initMouseEvent(
      String type,
      bool bubbles,
      bool cancelable,
      Window view,
      int detail,
      int screenX,
      int screenY,
      int clientX,
      int clientY,
      bool ctrlKey,
      bool altKey,
      bool shiftKey,
      bool metaKey,
      int button,
      EventTarget relatedTarget) {
    var relatedTarget_1 = _convertDartToNative_EventTarget(relatedTarget);
    _initMouseEvent_1(
        type,
        bubbles,
        cancelable,
        view,
        detail,
        screenX,
        screenY,
        clientX,
        clientY,
        ctrlKey,
        altKey,
        shiftKey,
        metaKey,
        button,
        relatedTarget_1);
    return;
  }

  @JSName('initMouseEvent')
  void _initMouseEvent_1(
      type,
      bubbles,
      cancelable,
      Window view,
      detail,
      screenX,
      screenY,
      clientX,
      clientY,
      ctrlKey,
      altKey,
      shiftKey,
      metaKey,
      button,
      relatedTarget) native;

  Point get client => new Point(_clientX, _clientY);

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  Point get movement => new Point(_movementX, _movementY);

  /**
   * The coordinates of the mouse pointer in target node coordinates.
   *
   * This value may vary between platforms if the target node moves
   * after the event has fired or if the element has CSS transforms affecting
   * it.
   */
  Point get offset {
    if (JS('bool', '!!#.offsetX', this)) {
      var x = JS('int', '#.offsetX', this);
      var y = JS('int', '#.offsetY', this);
      return new Point(x, y);
    } else {
      // Firefox does not support offsetX.
      if (!(this.target is Element)) {
        throw new UnsupportedError('offsetX is only supported on elements');
      }
      Element target = this.target;
      var point = (this.client - target.getBoundingClientRect().topLeft);
      return new Point(point.x.toInt(), point.y.toInt());
    }
  }

  Point get screen => new Point(_screenX, _screenY);

  Point get layer => new Point(_layerX, _layerY);

  Point get page => new Point(_pageX, _pageY);

  DataTransfer get dataTransfer =>
      JS('DataTransfer', "#['dataTransfer']", this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void MutationCallback(List mutations, MutationObserver observer);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents
@deprecated
@Native("MutationEvent")
class MutationEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MutationEvent._() {
    throw new UnsupportedError("Not supported");
  }

  static const int ADDITION = 2;

  static const int MODIFICATION = 1;

  static const int REMOVAL = 3;

  final int attrChange;

  final String attrName;

  final String newValue;

  final String prevValue;

  final Node relatedNode;

  void initMutationEvent(
      String type,
      bool bubbles,
      bool cancelable,
      Node relatedNode,
      String prevValue,
      String newValue,
      String attrName,
      int attrChange) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("MutationObserver,WebKitMutationObserver")
class MutationObserver extends Interceptor {
  void disconnect() native;

  void _observe(Node target, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      _observe_1(target, options_1);
      return;
    }
    _observe_2(target);
    return;
  }

  @JSName('observe')
  void _observe_1(Node target, options) native;
  @JSName('observe')
  void _observe_2(Node target) native;

  List<MutationRecord> takeRecords() native;

  /**
   * Checks to see if the mutation observer API is supported on the current
   * platform.
   */
  static bool get supported {
    return JS(
        'bool', '!!(window.MutationObserver || window.WebKitMutationObserver)');
  }

  /**
   * Observes the target for the specified changes.
   *
   * Some requirements for the optional parameters:
   *
   * * Either childList, attributes or characterData must be true.
   * * If attributeOldValue is true then attributes must also be true.
   * * If attributeFilter is specified then attributes must be true.
   * * If characterDataOldValue is true then characterData must be true.
   */
  void observe(Node target,
      {bool childList,
      bool attributes,
      bool characterData,
      bool subtree,
      bool attributeOldValue,
      bool characterDataOldValue,
      List<String> attributeFilter}) {
    // Parse options into map of known type.
    var parsedOptions = _createDict();

    // Override options passed in the map with named optional arguments.
    override(key, value) {
      if (value != null) _add(parsedOptions, key, value);
    }

    override('childList', childList);
    override('attributes', attributes);
    override('characterData', characterData);
    override('subtree', subtree);
    override('attributeOldValue', attributeOldValue);
    override('characterDataOldValue', characterDataOldValue);
    if (attributeFilter != null) {
      override('attributeFilter', _fixupList(attributeFilter));
    }

    _call(target, parsedOptions);
  }

  // TODO: Change to a set when const Sets are available.
  static final _boolKeys = const {
    'childList': true,
    'attributes': true,
    'characterData': true,
    'subtree': true,
    'attributeOldValue': true,
    'characterDataOldValue': true
  };

  static _createDict() => JS('var', '{}');
  static _add(m, String key, value) {
    JS('void', '#[#] = #', m, key, value);
  }

  static _fixupList(list) => list; // TODO: Ensure is a JavaScript Array.

  // Call native function with no conversions.
  @JSName('observe')
  void _call(target, options) native;

  factory MutationObserver(MutationCallback callback) {
    // Dummy statement to mark types as instantiated.
    JS('MutationObserver|MutationRecord', '0');

    return JS(
        'MutationObserver',
        'new(window.MutationObserver||window.WebKitMutationObserver||'
        'window.MozMutationObserver)(#)',
        convertDartClosureToJS(_wrapBinaryZone(callback), 2));
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MutationRecord")
class MutationRecord extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MutationRecord._() {
    throw new UnsupportedError("Not supported");
  }

  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> addedNodes;

  final String attributeName;

  final String attributeNamespace;

  final Node nextSibling;

  final String oldValue;

  final Node previousSibling;

  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> removedNodes;

  final Node target;

  final String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NavigationPreloadManager")
class NavigationPreloadManager extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigationPreloadManager._() {
    throw new UnsupportedError("Not supported");
  }

  Future disable() => promiseToFuture(JS("", "#.disable()", this));

  Future enable() => promiseToFuture(JS("", "#.enable()", this));

  Future<Map<String, dynamic>> getState() =>
      promiseToFutureAsMap(JS("", "#.getState()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Navigator")
class Navigator extends NavigatorConcurrentHardware
    implements
        NavigatorCookies,
        NavigatorLanguage,
        NavigatorOnLine,
        NavigatorAutomationInformation,
        NavigatorID {
  List<Gamepad> getGamepads() {
    var gamepadList = _getGamepads();

    // If no prototype we need one for the world to hookup to the proper Dart class.
    var jsProto = JS('', '#.prototype', gamepadList);
    if (jsProto == null) {
      JS('', '#.prototype = Object.create(null)', gamepadList);
    }

    applyExtension('GamepadList', gamepadList);
    return gamepadList;
  }

  String get language =>
      JS('String', '#.language || #.userLanguage', this, this);

  /**
   * Gets a stream (video and or audio) from the local computer.
   *
   * Use [MediaStream.supported] to check if this is supported by the current
   * platform. The arguments `audio` and `video` default to `false` (stream does
   * not use audio or video, respectively).
   *
   * Simple example usage:
   *
   *     window.navigator.getUserMedia(audio: true, video: true).then((stream) {
   *       var video = new VideoElement()
   *         ..autoplay = true
   *         ..src = Url.createObjectUrlFromStream(stream);
   *       document.body.append(video);
   *     });
   *
   * The user can also pass in Maps to the audio or video parameters to specify
   * mandatory and optional constraints for the media stream. Not passing in a
   * map, but passing in `true` will provide a MediaStream with audio or
   * video capabilities, but without any additional constraints. The particular
   * constraint names for audio and video are still in flux, but as of this
   * writing, here is an example providing more constraints.
   *
   *     window.navigator.getUserMedia(
   *         audio: true,
   *         video: {'mandatory':
   *                    { 'minAspectRatio': 1.333, 'maxAspectRatio': 1.334 },
   *                 'optional':
   *                    [{ 'minFrameRate': 60 },
   *                     { 'maxWidth': 640 }]
   *     });
   *
   * See also:
   * * [MediaStream.supported]
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  Future<MediaStream> getUserMedia({audio: false, video: false}) {
    var completer = new Completer<MediaStream>();
    var options = {'audio': audio, 'video': video};
    _ensureGetUserMedia();
    this._getUserMedia(convertDartToNative_SerializedScriptValue(options),
        (stream) {
      completer.complete(stream);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  _ensureGetUserMedia() {
    if (JS('bool', '!(#.getUserMedia)', this)) {
      JS(
          'void',
          '#.getUserMedia = '
          '(#.getUserMedia || #.webkitGetUserMedia || #.mozGetUserMedia ||'
          '#.msGetUserMedia)',
          this,
          this,
          this,
          this,
          this);
    }
  }

  @JSName('getUserMedia')
  void _getUserMedia(options, _NavigatorUserMediaSuccessCallback success,
      _NavigatorUserMediaErrorCallback error) native;

  // To suppress missing implicit constructor warnings.
  factory Navigator._() {
    throw new UnsupportedError("Not supported");
  }

  final _BudgetService budget;

  final _Clipboard clipboard;

  final NetworkInformation connection;

  final CredentialsContainer credentials;

  final num deviceMemory;

  final String doNotTrack;

  @Unstable()
  final Geolocation geolocation;

  final int maxTouchPoints;

  final MediaCapabilities mediaCapabilities;

  final MediaDevices mediaDevices;

  final MediaSession mediaSession;

  final MimeTypeArray mimeTypes;

  final _NFC nfc;

  final Permissions permissions;

  final Presentation presentation;

  @Unstable()
  final String productSub;

  final ServiceWorkerContainer serviceWorker;

  final StorageManager storage;

  @Unstable()
  final String vendor;

  @Unstable()
  final String vendorSub;

  final VR vr;

  @JSName('webkitPersistentStorage')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final DeprecatedStorageQuota persistentStorage;

  @JSName('webkitTemporaryStorage')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final DeprecatedStorageQuota temporaryStorage;

  void cancelKeyboardLock() native;

  Future getBattery() => promiseToFuture(JS("", "#.getBattery()", this));

  @JSName('getGamepads')
  @Returns('_GamepadList|Null')
  @Creates('_GamepadList')
  List<Gamepad> _getGamepads() native;

  Future<RelatedApplication> getInstalledRelatedApps() =>
      promiseToFuture<RelatedApplication>(
          JS("", "#.getInstalledRelatedApps()", this));

  Future getVRDisplays() => promiseToFuture(JS("", "#.getVRDisplays()", this));

  @Unstable()
  void registerProtocolHandler(String scheme, String url, String title) native;

  Future requestKeyboardLock([List<String> keyCodes]) {
    if (keyCodes != null) {
      List keyCodes_1 = convertDartToNative_StringArray(keyCodes);
      return _requestKeyboardLock_1(keyCodes_1);
    }
    return _requestKeyboardLock_2();
  }

  @JSName('requestKeyboardLock')
  Future _requestKeyboardLock_1(List keyCodes) =>
      promiseToFuture(JS("", "#.requestKeyboardLock(#)", this, keyCodes));
  @JSName('requestKeyboardLock')
  Future _requestKeyboardLock_2() =>
      promiseToFuture(JS("", "#.requestKeyboardLock()", this));

  @JSName('requestMIDIAccess')
  Future requestMidiAccess([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(
        JS("", "#.requestMidiAccess(#)", this, options_dict));
  }

  Future requestMediaKeySystemAccess(
          String keySystem, List<Map> supportedConfigurations) =>
      promiseToFuture(JS("", "#.requestMediaKeySystemAccess(#, #)", this,
          keySystem, supportedConfigurations));

  bool sendBeacon(String url, Object data) native;

  Future share([Map data]) {
    var data_dict = null;
    if (data != null) {
      data_dict = convertDartToNative_Dictionary(data);
    }
    return promiseToFuture(JS("", "#.share(#)", this, data_dict));
  }

  // From NavigatorAutomationInformation

  final bool webdriver;

  // From NavigatorCookies

  @Unstable()
  final bool cookieEnabled;

  // From NavigatorID

  final String appCodeName;

  final String appName;

  final String appVersion;

  final bool dartEnabled;

  final String platform;

  @Unstable()
  final String product;

  final String userAgent;

  // From NavigatorLanguage

  final List<String> languages;

  // From NavigatorOnLine

  @Unstable()
  final bool onLine;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NavigatorAutomationInformation")
class NavigatorAutomationInformation extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorAutomationInformation._() {
    throw new UnsupportedError("Not supported");
  }

  final bool webdriver;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NavigatorConcurrentHardware")
class NavigatorConcurrentHardware extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorConcurrentHardware._() {
    throw new UnsupportedError("Not supported");
  }

  final int hardwareConcurrency;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NavigatorCookies")
class NavigatorCookies extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorCookies._() {
    throw new UnsupportedError("Not supported");
  }

  final bool cookieEnabled;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class NavigatorID extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorID._() {
    throw new UnsupportedError("Not supported");
  }

  final String appCodeName;

  final String appName;

  final String appVersion;

  final bool dartEnabled;

  final String platform;

  final String product;

  final String userAgent;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class NavigatorLanguage extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorLanguage._() {
    throw new UnsupportedError("Not supported");
  }

  final String language;

  final List<String> languages;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class NavigatorOnLine extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorOnLine._() {
    throw new UnsupportedError("Not supported");
  }

  final bool onLine;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NavigatorUserMediaError")
class NavigatorUserMediaError extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorUserMediaError._() {
    throw new UnsupportedError("Not supported");
  }

  final String constraintName;

  final String message;

  final String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _NavigatorUserMediaErrorCallback(NavigatorUserMediaError error);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _NavigatorUserMediaSuccessCallback(MediaStream stream);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NetworkInformation")
class NetworkInformation extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory NetworkInformation._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  final num downlink;

  final num downlinkMax;

  final String effectiveType;

  final int rtt;

  final String type;

  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Lazy implementation of the child nodes of an element that does not request
 * the actual child nodes of an element until strictly necessary greatly
 * improving performance for the typical cases where it is not required.
 */
class _ChildNodeListLazy extends ListBase<Node> implements NodeListWrapper {
  final Node _this;

  _ChildNodeListLazy(this._this);

  Node get first {
    Node result = JS('Node|Null', '#.firstChild', _this);
    if (result == null) throw new StateError("No elements");
    return result;
  }

  Node get last {
    Node result = JS('Node|Null', '#.lastChild', _this);
    if (result == null) throw new StateError("No elements");
    return result;
  }

  Node get single {
    int l = this.length;
    if (l == 0) throw new StateError("No elements");
    if (l > 1) throw new StateError("More than one element");
    return JS('Node|Null', '#.firstChild', _this);
  }

  void add(Node value) {
    _this.append(value);
  }

  void addAll(Iterable<Node> iterable) {
    if (iterable is _ChildNodeListLazy) {
      _ChildNodeListLazy otherList = iterable;
      if (!identical(otherList._this, _this)) {
        // Optimized route for copying between nodes.
        for (var i = 0, len = otherList.length; i < len; ++i) {
          _this.append(otherList._this.firstChild);
        }
      }
      return;
    }
    for (Node node in iterable) {
      _this.append(node);
    }
  }

  void insert(int index, Node node) {
    if (index < 0 || index > length) {
      throw new RangeError.range(index, 0, length);
    }
    if (index == length) {
      _this.append(node);
    } else {
      _this.insertBefore(node, this[index]);
    }
  }

  void insertAll(int index, Iterable<Node> iterable) {
    if (index == length) {
      addAll(iterable);
    } else {
      var item = this[index];
      _this.insertAllBefore(iterable, item);
    }
  }

  void setAll(int index, Iterable<Node> iterable) {
    throw new UnsupportedError("Cannot setAll on Node list");
  }

  Node removeLast() {
    final result = last;
    if (result != null) {
      _this._removeChild(result);
    }
    return result;
  }

  Node removeAt(int index) {
    var result = this[index];
    if (result != null) {
      _this._removeChild(result);
    }
    return result;
  }

  bool remove(Object object) {
    if (object is! Node) return false;
    Node node = object;
    if (!identical(_this, node.parentNode)) return false;
    _this._removeChild(node);
    return true;
  }

  void _filter(bool test(Node node), bool removeMatching) {
    // This implementation of removeWhere/retainWhere is more efficient
    // than the default in ListBase. Child nodes can be removed in constant
    // time.
    Node child = _this.firstChild;
    while (child != null) {
      Node nextChild = child.nextNode;
      if (test(child) == removeMatching) {
        _this._removeChild(child);
      }
      child = nextChild;
    }
  }

  void removeWhere(bool test(Node node)) {
    _filter(test, true);
  }

  void retainWhere(bool test(Node node)) {
    _filter(test, false);
  }

  void clear() {
    _this._clearChildren();
  }

  void operator []=(int index, Node value) {
    _this._replaceChild(value, this[index]);
  }

  Iterator<Node> get iterator => _this.childNodes.iterator;

  // From List<Node>:

  // TODO(jacobr): this could be implemented for child node lists.
  // The exception we throw here is misleading.
  void sort([Comparator<Node> compare]) {
    throw new UnsupportedError("Cannot sort Node list");
  }

  void shuffle([Random random]) {
    throw new UnsupportedError("Cannot shuffle Node list");
  }

  // FIXME: implement these.
  void setRange(int start, int end, Iterable<Node> iterable,
      [int skipCount = 0]) {
    throw new UnsupportedError("Cannot setRange on Node list");
  }

  void fillRange(int start, int end, [Node fill]) {
    throw new UnsupportedError("Cannot fillRange on Node list");
  }

  void removeRange(int start, int end) {
    throw new UnsupportedError("Cannot removeRange on Node list");
  }
  // -- end List<Node> mixins.

  // TODO(jacobr): benchmark whether this is more efficient or whether caching
  // a local copy of childNodes is more efficient.
  int get length => _this.childNodes.length;

  set length(int value) {
    throw new UnsupportedError("Cannot set length on immutable List.");
  }

  Node operator [](int index) => _this.childNodes[index];

  List<Node> get rawList => _this.childNodes;
}

@Native("Node")
class Node extends EventTarget {
  // Custom element created callback.
  Node._created() : super._created();

  /**
   * A modifiable list of this node's children.
   */
  List<Node> get nodes {
    return new _ChildNodeListLazy(this);
  }

  set nodes(Iterable<Node> value) {
    // Copy list first since we don't want liveness during iteration.
    // TODO(jacobr): there is a better way to do this.
    var copy = value.toList();
    text = '';
    for (Node node in copy) {
      append(node);
    }
  }

  /**
   * Removes this node from the DOM.
   */
  void remove() {
    // TODO(jacobr): should we throw an exception if parent is already null?
    // TODO(vsm): Use the native remove when available.
    if (this.parentNode != null) {
      final Node parent = this.parentNode;
      parentNode._removeChild(this);
    }
  }

  /**
   * Replaces this node with another node.
   */
  Node replaceWith(Node otherNode) {
    try {
      final Node parent = this.parentNode;
      parent._replaceChild(otherNode, this);
    } catch (e) {}
    ;
    return this;
  }

  /**
   * Inserts all of the nodes into this node directly before refChild.
   *
   * See also:
   *
   * * [insertBefore]
   */
  Node insertAllBefore(Iterable<Node> newNodes, Node refChild) {
    if (newNodes is _ChildNodeListLazy) {
      _ChildNodeListLazy otherList = newNodes;
      if (identical(otherList._this, this)) {
        throw new ArgumentError(newNodes);
      }

      // Optimized route for copying between nodes.
      for (var i = 0, len = otherList.length; i < len; ++i) {
        this.insertBefore(otherList._this.firstChild, refChild);
      }
    } else {
      for (var node in newNodes) {
        this.insertBefore(node, refChild);
      }
    }
  }

  void _clearChildren() {
    while (firstChild != null) {
      _removeChild(firstChild);
    }
  }

  /**
   * Print out a String representation of this Node.
   */
  String toString() {
    String value = nodeValue; // Fetch DOM Node property once.
    return value == null ? super.toString() : value;
  }

  /**
   * A list of this node's children.
   *
   * ## Other resources
   *
   * * [Node.childNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
   *   from MDN.
   */
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> childNodes;

  // To suppress missing implicit constructor warnings.
  factory Node._() {
    throw new UnsupportedError("Not supported");
  }

  static const int ATTRIBUTE_NODE = 2;

  static const int CDATA_SECTION_NODE = 4;

  static const int COMMENT_NODE = 8;

  static const int DOCUMENT_FRAGMENT_NODE = 11;

  static const int DOCUMENT_NODE = 9;

  static const int DOCUMENT_TYPE_NODE = 10;

  static const int ELEMENT_NODE = 1;

  static const int ENTITY_NODE = 6;

  static const int ENTITY_REFERENCE_NODE = 5;

  static const int NOTATION_NODE = 12;

  static const int PROCESSING_INSTRUCTION_NODE = 7;

  static const int TEXT_NODE = 3;

  @JSName('baseURI')
  final String baseUri;

  /**
   * The first child of this node.
   *
   * ## Other resources
   *
   * * [Node.firstChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.firstChild)
   *   from MDN.
   */
  final Node firstChild;

  final bool isConnected;

  /**
   * The last child of this node.
   *
   * ## Other resources
   *
   * * [Node.lastChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.lastChild)
   *   from MDN.
   */
  final Node lastChild;

  @JSName('nextSibling')
  /**
   * The next sibling node.
   *
   * ## Other resources
   *
   * * [Node.nextSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling)
   *   from MDN.
   */
  final Node nextNode;

  /**
   * The name of this node.
   *
   * This varies by this node's [nodeType].
   *
   * ## Other resources
   *
   * * [Node.nodeName](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeName)
   *   from MDN. This page contains a table of [nodeName] values for each
   *   [nodeType].
   */
  final String nodeName;

  /**
   * The type of node.
   *
   * This value is one of:
   *
   * * [ATTRIBUTE_NODE] if this node is an attribute.
   * * [CDATA_SECTION_NODE] if this node is a [CDataSection].
   * * [COMMENT_NODE] if this node is a [Comment].
   * * [DOCUMENT_FRAGMENT_NODE] if this node is a [DocumentFragment].
   * * [DOCUMENT_NODE] if this node is a [Document].
   * * [DOCUMENT_TYPE_NODE] if this node is a [DocumentType] node.
   * * [ELEMENT_NODE] if this node is an [Element].
   * * [ENTITY_NODE] if this node is an entity.
   * * [ENTITY_REFERENCE_NODE] if this node is an entity reference.
   * * [NOTATION_NODE] if this node is a notation.
   * * [PROCESSING_INSTRUCTION_NODE] if this node is a [ProcessingInstruction].
   * * [TEXT_NODE] if this node is a [Text] node.
   *
   * ## Other resources
   *
   * * [Node.nodeType](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType)
   *   from MDN.
   */
  final int nodeType;

  /**
   * The value of this node.
   *
   * This varies by this type's [nodeType].
   *
   * ## Other resources
   *
   * * [Node.nodeValue](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeValue)
   *   from MDN. This page contains a table of [nodeValue] values for each
   *   [nodeType].
   */
  final String nodeValue;

  /**
   * The document this node belongs to.
   *
   * Returns null if this node does not belong to any document.
   *
   * ## Other resources
   *
   * * [Node.ownerDocument](https://developer.mozilla.org/en-US/docs/Web/API/Node.ownerDocument)
   *   from MDN.
   */
  final Document ownerDocument;

  @JSName('parentElement')
  /**
   * The parent element of this node.
   *
   * Returns null if this node either does not have a parent or its parent is
   * not an element.
   *
   * ## Other resources
   *
   * * [Node.parentElement](https://developer.mozilla.org/en-US/docs/Web/API/Node.parentElement)
   *   from W3C.
   */
  final Element parent;

  /**
   * The parent node of this node.
   *
   * ## Other resources
   *
   * * [Node.parentNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.parentNode)
   *   from MDN.
   */
  final Node parentNode;

  @JSName('previousSibling')
  /**
   * The previous sibling node.
   *
   * ## Other resources
   *
   * * [Node.previousSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.previousSibling)
   *   from MDN.
   */
  final Node previousNode;

  @JSName('textContent')
  /**
   * All text within this node and its descendents.
   *
   * ## Other resources
   *
   * * [Node.textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent)
   *   from MDN.
   */
  String text;

  @JSName('appendChild')
  /**
   * Adds a node to the end of the child [nodes] list of this node.
   *
   * If the node already exists in this document, it will be removed from its
   * current parent node, then added to this node.
   *
   * This method is more efficient than `nodes.add`, and is the preferred
   * way of appending a child node.
   */
  Node append(Node node) native;

  @JSName('cloneNode')
  /**
   * Returns a copy of this node.
   *
   * If [deep] is `true`, then all of this node's children and descendents are
   * copied as well. If [deep] is `false`, then only this node is copied.
   *
   * ## Other resources
   *
   * * [Node.cloneNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode)
   *   from MDN.
   */
  Node clone(bool deep) native;

  /**
   * Returns true if this node contains the specified node.
   *
   * ## Other resources
   *
   * * [Node.contains](https://developer.mozilla.org/en-US/docs/Web/API/Node.contains)
   *   from MDN.
   */
  bool contains(Node other) native;

  Node getRootNode([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _getRootNode_1(options_1);
    }
    return _getRootNode_2();
  }

  @JSName('getRootNode')
  Node _getRootNode_1(options) native;
  @JSName('getRootNode')
  Node _getRootNode_2() native;

  /**
   * Returns true if this node has any children.
   *
   * ## Other resources
   *
   * * [Node.hasChildNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.hasChildNodes)
   *   from MDN.
   */
  bool hasChildNodes() native;

  /**
   * Inserts all of the nodes into this node directly before refChild.
   *
   * ## Other resources
   *
   * * [Node.insertBefore](https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore)
   *   from MDN.
   */
  Node insertBefore(Node node, Node child) native;

  @JSName('removeChild')
  Node _removeChild(Node child) native;

  @JSName('replaceChild')
  Node _replaceChild(Node node, Node child) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("NodeFilter")
class NodeFilter extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NodeFilter._() {
    throw new UnsupportedError("Not supported");
  }

  static const int FILTER_ACCEPT = 1;

  static const int FILTER_REJECT = 2;

  static const int FILTER_SKIP = 3;

  static const int SHOW_ALL = 0xFFFFFFFF;

  static const int SHOW_COMMENT = 0x80;

  static const int SHOW_DOCUMENT = 0x100;

  static const int SHOW_DOCUMENT_FRAGMENT = 0x400;

  static const int SHOW_DOCUMENT_TYPE = 0x200;

  static const int SHOW_ELEMENT = 0x1;

  static const int SHOW_PROCESSING_INSTRUCTION = 0x40;

  static const int SHOW_TEXT = 0x4;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("NodeIterator")
class NodeIterator extends Interceptor {
  factory NodeIterator(Node root, int whatToShow) {
    return document._createNodeIterator(root, whatToShow, null);
  }
  // To suppress missing implicit constructor warnings.
  factory NodeIterator._() {
    throw new UnsupportedError("Not supported");
  }

  final bool pointerBeforeReferenceNode;

  final Node referenceNode;

  final Node root;

  final int whatToShow;

  void detach() native;

  Node nextNode() native;

  Node previousNode() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NodeList,RadioNodeList")
class NodeList extends Interceptor
    with ListMixin<Node>, ImmutableListMixin<Node>
    implements JavaScriptIndexingBehavior<Node>, List<Node> {
  // To suppress missing implicit constructor warnings.
  factory NodeList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  Node operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Node", "#[#]", this, index);
  }

  void operator []=(int index, Node value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Node> mixins.
  // Node is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Node get first {
    if (this.length > 0) {
      return JS('Node', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Node get last {
    int len = this.length;
    if (len > 0) {
      return JS('Node', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Node get single {
    int len = this.length;
    if (len == 1) {
      return JS('Node', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Node elementAt(int index) => this[index];
  // -- end List<Node> mixins.

  @JSName('item')
  Node _item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NonDocumentTypeChildNode")
class NonDocumentTypeChildNode extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NonDocumentTypeChildNode._() {
    throw new UnsupportedError("Not supported");
  }

  final Element nextElementSibling;

  final Element previousElementSibling;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NonElementParentNode")
class NonElementParentNode extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NonElementParentNode._() {
    throw new UnsupportedError("Not supported");
  }

  Element getElementById(String elementId) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NoncedElement")
class NoncedElement extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NoncedElement._() {
    throw new UnsupportedError("Not supported");
  }

  String nonce;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Notification")
class Notification extends EventTarget {
  factory Notification(String title,
      {String dir: null,
      String body: null,
      String lang: null,
      String tag: null,
      String icon: null}) {
    var parsedOptions = {};
    if (dir != null) parsedOptions['dir'] = dir;
    if (body != null) parsedOptions['body'] = body;
    if (lang != null) parsedOptions['lang'] = lang;
    if (tag != null) parsedOptions['tag'] = tag;
    if (icon != null) parsedOptions['icon'] = icon;
    return Notification._factoryNotification(title, parsedOptions);
  }
  // To suppress missing implicit constructor warnings.
  factory Notification._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `click` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> clickEvent =
      const EventStreamProvider<Event>('click');

  /**
   * Static factory designed to expose `close` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> closeEvent =
      const EventStreamProvider<Event>('close');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `show` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> showEvent =
      const EventStreamProvider<Event>('show');

  static Notification _factoryNotification(String title, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return Notification._create_1(title, options_1);
    }
    return Notification._create_2(title);
  }

  static Notification _create_1(title, options) =>
      JS('Notification', 'new Notification(#,#)', title, options);
  static Notification _create_2(title) =>
      JS('Notification', 'new Notification(#)', title);

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.Notification)');

  final List actions;

  final String badge;

  final String body;

  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final Object data;

  final String dir;

  final String icon;

  final String image;

  final String lang;

  static final int maxActions;

  static final String permission;

  final bool renotify;

  final bool requireInteraction;

  final bool silent;

  final String tag;

  final int timestamp;

  final String title;

  final List<int> vibrate;

  void close() native;

  @JSName('requestPermission')
  static Future _requestPermission(
      [_NotificationPermissionCallback deprecatedCallback]) native;

  @JSName('requestPermission')
  static Future<String> requestPermission() {
    var completer = new Completer<String>();
    _requestPermission((value) {
      completer.complete(value);
    });
    return completer.future;
  }

  /// Stream of `click` events handled by this [Notification].
  Stream<Event> get onClick => clickEvent.forTarget(this);

  /// Stream of `close` events handled by this [Notification].
  Stream<Event> get onClose => closeEvent.forTarget(this);

  /// Stream of `error` events handled by this [Notification].
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `show` events handled by this [Notification].
  Stream<Event> get onShow => showEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NotificationEvent")
class NotificationEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory NotificationEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory NotificationEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return NotificationEvent._create_1(type, eventInitDict_1);
  }
  static NotificationEvent _create_1(type, eventInitDict) => JS(
      'NotificationEvent', 'new NotificationEvent(#,#)', type, eventInitDict);

  final String action;

  final Notification notification;

  final String reply;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _NotificationPermissionCallback(String permission);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLOListElement")
class OListElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory OListElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory OListElement() => JS(
      'returns:OListElement;creates:OListElement;new:true',
      '#.createElement(#)',
      document,
      "ol");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OListElement.created() : super.created();

  bool reversed;

  int start;

  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
@Native("HTMLObjectElement")
class ObjectElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ObjectElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory ObjectElement() => document.createElement("object");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ObjectElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('object');

  WindowBase get contentWindow =>
      _convertNativeToDart_Window(this._get_contentWindow);
  @JSName('contentWindow')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_contentWindow;

  String data;

  final FormElement form;

  String height;

  String name;

  String type;

  String useMap;

  final String validationMessage;

  final ValidityState validity;

  String width;

  final bool willValidate;

  Node __getter__(String name) native;

  void __setter__(String name, Node value) native;

  bool checkValidity() native;

  bool reportValidity() native;

  void setCustomValidity(String error) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("OffscreenCanvas")
class OffscreenCanvas extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory OffscreenCanvas._() {
    throw new UnsupportedError("Not supported");
  }

  factory OffscreenCanvas(int width, int height) {
    return OffscreenCanvas._create_1(width, height);
  }
  static OffscreenCanvas _create_1(width, height) =>
      JS('OffscreenCanvas', 'new OffscreenCanvas(#,#)', width, height);

  int height;

  int width;

  Future<Blob> convertToBlob([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture<Blob>(
        JS("", "#.convertToBlob(#)", this, options_dict));
  }

  Object getContext(String contextType, [Map attributes]) {
    if (attributes != null) {
      var attributes_1 = convertDartToNative_Dictionary(attributes);
      return _getContext_1(contextType, attributes_1);
    }
    return _getContext_2(contextType);
  }

  @JSName('getContext')
  Object _getContext_1(contextType, attributes) native;
  @JSName('getContext')
  Object _getContext_2(contextType) native;

  ImageBitmap transferToImageBitmap() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("OffscreenCanvasRenderingContext2D")
class OffscreenCanvasRenderingContext2D extends Interceptor
    implements _CanvasPath {
  // To suppress missing implicit constructor warnings.
  factory OffscreenCanvasRenderingContext2D._() {
    throw new UnsupportedError("Not supported");
  }

  final OffscreenCanvas canvas;

  String direction;

  Object fillStyle;

  String filter;

  String font;

  num globalAlpha;

  String globalCompositeOperation;

  bool imageSmoothingEnabled;

  String imageSmoothingQuality;

  String lineCap;

  num lineDashOffset;

  String lineJoin;

  num lineWidth;

  num miterLimit;

  num shadowBlur;

  String shadowColor;

  num shadowOffsetX;

  num shadowOffsetY;

  Object strokeStyle;

  String textAlign;

  String textBaseline;

  void beginPath() native;

  void clearRect(num x, num y, num width, num height) native;

  void clip([Path2D path]) native;

  Future commit() => promiseToFuture(JS("", "#.commit()", this));

  ImageData createImageData(data_OR_imagedata_OR_sw,
      [int sh_OR_sw,
      imageDataColorSettings_OR_sh,
      Map imageDataColorSettings]) {
    if ((data_OR_imagedata_OR_sw is ImageData) &&
        sh_OR_sw == null &&
        imageDataColorSettings_OR_sh == null &&
        imageDataColorSettings == null) {
      var imagedata_1 = convertDartToNative_ImageData(data_OR_imagedata_OR_sw);
      return convertNativeToDart_ImageData(_createImageData_1(imagedata_1));
    }
    if (sh_OR_sw != null &&
        (data_OR_imagedata_OR_sw is int) &&
        imageDataColorSettings_OR_sh == null &&
        imageDataColorSettings == null) {
      return convertNativeToDart_ImageData(
          _createImageData_2(data_OR_imagedata_OR_sw, sh_OR_sw));
    }
    if ((imageDataColorSettings_OR_sh is Map) &&
        sh_OR_sw != null &&
        (data_OR_imagedata_OR_sw is int) &&
        imageDataColorSettings == null) {
      var imageDataColorSettings_1 =
          convertDartToNative_Dictionary(imageDataColorSettings_OR_sh);
      return convertNativeToDart_ImageData(_createImageData_3(
          data_OR_imagedata_OR_sw, sh_OR_sw, imageDataColorSettings_1));
    }
    if (imageDataColorSettings != null &&
        (imageDataColorSettings_OR_sh is int) &&
        sh_OR_sw != null &&
        data_OR_imagedata_OR_sw != null) {
      var imageDataColorSettings_1 =
          convertDartToNative_Dictionary(imageDataColorSettings);
      return convertNativeToDart_ImageData(_createImageData_4(
          data_OR_imagedata_OR_sw,
          sh_OR_sw,
          imageDataColorSettings_OR_sh,
          imageDataColorSettings_1));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('createImageData')
  _createImageData_1(imagedata) native;
  @JSName('createImageData')
  _createImageData_2(int sw, sh) native;
  @JSName('createImageData')
  _createImageData_3(int sw, sh, imageDataColorSettings) native;
  @JSName('createImageData')
  _createImageData_4(data, sw, int sh, imageDataColorSettings) native;

  CanvasGradient createLinearGradient(num x0, num y0, num x1, num y1) native;

  CanvasPattern createPattern(
      /*CanvasImageSource*/ image, String repetitionType) native;

  CanvasGradient createRadialGradient(
      num x0, num y0, num r0, num x1, num y1, num r1) native;

  void drawImage(/*CanvasImageSource*/ image, num sx_OR_x, num sy_OR_y,
      [num sw_OR_width,
      num height_OR_sh,
      num dx,
      num dy,
      num dw,
      num dh]) native;

  void fill([path_OR_winding, String winding]) native;

  void fillRect(num x, num y, num width, num height) native;

  void fillText(String text, num x, num y, [num maxWidth]) native;

  ImageData getImageData(int sx, int sy, int sw, int sh) {
    return convertNativeToDart_ImageData(_getImageData_1(sx, sy, sw, sh));
  }

  @JSName('getImageData')
  _getImageData_1(sx, sy, sw, sh) native;

  List<num> getLineDash() native;

  bool isPointInPath(path_OR_x, num x_OR_y, [winding_OR_y, String winding])
      native;

  bool isPointInStroke(path_OR_x, num x_OR_y, [num y]) native;

  TextMetrics measureText(String text) native;

  void putImageData(ImageData imagedata, int dx, int dy,
      [int dirtyX, int dirtyY, int dirtyWidth, int dirtyHeight]) {
    if (dirtyX == null &&
        dirtyY == null &&
        dirtyWidth == null &&
        dirtyHeight == null) {
      var imagedata_1 = convertDartToNative_ImageData(imagedata);
      _putImageData_1(imagedata_1, dx, dy);
      return;
    }
    if (dirtyHeight != null &&
        dirtyWidth != null &&
        dirtyY != null &&
        dirtyX != null) {
      var imagedata_1 = convertDartToNative_ImageData(imagedata);
      _putImageData_2(
          imagedata_1, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('putImageData')
  void _putImageData_1(imagedata, dx, dy) native;
  @JSName('putImageData')
  void _putImageData_2(
      imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) native;

  void resetTransform() native;

  void restore() native;

  void rotate(num angle) native;

  void save() native;

  void scale(num x, num y) native;

  void setLineDash(List<num> dash) native;

  void setTransform(num a, num b, num c, num d, num e, num f) native;

  void stroke([Path2D path]) native;

  void strokeRect(num x, num y, num width, num height) native;

  void strokeText(String text, num x, num y, [num maxWidth]) native;

  void transform(num a, num b, num c, num d, num e, num f) native;

  void translate(num x, num y) native;

  // From CanvasPath

  void arc(num x, num y, num radius, num startAngle, num endAngle,
      bool anticlockwise) native;

  void arcTo(num x1, num y1, num x2, num y2, num radius) native;

  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y)
      native;

  void closePath() native;

  void ellipse(num x, num y, num radiusX, num radiusY, num rotation,
      num startAngle, num endAngle, bool anticlockwise) native;

  void lineTo(num x, num y) native;

  void moveTo(num x, num y) native;

  void quadraticCurveTo(num cpx, num cpy, num x, num y) native;

  void rect(num x, num y, num width, num height) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLOptGroupElement")
class OptGroupElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory OptGroupElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory OptGroupElement() => JS(
      'returns:OptGroupElement;creates:OptGroupElement;new:true',
      '#.createElement(#)',
      document,
      "optgroup");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OptGroupElement.created() : super.created();

  bool disabled;

  String label;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLOptionElement")
class OptionElement extends HtmlElement {
  factory OptionElement(
      {String data: '', String value: '', bool selected: false}) {
    return new OptionElement._(data, value, null, selected);
  }

  factory OptionElement._(
      [String data, String value, bool defaultSelected, bool selected]) {
    if (selected != null) {
      return OptionElement._create_1(data, value, defaultSelected, selected);
    }
    if (defaultSelected != null) {
      return OptionElement._create_2(data, value, defaultSelected);
    }
    if (value != null) {
      return OptionElement._create_3(data, value);
    }
    if (data != null) {
      return OptionElement._create_4(data);
    }
    return OptionElement._create_5();
  }
  static OptionElement _create_1(data, value, defaultSelected, selected) => JS(
      'OptionElement',
      'new Option(#,#,#,#)',
      data,
      value,
      defaultSelected,
      selected);
  static OptionElement _create_2(data, value, defaultSelected) =>
      JS('OptionElement', 'new Option(#,#,#)', data, value, defaultSelected);
  static OptionElement _create_3(data, value) =>
      JS('OptionElement', 'new Option(#,#)', data, value);
  static OptionElement _create_4(data) =>
      JS('OptionElement', 'new Option(#)', data);
  static OptionElement _create_5() => JS('OptionElement', 'new Option()');
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OptionElement.created() : super.created();

  bool defaultSelected;

  bool disabled;

  final FormElement form;

  final int index;

  String label;

  bool selected;

  String value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("OrientationSensor")
class OrientationSensor extends Sensor {
  // To suppress missing implicit constructor warnings.
  factory OrientationSensor._() {
    throw new UnsupportedError("Not supported");
  }

  final List<num> quaternion;

  void populateMatrix(Object targetBuffer) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("HTMLOutputElement")
class OutputElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory OutputElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory OutputElement() => document.createElement("output");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OutputElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('output');

  String defaultValue;

  final FormElement form;

  final DomTokenList htmlFor;

  @Unstable()
  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> labels;

  String name;

  final String type;

  final String validationMessage;

  final ValidityState validity;

  String value;

  final bool willValidate;

  bool checkValidity() native;

  bool reportValidity() native;

  void setCustomValidity(String error) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("OverconstrainedError")
class OverconstrainedError extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory OverconstrainedError._() {
    throw new UnsupportedError("Not supported");
  }

  factory OverconstrainedError(String constraint, String message) {
    return OverconstrainedError._create_1(constraint, message);
  }
  static OverconstrainedError _create_1(constraint, message) => JS(
      'OverconstrainedError',
      'new OverconstrainedError(#,#)',
      constraint,
      message);

  final String constraint;

  final String message;

  final String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PageTransitionEvent")
class PageTransitionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PageTransitionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory PageTransitionEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return PageTransitionEvent._create_1(type, eventInitDict_1);
    }
    return PageTransitionEvent._create_2(type);
  }
  static PageTransitionEvent _create_1(type, eventInitDict) => JS(
      'PageTransitionEvent',
      'new PageTransitionEvent(#,#)',
      type,
      eventInitDict);
  static PageTransitionEvent _create_2(type) =>
      JS('PageTransitionEvent', 'new PageTransitionEvent(#)', type);

  final bool persisted;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaintRenderingContext2D")
class PaintRenderingContext2D extends Interceptor implements _CanvasPath {
  // To suppress missing implicit constructor warnings.
  factory PaintRenderingContext2D._() {
    throw new UnsupportedError("Not supported");
  }

  Matrix currentTransform;

  Object fillStyle;

  String filter;

  num globalAlpha;

  String globalCompositeOperation;

  bool imageSmoothingEnabled;

  String imageSmoothingQuality;

  String lineCap;

  num lineDashOffset;

  String lineJoin;

  num lineWidth;

  num miterLimit;

  num shadowBlur;

  String shadowColor;

  num shadowOffsetX;

  num shadowOffsetY;

  Object strokeStyle;

  void beginPath() native;

  void clearRect(num x, num y, num width, num height) native;

  void clip([path_OR_winding, String winding]) native;

  CanvasGradient createLinearGradient(num x0, num y0, num x1, num y1) native;

  CanvasPattern createPattern(
      /*CanvasImageSource*/ image, String repetitionType) native;

  CanvasGradient createRadialGradient(
      num x0, num y0, num r0, num x1, num y1, num r1) native;

  void drawImage(/*CanvasImageSource*/ image, num sx_OR_x, num sy_OR_y,
      [num sw_OR_width,
      num height_OR_sh,
      num dx,
      num dy,
      num dw,
      num dh]) native;

  void fill([path_OR_winding, String winding]) native;

  void fillRect(num x, num y, num width, num height) native;

  List<num> getLineDash() native;

  bool isPointInPath(path_OR_x, num x_OR_y, [winding_OR_y, String winding])
      native;

  bool isPointInStroke(path_OR_x, num x_OR_y, [num y]) native;

  void resetTransform() native;

  void restore() native;

  void rotate(num angle) native;

  void save() native;

  void scale(num x, num y) native;

  void setLineDash(List<num> dash) native;

  void setTransform(num a, num b, num c, num d, num e, num f) native;

  void stroke([Path2D path]) native;

  void strokeRect(num x, num y, num width, num height) native;

  void transform(num a, num b, num c, num d, num e, num f) native;

  void translate(num x, num y) native;

  // From CanvasPath

  void arc(num x, num y, num radius, num startAngle, num endAngle,
      bool anticlockwise) native;

  void arcTo(num x1, num y1, num x2, num y2, num radius) native;

  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y)
      native;

  void closePath() native;

  void ellipse(num x, num y, num radiusX, num radiusY, num rotation,
      num startAngle, num endAngle, bool anticlockwise) native;

  void lineTo(num x, num y) native;

  void moveTo(num x, num y) native;

  void quadraticCurveTo(num cpx, num cpy, num x, num y) native;

  void rect(num x, num y, num width, num height) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaintSize")
class PaintSize extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PaintSize._() {
    throw new UnsupportedError("Not supported");
  }

  final num height;

  final num width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaintWorkletGlobalScope")
class PaintWorkletGlobalScope extends WorkletGlobalScope {
  // To suppress missing implicit constructor warnings.
  factory PaintWorkletGlobalScope._() {
    throw new UnsupportedError("Not supported");
  }

  final num devicePixelRatio;

  void registerPaint(String name, Object paintCtor) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLParagraphElement")
class ParagraphElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ParagraphElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory ParagraphElement() => JS(
      'returns:ParagraphElement;creates:ParagraphElement;new:true',
      '#.createElement(#)',
      document,
      "p");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ParagraphElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("HTMLParamElement")
class ParamElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ParamElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory ParamElement() => JS(
      'returns:ParamElement;creates:ParamElement;new:true',
      '#.createElement(#)',
      document,
      "param");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ParamElement.created() : super.created();

  String name;

  String value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class ParentNode extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ParentNode._() {
    throw new UnsupportedError("Not supported");
  }

  final int _childElementCount;

  final List<Node> _children;

  final Element _firstElementChild;

  final Element _lastElementChild;

  Element querySelector(String selectors);

  List<Node> _querySelectorAll(String selectors);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PasswordCredential")
class PasswordCredential extends Credential implements CredentialUserData {
  // To suppress missing implicit constructor warnings.
  factory PasswordCredential._() {
    throw new UnsupportedError("Not supported");
  }

  factory PasswordCredential(data_OR_form) {
    if ((data_OR_form is Map)) {
      var data_1 = convertDartToNative_Dictionary(data_OR_form);
      return PasswordCredential._create_1(data_1);
    }
    if ((data_OR_form is FormElement)) {
      return PasswordCredential._create_2(data_OR_form);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static PasswordCredential _create_1(data_OR_form) =>
      JS('PasswordCredential', 'new PasswordCredential(#)', data_OR_form);
  static PasswordCredential _create_2(data_OR_form) =>
      JS('PasswordCredential', 'new PasswordCredential(#)', data_OR_form);

  Object additionalData;

  String idName;

  final String password;

  String passwordName;

  // From CredentialUserData

  @JSName('iconURL')
  final String iconUrl;

  final String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Path2D")
class Path2D extends Interceptor implements _CanvasPath {
  // To suppress missing implicit constructor warnings.
  factory Path2D._() {
    throw new UnsupportedError("Not supported");
  }

  factory Path2D([path_OR_text]) {
    if (path_OR_text == null) {
      return Path2D._create_1();
    }
    if ((path_OR_text is Path2D)) {
      return Path2D._create_2(path_OR_text);
    }
    if ((path_OR_text is String)) {
      return Path2D._create_3(path_OR_text);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static Path2D _create_1() => JS('Path2D', 'new Path2D()');
  static Path2D _create_2(path_OR_text) =>
      JS('Path2D', 'new Path2D(#)', path_OR_text);
  static Path2D _create_3(path_OR_text) =>
      JS('Path2D', 'new Path2D(#)', path_OR_text);

  void addPath(Path2D path, [Matrix transform]) native;

  // From CanvasPath

  void arc(num x, num y, num radius, num startAngle, num endAngle,
      bool anticlockwise) native;

  void arcTo(num x1, num y1, num x2, num y2, num radius) native;

  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y)
      native;

  void closePath() native;

  void ellipse(num x, num y, num radiusX, num radiusY, num rotation,
      num startAngle, num endAngle, bool anticlockwise) native;

  void lineTo(num x, num y) native;

  void moveTo(num x, num y) native;

  void quadraticCurveTo(num cpx, num cpy, num x, num y) native;

  void rect(num x, num y, num width, num height) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaymentAddress")
class PaymentAddress extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PaymentAddress._() {
    throw new UnsupportedError("Not supported");
  }

  final List<String> addressLine;

  final String city;

  final String country;

  final String dependentLocality;

  final String languageCode;

  final String organization;

  final String phone;

  final String postalCode;

  final String recipient;

  final String region;

  final String sortingCode;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaymentInstruments")
class PaymentInstruments extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PaymentInstruments._() {
    throw new UnsupportedError("Not supported");
  }

  Future clear() => promiseToFuture(JS("", "#.clear()", this));

  Future<bool> delete(String instrumentKey) =>
      promiseToFuture<bool>(JS("", "#.delete(#)", this, instrumentKey));

  Future<Map<String, dynamic>> get(String instrumentKey) =>
      promiseToFutureAsMap(JS("", "#.get(#)", this, instrumentKey));

  Future has(String instrumentKey) =>
      promiseToFuture(JS("", "#.has(#)", this, instrumentKey));

  Future<List<String>> keys() =>
      promiseToFuture<List<String>>(JS("", "#.keys()", this));

  Future set(String instrumentKey, Map details) {
    var details_dict = convertDartToNative_Dictionary(details);
    return promiseToFuture(
        JS("", "#.set(#, #)", this, instrumentKey, details_dict));
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaymentManager")
class PaymentManager extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PaymentManager._() {
    throw new UnsupportedError("Not supported");
  }

  final PaymentInstruments instruments;

  String userHint;
}
// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaymentRequest")
class PaymentRequest extends EventTarget {
  factory PaymentRequest(List<Map> methodData, Map details, [Map options]) {
    var methodData_1 = [];
    for (var i in methodData) {
      methodData_1.add(convertDartToNative_Dictionary(i));
    }
    if (options != null) {
      var details_1 = convertDartToNative_Dictionary(details);
      var options_2 = convertDartToNative_Dictionary(options);
      return PaymentRequest._create_1(methodData_1, details_1, options_2);
    }
    var details_1 = convertDartToNative_Dictionary(details);
    return PaymentRequest._create_2(methodData_1, details_1);
  }

  static PaymentRequest _create_1(methodData, details, options) => JS(
      'PaymentRequest',
      'new PaymentRequest(#,#,#)',
      methodData,
      details,
      options);
  static PaymentRequest _create_2(methodData, details) =>
      JS('PaymentRequest', 'new PaymentRequest(#,#)', methodData, details);

  // To suppress missing implicit constructor warnings.
  factory PaymentRequest._() {
    throw new UnsupportedError("Not supported");
  }

  final String id;

  final PaymentAddress shippingAddress;

  final String shippingOption;

  final String shippingType;

  Future abort() => promiseToFuture(JS("", "#.abort()", this));

  Future<bool> canMakePayment() =>
      promiseToFuture<bool>(JS("", "#.canMakePayment()", this));

  Future<PaymentResponse> show() =>
      promiseToFuture<PaymentResponse>(JS("", "#.show()", this));
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaymentRequestEvent")
class PaymentRequestEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory PaymentRequestEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory PaymentRequestEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return PaymentRequestEvent._create_1(type, eventInitDict_1);
  }
  static PaymentRequestEvent _create_1(type, eventInitDict) => JS(
      'PaymentRequestEvent',
      'new PaymentRequestEvent(#,#)',
      type,
      eventInitDict);

  final String instrumentKey;

  final List methodData;

  final List modifiers;

  final String paymentRequestId;

  final String paymentRequestOrigin;

  final String topLevelOrigin;

  final Object total;

  Future<WindowClient> openWindow(String url) =>
      promiseToFuture<WindowClient>(JS("", "#.openWindow(#)", this, url));

  void respondWith(Future response) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaymentRequestUpdateEvent")
class PaymentRequestUpdateEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PaymentRequestUpdateEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory PaymentRequestUpdateEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return PaymentRequestUpdateEvent._create_1(type, eventInitDict_1);
    }
    return PaymentRequestUpdateEvent._create_2(type);
  }
  static PaymentRequestUpdateEvent _create_1(type, eventInitDict) => JS(
      'PaymentRequestUpdateEvent',
      'new PaymentRequestUpdateEvent(#,#)',
      type,
      eventInitDict);
  static PaymentRequestUpdateEvent _create_2(type) =>
      JS('PaymentRequestUpdateEvent', 'new PaymentRequestUpdateEvent(#)', type);

  void updateWith(Future detailsPromise) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PaymentResponse")
class PaymentResponse extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PaymentResponse._() {
    throw new UnsupportedError("Not supported");
  }

  final Object details;

  final String methodName;

  final String payerEmail;

  final String payerName;

  final String payerPhone;

  final String requestId;

  final PaymentAddress shippingAddress;

  final String shippingOption;

  Future complete([String paymentResult]) =>
      promiseToFuture(JS("", "#.complete(#)", this, paymentResult));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE)
@Native("Performance")
class Performance extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory Performance._() {
    throw new UnsupportedError("Not supported");
  }

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.performance)');

  final MemoryInfo memory;

  final PerformanceNavigation navigation;

  final num timeOrigin;

  final PerformanceTiming timing;

  void clearMarks(String markName) native;

  void clearMeasures(String measureName) native;

  void clearResourceTimings() native;

  List<PerformanceEntry> getEntries() native;

  List<PerformanceEntry> getEntriesByName(String name, String entryType) native;

  List<PerformanceEntry> getEntriesByType(String entryType) native;

  void mark(String markName) native;

  void measure(String measureName, String startMark, String endMark) native;

  double now() native;

  void setResourceTimingBufferSize(int maxSize) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformanceEntry")
class PerformanceEntry extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PerformanceEntry._() {
    throw new UnsupportedError("Not supported");
  }

  final num duration;

  final String entryType;

  final String name;

  final num startTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformanceLongTaskTiming")
class PerformanceLongTaskTiming extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory PerformanceLongTaskTiming._() {
    throw new UnsupportedError("Not supported");
  }

  final List<TaskAttributionTiming> attribution;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformanceMark")
class PerformanceMark extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory PerformanceMark._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformanceMeasure")
class PerformanceMeasure extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory PerformanceMeasure._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("PerformanceNavigation")
class PerformanceNavigation extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PerformanceNavigation._() {
    throw new UnsupportedError("Not supported");
  }

  static const int TYPE_BACK_FORWARD = 2;

  static const int TYPE_NAVIGATE = 0;

  static const int TYPE_RELOAD = 1;

  static const int TYPE_RESERVED = 255;

  final int redirectCount;

  final int type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformanceNavigationTiming")
class PerformanceNavigationTiming extends PerformanceResourceTiming {
  // To suppress missing implicit constructor warnings.
  factory PerformanceNavigationTiming._() {
    throw new UnsupportedError("Not supported");
  }

  final num domComplete;

  final num domContentLoadedEventEnd;

  final num domContentLoadedEventStart;

  final num domInteractive;

  final num loadEventEnd;

  final num loadEventStart;

  final int redirectCount;

  final String type;

  final num unloadEventEnd;

  final num unloadEventStart;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformanceObserver")
class PerformanceObserver extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PerformanceObserver._() {
    throw new UnsupportedError("Not supported");
  }

  factory PerformanceObserver(PerformanceObserverCallback callback) {
    return PerformanceObserver._create_1(callback);
  }
  static PerformanceObserver _create_1(callback) =>
      JS('PerformanceObserver', 'new PerformanceObserver(#)', callback);

  void disconnect() native;

  void observe(Map options) {
    var options_1 = convertDartToNative_Dictionary(options);
    _observe_1(options_1);
    return;
  }

  @JSName('observe')
  void _observe_1(options) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void PerformanceObserverCallback(
    PerformanceObserverEntryList entries, PerformanceObserver observer);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformanceObserverEntryList")
class PerformanceObserverEntryList extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PerformanceObserverEntryList._() {
    throw new UnsupportedError("Not supported");
  }

  List<PerformanceEntry> getEntries() native;

  List<PerformanceEntry> getEntriesByName(String name, String entryType) native;

  List<PerformanceEntry> getEntriesByType(String entryType) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformancePaintTiming")
class PerformancePaintTiming extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory PerformancePaintTiming._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformanceResourceTiming")
class PerformanceResourceTiming extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory PerformanceResourceTiming._() {
    throw new UnsupportedError("Not supported");
  }

  final num connectEnd;

  final num connectStart;

  final int decodedBodySize;

  final num domainLookupEnd;

  final num domainLookupStart;

  final int encodedBodySize;

  final num fetchStart;

  final String initiatorType;

  final String nextHopProtocol;

  final num redirectEnd;

  final num redirectStart;

  final num requestStart;

  final num responseEnd;

  final num responseStart;

  final num secureConnectionStart;

  final List<PerformanceServerTiming> serverTiming;

  final int transferSize;

  final num workerStart;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PerformanceServerTiming")
class PerformanceServerTiming extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PerformanceServerTiming._() {
    throw new UnsupportedError("Not supported");
  }

  final String description;

  final num duration;

  final String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("PerformanceTiming")
class PerformanceTiming extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PerformanceTiming._() {
    throw new UnsupportedError("Not supported");
  }

  final int connectEnd;

  final int connectStart;

  final int domComplete;

  final int domContentLoadedEventEnd;

  final int domContentLoadedEventStart;

  final int domInteractive;

  final int domLoading;

  final int domainLookupEnd;

  final int domainLookupStart;

  final int fetchStart;

  final int loadEventEnd;

  final int loadEventStart;

  final int navigationStart;

  final int redirectEnd;

  final int redirectStart;

  final int requestStart;

  final int responseEnd;

  final int responseStart;

  final int secureConnectionStart;

  final int unloadEventEnd;

  final int unloadEventStart;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PermissionStatus")
class PermissionStatus extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory PermissionStatus._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  final String state;

  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Permissions")
class Permissions extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Permissions._() {
    throw new UnsupportedError("Not supported");
  }

  Future<PermissionStatus> query(Map permission) {
    var permission_dict = convertDartToNative_Dictionary(permission);
    return promiseToFuture<PermissionStatus>(
        JS("", "#.query(#)", this, permission_dict));
  }

  Future<PermissionStatus> request(Map permissions) {
    var permissions_dict = convertDartToNative_Dictionary(permissions);
    return promiseToFuture<PermissionStatus>(
        JS("", "#.request(#)", this, permissions_dict));
  }

  Future<PermissionStatus> requestAll(List<Map> permissions) =>
      promiseToFuture<PermissionStatus>(
          JS("", "#.requestAll(#)", this, permissions));

  Future<PermissionStatus> revoke(Map permission) {
    var permission_dict = convertDartToNative_Dictionary(permission);
    return promiseToFuture<PermissionStatus>(
        JS("", "#.revoke(#)", this, permission_dict));
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PhotoCapabilities")
class PhotoCapabilities extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PhotoCapabilities._() {
    throw new UnsupportedError("Not supported");
  }

  final List fillLightMode;

  final MediaSettingsRange imageHeight;

  final MediaSettingsRange imageWidth;

  final String redEyeReduction;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLPictureElement")
class PictureElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory PictureElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  PictureElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Plugin")
class Plugin extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Plugin._() {
    throw new UnsupportedError("Not supported");
  }

  final String description;

  final String filename;

  final int length;

  final String name;

  MimeType item(int index) native;

  MimeType namedItem(String name) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PluginArray")
class PluginArray extends Interceptor
    with ListMixin<Plugin>, ImmutableListMixin<Plugin>
    implements JavaScriptIndexingBehavior<Plugin>, List<Plugin> {
  // To suppress missing implicit constructor warnings.
  factory PluginArray._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  Plugin operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Plugin", "#[#]", this, index);
  }

  void operator []=(int index, Plugin value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Plugin> mixins.
  // Plugin is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Plugin get first {
    if (this.length > 0) {
      return JS('Plugin', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Plugin get last {
    int len = this.length;
    if (len > 0) {
      return JS('Plugin', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Plugin get single {
    int len = this.length;
    if (len == 1) {
      return JS('Plugin', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Plugin elementAt(int index) => this[index];
  // -- end List<Plugin> mixins.

  Plugin item(int index) native;

  Plugin namedItem(String name) native;

  void refresh(bool reload) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PointerEvent")
class PointerEvent extends MouseEvent {
  // To suppress missing implicit constructor warnings.
  factory PointerEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory PointerEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return PointerEvent._create_1(type, eventInitDict_1);
    }
    return PointerEvent._create_2(type);
  }
  static PointerEvent _create_1(type, eventInitDict) =>
      JS('PointerEvent', 'new PointerEvent(#,#)', type, eventInitDict);
  static PointerEvent _create_2(type) =>
      JS('PointerEvent', 'new PointerEvent(#)', type);

  final num height;

  final bool isPrimary;

  final int pointerId;

  final String pointerType;

  final num pressure;

  final num tangentialPressure;

  final int tiltX;

  final int tiltY;

  final int twist;

  final num width;

  List<PointerEvent> getCoalescedEvents() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("PopStateEvent")
class PopStateEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PopStateEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory PopStateEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return PopStateEvent._create_1(type, eventInitDict_1);
    }
    return PopStateEvent._create_2(type);
  }
  static PopStateEvent _create_1(type, eventInitDict) =>
      JS('PopStateEvent', 'new PopStateEvent(#,#)', type, eventInitDict);
  static PopStateEvent _create_2(type) =>
      JS('PopStateEvent', 'new PopStateEvent(#)', type);

  dynamic get state =>
      convertNativeToDart_SerializedScriptValue(this._get_state);
  @JSName('state')
  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final dynamic _get_state;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Unstable()
typedef void _PositionCallback(Geoposition position);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("PositionError")
class PositionError extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PositionError._() {
    throw new UnsupportedError("Not supported");
  }

  static const int PERMISSION_DENIED = 1;

  static const int POSITION_UNAVAILABLE = 2;

  static const int TIMEOUT = 3;

  final int code;

  final String message;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Unstable()
typedef void _PositionErrorCallback(PositionError error);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLPreElement")
class PreElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory PreElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory PreElement() => JS('returns:PreElement;creates:PreElement;new:true',
      '#.createElement(#)', document, "pre");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  PreElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Presentation")
class Presentation extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Presentation._() {
    throw new UnsupportedError("Not supported");
  }

  PresentationRequest defaultRequest;

  final PresentationReceiver receiver;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PresentationAvailability")
class PresentationAvailability extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory PresentationAvailability._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  final bool value;

  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PresentationConnection")
class PresentationConnection extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory PresentationConnection._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  String binaryType;

  final String id;

  final String state;

  final String url;

  void close() native;

  void send(data_OR_message) native;

  void terminate() native;

  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PresentationConnectionAvailableEvent")
class PresentationConnectionAvailableEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PresentationConnectionAvailableEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory PresentationConnectionAvailableEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return PresentationConnectionAvailableEvent._create_1(
        type, eventInitDict_1);
  }
  static PresentationConnectionAvailableEvent _create_1(type, eventInitDict) =>
      JS('PresentationConnectionAvailableEvent',
          'new PresentationConnectionAvailableEvent(#,#)', type, eventInitDict);

  final PresentationConnection connection;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PresentationConnectionCloseEvent")
class PresentationConnectionCloseEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PresentationConnectionCloseEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory PresentationConnectionCloseEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return PresentationConnectionCloseEvent._create_1(type, eventInitDict_1);
  }
  static PresentationConnectionCloseEvent _create_1(type, eventInitDict) => JS(
      'PresentationConnectionCloseEvent',
      'new PresentationConnectionCloseEvent(#,#)',
      type,
      eventInitDict);

  final String message;

  final String reason;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PresentationConnectionList")
class PresentationConnectionList extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory PresentationConnectionList._() {
    throw new UnsupportedError("Not supported");
  }

  final List<PresentationConnection> connections;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PresentationReceiver")
class PresentationReceiver extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PresentationReceiver._() {
    throw new UnsupportedError("Not supported");
  }

  Future<PresentationConnectionList> get connectionList =>
      promiseToFuture<PresentationConnectionList>(
          JS("", "#.connectionList", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PresentationRequest")
class PresentationRequest extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory PresentationRequest._() {
    throw new UnsupportedError("Not supported");
  }

  factory PresentationRequest(url_OR_urls) {
    if ((url_OR_urls is String)) {
      return PresentationRequest._create_1(url_OR_urls);
    }
    if ((url_OR_urls is List<String>)) {
      List urls_1 = convertDartToNative_StringArray(url_OR_urls);
      return PresentationRequest._create_2(urls_1);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static PresentationRequest _create_1(url_OR_urls) =>
      JS('PresentationRequest', 'new PresentationRequest(#)', url_OR_urls);
  static PresentationRequest _create_2(url_OR_urls) =>
      JS('PresentationRequest', 'new PresentationRequest(#)', url_OR_urls);

  Future<PresentationAvailability> getAvailability() =>
      promiseToFuture<PresentationAvailability>(
          JS("", "#.getAvailability()", this));

  Future<PresentationConnection> reconnect(String id) =>
      promiseToFuture<PresentationConnection>(
          JS("", "#.reconnect(#)", this, id));

  Future<PresentationConnection> start() =>
      promiseToFuture<PresentationConnection>(JS("", "#.start()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("ProcessingInstruction")
class ProcessingInstruction extends CharacterData {
  // To suppress missing implicit constructor warnings.
  factory ProcessingInstruction._() {
    throw new UnsupportedError("Not supported");
  }

  final StyleSheet sheet;

  final String target;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("HTMLProgressElement")
class ProgressElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ProgressElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory ProgressElement() => document.createElement("progress");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ProgressElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('progress');

  @Unstable()
  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> labels;

  num max;

  final num position;

  num value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ProgressEvent")
class ProgressEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory ProgressEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory ProgressEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return ProgressEvent._create_1(type, eventInitDict_1);
    }
    return ProgressEvent._create_2(type);
  }
  static ProgressEvent _create_1(type, eventInitDict) =>
      JS('ProgressEvent', 'new ProgressEvent(#,#)', type, eventInitDict);
  static ProgressEvent _create_2(type) =>
      JS('ProgressEvent', 'new ProgressEvent(#)', type);

  final bool lengthComputable;

  final int loaded;

  final int total;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PromiseRejectionEvent")
class PromiseRejectionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PromiseRejectionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory PromiseRejectionEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return PromiseRejectionEvent._create_1(type, eventInitDict_1);
  }
  static PromiseRejectionEvent _create_1(type, eventInitDict) => JS(
      'PromiseRejectionEvent',
      'new PromiseRejectionEvent(#,#)',
      type,
      eventInitDict);

  Future get promise => promiseToFuture(JS("", "#.promise", this));

  final Object reason;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PublicKeyCredential")
class PublicKeyCredential extends Credential {
  // To suppress missing implicit constructor warnings.
  factory PublicKeyCredential._() {
    throw new UnsupportedError("Not supported");
  }

  final ByteBuffer rawId;

  final AuthenticatorResponse response;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PushEvent")
class PushEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory PushEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory PushEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return PushEvent._create_1(type, eventInitDict_1);
    }
    return PushEvent._create_2(type);
  }
  static PushEvent _create_1(type, eventInitDict) =>
      JS('PushEvent', 'new PushEvent(#,#)', type, eventInitDict);
  static PushEvent _create_2(type) => JS('PushEvent', 'new PushEvent(#)', type);

  final PushMessageData data;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PushManager")
class PushManager extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PushManager._() {
    throw new UnsupportedError("Not supported");
  }

  static final List<String> supportedContentEncodings;

  Future<PushSubscription> getSubscription() =>
      promiseToFuture<PushSubscription>(JS("", "#.getSubscription()", this));

  Future permissionState([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(JS("", "#.permissionState(#)", this, options_dict));
  }

  Future<PushSubscription> subscribe([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture<PushSubscription>(
        JS("", "#.subscribe(#)", this, options_dict));
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PushMessageData")
class PushMessageData extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PushMessageData._() {
    throw new UnsupportedError("Not supported");
  }

  ByteBuffer arrayBuffer() native;

  Blob blob() native;

  Object json() native;

  String text() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PushSubscription")
class PushSubscription extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PushSubscription._() {
    throw new UnsupportedError("Not supported");
  }

  final String endpoint;

  final int expirationTime;

  final PushSubscriptionOptions options;

  ByteBuffer getKey(String name) native;

  Future<bool> unsubscribe() =>
      promiseToFuture<bool>(JS("", "#.unsubscribe()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("PushSubscriptionOptions")
class PushSubscriptionOptions extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PushSubscriptionOptions._() {
    throw new UnsupportedError("Not supported");
  }

  final ByteBuffer applicationServerKey;

  final bool userVisibleOnly;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLQuoteElement")
class QuoteElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory QuoteElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory QuoteElement() => JS(
      'returns:QuoteElement;creates:QuoteElement;new:true',
      '#.createElement(#)',
      document,
      "q");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  QuoteElement.created() : super.created();

  String cite;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void RtcPeerConnectionErrorCallback(DomException exception);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void _RtcSessionDescriptionCallback(RtcSessionDescription sdp);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void RtcStatsCallback(RtcStatsResponse response);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Unstable()
@Native("Range")
class Range extends Interceptor {
  factory Range() => document.createRange();

  factory Range.fromPoint(Point point) =>
      document._caretRangeFromPoint(point.x, point.y);
  // To suppress missing implicit constructor warnings.
  factory Range._() {
    throw new UnsupportedError("Not supported");
  }

  static const int END_TO_END = 2;

  static const int END_TO_START = 3;

  static const int START_TO_END = 1;

  static const int START_TO_START = 0;

  final bool collapsed;

  final Node commonAncestorContainer;

  final Node endContainer;

  final int endOffset;

  final Node startContainer;

  final int startOffset;

  DocumentFragment cloneContents() native;

  Range cloneRange() native;

  void collapse([bool toStart]) native;

  int compareBoundaryPoints(int how, Range sourceRange) native;

  int comparePoint(Node node, int offset) native;

  DocumentFragment createContextualFragment(String fragment) native;

  void deleteContents() native;

  void detach() native;

  void expand(String unit) native;

  DocumentFragment extractContents() native;

  Rectangle getBoundingClientRect() native;

  @JSName('getClientRects')
  @Returns('DomRectList|Null')
  @Creates('DomRectList')
  List<Rectangle> _getClientRects() native;

  void insertNode(Node node) native;

  bool isPointInRange(Node node, int offset) native;

  void selectNode(Node node) native;

  void selectNodeContents(Node node) native;

  void setEnd(Node node, int offset) native;

  void setEndAfter(Node node) native;

  void setEndBefore(Node node) native;

  void setStart(Node node, int offset) native;

  void setStartAfter(Node node) native;

  void setStartBefore(Node node) native;

  void surroundContents(Node newParent) native;

  List<Rectangle> getClientRects() {
    var value = _getClientRects();

    // If no prototype we need one for the world to hookup to the proper Dart class.
    var jsProto = JS('', '#.prototype', value);
    if (jsProto == null) {
      JS('', '#.prototype = Object.create(null)', value);
    }

    applyExtension('DOMRectList', value);

    return value;
  }

  /**
   * Checks if createContextualFragment is supported.
   *
   * See also:
   *
   * * [createContextualFragment]
   */
  static bool get supportsCreateContextualFragment =>
      JS('bool', '("createContextualFragment" in window.Range.prototype)');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RelatedApplication")
class RelatedApplication extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory RelatedApplication._() {
    throw new UnsupportedError("Not supported");
  }

  final String id;

  final String platform;

  final String url;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RelativeOrientationSensor")
class RelativeOrientationSensor extends OrientationSensor {
  // To suppress missing implicit constructor warnings.
  factory RelativeOrientationSensor._() {
    throw new UnsupportedError("Not supported");
  }

  factory RelativeOrientationSensor([Map sensorOptions]) {
    if (sensorOptions != null) {
      var sensorOptions_1 = convertDartToNative_Dictionary(sensorOptions);
      return RelativeOrientationSensor._create_1(sensorOptions_1);
    }
    return RelativeOrientationSensor._create_2();
  }
  static RelativeOrientationSensor _create_1(sensorOptions) => JS(
      'RelativeOrientationSensor',
      'new RelativeOrientationSensor(#)',
      sensorOptions);
  static RelativeOrientationSensor _create_2() =>
      JS('RelativeOrientationSensor', 'new RelativeOrientationSensor()');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RemotePlayback")
class RemotePlayback extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory RemotePlayback._() {
    throw new UnsupportedError("Not supported");
  }

  final String state;

  Future cancelWatchAvailability([int id]) =>
      promiseToFuture(JS("", "#.cancelWatchAvailability(#)", this, id));

  Future prompt() => promiseToFuture(JS("", "#.prompt()", this));

  Future<int> watchAvailability(RemotePlaybackAvailabilityCallback callback) =>
      promiseToFuture<int>(JS("", "#.watchAvailability(#)", this, callback));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void RemotePlaybackAvailabilityCallback(bool available);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ReportBody")
class ReportBody extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ReportBody._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ReportingObserver")
class ReportingObserver extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ReportingObserver._() {
    throw new UnsupportedError("Not supported");
  }

  factory ReportingObserver(ReportingObserverCallback callback) {
    return ReportingObserver._create_1(callback);
  }
  static ReportingObserver _create_1(callback) =>
      JS('ReportingObserver', 'new ReportingObserver(#)', callback);

  void disconnect() native;

  void observe() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void ReportingObserverCallback(
    List reports, ReportingObserver observer);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void RequestAnimationFrameCallback(num highResTime);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ResizeObserver")
class ResizeObserver extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ResizeObserver._() {
    throw new UnsupportedError("Not supported");
  }

  factory ResizeObserver(ResizeObserverCallback callback) {
    return ResizeObserver._create_1(callback);
  }
  static ResizeObserver _create_1(callback) =>
      JS('ResizeObserver', 'new ResizeObserver(#)', callback);

  void disconnect() native;

  void observe(Element target) native;

  void unobserve(Element target) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void ResizeObserverCallback(
    List<ResizeObserverEntry> entries, ResizeObserver observer);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ResizeObserverEntry")
class ResizeObserverEntry extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ResizeObserverEntry._() {
    throw new UnsupportedError("Not supported");
  }

  final DomRectReadOnly contentRect;

  final Element target;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCCertificate")
class RtcCertificate extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory RtcCertificate._() {
    throw new UnsupportedError("Not supported");
  }

  final int expires;

  List<Map> getFingerprints() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCDataChannel,DataChannel")
class RtcDataChannel extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory RtcDataChannel._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `close` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> closeEvent =
      const EventStreamProvider<Event>('close');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `open` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> openEvent =
      const EventStreamProvider<Event>('open');

  String binaryType;

  final int bufferedAmount;

  int bufferedAmountLowThreshold;

  final int id;

  final String label;

  final int maxRetransmitTime;

  final int maxRetransmits;

  final bool negotiated;

  final bool ordered;

  final String protocol;

  final String readyState;

  final bool reliable;

  void close() native;

  void send(data) native;

  @JSName('send')
  void sendBlob(Blob data) native;

  @JSName('send')
  void sendByteBuffer(ByteBuffer data) native;

  @JSName('send')
  void sendString(String data) native;

  @JSName('send')
  void sendTypedData(TypedData data) native;

  /// Stream of `close` events handled by this [RtcDataChannel].
  Stream<Event> get onClose => closeEvent.forTarget(this);

  /// Stream of `error` events handled by this [RtcDataChannel].
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [RtcDataChannel].
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `open` events handled by this [RtcDataChannel].
  Stream<Event> get onOpen => openEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCDataChannelEvent")
class RtcDataChannelEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory RtcDataChannelEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory RtcDataChannelEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return RtcDataChannelEvent._create_1(type, eventInitDict_1);
  }
  static RtcDataChannelEvent _create_1(type, eventInitDict) => JS(
      'RtcDataChannelEvent',
      'new RTCDataChannelEvent(#,#)',
      type,
      eventInitDict);

  final RtcDataChannel channel;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCDTMFSender")
class RtcDtmfSender extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory RtcDtmfSender._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `tonechange` events to event
   * handlers that are not necessarily instances of [RtcDtmfSender].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<RtcDtmfToneChangeEvent> toneChangeEvent =
      const EventStreamProvider<RtcDtmfToneChangeEvent>('tonechange');

  @JSName('canInsertDTMF')
  final bool canInsertDtmf;

  final int duration;

  final int interToneGap;

  final String toneBuffer;

  final MediaStreamTrack track;

  @JSName('insertDTMF')
  void insertDtmf(String tones, [int duration, int interToneGap]) native;

  /// Stream of `tonechange` events handled by this [RtcDtmfSender].
  Stream<RtcDtmfToneChangeEvent> get onToneChange =>
      toneChangeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCDTMFToneChangeEvent")
class RtcDtmfToneChangeEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory RtcDtmfToneChangeEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory RtcDtmfToneChangeEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return RtcDtmfToneChangeEvent._create_1(type, eventInitDict_1);
  }
  static RtcDtmfToneChangeEvent _create_1(type, eventInitDict) => JS(
      'RtcDtmfToneChangeEvent',
      'new RTCDTMFToneChangeEvent(#,#)',
      type,
      eventInitDict);

  final String tone;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("RTCIceCandidate,mozRTCIceCandidate")
class RtcIceCandidate extends Interceptor {
  factory RtcIceCandidate(Map dictionary) {
    // TODO(efortuna): Remove this check if when you can actually construct with
    // the unprefixed RTCIceCandidate in Firefox (currently both are defined,
    // but one can't be used as a constructor).
    var constructorName = JS(
        '',
        'window[#]',
        Device.isFirefox
            ? '${Device.propertyPrefix}RTCIceCandidate'
            : 'RTCIceCandidate');
    return JS('RtcIceCandidate', 'new #(#)', constructorName,
        convertDartToNative_SerializedScriptValue(dictionary));
  }
  // To suppress missing implicit constructor warnings.
  factory RtcIceCandidate._() {
    throw new UnsupportedError("Not supported");
  }

  String candidate;

  int sdpMLineIndex;

  String sdpMid;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCLegacyStatsReport")
class RtcLegacyStatsReport extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory RtcLegacyStatsReport._() {
    throw new UnsupportedError("Not supported");
  }

  final String id;

  DateTime get timestamp => convertNativeToDart_DateTime(this._get_timestamp);
  @JSName('timestamp')
  final dynamic _get_timestamp;

  final String type;

  List<String> names() native;

  String stat(String name) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("RTCPeerConnection,webkitRTCPeerConnection,mozRTCPeerConnection")
class RtcPeerConnection extends EventTarget {
  factory RtcPeerConnection(Map rtcIceServers, [Map mediaConstraints]) {
    var constructorName = JS('RtcPeerConnection', 'window[#]',
        '${Device.propertyPrefix}RTCPeerConnection');
    if (mediaConstraints != null) {
      return JS(
          'RtcPeerConnection',
          'new #(#,#)',
          constructorName,
          convertDartToNative_SerializedScriptValue(rtcIceServers),
          convertDartToNative_SerializedScriptValue(mediaConstraints));
    } else {
      return JS('RtcPeerConnection', 'new #(#)', constructorName,
          convertDartToNative_SerializedScriptValue(rtcIceServers));
    }
  }

  /**
   * Checks if Real Time Communication (RTC) APIs are supported and enabled on
   * the current platform.
   */
  static bool get supported {
    // Currently in Firefox some of the RTC elements are defined but throw an
    // error unless the user has specifically enabled them in their
    // about:config. So we have to construct an element to actually test if RTC
    // is supported at the given time.
    try {
      new RtcPeerConnection({
        "iceServers": [
          {"url": "stun:localhost"}
        ]
      });
      return true;
    } catch (_) {
      return false;
    }
    return false;
  }

  /**
  * Temporarily exposes _getStats and old getStats as getLegacyStats until Chrome fully supports
  * new getStats API.
  */
  Future<RtcStatsResponse> getLegacyStats([MediaStreamTrack selector]) {
    var completer = new Completer<RtcStatsResponse>();
    _getStats((value) {
      completer.complete(value);
    }, selector);
    return completer.future;
  }

  @JSName('getStats')
  Future _getStats(
      [RtcStatsCallback successCallback, MediaStreamTrack selector]) native;

  static Future generateCertificate(/*AlgorithmIdentifier*/ keygenAlgorithm) =>
      JS('dynamic', 'generateCertificate(#)', keygenAlgorithm);

  // To suppress missing implicit constructor warnings.
  factory RtcPeerConnection._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `addstream` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MediaStreamEvent> addStreamEvent =
      const EventStreamProvider<MediaStreamEvent>('addstream');

  /**
   * Static factory designed to expose `datachannel` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<RtcDataChannelEvent> dataChannelEvent =
      const EventStreamProvider<RtcDataChannelEvent>('datachannel');

  /**
   * Static factory designed to expose `icecandidate` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<RtcPeerConnectionIceEvent>
      iceCandidateEvent =
      const EventStreamProvider<RtcPeerConnectionIceEvent>('icecandidate');

  /**
   * Static factory designed to expose `iceconnectionstatechange` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> iceConnectionStateChangeEvent =
      const EventStreamProvider<Event>('iceconnectionstatechange');

  /**
   * Static factory designed to expose `negotiationneeded` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> negotiationNeededEvent =
      const EventStreamProvider<Event>('negotiationneeded');

  /**
   * Static factory designed to expose `removestream` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MediaStreamEvent> removeStreamEvent =
      const EventStreamProvider<MediaStreamEvent>('removestream');

  /**
   * Static factory designed to expose `signalingstatechange` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> signalingStateChangeEvent =
      const EventStreamProvider<Event>('signalingstatechange');

  final String iceConnectionState;

  final String iceGatheringState;

  final RtcSessionDescription localDescription;

  final RtcSessionDescription remoteDescription;

  final String signalingState;

  Future addIceCandidate(Object candidate,
          [VoidCallback successCallback,
          RtcPeerConnectionErrorCallback failureCallback]) =>
      promiseToFuture(JS("", "#.addIceCandidate(#, #, #)", this, candidate,
          successCallback, failureCallback));

  void addStream(MediaStream stream, [Map mediaConstraints]) {
    if (mediaConstraints != null) {
      var mediaConstraints_1 = convertDartToNative_Dictionary(mediaConstraints);
      _addStream_1(stream, mediaConstraints_1);
      return;
    }
    _addStream_2(stream);
    return;
  }

  @JSName('addStream')
  void _addStream_1(MediaStream stream, mediaConstraints) native;
  @JSName('addStream')
  void _addStream_2(MediaStream stream) native;

  RtcRtpSender addTrack(MediaStreamTrack track, MediaStream streams) native;

  void close() native;

  Future<RtcSessionDescription> createAnswer([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture<RtcSessionDescription>(
        JS("", "#.createAnswer(#)", this, options_dict));
  }

  @JSName('createDTMFSender')
  RtcDtmfSender createDtmfSender(MediaStreamTrack track) native;

  RtcDataChannel createDataChannel(String label, [Map dataChannelDict]) {
    if (dataChannelDict != null) {
      var dataChannelDict_1 = convertDartToNative_Dictionary(dataChannelDict);
      return _createDataChannel_1(label, dataChannelDict_1);
    }
    return _createDataChannel_2(label);
  }

  @JSName('createDataChannel')
  RtcDataChannel _createDataChannel_1(label, dataChannelDict) native;
  @JSName('createDataChannel')
  RtcDataChannel _createDataChannel_2(label) native;

  Future<RtcSessionDescription> createOffer([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture<RtcSessionDescription>(
        JS("", "#.createOffer(#)", this, options_dict));
  }

  List<MediaStream> getLocalStreams() native;

  List<RtcRtpReceiver> getReceivers() native;

  List<MediaStream> getRemoteStreams() native;

  List<RtcRtpSender> getSenders() native;

  Future<RtcStatsReport> getStats() =>
      promiseToFuture<RtcStatsReport>(JS("", "#.getStats()", this));

  void removeStream(MediaStream stream) native;

  void removeTrack(RtcRtpSender sender) native;

  void setConfiguration(Map configuration) {
    var configuration_1 = convertDartToNative_Dictionary(configuration);
    _setConfiguration_1(configuration_1);
    return;
  }

  @JSName('setConfiguration')
  void _setConfiguration_1(configuration) native;

  Future setLocalDescription(Map description) {
    var description_dict = convertDartToNative_Dictionary(description);
    return promiseToFuture(
        JS("", "#.setLocalDescription(#)", this, description_dict));
  }

  Future setRemoteDescription(Map description) {
    var description_dict = convertDartToNative_Dictionary(description);
    return promiseToFuture(
        JS("", "#.setRemoteDescription(#)", this, description_dict));
  }

  /// Stream of `addstream` events handled by this [RtcPeerConnection].
  Stream<MediaStreamEvent> get onAddStream => addStreamEvent.forTarget(this);

  /// Stream of `datachannel` events handled by this [RtcPeerConnection].
  Stream<RtcDataChannelEvent> get onDataChannel =>
      dataChannelEvent.forTarget(this);

  /// Stream of `icecandidate` events handled by this [RtcPeerConnection].
  Stream<RtcPeerConnectionIceEvent> get onIceCandidate =>
      iceCandidateEvent.forTarget(this);

  /// Stream of `iceconnectionstatechange` events handled by this [RtcPeerConnection].
  Stream<Event> get onIceConnectionStateChange =>
      iceConnectionStateChangeEvent.forTarget(this);

  /// Stream of `negotiationneeded` events handled by this [RtcPeerConnection].
  Stream<Event> get onNegotiationNeeded =>
      negotiationNeededEvent.forTarget(this);

  /// Stream of `removestream` events handled by this [RtcPeerConnection].
  Stream<MediaStreamEvent> get onRemoveStream =>
      removeStreamEvent.forTarget(this);

  /// Stream of `signalingstatechange` events handled by this [RtcPeerConnection].
  Stream<Event> get onSignalingStateChange =>
      signalingStateChangeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCPeerConnectionIceEvent")
class RtcPeerConnectionIceEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory RtcPeerConnectionIceEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory RtcPeerConnectionIceEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return RtcPeerConnectionIceEvent._create_1(type, eventInitDict_1);
    }
    return RtcPeerConnectionIceEvent._create_2(type);
  }
  static RtcPeerConnectionIceEvent _create_1(type, eventInitDict) => JS(
      'RtcPeerConnectionIceEvent',
      'new RTCPeerConnectionIceEvent(#,#)',
      type,
      eventInitDict);
  static RtcPeerConnectionIceEvent _create_2(type) =>
      JS('RtcPeerConnectionIceEvent', 'new RTCPeerConnectionIceEvent(#)', type);

  final RtcIceCandidate candidate;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCRtpContributingSource")
class RtcRtpContributingSource extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory RtcRtpContributingSource._() {
    throw new UnsupportedError("Not supported");
  }

  final int source;

  final num timestamp;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCRtpReceiver")
class RtcRtpReceiver extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory RtcRtpReceiver._() {
    throw new UnsupportedError("Not supported");
  }

  final MediaStreamTrack track;

  List<RtcRtpContributingSource> getContributingSources() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCRtpSender")
class RtcRtpSender extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory RtcRtpSender._() {
    throw new UnsupportedError("Not supported");
  }

  final MediaStreamTrack track;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("RTCSessionDescription,mozRTCSessionDescription")
class RtcSessionDescription extends Interceptor {
  factory RtcSessionDescription(Map dictionary) {
    // TODO(efortuna): Remove this check if when you can actually construct with
    // the unprefixed RTCIceCandidate in Firefox (currently both are defined,
    // but one can't be used as a constructor).
    var constructorName = JS(
        '',
        'window[#]',
        Device.isFirefox
            ? '${Device.propertyPrefix}RTCSessionDescription'
            : 'RTCSessionDescription');
    return JS('RtcSessionDescription', 'new #(#)', constructorName,
        convertDartToNative_SerializedScriptValue(dictionary));
  }
  // To suppress missing implicit constructor warnings.
  factory RtcSessionDescription._() {
    throw new UnsupportedError("Not supported");
  }

  String sdp;

  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCStatsReport")
class RtcStatsReport extends Interceptor with MapMixin<String, dynamic> {
  // To suppress missing implicit constructor warnings.
  factory RtcStatsReport._() {
    throw new UnsupportedError("Not supported");
  }

  Map _getItem(String key) =>
      convertNativeToDart_Dictionary(JS('', '#.get(#)', this, key));

  void addAll(Map<String, dynamic> other) {
    throw new UnsupportedError("Not supported");
  }

  bool containsValue(dynamic value) => values.any((e) => e == value);

  bool containsKey(dynamic key) => _getItem(key) != null;

  Map operator [](dynamic key) => _getItem(key);

  void forEach(void f(String key, dynamic value)) {
    var entries = JS('', '#.entries()', this);
    while (true) {
      var entry = JS('', '#.next()', entries);
      if (JS('bool', '#.done', entry)) return;
      f(JS('String', '#.value[0]', entry),
          convertNativeToDart_Dictionary(JS('', '#.value[1]', entry)));
    }
  }

  Iterable<String> get keys {
    final keys = <String>[];
    forEach((k, v) => keys.add(k));
    return keys;
  }

  Iterable<Map> get values {
    final values = <Map>[];
    forEach((k, v) => values.add(v));
    return values;
  }

  int get length => JS('int', '#.size', this);

  bool get isEmpty => length == 0;

  bool get isNotEmpty => !isEmpty;

  void operator []=(String key, dynamic value) {
    throw new UnsupportedError("Not supported");
  }

  dynamic putIfAbsent(String key, dynamic ifAbsent()) {
    throw new UnsupportedError("Not supported");
  }

  String remove(dynamic key) {
    throw new UnsupportedError("Not supported");
  }

  void clear() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCStatsResponse")
class RtcStatsResponse extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory RtcStatsResponse._() {
    throw new UnsupportedError("Not supported");
  }

  RtcLegacyStatsReport namedItem(String name) native;

  List<RtcLegacyStatsReport> result() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("RTCTrackEvent")
class RtcTrackEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory RtcTrackEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory RtcTrackEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return RtcTrackEvent._create_1(type, eventInitDict_1);
  }
  static RtcTrackEvent _create_1(type, eventInitDict) =>
      JS('RtcTrackEvent', 'new RTCTrackEvent(#,#)', type, eventInitDict);

  final RtcRtpReceiver receiver;

  final List<MediaStream> streams;

  final MediaStreamTrack track;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Screen")
class Screen extends Interceptor {
  Rectangle get available =>
      new Rectangle(_availLeft, _availTop, _availWidth, _availHeight);
  // To suppress missing implicit constructor warnings.
  factory Screen._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('availHeight')
  final int _availHeight;

  @JSName('availLeft')
  final int _availLeft;

  @JSName('availTop')
  final int _availTop;

  @JSName('availWidth')
  final int _availWidth;

  final int colorDepth;

  final int height;

  bool keepAwake;

  final ScreenOrientation orientation;

  final int pixelDepth;

  final int width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ScreenOrientation")
class ScreenOrientation extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory ScreenOrientation._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  final int angle;

  final String type;

  Future lock(String orientation) =>
      promiseToFuture(JS("", "#.lock(#)", this, orientation));

  void unlock() native;

  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLScriptElement")
class ScriptElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ScriptElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory ScriptElement() => JS(
      'returns:ScriptElement;creates:ScriptElement;new:true',
      '#.createElement(#)',
      document,
      "script");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ScriptElement.created() : super.created();

  bool async;

  String charset;

  String crossOrigin;

  bool defer;

  String integrity;

  bool noModule;

  String src;

  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ScrollState")
class ScrollState extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ScrollState._() {
    throw new UnsupportedError("Not supported");
  }

  factory ScrollState([Map scrollStateInit]) {
    if (scrollStateInit != null) {
      var scrollStateInit_1 = convertDartToNative_Dictionary(scrollStateInit);
      return ScrollState._create_1(scrollStateInit_1);
    }
    return ScrollState._create_2();
  }
  static ScrollState _create_1(scrollStateInit) =>
      JS('ScrollState', 'new ScrollState(#)', scrollStateInit);
  static ScrollState _create_2() => JS('ScrollState', 'new ScrollState()');

  final num deltaGranularity;

  final num deltaX;

  final num deltaY;

  final bool fromUserInput;

  final bool inInertialPhase;

  final bool isBeginning;

  final bool isDirectManipulation;

  final bool isEnding;

  final int positionX;

  final int positionY;

  final num velocityX;

  final num velocityY;

  void consumeDelta(num x, num y) native;

  void distributeToScrollChainDescendant() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void ScrollStateCallback(ScrollState scrollState);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ScrollTimeline")
class ScrollTimeline extends AnimationTimeline {
  // To suppress missing implicit constructor warnings.
  factory ScrollTimeline._() {
    throw new UnsupportedError("Not supported");
  }

  factory ScrollTimeline([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return ScrollTimeline._create_1(options_1);
    }
    return ScrollTimeline._create_2();
  }
  static ScrollTimeline _create_1(options) =>
      JS('ScrollTimeline', 'new ScrollTimeline(#)', options);
  static ScrollTimeline _create_2() =>
      JS('ScrollTimeline', 'new ScrollTimeline()');

  final String orientation;

  final Element scrollSource;

  final Object timeRange;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SecurityPolicyViolationEvent")
class SecurityPolicyViolationEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory SecurityPolicyViolationEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory SecurityPolicyViolationEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return SecurityPolicyViolationEvent._create_1(type, eventInitDict_1);
    }
    return SecurityPolicyViolationEvent._create_2(type);
  }
  static SecurityPolicyViolationEvent _create_1(type, eventInitDict) => JS(
      'SecurityPolicyViolationEvent',
      'new SecurityPolicyViolationEvent(#,#)',
      type,
      eventInitDict);
  static SecurityPolicyViolationEvent _create_2(type) => JS(
      'SecurityPolicyViolationEvent',
      'new SecurityPolicyViolationEvent(#)',
      type);

  @JSName('blockedURI')
  final String blockedUri;

  final int columnNumber;

  final String disposition;

  @JSName('documentURI')
  final String documentUri;

  final String effectiveDirective;

  final int lineNumber;

  final String originalPolicy;

  final String referrer;

  final String sample;

  final String sourceFile;

  final int statusCode;

  final String violatedDirective;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLSelectElement")
class SelectElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory SelectElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory SelectElement() => JS(
      'returns:SelectElement;creates:SelectElement;new:true',
      '#.createElement(#)',
      document,
      "select");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  SelectElement.created() : super.created();

  bool autofocus;

  bool disabled;

  final FormElement form;

  @Unstable()
  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> labels;

  int length;

  bool multiple;

  String name;

  bool required;

  int selectedIndex;

  int size;

  final String type;

  final String validationMessage;

  final ValidityState validity;

  String value;

  final bool willValidate;

  void __setter__(int index, OptionElement option) native;

  void add(Object element, Object before) native;

  bool checkValidity() native;

  Element item(int index) native;

  OptionElement namedItem(String name) native;

  bool reportValidity() native;

  void setCustomValidity(String error) native;

  // Override default options, since IE returns SelectElement itself and it
  // does not operate as a List.
  List<OptionElement> get options {
    dynamic options = this.querySelectorAll<OptionElement>('option');
    return new UnmodifiableListView(options.toList());
  }

  List<OptionElement> get selectedOptions {
    // IE does not change the selected flag for single-selection items.
    if (this.multiple) {
      var options = this.options.where((o) => o.selected).toList();
      return new UnmodifiableListView(options);
    } else {
      return [this.options[this.selectedIndex]];
    }
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Selection")
class Selection extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Selection._() {
    throw new UnsupportedError("Not supported");
  }

  final Node anchorNode;

  final int anchorOffset;

  final Node baseNode;

  final int baseOffset;

  final Node extentNode;

  final int extentOffset;

  final Node focusNode;

  final int focusOffset;

  final bool isCollapsed;

  final int rangeCount;

  final String type;

  void addRange(Range range) native;

  void collapse(Node node, [int offset]) native;

  void collapseToEnd() native;

  void collapseToStart() native;

  bool containsNode(Node node, [bool allowPartialContainment]) native;

  void deleteFromDocument() native;

  void empty() native;

  void extend(Node node, [int offset]) native;

  Range getRangeAt(int index) native;

  void modify(String alter, String direction, String granularity) native;

  void removeAllRanges() native;

  void removeRange(Range range) native;

  void selectAllChildren(Node node) native;

  void setBaseAndExtent(
      Node baseNode, int baseOffset, Node extentNode, int extentOffset) native;

  void setPosition(Node node, [int offset]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Sensor")
class Sensor extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory Sensor._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  final bool activated;

  final bool hasReading;

  final num timestamp;

  void start() native;

  void stop() native;

  Stream<Event> get onError => errorEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SensorErrorEvent")
class SensorErrorEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory SensorErrorEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory SensorErrorEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return SensorErrorEvent._create_1(type, eventInitDict_1);
  }
  static SensorErrorEvent _create_1(type, eventInitDict) =>
      JS('SensorErrorEvent', 'new SensorErrorEvent(#,#)', type, eventInitDict);

  final DomException error;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ServiceWorker")
class ServiceWorker extends EventTarget implements AbstractWorker {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorker._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  @JSName('scriptURL')
  final String scriptUrl;

  final String state;

  void postMessage(Object message, [List<Object> transfer]) native;

  Stream<Event> get onError => errorEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ServiceWorkerContainer")
class ServiceWorkerContainer extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerContainer._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  final ServiceWorker controller;

  Future<ServiceWorkerRegistration> get ready =>
      promiseToFuture<ServiceWorkerRegistration>(JS("", "#.ready", this));

  Future<ServiceWorkerRegistration> getRegistration([String documentURL]) =>
      promiseToFuture<ServiceWorkerRegistration>(
          JS("", "#.getRegistration(#)", this, documentURL));

  Future<List<ServiceWorkerRegistration>> getRegistrations() =>
      promiseToFuture<List<ServiceWorkerRegistration>>(
          JS("", "#.getRegistrations()", this));

  Future<ServiceWorkerRegistration> register(String url, [Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture<ServiceWorkerRegistration>(
        JS("", "#.register(#, #)", this, url, options_dict));
  }

  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ServiceWorkerGlobalScope")
class ServiceWorkerGlobalScope extends WorkerGlobalScope {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerGlobalScope._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> activateEvent =
      const EventStreamProvider<Event>('activate');

  static const EventStreamProvider<Event> fetchEvent =
      const EventStreamProvider<Event>('fetch');

  static const EventStreamProvider<ForeignFetchEvent> foreignfetchEvent =
      const EventStreamProvider<ForeignFetchEvent>('foreignfetch');

  static const EventStreamProvider<Event> installEvent =
      const EventStreamProvider<Event>('install');

  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  final Clients clients;

  final ServiceWorkerRegistration registration;

  Future skipWaiting() => promiseToFuture(JS("", "#.skipWaiting()", this));

  Stream<Event> get onActivate => activateEvent.forTarget(this);

  Stream<Event> get onFetch => fetchEvent.forTarget(this);

  Stream<ForeignFetchEvent> get onForeignfetch =>
      foreignfetchEvent.forTarget(this);

  Stream<Event> get onInstall => installEvent.forTarget(this);

  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  static ServiceWorkerGlobalScope get instance {
    return _workerSelf as ServiceWorkerGlobalScope;
  }
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ServiceWorkerRegistration")
class ServiceWorkerRegistration extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerRegistration._() {
    throw new UnsupportedError("Not supported");
  }

  final ServiceWorker active;

  final BackgroundFetchManager backgroundFetch;

  final ServiceWorker installing;

  final NavigationPreloadManager navigationPreload;

  final PaymentManager paymentManager;

  final PushManager pushManager;

  final String scope;

  final SyncManager sync;

  final ServiceWorker waiting;

  Future<List<Notification>> getNotifications([Map filter]) {
    var filter_dict = null;
    if (filter != null) {
      filter_dict = convertDartToNative_Dictionary(filter);
    }
    return promiseToFuture<List<Notification>>(
        JS("", "#.getNotifications(#)", this, filter_dict));
  }

  Future showNotification(String title, [Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(
        JS("", "#.showNotification(#, #)", this, title, options_dict));
  }

  Future<bool> unregister() =>
      promiseToFuture<bool>(JS("", "#.unregister()", this));

  Future update() => promiseToFuture(JS("", "#.update()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME, '26')
@Native("HTMLShadowElement")
class ShadowElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ShadowElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory ShadowElement() => document.createElement("shadow");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ShadowElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('shadow');

  @Returns('NodeList|Null')
  @Creates('NodeList')
  List<Node> getDistributedNodes() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@SupportedBrowser(SupportedBrowser.CHROME, '26')
@Native("ShadowRoot")
class ShadowRoot extends DocumentFragment implements DocumentOrShadowRoot {
  // To suppress missing implicit constructor warnings.
  factory ShadowRoot._() {
    throw new UnsupportedError("Not supported");
  }

  final bool delegatesFocus;

  final Element host;

  @JSName('innerHTML')
  String innerHtml;

  final String mode;

  final ShadowRoot olderShadowRoot;

  // From DocumentOrShadowRoot

  final Element activeElement;

  final Element fullscreenElement;

  final Element pointerLockElement;

  @Returns('_StyleSheetList|Null')
  @Creates('_StyleSheetList')
  final List<StyleSheet> styleSheets;

  Element elementFromPoint(int x, int y) native;

  List<Element> elementsFromPoint(int x, int y) native;

  Selection getSelection() native;

  static bool get supported => JS(
      'bool',
      '!!(Element.prototype.createShadowRoot||'
      'Element.prototype.webkitCreateShadowRoot)');

  static bool _shadowRootDeprecationReported = false;
  static void _shadowRootDeprecationReport() {
    if (!_shadowRootDeprecationReported) {
      window.console.warn('''
ShadowRoot.resetStyleInheritance and ShadowRoot.applyAuthorStyles now deprecated in dart:html.
Please remove them from your code.
''');
      _shadowRootDeprecationReported = true;
    }
  }

  @deprecated
  bool get resetStyleInheritance {
    _shadowRootDeprecationReport();
    // Default value from when it was specified.
    return false;
  }

  @deprecated
  set resetStyleInheritance(bool value) {
    _shadowRootDeprecationReport();
  }

  @deprecated
  bool get applyAuthorStyles {
    _shadowRootDeprecationReport();
    // Default value from when it was specified.
    return false;
  }

  @deprecated
  set applyAuthorStyles(bool value) {
    _shadowRootDeprecationReport();
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SharedArrayBuffer")
class SharedArrayBuffer extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory SharedArrayBuffer._() {
    throw new UnsupportedError("Not supported");
  }

  final int byteLength;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SharedWorker")
class SharedWorker extends EventTarget implements AbstractWorker {
  // To suppress missing implicit constructor warnings.
  factory SharedWorker._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  factory SharedWorker(String scriptURL, [String name]) {
    if (name != null) {
      return SharedWorker._create_1(scriptURL, name);
    }
    return SharedWorker._create_2(scriptURL);
  }
  static SharedWorker _create_1(scriptURL, name) =>
      JS('SharedWorker', 'new SharedWorker(#,#)', scriptURL, name);
  static SharedWorker _create_2(scriptURL) =>
      JS('SharedWorker', 'new SharedWorker(#)', scriptURL);

  final MessagePort port;

  Stream<Event> get onError => errorEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SharedWorkerGlobalScope")
class SharedWorkerGlobalScope extends WorkerGlobalScope {
  // To suppress missing implicit constructor warnings.
  factory SharedWorkerGlobalScope._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `connect` events to event
   * handlers that are not necessarily instances of [SharedWorkerGlobalScope].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> connectEvent =
      const EventStreamProvider<Event>('connect');

  static const int PERSISTENT = 1;

  static const int TEMPORARY = 0;

  final String name;

  void close() native;

  @JSName('webkitRequestFileSystem')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void _webkitRequestFileSystem(int type, int size,
      [_FileSystemCallback successCallback,
      _ErrorCallback errorCallback]) native;

  @JSName('webkitRequestFileSystemSync')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  _DOMFileSystemSync requestFileSystemSync(int type, int size) native;

  @JSName('webkitResolveLocalFileSystemSyncURL')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  _EntrySync resolveLocalFileSystemSyncUrl(String url) native;

  @JSName('webkitResolveLocalFileSystemURL')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void _webkitResolveLocalFileSystemUrl(
      String url, _EntryCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  /// Stream of `connect` events handled by this [SharedWorkerGlobalScope].
  Stream<Event> get onConnect => connectEvent.forTarget(this);

  static SharedWorkerGlobalScope get instance {
    return _workerSelf as SharedWorkerGlobalScope;
  }
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLSlotElement")
class SlotElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory SlotElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  SlotElement.created() : super.created();

  String name;

  List<Node> assignedNodes([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _assignedNodes_1(options_1);
    }
    return _assignedNodes_2();
  }

  @JSName('assignedNodes')
  List<Node> _assignedNodes_1(options) native;
  @JSName('assignedNodes')
  List<Node> _assignedNodes_2() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SourceBuffer")
class SourceBuffer extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory SourceBuffer._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> abortEvent =
      const EventStreamProvider<Event>('abort');

  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  num appendWindowEnd;

  num appendWindowStart;

  final AudioTrackList audioTracks;

  final TimeRanges buffered;

  String mode;

  num timestampOffset;

  TrackDefaultList trackDefaults;

  final bool updating;

  final VideoTrackList videoTracks;

  void abort() native;

  void appendBuffer(ByteBuffer data) native;

  @JSName('appendBuffer')
  void appendTypedData(TypedData data) native;

  void remove(num start, num end) native;

  Stream<Event> get onAbort => abortEvent.forTarget(this);

  Stream<Event> get onError => errorEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SourceBufferList")
class SourceBufferList extends EventTarget
    with ListMixin<SourceBuffer>, ImmutableListMixin<SourceBuffer>
    implements JavaScriptIndexingBehavior<SourceBuffer>, List<SourceBuffer> {
  // To suppress missing implicit constructor warnings.
  factory SourceBufferList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  SourceBuffer operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("SourceBuffer", "#[#]", this, index);
  }

  void operator []=(int index, SourceBuffer value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<SourceBuffer> mixins.
  // SourceBuffer is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  SourceBuffer get first {
    if (this.length > 0) {
      return JS('SourceBuffer', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  SourceBuffer get last {
    int len = this.length;
    if (len > 0) {
      return JS('SourceBuffer', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  SourceBuffer get single {
    int len = this.length;
    if (len == 1) {
      return JS('SourceBuffer', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  SourceBuffer elementAt(int index) => this[index];
  // -- end List<SourceBuffer> mixins.

  SourceBuffer item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLSourceElement")
class SourceElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory SourceElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory SourceElement() => JS(
      'returns:SourceElement;creates:SourceElement;new:true',
      '#.createElement(#)',
      document,
      "source");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  SourceElement.created() : super.created();

  String media;

  String sizes;

  String src;

  String srcset;

  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLSpanElement")
class SpanElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory SpanElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory SpanElement() => JS(
      'returns:SpanElement;creates:SpanElement;new:true',
      '#.createElement(#)',
      document,
      "span");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  SpanElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SpeechGrammar")
class SpeechGrammar extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory SpeechGrammar._() {
    throw new UnsupportedError("Not supported");
  }

  factory SpeechGrammar() {
    return SpeechGrammar._create_1();
  }
  static SpeechGrammar _create_1() =>
      JS('SpeechGrammar', 'new SpeechGrammar()');

  String src;

  num weight;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SpeechGrammarList")
class SpeechGrammarList extends Interceptor
    with ListMixin<SpeechGrammar>, ImmutableListMixin<SpeechGrammar>
    implements JavaScriptIndexingBehavior<SpeechGrammar>, List<SpeechGrammar> {
  // To suppress missing implicit constructor warnings.
  factory SpeechGrammarList._() {
    throw new UnsupportedError("Not supported");
  }

  factory SpeechGrammarList() {
    return SpeechGrammarList._create_1();
  }
  static SpeechGrammarList _create_1() =>
      JS('SpeechGrammarList', 'new SpeechGrammarList()');

  int get length => JS("int", "#.length", this);

  SpeechGrammar operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("SpeechGrammar", "#[#]", this, index);
  }

  void operator []=(int index, SpeechGrammar value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<SpeechGrammar> mixins.
  // SpeechGrammar is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  SpeechGrammar get first {
    if (this.length > 0) {
      return JS('SpeechGrammar', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  SpeechGrammar get last {
    int len = this.length;
    if (len > 0) {
      return JS('SpeechGrammar', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  SpeechGrammar get single {
    int len = this.length;
    if (len == 1) {
      return JS('SpeechGrammar', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  SpeechGrammar elementAt(int index) => this[index];
  // -- end List<SpeechGrammar> mixins.

  void addFromString(String string, [num weight]) native;

  void addFromUri(String src, [num weight]) native;

  SpeechGrammar item(int index) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Native("SpeechRecognition")
class SpeechRecognition extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognition._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `audioend` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> audioEndEvent =
      const EventStreamProvider<Event>('audioend');

  /**
   * Static factory designed to expose `audiostart` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> audioStartEvent =
      const EventStreamProvider<Event>('audiostart');

  /**
   * Static factory designed to expose `end` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> endEvent =
      const EventStreamProvider<Event>('end');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<SpeechRecognitionError> errorEvent =
      const EventStreamProvider<SpeechRecognitionError>('error');

  /**
   * Static factory designed to expose `nomatch` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<SpeechRecognitionEvent> noMatchEvent =
      const EventStreamProvider<SpeechRecognitionEvent>('nomatch');

  /**
   * Static factory designed to expose `result` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<SpeechRecognitionEvent> resultEvent =
      const EventStreamProvider<SpeechRecognitionEvent>('result');

  /**
   * Static factory designed to expose `soundend` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> soundEndEvent =
      const EventStreamProvider<Event>('soundend');

  /**
   * Static factory designed to expose `soundstart` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> soundStartEvent =
      const EventStreamProvider<Event>('soundstart');

  /**
   * Static factory designed to expose `speechend` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> speechEndEvent =
      const EventStreamProvider<Event>('speechend');

  /**
   * Static factory designed to expose `speechstart` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> speechStartEvent =
      const EventStreamProvider<Event>('speechstart');

  /**
   * Static factory designed to expose `start` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> startEvent =
      const EventStreamProvider<Event>('start');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS(
      'bool', '!!(window.SpeechRecognition || window.webkitSpeechRecognition)');

  MediaStreamTrack audioTrack;

  bool continuous;

  SpeechGrammarList grammars;

  bool interimResults;

  String lang;

  int maxAlternatives;

  void abort() native;

  void start() native;

  void stop() native;

  /// Stream of `audioend` events handled by this [SpeechRecognition].
  Stream<Event> get onAudioEnd => audioEndEvent.forTarget(this);

  /// Stream of `audiostart` events handled by this [SpeechRecognition].
  Stream<Event> get onAudioStart => audioStartEvent.forTarget(this);

  /// Stream of `end` events handled by this [SpeechRecognition].
  Stream<Event> get onEnd => endEvent.forTarget(this);

  /// Stream of `error` events handled by this [SpeechRecognition].
  Stream<SpeechRecognitionError> get onError => errorEvent.forTarget(this);

  /// Stream of `nomatch` events handled by this [SpeechRecognition].
  Stream<SpeechRecognitionEvent> get onNoMatch => noMatchEvent.forTarget(this);

  /// Stream of `result` events handled by this [SpeechRecognition].
  Stream<SpeechRecognitionEvent> get onResult => resultEvent.forTarget(this);

  /// Stream of `soundend` events handled by this [SpeechRecognition].
  Stream<Event> get onSoundEnd => soundEndEvent.forTarget(this);

  /// Stream of `soundstart` events handled by this [SpeechRecognition].
  Stream<Event> get onSoundStart => soundStartEvent.forTarget(this);

  /// Stream of `speechend` events handled by this [SpeechRecognition].
  Stream<Event> get onSpeechEnd => speechEndEvent.forTarget(this);

  /// Stream of `speechstart` events handled by this [SpeechRecognition].
  Stream<Event> get onSpeechStart => speechStartEvent.forTarget(this);

  /// Stream of `start` events handled by this [SpeechRecognition].
  Stream<Event> get onStart => startEvent.forTarget(this);

  factory SpeechRecognition() {
    return JS('SpeechRecognition',
        'new (window.SpeechRecognition || window.webkitSpeechRecognition)()');
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Native("SpeechRecognitionAlternative")
class SpeechRecognitionAlternative extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionAlternative._() {
    throw new UnsupportedError("Not supported");
  }

  final num confidence;

  final String transcript;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Native("SpeechRecognitionError")
class SpeechRecognitionError extends Event {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionError._() {
    throw new UnsupportedError("Not supported");
  }

  factory SpeechRecognitionError(String type, [Map initDict]) {
    if (initDict != null) {
      var initDict_1 = convertDartToNative_Dictionary(initDict);
      return SpeechRecognitionError._create_1(type, initDict_1);
    }
    return SpeechRecognitionError._create_2(type);
  }
  static SpeechRecognitionError _create_1(type, initDict) => JS(
      'SpeechRecognitionError',
      'new SpeechRecognitionError(#,#)',
      type,
      initDict);
  static SpeechRecognitionError _create_2(type) =>
      JS('SpeechRecognitionError', 'new SpeechRecognitionError(#)', type);

  final String error;

  final String message;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Native("SpeechRecognitionEvent")
class SpeechRecognitionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory SpeechRecognitionEvent(String type, [Map initDict]) {
    if (initDict != null) {
      var initDict_1 = convertDartToNative_Dictionary(initDict);
      return SpeechRecognitionEvent._create_1(type, initDict_1);
    }
    return SpeechRecognitionEvent._create_2(type);
  }
  static SpeechRecognitionEvent _create_1(type, initDict) => JS(
      'SpeechRecognitionEvent',
      'new SpeechRecognitionEvent(#,#)',
      type,
      initDict);
  static SpeechRecognitionEvent _create_2(type) =>
      JS('SpeechRecognitionEvent', 'new SpeechRecognitionEvent(#)', type);

  final Document emma;

  final Document interpretation;

  final int resultIndex;

  @Returns('_SpeechRecognitionResultList|Null')
  @Creates('_SpeechRecognitionResultList')
  final List<SpeechRecognitionResult> results;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Native("SpeechRecognitionResult")
class SpeechRecognitionResult extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionResult._() {
    throw new UnsupportedError("Not supported");
  }

  final bool isFinal;

  final int length;

  SpeechRecognitionAlternative item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SpeechSynthesis")
class SpeechSynthesis extends EventTarget {
  List<SpeechSynthesisVoice> getVoices() {
    List<SpeechSynthesisVoice> voices = _getVoices();
    if (voices.length > 0) applyExtension('SpeechSynthesisVoice', voices[0]);
    return voices;
  }

  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesis._() {
    throw new UnsupportedError("Not supported");
  }

  final bool paused;

  final bool pending;

  final bool speaking;

  void cancel() native;

  @JSName('getVoices')
  List<SpeechSynthesisVoice> _getVoices() native;

  void pause() native;

  void resume() native;

  void speak(SpeechSynthesisUtterance utterance) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SpeechSynthesisEvent")
class SpeechSynthesisEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesisEvent._() {
    throw new UnsupportedError("Not supported");
  }

  final int charIndex;

  final num elapsedTime;

  final String name;

  final SpeechSynthesisUtterance utterance;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SpeechSynthesisUtterance")
class SpeechSynthesisUtterance extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesisUtterance._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `boundary` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<SpeechSynthesisEvent> boundaryEvent =
      const EventStreamProvider<SpeechSynthesisEvent>('boundary');

  /**
   * Static factory designed to expose `end` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<SpeechSynthesisEvent> endEvent =
      const EventStreamProvider<SpeechSynthesisEvent>('end');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `mark` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<SpeechSynthesisEvent> markEvent =
      const EventStreamProvider<SpeechSynthesisEvent>('mark');

  /**
   * Static factory designed to expose `pause` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> pauseEvent =
      const EventStreamProvider<Event>('pause');

  /**
   * Static factory designed to expose `resume` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<SpeechSynthesisEvent> resumeEvent =
      const EventStreamProvider<SpeechSynthesisEvent>('resume');

  /**
   * Static factory designed to expose `start` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<SpeechSynthesisEvent> startEvent =
      const EventStreamProvider<SpeechSynthesisEvent>('start');

  factory SpeechSynthesisUtterance([String text]) {
    if (text != null) {
      return SpeechSynthesisUtterance._create_1(text);
    }
    return SpeechSynthesisUtterance._create_2();
  }
  static SpeechSynthesisUtterance _create_1(text) =>
      JS('SpeechSynthesisUtterance', 'new SpeechSynthesisUtterance(#)', text);
  static SpeechSynthesisUtterance _create_2() =>
      JS('SpeechSynthesisUtterance', 'new SpeechSynthesisUtterance()');

  String lang;

  num pitch;

  num rate;

  String text;

  SpeechSynthesisVoice voice;

  num volume;

  /// Stream of `boundary` events handled by this [SpeechSynthesisUtterance].
  Stream<SpeechSynthesisEvent> get onBoundary => boundaryEvent.forTarget(this);

  /// Stream of `end` events handled by this [SpeechSynthesisUtterance].
  Stream<SpeechSynthesisEvent> get onEnd => endEvent.forTarget(this);

  /// Stream of `error` events handled by this [SpeechSynthesisUtterance].
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `mark` events handled by this [SpeechSynthesisUtterance].
  Stream<SpeechSynthesisEvent> get onMark => markEvent.forTarget(this);

  /// Stream of `pause` events handled by this [SpeechSynthesisUtterance].
  Stream<Event> get onPause => pauseEvent.forTarget(this);

  /// Stream of `resume` events handled by this [SpeechSynthesisUtterance].
  Stream<SpeechSynthesisEvent> get onResume => resumeEvent.forTarget(this);

  /// Stream of `start` events handled by this [SpeechSynthesisUtterance].
  Stream<SpeechSynthesisEvent> get onStart => startEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SpeechSynthesisVoice")
class SpeechSynthesisVoice extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesisVoice._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('default')
  final bool defaultValue;

  final String lang;

  final bool localService;

  final String name;

  @JSName('voiceURI')
  final String voiceUri;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("StaticRange")
class StaticRange extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory StaticRange._() {
    throw new UnsupportedError("Not supported");
  }

  final bool collapsed;

  final Node endContainer;

  final int endOffset;

  final Node startContainer;

  final int startOffset;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * The type used by the
 * [Window.localStorage] and [Window.sessionStorage] properties.
 * Storage is implemented as a Map&lt;String, String>.
 *
 * To store and get values, use Dart's built-in map syntax:
 *
 *     window.localStorage['key1'] = 'val1';
 *     window.localStorage['key2'] = 'val2';
 *     window.localStorage['key3'] = 'val3';
 *     assert(window.localStorage['key3'] == 'val3');
 *
 * You can use [Map](http://api.dartlang.org/dart_core/Map.html) APIs
 * such as containsValue(), clear(), and length:
 *
 *     assert(window.localStorage.containsValue('does not exist') == false);
 *     window.localStorage.clear();
 *     assert(window.localStorage.length == 0);
 *
 * For more examples of using this API, see
 * [localstorage_test.dart](http://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/tests/html/localstorage_test.dart).
 * For details on using the Map API, see the
 * [Maps](https://www.dartlang.org/guides/libraries/library-tour#maps)
 * section of the library tour.
 */
@Unstable()
@Native("Storage")
class Storage extends Interceptor with MapMixin<String, String> {
  void addAll(Map<String, String> other) {
    other.forEach((k, v) {
      this[k] = v;
    });
  }

  // TODO(nweiz): update this when maps support lazy iteration
  bool containsValue(Object value) => values.any((e) => e == value);

  bool containsKey(Object key) => _getItem(key) != null;

  String operator [](Object key) => _getItem(key);

  void operator []=(String key, String value) {
    _setItem(key, value);
  }

  String putIfAbsent(String key, String ifAbsent()) {
    if (!containsKey(key)) this[key] = ifAbsent();
    return this[key];
  }

  String remove(Object key) {
    final value = this[key];
    _removeItem(key);
    return value;
  }

  void clear() => _clear();

  void forEach(void f(String key, String value)) {
    for (var i = 0; true; i++) {
      final key = _key(i);
      if (key == null) return;

      f(key, this[key]);
    }
  }

  Iterable<String> get keys {
    final keys = <String>[];
    forEach((k, v) => keys.add(k));
    return keys;
  }

  Iterable<String> get values {
    final values = <String>[];
    forEach((k, v) => values.add(v));
    return values;
  }

  int get length => _length;

  bool get isEmpty => _key(0) == null;

  bool get isNotEmpty => !isEmpty;
  // To suppress missing implicit constructor warnings.
  factory Storage._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('length')
  final int _length;

  @JSName('clear')
  void _clear() native;

  @JSName('getItem')
  String _getItem(String key) native;

  @JSName('key')
  String _key(int index) native;

  @JSName('removeItem')
  void _removeItem(String key) native;

  @JSName('setItem')
  void _setItem(String key, String value) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void StorageErrorCallback(DomError error);
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Unstable()
@Native("StorageEvent")
class StorageEvent extends Event {
  factory StorageEvent(String type,
      {bool canBubble: false,
      bool cancelable: false,
      String key,
      String oldValue,
      String newValue,
      String url,
      Storage storageArea}) {
    StorageEvent e = document._createEvent("StorageEvent");
    e._initStorageEvent(
        type, canBubble, cancelable, key, oldValue, newValue, url, storageArea);
    return e;
  }

  factory StorageEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return StorageEvent._create_1(type, eventInitDict_1);
    }
    return StorageEvent._create_2(type);
  }
  static StorageEvent _create_1(type, eventInitDict) =>
      JS('StorageEvent', 'new StorageEvent(#,#)', type, eventInitDict);
  static StorageEvent _create_2(type) =>
      JS('StorageEvent', 'new StorageEvent(#)', type);

  final String key;

  final String newValue;

  final String oldValue;

  final Storage storageArea;

  final String url;

  @JSName('initStorageEvent')
  void _initStorageEvent(
      String typeArg,
      bool canBubbleArg,
      bool cancelableArg,
      String keyArg,
      String oldValueArg,
      String newValueArg,
      String urlArg,
      Storage storageAreaArg) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("StorageManager")
class StorageManager extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory StorageManager._() {
    throw new UnsupportedError("Not supported");
  }

  Future<Map<String, dynamic>> estimate() =>
      promiseToFutureAsMap(JS("", "#.estimate()", this));

  Future<bool> persist() => promiseToFuture<bool>(JS("", "#.persist()", this));

  Future<bool> persisted() =>
      promiseToFuture<bool>(JS("", "#.persisted()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void StorageQuotaCallback(int grantedQuotaInBytes);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void StorageUsageCallback(
    int currentUsageInBytes, int currentQuotaInBytes);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLStyleElement")
class StyleElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory StyleElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory StyleElement() => JS(
      'returns:StyleElement;creates:StyleElement;new:true',
      '#.createElement(#)',
      document,
      "style");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  StyleElement.created() : super.created();

  bool disabled;

  String media;

  final StyleSheet sheet;

  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("StyleMedia")
class StyleMedia extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory StyleMedia._() {
    throw new UnsupportedError("Not supported");
  }

  final String type;

  bool matchMedium(String mediaquery) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("StylePropertyMap")
class StylePropertyMap extends StylePropertyMapReadonly {
  // To suppress missing implicit constructor warnings.
  factory StylePropertyMap._() {
    throw new UnsupportedError("Not supported");
  }

  void append(String property, Object value) native;

  void delete(String property) native;

  void set(String property, Object value) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("StylePropertyMapReadonly")
class StylePropertyMapReadonly extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory StylePropertyMapReadonly._() {
    throw new UnsupportedError("Not supported");
  }

  CssStyleValue get(String property) native;

  List<CssStyleValue> getAll(String property) native;

  List<String> getProperties() native;

  bool has(String property) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("StyleSheet")
class StyleSheet extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory StyleSheet._() {
    throw new UnsupportedError("Not supported");
  }

  bool disabled;

  final String href;

  final MediaList media;

  final Node ownerNode;

  final StyleSheet parentStyleSheet;

  final String title;

  final String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SyncEvent")
class SyncEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory SyncEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory SyncEvent(String type, Map init) {
    var init_1 = convertDartToNative_Dictionary(init);
    return SyncEvent._create_1(type, init_1);
  }
  static SyncEvent _create_1(type, init) =>
      JS('SyncEvent', 'new SyncEvent(#,#)', type, init);

  final bool lastChance;

  final String tag;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SyncManager")
class SyncManager extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory SyncManager._() {
    throw new UnsupportedError("Not supported");
  }

  Future<List<String>> getTags() =>
      promiseToFuture<List<String>>(JS("", "#.getTags()", this));

  Future register(String tag) =>
      promiseToFuture(JS("", "#.register(#)", this, tag));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLTableCaptionElement")
class TableCaptionElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TableCaptionElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory TableCaptionElement() => JS(
      'returns:TableCaptionElement;creates:TableCaptionElement;new:true',
      '#.createElement(#)',
      document,
      "caption");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableCaptionElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native(
    "HTMLTableCellElement,HTMLTableDataCellElement,HTMLTableHeaderCellElement")
class TableCellElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TableCellElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory TableCellElement() => JS(
      'returns:TableCellElement;creates:TableCellElement;new:true',
      '#.createElement(#)',
      document,
      "td");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableCellElement.created() : super.created();

  final int cellIndex;

  int colSpan;

  String headers;

  int rowSpan;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLTableColElement")
class TableColElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TableColElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory TableColElement() => JS(
      'returns:TableColElement;creates:TableColElement;new:true',
      '#.createElement(#)',
      document,
      "col");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableColElement.created() : super.created();

  int span;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLTableElement")
class TableElement extends HtmlElement {
  List<TableSectionElement> get tBodies =>
      new _WrappedList<TableSectionElement>(_tBodies);

  List<TableRowElement> get rows => new _WrappedList<TableRowElement>(_rows);

  TableRowElement addRow() {
    return insertRow(-1);
  }

  TableCaptionElement createCaption() => _createCaption();
  TableSectionElement createTBody() => _createTBody();
  TableSectionElement createTFoot() => _createTFoot();
  TableSectionElement createTHead() => _createTHead();
  TableRowElement insertRow(int index) => _insertRow(index);

  TableSectionElement _createTBody() {
    if (JS('bool', '!!#.createTBody', this)) {
      return this._nativeCreateTBody();
    }
    var tbody = new Element.tag('tbody');
    this.children.add(tbody);
    return tbody;
  }

  @JSName('createTBody')
  TableSectionElement _nativeCreateTBody() native;

  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (Range.supportsCreateContextualFragment) {
      return super.createFragment(html,
          validator: validator, treeSanitizer: treeSanitizer);
    }
    // IE9 workaround which does not support innerHTML on Table elements.
    var contextualHtml = '<table>$html</table>';
    var table = new Element.html(contextualHtml,
        validator: validator, treeSanitizer: treeSanitizer);
    var fragment = new DocumentFragment();
    fragment.nodes.addAll(table.nodes);

    return fragment;
  }

  // To suppress missing implicit constructor warnings.
  factory TableElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory TableElement() => JS(
      'returns:TableElement;creates:TableElement;new:true',
      '#.createElement(#)',
      document,
      "table");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableElement.created() : super.created();

  TableCaptionElement caption;

  @JSName('rows')
  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> _rows;

  @JSName('tBodies')
  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> _tBodies;

  TableSectionElement tFoot;

  TableSectionElement tHead;

  @JSName('createCaption')
  TableCaptionElement _createCaption() native;

  @JSName('createTFoot')
  TableSectionElement _createTFoot() native;

  @JSName('createTHead')
  TableSectionElement _createTHead() native;

  void deleteCaption() native;

  void deleteRow(int index) native;

  void deleteTFoot() native;

  void deleteTHead() native;

  @JSName('insertRow')
  TableRowElement _insertRow([int index]) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLTableRowElement")
class TableRowElement extends HtmlElement {
  List<TableCellElement> get cells =>
      new _WrappedList<TableCellElement>(_cells);

  TableCellElement addCell() {
    return insertCell(-1);
  }

  TableCellElement insertCell(int index) => _insertCell(index);

  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (Range.supportsCreateContextualFragment) {
      return super.createFragment(html,
          validator: validator, treeSanitizer: treeSanitizer);
    }
    // IE9 workaround which does not support innerHTML on Table elements.
    var fragment = new DocumentFragment();
    var section = new TableElement()
        .createFragment(html,
            validator: validator, treeSanitizer: treeSanitizer)
        .nodes
        .single;
    var row = section.nodes.single;
    fragment.nodes.addAll(row.nodes);
    return fragment;
  }

  // To suppress missing implicit constructor warnings.
  factory TableRowElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory TableRowElement() => JS(
      'returns:TableRowElement;creates:TableRowElement;new:true',
      '#.createElement(#)',
      document,
      "tr");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableRowElement.created() : super.created();

  @JSName('cells')
  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> _cells;

  final int rowIndex;

  final int sectionRowIndex;

  void deleteCell(int index) native;

  @JSName('insertCell')
  HtmlElement _insertCell([int index]) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLTableSectionElement")
class TableSectionElement extends HtmlElement {
  List<TableRowElement> get rows => new _WrappedList<TableRowElement>(_rows);

  TableRowElement addRow() {
    return insertRow(-1);
  }

  TableRowElement insertRow(int index) => _insertRow(index);

  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (Range.supportsCreateContextualFragment) {
      return super.createFragment(html,
          validator: validator, treeSanitizer: treeSanitizer);
    }
    // IE9 workaround which does not support innerHTML on Table elements.
    var fragment = new DocumentFragment();
    var section = new TableElement()
        .createFragment(html,
            validator: validator, treeSanitizer: treeSanitizer)
        .nodes
        .single;
    fragment.nodes.addAll(section.nodes);
    return fragment;
  }

  // To suppress missing implicit constructor warnings.
  factory TableSectionElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableSectionElement.created() : super.created();

  @JSName('rows')
  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> _rows;

  void deleteRow(int index) native;

  @JSName('insertRow')
  HtmlElement _insertRow([int index]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TaskAttributionTiming")
class TaskAttributionTiming extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory TaskAttributionTiming._() {
    throw new UnsupportedError("Not supported");
  }

  final String containerId;

  final String containerName;

  final String containerSrc;

  final String containerType;

  @JSName('scriptURL')
  final String scriptUrl;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("HTMLTemplateElement")
class TemplateElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TemplateElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory TemplateElement() => document.createElement("template");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TemplateElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('template');

  final DocumentFragment content;

  /**
   * An override to place the contents into content rather than as child nodes.
   *
   * See also:
   *
   * * <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#innerhtml-on-templates>
   */
  void setInnerHtml(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    text = null;
    var fragment = createFragment(html,
        validator: validator, treeSanitizer: treeSanitizer);

    content.append(fragment);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Native("Text")
class Text extends CharacterData {
  factory Text(String data) => JS(
      'returns:Text;depends:none;effects:none;new:true',
      '#.createTextNode(#)',
      document,
      data);
  // To suppress missing implicit constructor warnings.
  factory Text._() {
    throw new UnsupportedError("Not supported");
  }

  final SlotElement assignedSlot;

  final String wholeText;

  @Returns('NodeList|Null')
  @Creates('NodeList')
  List<Node> getDestinationInsertionPoints() native;

  Text splitText(int offset) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLTextAreaElement")
class TextAreaElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TextAreaElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory TextAreaElement() => JS(
      'returns:TextAreaElement;creates:TextAreaElement;new:true',
      '#.createElement(#)',
      document,
      "textarea");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TextAreaElement.created() : super.created();

  String autocapitalize;

  bool autofocus;

  int cols;

  String defaultValue;

  String dirName;

  bool disabled;

  final FormElement form;

  @Unstable()
  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> labels;

  int maxLength;

  int minLength;

  String name;

  String placeholder;

  bool readOnly;

  bool required;

  int rows;

  String selectionDirection;

  int selectionEnd;

  int selectionStart;

  final int textLength;

  final String type;

  final String validationMessage;

  final ValidityState validity;

  String value;

  final bool willValidate;

  String wrap;

  bool checkValidity() native;

  bool reportValidity() native;

  void select() native;

  void setCustomValidity(String error) native;

  void setRangeText(String replacement,
      {int start, int end, String selectionMode}) native;

  void setSelectionRange(int start, int end, [String direction]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TextDetector")
class TextDetector extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TextDetector._() {
    throw new UnsupportedError("Not supported");
  }

  factory TextDetector() {
    return TextDetector._create_1();
  }
  static TextDetector _create_1() => JS('TextDetector', 'new TextDetector()');

  Future<List<DetectedText>> detect(/*ImageBitmapSource*/ image) =>
      promiseToFuture<List<DetectedText>>(JS("", "#.detect(#)", this, image));
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Unstable()
@Native("TextEvent")
class TextEvent extends UIEvent {
  factory TextEvent(String type,
      {bool canBubble: false,
      bool cancelable: false,
      Window view,
      String data}) {
    if (view == null) {
      view = window;
    }
    TextEvent e = document._createEvent("TextEvent");
    e._initTextEvent(type, canBubble, cancelable, view, data);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory TextEvent._() {
    throw new UnsupportedError("Not supported");
  }

  final String data;

  @JSName('initTextEvent')
  void _initTextEvent(String type, bool bubbles, bool cancelable, Window view,
      String data) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TextMetrics")
class TextMetrics extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TextMetrics._() {
    throw new UnsupportedError("Not supported");
  }

  final num actualBoundingBoxAscent;

  final num actualBoundingBoxDescent;

  final num actualBoundingBoxLeft;

  final num actualBoundingBoxRight;

  final num alphabeticBaseline;

  final num emHeightAscent;

  final num emHeightDescent;

  final num fontBoundingBoxAscent;

  final num fontBoundingBoxDescent;

  final num hangingBaseline;

  final num ideographicBaseline;

  final num width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TextTrack")
class TextTrack extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory TextTrack._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `cuechange` events to event
   * handlers that are not necessarily instances of [TextTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> cueChangeEvent =
      const EventStreamProvider<Event>('cuechange');

  final TextTrackCueList activeCues;

  final TextTrackCueList cues;

  final String id;

  final String kind;

  final String label;

  final String language;

  String mode;

  void addCue(TextTrackCue cue) native;

  void removeCue(TextTrackCue cue) native;

  /// Stream of `cuechange` events handled by this [TextTrack].
  Stream<Event> get onCueChange => cueChangeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TextTrackCue")
class TextTrackCue extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory TextTrackCue._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `enter` events to event
   * handlers that are not necessarily instances of [TextTrackCue].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> enterEvent =
      const EventStreamProvider<Event>('enter');

  /**
   * Static factory designed to expose `exit` events to event
   * handlers that are not necessarily instances of [TextTrackCue].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> exitEvent =
      const EventStreamProvider<Event>('exit');

  num endTime;

  String id;

  bool pauseOnExit;

  num startTime;

  final TextTrack track;

  /// Stream of `enter` events handled by this [TextTrackCue].
  Stream<Event> get onEnter => enterEvent.forTarget(this);

  /// Stream of `exit` events handled by this [TextTrackCue].
  Stream<Event> get onExit => exitEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TextTrackCueList")
class TextTrackCueList extends Interceptor
    with ListMixin<TextTrackCue>, ImmutableListMixin<TextTrackCue>
    implements List<TextTrackCue>, JavaScriptIndexingBehavior<TextTrackCue> {
  // To suppress missing implicit constructor warnings.
  factory TextTrackCueList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  TextTrackCue operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("TextTrackCue", "#[#]", this, index);
  }

  void operator []=(int index, TextTrackCue value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<TextTrackCue> mixins.
  // TextTrackCue is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  TextTrackCue get first {
    if (this.length > 0) {
      return JS('TextTrackCue', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  TextTrackCue get last {
    int len = this.length;
    if (len > 0) {
      return JS('TextTrackCue', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  TextTrackCue get single {
    int len = this.length;
    if (len == 1) {
      return JS('TextTrackCue', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  TextTrackCue elementAt(int index) => this[index];
  // -- end List<TextTrackCue> mixins.

  TextTrackCue __getter__(int index) native;

  TextTrackCue getCueById(String id) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TextTrackList")
class TextTrackList extends EventTarget
    with ListMixin<TextTrack>, ImmutableListMixin<TextTrack>
    implements List<TextTrack>, JavaScriptIndexingBehavior<TextTrack> {
  // To suppress missing implicit constructor warnings.
  factory TextTrackList._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `addtrack` events to event
   * handlers that are not necessarily instances of [TextTrackList].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<TrackEvent> addTrackEvent =
      const EventStreamProvider<TrackEvent>('addtrack');

  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  int get length => JS("int", "#.length", this);

  TextTrack operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("TextTrack", "#[#]", this, index);
  }

  void operator []=(int index, TextTrack value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<TextTrack> mixins.
  // TextTrack is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  TextTrack get first {
    if (this.length > 0) {
      return JS('TextTrack', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  TextTrack get last {
    int len = this.length;
    if (len > 0) {
      return JS('TextTrack', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  TextTrack get single {
    int len = this.length;
    if (len == 1) {
      return JS('TextTrack', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  TextTrack elementAt(int index) => this[index];
  // -- end List<TextTrack> mixins.

  TextTrack __getter__(int index) native;

  TextTrack getTrackById(String id) native;

  /// Stream of `addtrack` events handled by this [TextTrackList].
  Stream<TrackEvent> get onAddTrack => addTrackEvent.forTarget(this);

  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLTimeElement")
class TimeElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TimeElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TimeElement.created() : super.created();

  String dateTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("TimeRanges")
class TimeRanges extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TimeRanges._() {
    throw new UnsupportedError("Not supported");
  }

  final int length;

  double end(int index) native;

  double start(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void TimeoutHandler();
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLTitleElement")
class TitleElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TitleElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory TitleElement() => JS(
      'returns:TitleElement;creates:TitleElement;new:true',
      '#.createElement(#)',
      document,
      "title");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TitleElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Touch")
class Touch extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Touch._() {
    throw new UnsupportedError("Not supported");
  }

  factory Touch(Map initDict) {
    var initDict_1 = convertDartToNative_Dictionary(initDict);
    return Touch._create_1(initDict_1);
  }
  static Touch _create_1(initDict) => JS('Touch', 'new Touch(#)', initDict);

  @JSName('clientX')
  final num _clientX;

  @JSName('clientY')
  final num _clientY;

  final num force;

  final int identifier;

  @JSName('pageX')
  final num _pageX;

  @JSName('pageY')
  final num _pageY;

  @JSName('radiusX')
  final num _radiusX;

  @JSName('radiusY')
  final num _radiusY;

  final String region;

  final num rotationAngle;

  @JSName('screenX')
  final num _screenX;

  @JSName('screenY')
  final num _screenY;

  EventTarget get target => _convertNativeToDart_EventTarget(this._get_target);
  @JSName('target')
  @Creates('Element|Document')
  @Returns('Element|Document')
  final dynamic _get_target;

// As of Chrome 37, these all changed from long to double.  This code
// preserves backwards compatibility for the time being.
  int get __clientX => JS('num', '#.clientX', this).round();
  int get __clientY => JS('num', '#.clientY', this).round();
  int get __screenX => JS('num', '#.screenX', this).round();
  int get __screenY => JS('num', '#.screenY', this).round();
  int get __pageX => JS('num', '#.pageX', this).round();
  int get __pageY => JS('num', '#.pageY', this).round();
  int get __radiusX => JS('num', '#.radiusX', this).round();
  int get __radiusY => JS('num', '#.radiusY', this).round();

  Point get client => new Point(__clientX, __clientY);

  Point get page => new Point(__pageX, __pageY);

  Point get screen => new Point(__screenX, __screenY);

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  int get radiusX => __radiusX;

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  int get radiusY => __radiusY;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Native("TouchEvent")
class TouchEvent extends UIEvent {
  // To suppress missing implicit constructor warnings.
  factory TouchEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory TouchEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return TouchEvent._create_1(type, eventInitDict_1);
    }
    return TouchEvent._create_2(type);
  }
  static TouchEvent _create_1(type, eventInitDict) =>
      JS('TouchEvent', 'new TouchEvent(#,#)', type, eventInitDict);
  static TouchEvent _create_2(type) =>
      JS('TouchEvent', 'new TouchEvent(#)', type);

  final bool altKey;

  final TouchList changedTouches;

  final bool ctrlKey;

  final bool metaKey;

  final bool shiftKey;

  final TouchList targetTouches;

  final TouchList touches;

  /**
   * Checks if touch events supported on the current platform.
   *
   * Note that touch events are only supported if the user is using a touch
   * device.
   */
  static bool get supported => Device.isEventTypeSupported('TouchEvent');
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Native("TouchList")
class TouchList extends Interceptor
    with ListMixin<Touch>, ImmutableListMixin<Touch>
    implements JavaScriptIndexingBehavior<Touch>, List<Touch> {
  /// NB: This constructor likely does not work as you might expect it to! This
  /// constructor will simply fail (returning null) if you are not on a device
  /// with touch enabled. See dartbug.com/8314.
  // TODO(5760): createTouchList now uses varargs.
  factory TouchList() => null; //document._createTouchList();
  // To suppress missing implicit constructor warnings.
  factory TouchList._() {
    throw new UnsupportedError("Not supported");
  }

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!document.createTouchList');

  int get length => JS("int", "#.length", this);

  Touch operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Touch", "#[#]", this, index);
  }

  void operator []=(int index, Touch value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Touch> mixins.
  // Touch is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Touch get first {
    if (this.length > 0) {
      return JS('Touch', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Touch get last {
    int len = this.length;
    if (len > 0) {
      return JS('Touch', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Touch get single {
    int len = this.length;
    if (len == 1) {
      return JS('Touch', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Touch elementAt(int index) => this[index];
  // -- end List<Touch> mixins.

  Touch item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TrackDefault")
class TrackDefault extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TrackDefault._() {
    throw new UnsupportedError("Not supported");
  }

  factory TrackDefault(
      String type, String language, String label, List<String> kinds,
      [String byteStreamTrackID]) {
    if (byteStreamTrackID != null) {
      List kinds_1 = convertDartToNative_StringArray(kinds);
      return TrackDefault._create_1(
          type, language, label, kinds_1, byteStreamTrackID);
    }
    List kinds_1 = convertDartToNative_StringArray(kinds);
    return TrackDefault._create_2(type, language, label, kinds_1);
  }
  static TrackDefault _create_1(
          type, language, label, kinds, byteStreamTrackID) =>
      JS('TrackDefault', 'new TrackDefault(#,#,#,#,#)', type, language, label,
          kinds, byteStreamTrackID);
  static TrackDefault _create_2(type, language, label, kinds) => JS(
      'TrackDefault',
      'new TrackDefault(#,#,#,#)',
      type,
      language,
      label,
      kinds);

  final String byteStreamTrackID;

  final Object kinds;

  final String label;

  final String language;

  final String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TrackDefaultList")
class TrackDefaultList extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TrackDefaultList._() {
    throw new UnsupportedError("Not supported");
  }

  factory TrackDefaultList([List<TrackDefault> trackDefaults]) {
    if (trackDefaults != null) {
      return TrackDefaultList._create_1(trackDefaults);
    }
    return TrackDefaultList._create_2();
  }
  static TrackDefaultList _create_1(trackDefaults) =>
      JS('TrackDefaultList', 'new TrackDefaultList(#)', trackDefaults);
  static TrackDefaultList _create_2() =>
      JS('TrackDefaultList', 'new TrackDefaultList()');

  final int length;

  TrackDefault item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("HTMLTrackElement")
class TrackElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TrackElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory TrackElement() => document.createElement("track");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TrackElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('track');

  static const int ERROR = 3;

  static const int LOADED = 2;

  static const int LOADING = 1;

  static const int NONE = 0;

  @JSName('default')
  bool defaultValue;

  String kind;

  String label;

  final int readyState;

  String src;

  String srclang;

  final TextTrack track;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("TrackEvent")
class TrackEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory TrackEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory TrackEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return TrackEvent._create_1(type, eventInitDict_1);
    }
    return TrackEvent._create_2(type);
  }
  static TrackEvent _create_1(type, eventInitDict) =>
      JS('TrackEvent', 'new TrackEvent(#,#)', type, eventInitDict);
  static TrackEvent _create_2(type) =>
      JS('TrackEvent', 'new TrackEvent(#)', type);

  @Creates('Null')
  final Object track;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TransitionEvent,WebKitTransitionEvent")
class TransitionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory TransitionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory TransitionEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return TransitionEvent._create_1(type, eventInitDict_1);
    }
    return TransitionEvent._create_2(type);
  }
  static TransitionEvent _create_1(type, eventInitDict) =>
      JS('TransitionEvent', 'new TransitionEvent(#,#)', type, eventInitDict);
  static TransitionEvent _create_2(type) =>
      JS('TransitionEvent', 'new TransitionEvent(#)', type);

  final num elapsedTime;

  final String propertyName;

  final String pseudoElement;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Unstable()
@Native("TreeWalker")
class TreeWalker extends Interceptor {
  factory TreeWalker(Node root, int whatToShow) {
    return document._createTreeWalker(root, whatToShow, null);
  }
  // To suppress missing implicit constructor warnings.
  factory TreeWalker._() {
    throw new UnsupportedError("Not supported");
  }

  Node currentNode;

  final NodeFilter filter;

  final Node root;

  final int whatToShow;

  Node firstChild() native;

  Node lastChild() native;

  Node nextNode() native;

  Node nextSibling() native;

  Node parentNode() native;

  Node previousNode() native;

  Node previousSibling() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TrustedHTML")
class TrustedHtml extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TrustedHtml._() {
    throw new UnsupportedError("Not supported");
  }

  static TrustedHtml escape(String html) native;

  static TrustedHtml unsafelyCreate(String html) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TrustedScriptURL")
class TrustedScriptUrl extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TrustedScriptUrl._() {
    throw new UnsupportedError("Not supported");
  }

  static TrustedScriptUrl unsafelyCreate(String url) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("TrustedURL")
class TrustedUrl extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TrustedUrl._() {
    throw new UnsupportedError("Not supported");
  }

  static TrustedUrl create(String url) native;

  static TrustedUrl unsafelyCreate(String url) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Native("UIEvent")
class UIEvent extends Event {
  // In JS, canBubble and cancelable are technically required parameters to
  // init*Event. In practice, though, if they aren't provided they simply
  // default to false (since that's Boolean(undefined)).
  //
  // Contrary to JS, we default canBubble and cancelable to true, since that's
  // what people want most of the time anyway.
  factory UIEvent(String type,
      {Window view,
      int detail: 0,
      bool canBubble: true,
      bool cancelable: true}) {
    if (view == null) {
      view = window;
    }
    UIEvent e = document._createEvent("UIEvent");
    e._initUIEvent(type, canBubble, cancelable, view, detail);
    return e;
  }

  factory UIEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return UIEvent._create_1(type, eventInitDict_1);
    }
    return UIEvent._create_2(type);
  }
  static UIEvent _create_1(type, eventInitDict) =>
      JS('UIEvent', 'new UIEvent(#,#)', type, eventInitDict);
  static UIEvent _create_2(type) => JS('UIEvent', 'new UIEvent(#)', type);

  final int detail;

  final InputDeviceCapabilities sourceCapabilities;

  WindowBase get view => _convertNativeToDart_Window(this._get_view);
  @JSName('view')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_view;

  @JSName('which')
  @Unstable()
  final int _which;

  @JSName('initUIEvent')
  void _initUIEvent(String type, bool bubbles, bool cancelable, Window view,
      int detail) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLUListElement")
class UListElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory UListElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory UListElement() => JS(
      'returns:UListElement;creates:UListElement;new:true',
      '#.createElement(#)',
      document,
      "ul");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  UListElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("UnderlyingSourceBase")
class UnderlyingSourceBase extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory UnderlyingSourceBase._() {
    throw new UnsupportedError("Not supported");
  }

  Future cancel(Object reason) =>
      promiseToFuture(JS("", "#.cancel(#)", this, reason));

  void notifyLockAcquired() native;

  void notifyLockReleased() native;

  Future pull() => promiseToFuture(JS("", "#.pull()", this));

  Future start(Object stream) =>
      promiseToFuture(JS("", "#.start(#)", this, stream));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLUnknownElement")
class UnknownElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory UnknownElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  UnknownElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("URL")
class Url extends Interceptor {
  static String createObjectUrl(blob_OR_source_OR_stream) => JS(
      'String',
      '(self.URL || self.webkitURL).createObjectURL(#)',
      blob_OR_source_OR_stream);

  static String createObjectUrlFromSource(MediaSource source) =>
      JS('String', '(self.URL || self.webkitURL).createObjectURL(#)', source);

  static String createObjectUrlFromStream(MediaStream stream) =>
      JS('String', '(self.URL || self.webkitURL).createObjectURL(#)', stream);

  static String createObjectUrlFromBlob(Blob blob) =>
      JS('String', '(self.URL || self.webkitURL).createObjectURL(#)', blob);

  static void revokeObjectUrl(String url) =>
      JS('void', '(self.URL || self.webkitURL).revokeObjectURL(#)', url);

  String toString() => JS('String', 'String(#)', this);

  // To suppress missing implicit constructor warnings.
  factory Url._() {
    throw new UnsupportedError("Not supported");
  }

  String hash;

  String host;

  String hostname;

  String href;

  final String origin;

  String password;

  String pathname;

  String port;

  String protocol;

  String search;

  final UrlSearchParams searchParams;

  String username;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("URLSearchParams")
class UrlSearchParams extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory UrlSearchParams._() {
    throw new UnsupportedError("Not supported");
  }

  factory UrlSearchParams([Object init]) {
    if (init != null) {
      return UrlSearchParams._create_1(init);
    }
    return UrlSearchParams._create_2();
  }
  static UrlSearchParams _create_1(init) =>
      JS('UrlSearchParams', 'new URLSearchParams(#)', init);
  static UrlSearchParams _create_2() =>
      JS('UrlSearchParams', 'new URLSearchParams()');

  void append(String name, String value) native;

  void delete(String name) native;

  String get(String name) native;

  List<String> getAll(String name) native;

  bool has(String name) native;

  void set(String name, String value) native;

  void sort() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class UrlUtilsReadOnly extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory UrlUtilsReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  final String hash;

  final String host;

  final String hostname;

  final String href;

  final String origin;

  final String pathname;

  final String port;

  final String protocol;

  final String search;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VR")
class VR extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory VR._() {
    throw new UnsupportedError("Not supported");
  }

  Future getDevices() => promiseToFuture(JS("", "#.getDevices()", this));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRCoordinateSystem")
class VRCoordinateSystem extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VRCoordinateSystem._() {
    throw new UnsupportedError("Not supported");
  }

  Float32List getTransformTo(VRCoordinateSystem other) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRDevice")
class VRDevice extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory VRDevice._() {
    throw new UnsupportedError("Not supported");
  }

  final String deviceName;

  final bool isExternal;

  Future requestSession([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(JS("", "#.requestSession(#)", this, options_dict));
  }

  Future supportsSession([Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(JS("", "#.supportsSession(#)", this, options_dict));
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRDeviceEvent")
class VRDeviceEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory VRDeviceEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory VRDeviceEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return VRDeviceEvent._create_1(type, eventInitDict_1);
  }
  static VRDeviceEvent _create_1(type, eventInitDict) =>
      JS('VRDeviceEvent', 'new VRDeviceEvent(#,#)', type, eventInitDict);

  final VRDevice device;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRDisplay")
class VRDisplay extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory VRDisplay._() {
    throw new UnsupportedError("Not supported");
  }

  final VRDisplayCapabilities capabilities;

  num depthFar;

  num depthNear;

  final int displayId;

  final String displayName;

  final bool isPresenting;

  final VRStageParameters stageParameters;

  void cancelAnimationFrame(int handle) native;

  Future exitPresent() => promiseToFuture(JS("", "#.exitPresent()", this));

  VREyeParameters getEyeParameters(String whichEye) native;

  bool getFrameData(VRFrameData frameData) native;

  List<Map> getLayers() native;

  int requestAnimationFrame(FrameRequestCallback callback) native;

  Future requestPresent(List<Map> layers) =>
      promiseToFuture(JS("", "#.requestPresent(#)", this, layers));

  void submitFrame() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRDisplayCapabilities")
class VRDisplayCapabilities extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VRDisplayCapabilities._() {
    throw new UnsupportedError("Not supported");
  }

  final bool canPresent;

  final bool hasExternalDisplay;

  final bool hasPosition;

  final int maxLayers;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRDisplayEvent")
class VRDisplayEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory VRDisplayEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory VRDisplayEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return VRDisplayEvent._create_1(type, eventInitDict_1);
    }
    return VRDisplayEvent._create_2(type);
  }
  static VRDisplayEvent _create_1(type, eventInitDict) =>
      JS('VRDisplayEvent', 'new VRDisplayEvent(#,#)', type, eventInitDict);
  static VRDisplayEvent _create_2(type) =>
      JS('VRDisplayEvent', 'new VRDisplayEvent(#)', type);

  final VRDisplay display;

  final String reason;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VREyeParameters")
class VREyeParameters extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VREyeParameters._() {
    throw new UnsupportedError("Not supported");
  }

  final Float32List offset;

  final int renderHeight;

  final int renderWidth;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRFrameData")
class VRFrameData extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VRFrameData._() {
    throw new UnsupportedError("Not supported");
  }

  factory VRFrameData() {
    return VRFrameData._create_1();
  }
  static VRFrameData _create_1() => JS('VRFrameData', 'new VRFrameData()');

  final Float32List leftProjectionMatrix;

  final Float32List leftViewMatrix;

  final VRPose pose;

  final Float32List rightProjectionMatrix;

  final Float32List rightViewMatrix;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRFrameOfReference")
class VRFrameOfReference extends VRCoordinateSystem {
  // To suppress missing implicit constructor warnings.
  factory VRFrameOfReference._() {
    throw new UnsupportedError("Not supported");
  }

  final VRStageBounds bounds;

  final num emulatedHeight;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRPose")
class VRPose extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VRPose._() {
    throw new UnsupportedError("Not supported");
  }

  final Float32List angularAcceleration;

  final Float32List angularVelocity;

  final Float32List linearAcceleration;

  final Float32List linearVelocity;

  final Float32List orientation;

  final Float32List position;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRSession")
class VRSession extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory VRSession._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> blurEvent =
      const EventStreamProvider<Event>('blur');

  static const EventStreamProvider<Event> focusEvent =
      const EventStreamProvider<Event>('focus');

  num depthFar;

  num depthNear;

  final VRDevice device;

  final bool exclusive;

  Future end() => promiseToFuture(JS("", "#.end()", this));

  Future requestFrameOfReference(String type, [Map options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture(
        JS("", "#.requestFrameOfReference(#, #)", this, type, options_dict));
  }

  Stream<Event> get onBlur => blurEvent.forTarget(this);

  Stream<Event> get onFocus => focusEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRSessionEvent")
class VRSessionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory VRSessionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory VRSessionEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return VRSessionEvent._create_1(type, eventInitDict_1);
  }
  static VRSessionEvent _create_1(type, eventInitDict) =>
      JS('VRSessionEvent', 'new VRSessionEvent(#,#)', type, eventInitDict);

  final VRSession session;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRStageBounds")
class VRStageBounds extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VRStageBounds._() {
    throw new UnsupportedError("Not supported");
  }

  final List<VRStageBoundsPoint> geometry;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRStageBoundsPoint")
class VRStageBoundsPoint extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VRStageBoundsPoint._() {
    throw new UnsupportedError("Not supported");
  }

  final num x;

  final num z;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VRStageParameters")
class VRStageParameters extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VRStageParameters._() {
    throw new UnsupportedError("Not supported");
  }

  final Float32List sittingToStandingTransform;

  final num sizeX;

  final num sizeZ;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ValidityState")
class ValidityState extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ValidityState._() {
    throw new UnsupportedError("Not supported");
  }

  final bool badInput;

  final bool customError;

  final bool patternMismatch;

  final bool rangeOverflow;

  final bool rangeUnderflow;

  final bool stepMismatch;

  final bool tooLong;

  final bool tooShort;

  final bool typeMismatch;

  final bool valid;

  final bool valueMissing;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("HTMLVideoElement")
class VideoElement extends MediaElement implements CanvasImageSource {
  // To suppress missing implicit constructor warnings.
  factory VideoElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory VideoElement() => JS(
      'returns:VideoElement;creates:VideoElement;new:true',
      '#.createElement(#)',
      document,
      "video");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  VideoElement.created() : super.created();

  int height;

  String poster;

  final int videoHeight;

  final int videoWidth;

  @JSName('webkitDecodedFrameCount')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final int decodedFrameCount;

  @JSName('webkitDroppedFrameCount')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  final int droppedFrameCount;

  int width;

  VideoPlaybackQuality getVideoPlaybackQuality() native;

  @JSName('webkitEnterFullscreen')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void enterFullscreen() native;

  @JSName('webkitExitFullscreen')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void exitFullscreen() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VideoPlaybackQuality")
class VideoPlaybackQuality extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VideoPlaybackQuality._() {
    throw new UnsupportedError("Not supported");
  }

  final int corruptedVideoFrames;

  final num creationTime;

  final int droppedVideoFrames;

  final int totalVideoFrames;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VideoTrack")
class VideoTrack extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VideoTrack._() {
    throw new UnsupportedError("Not supported");
  }

  final String id;

  final String kind;

  final String label;

  final String language;

  bool selected;

  final SourceBuffer sourceBuffer;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VideoTrackList")
class VideoTrackList extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory VideoTrackList._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  final int length;

  final int selectedIndex;

  VideoTrack __getter__(int index) native;

  VideoTrack getTrackById(String id) native;

  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VisualViewport")
class VisualViewport extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory VisualViewport._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> resizeEvent =
      const EventStreamProvider<Event>('resize');

  static const EventStreamProvider<Event> scrollEvent =
      const EventStreamProvider<Event>('scroll');

  final num height;

  final num offsetLeft;

  final num offsetTop;

  final num pageLeft;

  final num pageTop;

  final num scale;

  final num width;

  Stream<Event> get onResize => resizeEvent.forTarget(this);

  Stream<Event> get onScroll => scrollEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

typedef void VoidCallback();
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VTTCue")
class VttCue extends TextTrackCue {
  // To suppress missing implicit constructor warnings.
  factory VttCue._() {
    throw new UnsupportedError("Not supported");
  }

  factory VttCue(num startTime, num endTime, String text) {
    return VttCue._create_1(startTime, endTime, text);
  }
  static VttCue _create_1(startTime, endTime, text) =>
      JS('VttCue', 'new VTTCue(#,#,#)', startTime, endTime, text);

  String align;

  @Creates('Null')
  @Returns('num|String')
  Object line;

  @Creates('Null')
  @Returns('num|String')
  Object position;

  VttRegion region;

  num size;

  bool snapToLines;

  String text;

  String vertical;

  @JSName('getCueAsHTML')
  DocumentFragment getCueAsHtml() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("VTTRegion")
class VttRegion extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VttRegion._() {
    throw new UnsupportedError("Not supported");
  }

  factory VttRegion() {
    return VttRegion._create_1();
  }
  static VttRegion _create_1() => JS('VttRegion', 'new VTTRegion()');

  String id;

  int lines;

  num regionAnchorX;

  num regionAnchorY;

  String scroll;

  num viewportAnchorX;

  num viewportAnchorY;

  num width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Use the WebSocket interface to connect to a WebSocket,
 * and to send and receive data on that WebSocket.
 *
 * To use a WebSocket in your web app, first create a WebSocket object,
 * passing the WebSocket URL as an argument to the constructor.
 *
 *     var webSocket = new WebSocket('ws://127.0.0.1:1337/ws');
 *
 * To send data on the WebSocket, use the [send] method.
 *
 *     if (webSocket != null && webSocket.readyState == WebSocket.OPEN) {
 *       webSocket.send(data);
 *     } else {
 *       print('WebSocket not connected, message $data not sent');
 *     }
 *
 * To receive data on the WebSocket, register a listener for message events.
 *
 *     webSocket.onMessage.listen((MessageEvent e) {
 *       receivedData(e.data);
 *     });
 *
 * The message event handler receives a [MessageEvent] object
 * as its sole argument.
 * You can also define open, close, and error handlers,
 * as specified by [WebSocketEvents].
 *
 * For more information, see the
 * [WebSockets](http://www.dartlang.org/docs/library-tour/#html-websockets)
 * section of the library tour and
 * [Introducing WebSockets](http://www.html5rocks.com/en/tutorials/websockets/basics/),
 * an HTML5Rocks.com tutorial.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
@Native("WebSocket")
class WebSocket extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory WebSocket._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `close` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<CloseEvent> closeEvent =
      const EventStreamProvider<CloseEvent>('close');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `open` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> openEvent =
      const EventStreamProvider<Event>('open');

  factory WebSocket(String url, [Object protocols]) {
    if (protocols != null) {
      return WebSocket._create_1(url, protocols);
    }
    return WebSocket._create_2(url);
  }
  static WebSocket _create_1(url, protocols) =>
      JS('WebSocket', 'new WebSocket(#,#)', url, protocols);
  static WebSocket _create_2(url) => JS('WebSocket', 'new WebSocket(#)', url);

  /// Checks if this type is supported on the current platform.
  static bool get supported =>
      JS('bool', 'typeof window.WebSocket != "undefined"');

  static const int CLOSED = 3;

  static const int CLOSING = 2;

  static const int CONNECTING = 0;

  static const int OPEN = 1;

  String binaryType;

  final int bufferedAmount;

  final String extensions;

  final String protocol;

  final int readyState;

  final String url;

  void close([int code, String reason]) native;

  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in contrast, only accept data of the specified type.
   */
  void send(data) native;

  @JSName('send')
  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in contrast, only accept data of the specified type.
   */
  void sendBlob(Blob data) native;

  @JSName('send')
  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in contrast, only accept data of the specified type.
   */
  void sendByteBuffer(ByteBuffer data) native;

  @JSName('send')
  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in contrast, only accept data of the specified type.
   */
  void sendString(String data) native;

  @JSName('send')
  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in contrast, only accept data of the specified type.
   */
  void sendTypedData(TypedData data) native;

  /// Stream of `close` events handled by this [WebSocket].
  Stream<CloseEvent> get onClose => closeEvent.forTarget(this);

  /// Stream of `error` events handled by this [WebSocket].
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [WebSocket].
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `open` events handled by this [WebSocket].
  Stream<Event> get onOpen => openEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("WheelEvent")
class WheelEvent extends MouseEvent {
  factory WheelEvent(String type,
      {Window view,
      num deltaX: 0,
      num deltaY: 0,
      num deltaZ: 0,
      int deltaMode: 0,
      int detail: 0,
      int screenX: 0,
      int screenY: 0,
      int clientX: 0,
      int clientY: 0,
      int button: 0,
      bool canBubble: true,
      bool cancelable: true,
      bool ctrlKey: false,
      bool altKey: false,
      bool shiftKey: false,
      bool metaKey: false,
      EventTarget relatedTarget}) {
    var options = {
      'view': view,
      'deltaMode': deltaMode,
      'deltaX': deltaX,
      'deltaY': deltaY,
      'deltaZ': deltaZ,
      'detail': detail,
      'screenX': screenX,
      'screenY': screenY,
      'clientX': clientX,
      'clientY': clientY,
      'button': button,
      'bubbles': canBubble,
      'cancelable': cancelable,
      'ctrlKey': ctrlKey,
      'altKey': altKey,
      'shiftKey': shiftKey,
      'metaKey': metaKey,
      'relatedTarget': relatedTarget,
    };

    if (view == null) {
      view = window;
    }

    return JS('WheelEvent', 'new WheelEvent(#, #)', type,
        convertDartToNative_Dictionary(options));
  }

  factory WheelEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return WheelEvent._create_1(type, eventInitDict_1);
    }
    return WheelEvent._create_2(type);
  }
  static WheelEvent _create_1(type, eventInitDict) =>
      JS('WheelEvent', 'new WheelEvent(#,#)', type, eventInitDict);
  static WheelEvent _create_2(type) =>
      JS('WheelEvent', 'new WheelEvent(#)', type);

  static const int DOM_DELTA_LINE = 0x01;

  static const int DOM_DELTA_PAGE = 0x02;

  static const int DOM_DELTA_PIXEL = 0x00;

  @JSName('deltaX')
  final num _deltaX;

  @JSName('deltaY')
  final num _deltaY;

  final num deltaZ;

  /**
   * The amount that is expected to scroll vertically, in units determined by
   * [deltaMode].
   *
   * See also:
   *
   * * [WheelEvent.deltaY](http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-WheelEvent-deltaY) from the W3C.
   */
  num get deltaY {
    if (JS('bool', '#.deltaY !== undefined', this)) {
      // W3C WheelEvent
      return this._deltaY;
    }
    throw new UnsupportedError('deltaY is not supported');
  }

  /**
   * The amount that is expected to scroll horizontally, in units determined by
   * [deltaMode].
   *
   * See also:
   *
   * * [WheelEvent.deltaX](http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-WheelEvent-deltaX) from the W3C.
   */
  num get deltaX {
    if (JS('bool', '#.deltaX !== undefined', this)) {
      // W3C WheelEvent
      return this._deltaX;
    }
    throw new UnsupportedError('deltaX is not supported');
  }

  int get deltaMode {
    if (JS('bool', '!!(#.deltaMode)', this)) {
      return JS('int', '#.deltaMode', this);
    }
    // If not available then we're poly-filling and doing pixel scroll.
    return 0;
  }

  num get _wheelDelta => JS('num', '#.wheelDelta', this);
  num get _wheelDeltaX => JS('num', '#.wheelDeltaX', this);
  num get _detail => JS('num', '#.detail', this);

  bool get _hasInitMouseScrollEvent =>
      JS('bool', '!!(#.initMouseScrollEvent)', this);

  @JSName('initMouseScrollEvent')
  void _initMouseScrollEvent(
      String type,
      bool canBubble,
      bool cancelable,
      Window view,
      int detail,
      int screenX,
      int screenY,
      int clientX,
      int clientY,
      bool ctrlKey,
      bool altKey,
      bool shiftKey,
      bool metaKey,
      int button,
      EventTarget relatedTarget,
      int axis) native;

  bool get _hasInitWheelEvent => JS('bool', '!!(#.initWheelEvent)', this);
  @JSName('initWheelEvent')
  void _initWheelEvent(
      String eventType,
      bool canBubble,
      bool cancelable,
      Window view,
      int detail,
      int screenX,
      int screenY,
      int clientX,
      int clientY,
      int button,
      EventTarget relatedTarget,
      String modifiersList,
      int deltaX,
      int deltaY,
      int deltaZ,
      int deltaMode) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Top-level container for the current browser tab or window.
 *
 * In a web browser, each window has a [Window] object, but within the context
 * of a script, this object represents only the current window.
 * Each other window, tab, and iframe has its own [Window] object.
 *
 * Each window contains a [Document] object, which contains all of the window's
 * content.
 *
 * Use the top-level `window` object to access the current window.
 * For example:
 *
 *     // Draw a scene when the window repaints.
 *     drawScene(num delta) {...}
 *     window.animationFrame.then(drawScene);.
 *
 *     // Write to the console.
 *     window.console.log('Jinkies!');
 *     window.console.error('Jeepers!');
 *
 * **Note:** This class represents only the current window, while [WindowBase]
 * is a representation of any window, including other tabs, windows, and frames.
 *
 * ## See also
 *
 * * [WindowBase]
 *
 * ## Other resources
 *
 * * [DOM Window](https://developer.mozilla.org/en-US/docs/DOM/window) from MDN.
 * * [Window](http://www.w3.org/TR/Window/) from the W3C.
 */
@Native("Window,DOMWindow")
class Window extends EventTarget
    implements
        WindowEventHandlers,
        WindowBase,
        GlobalEventHandlers,
        _WindowTimers,
        WindowBase64 {
  /**
   * Returns a Future that completes just before the window is about to
   * repaint so the user can draw an animation frame.
   *
   * If you need to later cancel this animation, use [requestAnimationFrame]
   * instead.
   *
   * The [Future] completes to a timestamp that represents a floating
   * point value of the number of milliseconds that have elapsed since the page
   * started to load (which is also the timestamp at this call to
   * animationFrame).
   *
   * Note: The code that runs when the future completes should call
   * [animationFrame] again for the animation to continue.
   */
  Future<num> get animationFrame {
    var completer = new Completer<num>.sync();
    requestAnimationFrame((time) {
      completer.complete(time);
    });
    return completer.future;
  }

  /**
   * The newest document in this window.
   *
   * ## Other resources
   *
   * * [Loading web
   *   pages](https://html.spec.whatwg.org/multipage/browsers.html)
   *   from WHATWG.
   */
  Document get document => JS('Document', '#.document', this);

  WindowBase _open2(url, name) =>
      JS('Window|Null', '#.open(#,#)', this, url, name);

  WindowBase _open3(url, name, options) =>
      JS('Window|Null', '#.open(#,#,#)', this, url, name, options);

  /**
   * Opens a new window.
   *
   * ## Other resources
   *
   * * [Window.open](https://developer.mozilla.org/en-US/docs/Web/API/Window.open)
   *   from MDN.
   * * [Window open](http://docs.webplatform.org/wiki/dom/methods/open)
   *   from WebPlatform.org.
   */
  WindowBase open(String url, String name, [String options]) {
    if (options == null) {
      return _DOMWindowCrossFrame._createSafe(_open2(url, name));
    } else {
      return _DOMWindowCrossFrame._createSafe(_open3(url, name, options));
    }
  }

  // API level getter and setter for Location.
  // TODO: The cross domain safe wrapper can be inserted here.
  /**
   * The current location of this window.
   *
   *     Location currentLocation = window.location;
   *     print(currentLocation.href); // 'http://www.example.com:80/'
   */
  Location get location => _location;

  // TODO: consider forcing users to do: window.location.assign('string').
  /**
   * Sets the window's location, which causes the browser to navigate to the new
   * location. [value] may be a Location object or a String.
   */
  set location(value) {
    _location = value;
  }

  // Native getter and setter to access raw Location object.
  dynamic get _location => JS('Location|Null', '#.location', this);
  set _location(value) {
    JS('void', '#.location = #', this, value);
  }

  /**
   * Called to draw an animation frame and then request the window to repaint
   * after [callback] has finished (creating the animation).
   *
   * Use this method only if you need to later call [cancelAnimationFrame]. If
   * not, the preferred Dart idiom is to set animation frames by calling
   * [animationFrame], which returns a Future.
   *
   * Returns a non-zero valued integer to represent the request id for this
   * request. This value only needs to be saved if you intend to call
   * [cancelAnimationFrame] so you can specify the particular animation to
   * cancel.
   *
   * Note: The supplied [callback] needs to call [requestAnimationFrame] again
   * for the animation to continue.
   */
  int requestAnimationFrame(FrameRequestCallback callback) {
    _ensureRequestAnimationFrame();
    return _requestAnimationFrame(_wrapZone(callback));
  }

  /**
   * Cancels an animation frame request.
   *
   * ## Other resources
   *
   * * [Window.cancelAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/Window.cancelAnimationFrame)
   *   from MDN.
   */
  void cancelAnimationFrame(int id) {
    _ensureRequestAnimationFrame();
    _cancelAnimationFrame(id);
  }

  @JSName('requestAnimationFrame')
  int _requestAnimationFrame(FrameRequestCallback callback) native;

  @JSName('cancelAnimationFrame')
  void _cancelAnimationFrame(int id) native;

  _ensureRequestAnimationFrame() {
    if (JS('bool', '!!(#.requestAnimationFrame && #.cancelAnimationFrame)',
        this, this)) return;

    JS(
        'void',
        r"""
  (function($this) {
   var vendors = ['ms', 'moz', 'webkit', 'o'];
   for (var i = 0; i < vendors.length && !$this.requestAnimationFrame; ++i) {
     $this.requestAnimationFrame = $this[vendors[i] + 'RequestAnimationFrame'];
     $this.cancelAnimationFrame =
         $this[vendors[i]+'CancelAnimationFrame'] ||
         $this[vendors[i]+'CancelRequestAnimationFrame'];
   }
   if ($this.requestAnimationFrame && $this.cancelAnimationFrame) return;
   $this.requestAnimationFrame = function(callback) {
      return window.setTimeout(function() {
        callback(Date.now());
      }, 16 /* 16ms ~= 60fps */);
   };
   $this.cancelAnimationFrame = function(id) { clearTimeout(id); }
  })(#)""",
        this);
  }

  /**
   * Gets an instance of the Indexed DB factory to being using Indexed DB.
   *
   * Use [indexed_db.IdbFactory.supported] to check if Indexed DB is supported on the
   * current platform.
   */
  @SupportedBrowser(SupportedBrowser.CHROME, '23.0')
  @SupportedBrowser(SupportedBrowser.FIREFOX, '15.0')
  @SupportedBrowser(SupportedBrowser.IE, '10.0')
  IdbFactory get indexedDB => JS(
      'IdbFactory|Null', // If not supported, returns null.
      '#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB',
      this,
      this,
      this);

  /// The debugging console for this window.
  Console get console => Console._safeConsole;

  /**
   * Access a sandboxed file system of `size` bytes.
   *
   * If `persistent` is true, the application will request permission from the
   * user to create lasting storage. This storage cannot be freed without the
   * user's permission. Returns a [Future] whose value stores a reference to
   * the sandboxed file system for use. Because the file system is sandboxed,
   * applications cannot access file systems created in other web pages.
   */
  Future<FileSystem> requestFileSystem(int size, {bool persistent: false}) {
    return _requestFileSystem(persistent ? 1 : 0, size);
  }

  /**
   * convertPointFromNodeToPage and convertPointFromPageToNode are removed.
   * see http://dev.w3.org/csswg/cssom-view/#geometry
   */
  static bool get supportsPointConversions => DomPoint.supported;
  // To suppress missing implicit constructor warnings.
  factory Window._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `contentloaded` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> contentLoadedEvent =
      const EventStreamProvider<Event>('DOMContentLoaded');

  /**
   * Static factory designed to expose `devicemotion` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<DeviceMotionEvent> deviceMotionEvent =
      const EventStreamProvider<DeviceMotionEvent>('devicemotion');

  /**
   * Static factory designed to expose `deviceorientation` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<DeviceOrientationEvent>
      deviceOrientationEvent =
      const EventStreamProvider<DeviceOrientationEvent>('deviceorientation');

  /**
   * Static factory designed to expose `hashchange` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> hashChangeEvent =
      const EventStreamProvider<Event>('hashchange');

  static const EventStreamProvider<Event> loadStartEvent =
      const EventStreamProvider<Event>('loadstart');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `offline` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> offlineEvent =
      const EventStreamProvider<Event>('offline');

  /**
   * Static factory designed to expose `online` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> onlineEvent =
      const EventStreamProvider<Event>('online');

  /**
   * Static factory designed to expose `pagehide` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> pageHideEvent =
      const EventStreamProvider<Event>('pagehide');

  /**
   * Static factory designed to expose `pageshow` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> pageShowEvent =
      const EventStreamProvider<Event>('pageshow');

  /**
   * Static factory designed to expose `popstate` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<PopStateEvent> popStateEvent =
      const EventStreamProvider<PopStateEvent>('popstate');

  static const EventStreamProvider<Event> progressEvent =
      const EventStreamProvider<Event>('progress');

  /**
   * Static factory designed to expose `storage` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<StorageEvent> storageEvent =
      const EventStreamProvider<StorageEvent>('storage');

  /**
   * Static factory designed to expose `unload` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> unloadEvent =
      const EventStreamProvider<Event>('unload');

  /**
   * Static factory designed to expose `animationend` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  static const EventStreamProvider<AnimationEvent> animationEndEvent =
      const EventStreamProvider<AnimationEvent>('webkitAnimationEnd');

  /**
   * Static factory designed to expose `animationiteration` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  static const EventStreamProvider<AnimationEvent> animationIterationEvent =
      const EventStreamProvider<AnimationEvent>('webkitAnimationIteration');

  /**
   * Static factory designed to expose `animationstart` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  static const EventStreamProvider<AnimationEvent> animationStartEvent =
      const EventStreamProvider<AnimationEvent>('webkitAnimationStart');

  /**
   * Indicates that file system data cannot be cleared unless given user
   * permission.
   *
   * ## Other resources
   *
   * * [Exploring the FileSystem
   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/)
   *   from HTML5Rocks.
   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)
   *   from W3C.
   */
  static const int PERSISTENT = 1;

  /**
   * Indicates that file system data can be cleared at any time.
   *
   * ## Other resources
   *
   * * [Exploring the FileSystem
   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)
   *   from W3C.
   */
  static const int TEMPORARY = 0;

  final _Worklet animationWorklet;

  /**
   * The application cache for this window.
   *
   * ## Other resources
   *
   * * [A beginner's guide to using the application
   *   cache](http://www.html5rocks.com/en/tutorials/appcache/beginner)
   *   from HTML5Rocks.
   * * [Application cache
   *   API](https://html.spec.whatwg.org/multipage/browsers.html#application-cache-api)
   *   from WHATWG.
   */
  final ApplicationCache applicationCache;

  final _Worklet audioWorklet;

  final CacheStorage caches;

  final bool closed;

  final CookieStore cookieStore;

  /**
   * Entrypoint for the browser's cryptographic functions.
   *
   * ## Other resources
   *
   * * [Web cryptography API](http://www.w3.org/TR/WebCryptoAPI/) from W3C.
   */
  final Crypto crypto;

  final CustomElementRegistry customElements;

  /// *Deprecated*.
  String defaultStatus;

  /// *Deprecated*.
  String defaultstatus;

  /**
   * The ratio between physical pixels and logical CSS pixels.
   *
   * ## Other resources
   *
   * * [devicePixelRatio](http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html)
   *   from quirksmode.
   * * [More about devicePixelRatio](http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html)
   *   from quirksmode.
   */
  final num devicePixelRatio;

  final External external;

  /**
   * The current session history for this window's newest document.
   *
   * ## Other resources
   *
   * * [Loading web pages](https://html.spec.whatwg.org/multipage/browsers.html)
   *   from WHATWG.
   */
  final History history;

  /**
   * The height of the viewport including scrollbars.
   *
   * ## Other resources
   *
   * * [innerHeight](http://docs.webplatform.org/wiki/css/cssom/properties/innerHeight)
   *   from WebPlatform.org.
   */
  final int innerHeight;

  /**
   * The width of the viewport including scrollbars.
   *
   * ## Other resources
   *
   * * [innerWidth](http://docs.webplatform.org/wiki/css/cssom/properties/innerWidth)
   *   from WebPlatform.org.
   */
  final int innerWidth;

  final bool isSecureContext;

  /**
   * Storage for this window that persists across sessions.
   *
   * ## Other resources
   *
   * * [DOM storage guide](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage)
   *   from MDN.
   * * [The past, present & future of local storage for web
   *   applications](http://diveintohtml5.info/storage.html) from Dive Into HTML5.
   * * [Local storage specification](http://www.w3.org/TR/webstorage/#the-localstorage-attribute)
   *   from W3C.
   */
  final Storage localStorage;

  /**
   * This window's location bar, which displays the URL.
   *
   * ## Other resources
   *
   * * [Browser interface
   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
   *   from WHATWG.
   */
  final BarProp locationbar;

  /**
   * This window's menu bar, which displays menu commands.
   *
   * ## Other resources
   *
   * * [Browser interface
   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
   *   from WHATWG.
   */
  final BarProp menubar;

  /**
   * The name of this window.
   *
   * ## Other resources
   *
   * * [Window name](http://docs.webplatform.org/wiki/html/attributes/name_(window))
   *   from WebPlatform.org.
   */
  String name;

  /**
   * The user agent accessing this window.
   *
   * ## Other resources
   *
   * * [The navigator
   *   object](https://html.spec.whatwg.org/multipage/webappapis.html#the-navigator-object)
   *   from WHATWG.
   */
  final Navigator navigator;

  /**
   * Whether objects are drawn offscreen before being displayed.
   *
   * ## Other resources
   *
   * * [offscreenBuffering](http://docs.webplatform.org/wiki/dom/properties/offscreenBuffering)
   *   from WebPlatform.org.
   */
  final bool offscreenBuffering;

  WindowBase get opener => _convertNativeToDart_Window(this._get_opener);
  @JSName('opener')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_opener;

  set opener(Window value) {
    JS("void", "#.opener = #", this, value);
  }

  final int orientation;

  final String origin;

  /**
   * The height of this window including all user interface elements.
   *
   * ## Other resources
   *
   * * [outerHeight](http://docs.webplatform.org/wiki/css/cssom/properties/outerHeight)
   *   from WebPlatform.org.
   */
  final int outerHeight;

  /**
   * The width of the window including all user interface elements.
   *
   * ## Other resources
   *
   * * [outerWidth](http://docs.webplatform.org/wiki/css/cssom/properties/outerWidth)
   *   from WebPlatform.org.
   */
  final int outerWidth;

  @JSName('pageXOffset')
  /**
   * The distance this window has been scrolled horizontally.
   *
   * This attribute is an alias for [scrollX].
   *
   * ## Other resources
   *
   * * [The Screen interface
   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollX and
   *   pageXOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)
   *   from MDN.
   */
  final num _pageXOffset;

  @JSName('pageYOffset')
  /**
   * The distance this window has been scrolled vertically.
   *
   * This attribute is an alias for [scrollY].
   *
   * ## Other resources
   *
   * * [The Screen interface
   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollY and
   *   pageYOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)
   *   from MDN.
   */
  final num _pageYOffset;

  WindowBase get parent => _convertNativeToDart_Window(this._get_parent);
  @JSName('parent')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_parent;

  /**
   * Timing and navigation data for this window.
   *
   * ## Other resources
   *
   * * [Measuring page load speed with navigation
   *   timeing](http://www.html5rocks.com/en/tutorials/webperformance/basics/)
   *   from HTML5Rocks.
   * * [Navigation timing
   *   specification](http://www.w3.org/TR/navigation-timing/) from W3C.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE)
  final Performance performance;

  /**
   * Information about the screen displaying this window.
   *
   * ## Other resources
   *
   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
   *   from W3C.
   */
  final Screen screen;

  /**
   * The distance from the left side of the screen to the left side of this
   * window.
   *
   * ## Other resources
   *
   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
   *   from W3C.
   */
  final int screenLeft;

  /**
   * The distance from the top of the screen to the top of this window.
   *
   * ## Other resources
   *
   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
   *   from W3C.
   */
  final int screenTop;

  /**
   * The distance from the left side of the screen to the mouse pointer.
   *
   * ## Other resources
   *
   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
   *   from W3C.
   */
  final int screenX;

  /**
   * The distance from the top of the screen to the mouse pointer.
   *
   * ## Other resources
   *
   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
   *   from W3C.
   */
  final int screenY;

  /**
   * This window's scroll bars.
   *
   * ## Other resources
   *
   * * [Browser interface
   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
   *   from WHATWG.
   */
  final BarProp scrollbars;

  /**
   * The current window.
   *
   * ## Other resources
   *
   * * [Window.self](https://developer.mozilla.org/en-US/docs/Web/API/Window.self)
   *   from MDN.
   */
  WindowBase get self => _convertNativeToDart_Window(this._get_self);
  @JSName('self')
  /**
   * The current window.
   *
   * ## Other resources
   *
   * * [Window.self](https://developer.mozilla.org/en-US/docs/Web/API/Window.self)
   *   from MDN.
   */
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_self;

  /**
   * Storage for this window that is cleared when this session ends.
   *
   * ## Other resources
   *
   * * [DOM storage
   *   guide](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage)
   *   from MDN.
   * * [The past, present & future of local storage for web
   *   applications](http://diveintohtml5.info/storage.html) from Dive Into HTML5.
   * * [Local storage
   *   specification](http://www.w3.org/TR/webstorage/#dom-sessionstorage) from W3C.
   */
  final Storage sessionStorage;

  /**
   * Access to speech synthesis in the browser.
   *
   * ## Other resources
   *
   * * [Web speech
   *   specification](https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section)
   *   from W3C.
   */
  final SpeechSynthesis speechSynthesis;

  /// *Deprecated*.
  String status;

  /**
   * This window's status bar.
   *
   * ## Other resources
   *
   * * [Browser interface
   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
   *   from WHATWG.
   */
  final BarProp statusbar;

  /**
   * Access to CSS media queries.
   *
   * ## Other resources
   *
   * * [StyleMedia class
   *   reference](https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/StyleMedia/)
   *   from Safari Developer Library.
   */
  final StyleMedia styleMedia;

  /**
   * This window's tool bar.
   *
   * ## Other resources
   *
   * * [Browser interface
   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
   *   from WHATWG.
   */
  final BarProp toolbar;

  WindowBase get top => _convertNativeToDart_Window(this._get_top);
  @JSName('top')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_top;

  final VisualViewport visualViewport;

  /**
   * The current window.
   *
   * ## Other resources
   *
   * * [Window.window](https://developer.mozilla.org/en-US/docs/Web/API/Window.window)
   *   from MDN.
   */
  WindowBase get window => _convertNativeToDart_Window(this._get_window);
  @JSName('window')
  /**
   * The current window.
   *
   * ## Other resources
   *
   * * [Window.window](https://developer.mozilla.org/en-US/docs/Web/API/Window.window)
   *   from MDN.
   */
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_window;

  @Creates('Window|=Object')
  @Returns('Window|=Object')
  WindowBase __getter__(index_OR_name) {
    if ((index_OR_name is int)) {
      return _convertNativeToDart_Window(__getter___1(index_OR_name));
    }
    if ((index_OR_name is String)) {
      return _convertNativeToDart_Window(__getter___2(index_OR_name));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('__getter__')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  __getter___1(int index) native;
  @JSName('__getter__')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  __getter___2(String name) native;

  /**
   * Displays a modal alert to the user.
   *
   * ## Other resources
   *
   * * [User prompts](https://html.spec.whatwg.org/multipage/webappapis.html#user-prompts)
   *   from WHATWG.
   */
  void alert([String message]) native;

  void cancelIdleCallback(int handle) native;

  void close() native;

  /**
   * Displays a modal OK/Cancel prompt to the user.
   *
   * ## Other resources
   *
   * * [User prompts](https://html.spec.whatwg.org/multipage/webappapis.html#user-prompts)
   *   from WHATWG.
   */
  bool confirm([String message]) native;

  Future fetch(/*RequestInfo*/ input, [Map init]) {
    var init_dict = null;
    if (init != null) {
      init_dict = convertDartToNative_Dictionary(init);
    }
    return promiseToFuture(JS("", "#.fetch(#, #)", this, input, init_dict));
  }

  /**
   * Finds text in this window.
   *
   * ## Other resources
   *
   * * [Window.find](https://developer.mozilla.org/en-US/docs/Web/API/Window.find)
   *   from MDN.
   */
  bool find(String string, bool caseSensitive, bool backwards, bool wrap,
      bool wholeWord, bool searchInFrames, bool showDialog) native;

  @JSName('getComputedStyle')
  CssStyleDeclaration _getComputedStyle(Element elt, [String pseudoElt]) native;

  StylePropertyMapReadonly getComputedStyleMap(
      Element element, String pseudoElement) native;

  @JSName('getMatchedCSSRules')
  /**
   * Returns all CSS rules that apply to the element's pseudo-element.
   */
  @Returns('_CssRuleList|Null')
  @Creates('_CssRuleList')
  List<CssRule> getMatchedCssRules(Element element, String pseudoElement)
      native;

  /**
   * Returns the currently selected text.
   *
   * ## Other resources
   *
   * * [Window.getSelection](https://developer.mozilla.org/en-US/docs/Web/API/Window.getSelection)
   *   from MDN.
   */
  Selection getSelection() native;

  /**
   * Returns a list of media queries for the given query string.
   *
   * ## Other resources
   *
   * * [Testing media
   *   queries](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries)
   *   from MDN.
   * * [The MediaQueryList
   *   specification](http://www.w3.org/TR/cssom-view/#the-mediaquerylist-interface) from W3C.
   */
  MediaQueryList matchMedia(String query) native;

  /**
   * Moves this window.
   *
   * x and y can be negative.
   *
   * ## Other resources
   *
   * * [Window.moveBy](https://developer.mozilla.org/en-US/docs/Web/API/Window.moveBy)
   *   from MDN.
   * * [Window.moveBy](http://dev.w3.org/csswg/cssom-view/#dom-window-moveby) from W3C.
   */
  void moveBy(int x, int y) native;

  @JSName('moveTo')
  void _moveTo(int x, int y) native;

  @JSName('openDatabase')

  /// *Deprecated.*
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Creates('SqlDatabase')
  SqlDatabase _openDatabase(
      String name, String version, String displayName, int estimatedSize,
      [DatabaseCallback creationCallback]) native;

  void postMessage(/*any*/ message, String targetOrigin,
      [List<Object> transfer]) {
    if (transfer != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, targetOrigin, transfer);
      return;
    }
    var message_1 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_1, targetOrigin);
    return;
  }

  @JSName('postMessage')
  void _postMessage_1(message, targetOrigin, List<Object> transfer) native;
  @JSName('postMessage')
  void _postMessage_2(message, targetOrigin) native;

  /**
   * Opens the print dialog for this window.
   *
   * ## Other resources
   *
   * * [Window.print](https://developer.mozilla.org/en-US/docs/Web/API/Window.print)
   *   from MDN.
   */
  void print() native;

  int requestIdleCallback(IdleRequestCallback callback, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _requestIdleCallback_1(callback, options_1);
    }
    return _requestIdleCallback_2(callback);
  }

  @JSName('requestIdleCallback')
  int _requestIdleCallback_1(IdleRequestCallback callback, options) native;
  @JSName('requestIdleCallback')
  int _requestIdleCallback_2(IdleRequestCallback callback) native;

  /**
   * Resizes this window by an offset.
   *
   * ## Other resources
   *
   * * [Window resizeBy](http://docs.webplatform.org/wiki/dom/methods/resizeBy)
   *   from WebPlatform.org.
   */
  void resizeBy(int x, int y) native;

  /**
   * Resizes this window to a specific width and height.
   *
   * ## Other resources
   *
   * * [Window resizeTo](http://docs.webplatform.org/wiki/dom/methods/resizeTo)
   *   from WebPlatform.org.
   */
  void resizeTo(int x, int y) native;

  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
   *   from WebPlatform.org.
   */
  void scroll([options_OR_x, y, Map scrollOptions]) {
    if (options_OR_x == null && y == null && scrollOptions == null) {
      _scroll_1();
      return;
    }
    if ((options_OR_x is Map) && y == null && scrollOptions == null) {
      var options_1 = convertDartToNative_Dictionary(options_OR_x);
      _scroll_2(options_1);
      return;
    }
    if ((y is num) && (options_OR_x is num) && scrollOptions == null) {
      _scroll_3(options_OR_x, y);
      return;
    }
    if ((y is int) && (options_OR_x is int) && scrollOptions == null) {
      _scroll_4(options_OR_x, y);
      return;
    }
    if (scrollOptions != null && (y is int) && (options_OR_x is int)) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scroll_5(options_OR_x, y, scrollOptions_1);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('scroll')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
   *   from WebPlatform.org.
   */
  void _scroll_1() native;
  @JSName('scroll')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
   *   from WebPlatform.org.
   */
  void _scroll_2(options) native;
  @JSName('scroll')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
   *   from WebPlatform.org.
   */
  void _scroll_3(num x, num y) native;
  @JSName('scroll')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
   *   from WebPlatform.org.
   */
  void _scroll_4(int x, int y) native;
  @JSName('scroll')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
   *   from WebPlatform.org.
   */
  void _scroll_5(int x, int y, scrollOptions) native;

  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
   *   from WebPlatform.org.
   */
  void scrollBy([options_OR_x, y, Map scrollOptions]) {
    if (options_OR_x == null && y == null && scrollOptions == null) {
      _scrollBy_1();
      return;
    }
    if ((options_OR_x is Map) && y == null && scrollOptions == null) {
      var options_1 = convertDartToNative_Dictionary(options_OR_x);
      _scrollBy_2(options_1);
      return;
    }
    if ((y is num) && (options_OR_x is num) && scrollOptions == null) {
      _scrollBy_3(options_OR_x, y);
      return;
    }
    if ((y is int) && (options_OR_x is int) && scrollOptions == null) {
      _scrollBy_4(options_OR_x, y);
      return;
    }
    if (scrollOptions != null && (y is int) && (options_OR_x is int)) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scrollBy_5(options_OR_x, y, scrollOptions_1);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
   *   from WebPlatform.org.
   */
  void _scrollBy_1() native;
  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
   *   from WebPlatform.org.
   */
  void _scrollBy_2(options) native;
  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
   *   from WebPlatform.org.
   */
  void _scrollBy_3(num x, num y) native;
  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
   *   from WebPlatform.org.
   */
  void _scrollBy_4(int x, int y) native;
  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
   *   from WebPlatform.org.
   */
  void _scrollBy_5(int x, int y, scrollOptions) native;

  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
   *   from WebPlatform.org.
   */
  void scrollTo([options_OR_x, y, Map scrollOptions]) {
    if (options_OR_x == null && y == null && scrollOptions == null) {
      _scrollTo_1();
      return;
    }
    if ((options_OR_x is Map) && y == null && scrollOptions == null) {
      var options_1 = convertDartToNative_Dictionary(options_OR_x);
      _scrollTo_2(options_1);
      return;
    }
    if ((y is num) && (options_OR_x is num) && scrollOptions == null) {
      _scrollTo_3(options_OR_x, y);
      return;
    }
    if ((y is int) && (options_OR_x is int) && scrollOptions == null) {
      _scrollTo_4(options_OR_x, y);
      return;
    }
    if (scrollOptions != null && (y is int) && (options_OR_x is int)) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scrollTo_5(options_OR_x, y, scrollOptions_1);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('scrollTo')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
   *   from WebPlatform.org.
   */
  void _scrollTo_1() native;
  @JSName('scrollTo')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
   *   from WebPlatform.org.
   */
  void _scrollTo_2(options) native;
  @JSName('scrollTo')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
   *   from WebPlatform.org.
   */
  void _scrollTo_3(num x, num y) native;
  @JSName('scrollTo')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
   *   from WebPlatform.org.
   */
  void _scrollTo_4(int x, int y) native;
  @JSName('scrollTo')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
   *   from WebPlatform.org.
   */
  void _scrollTo_5(int x, int y, scrollOptions) native;

  /**
   * Stops the window from loading.
   *
   * ## Other resources
   *
   * * [The Window
   *   object](http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object)
   *   from W3C.
   */
  void stop() native;

  @JSName('webkitRequestFileSystem')
  @SupportedBrowser(SupportedBrowser.CHROME)
  void __requestFileSystem(
      int type, int size, _FileSystemCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  @JSName('webkitRequestFileSystem')
  @SupportedBrowser(SupportedBrowser.CHROME)
  Future<FileSystem> _requestFileSystem(int type, int size) {
    var completer = new Completer<FileSystem>();
    __requestFileSystem(type, size, (value) {
      applyExtension('DOMFileSystem', value);
      applyExtension('DirectoryEntry', value.root);
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('webkitResolveLocalFileSystemURL')
  /**
   * Asynchronously retrieves a local filesystem entry.
   *
   * ## Other resources
   *
   * * [Obtaining access to file system entry
   *   points](http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
   * from W3C.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  void _resolveLocalFileSystemUrl(String url, _EntryCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  @JSName('webkitResolveLocalFileSystemURL')
  /**
   * Asynchronously retrieves a local filesystem entry.
   *
   * ## Other resources
   *
   * * [Obtaining access to file system entry
   *   points](http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
   * from W3C.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  Future<Entry> resolveLocalFileSystemUrl(String url) {
    var completer = new Completer<Entry>();
    _resolveLocalFileSystemUrl(url, (value) {
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  // From WindowBase64

  String atob(String atob) native;

  String btoa(String btoa) native;

  // From WindowTimers

  @JSName('setInterval')
  int _setInterval_String(String handler, [int timeout, Object arguments])
      native;

  @JSName('setTimeout')
  int _setTimeout_String(String handler, [int timeout, Object arguments])
      native;

  @JSName('clearInterval')
  void _clearInterval([int handle]) native;

  @JSName('clearTimeout')
  void _clearTimeout([int handle]) native;

  @JSName('setInterval')
  int _setInterval(Object handler, [int timeout]) native;

  @JSName('setTimeout')
  int _setTimeout(Object handler, [int timeout]) native;

  /// Stream of `contentloaded` events handled by this [Window].
  Stream<Event> get onContentLoaded => contentLoadedEvent.forTarget(this);

  /// Stream of `abort` events handled by this [Window].
  Stream<Event> get onAbort => Element.abortEvent.forTarget(this);

  /// Stream of `blur` events handled by this [Window].
  Stream<Event> get onBlur => Element.blurEvent.forTarget(this);

  Stream<Event> get onCanPlay => Element.canPlayEvent.forTarget(this);

  Stream<Event> get onCanPlayThrough =>
      Element.canPlayThroughEvent.forTarget(this);

  /// Stream of `change` events handled by this [Window].
  Stream<Event> get onChange => Element.changeEvent.forTarget(this);

  /// Stream of `click` events handled by this [Window].
  Stream<MouseEvent> get onClick => Element.clickEvent.forTarget(this);

  /// Stream of `contextmenu` events handled by this [Window].
  Stream<MouseEvent> get onContextMenu =>
      Element.contextMenuEvent.forTarget(this);

  /// Stream of `doubleclick` events handled by this [Window].
  Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);

  /// Stream of `devicemotion` events handled by this [Window].
  Stream<DeviceMotionEvent> get onDeviceMotion =>
      deviceMotionEvent.forTarget(this);

  /// Stream of `deviceorientation` events handled by this [Window].
  Stream<DeviceOrientationEvent> get onDeviceOrientation =>
      deviceOrientationEvent.forTarget(this);

  /// Stream of `drag` events handled by this [Window].
  Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);

  /// Stream of `dragend` events handled by this [Window].
  Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);

  /// Stream of `dragenter` events handled by this [Window].
  Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);

  /// Stream of `dragleave` events handled by this [Window].
  Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);

  /// Stream of `dragover` events handled by this [Window].
  Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);

  /// Stream of `dragstart` events handled by this [Window].
  Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);

  /// Stream of `drop` events handled by this [Window].
  Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);

  Stream<Event> get onDurationChange =>
      Element.durationChangeEvent.forTarget(this);

  Stream<Event> get onEmptied => Element.emptiedEvent.forTarget(this);

  Stream<Event> get onEnded => Element.endedEvent.forTarget(this);

  /// Stream of `error` events handled by this [Window].
  Stream<Event> get onError => Element.errorEvent.forTarget(this);

  /// Stream of `focus` events handled by this [Window].
  Stream<Event> get onFocus => Element.focusEvent.forTarget(this);

  /// Stream of `hashchange` events handled by this [Window].
  Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);

  /// Stream of `input` events handled by this [Window].
  Stream<Event> get onInput => Element.inputEvent.forTarget(this);

  /// Stream of `invalid` events handled by this [Window].
  Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);

  /// Stream of `keydown` events handled by this [Window].
  Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);

  /// Stream of `keypress` events handled by this [Window].
  Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);

  /// Stream of `keyup` events handled by this [Window].
  Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);

  /// Stream of `load` events handled by this [Window].
  Stream<Event> get onLoad => Element.loadEvent.forTarget(this);

  Stream<Event> get onLoadedData => Element.loadedDataEvent.forTarget(this);

  Stream<Event> get onLoadedMetadata =>
      Element.loadedMetadataEvent.forTarget(this);

  Stream<Event> get onLoadStart => loadStartEvent.forTarget(this);

  /// Stream of `message` events handled by this [Window].
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `mousedown` events handled by this [Window].
  Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);

  /// Stream of `mouseenter` events handled by this [Window].
  Stream<MouseEvent> get onMouseEnter =>
      Element.mouseEnterEvent.forTarget(this);

  /// Stream of `mouseleave` events handled by this [Window].
  Stream<MouseEvent> get onMouseLeave =>
      Element.mouseLeaveEvent.forTarget(this);

  /// Stream of `mousemove` events handled by this [Window].
  Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);

  /// Stream of `mouseout` events handled by this [Window].
  Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);

  /// Stream of `mouseover` events handled by this [Window].
  Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);

  /// Stream of `mouseup` events handled by this [Window].
  Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);

  /// Stream of `mousewheel` events handled by this [Window].
  Stream<WheelEvent> get onMouseWheel =>
      Element.mouseWheelEvent.forTarget(this);

  /// Stream of `offline` events handled by this [Window].
  Stream<Event> get onOffline => offlineEvent.forTarget(this);

  /// Stream of `online` events handled by this [Window].
  Stream<Event> get onOnline => onlineEvent.forTarget(this);

  /// Stream of `pagehide` events handled by this [Window].
  Stream<Event> get onPageHide => pageHideEvent.forTarget(this);

  /// Stream of `pageshow` events handled by this [Window].
  Stream<Event> get onPageShow => pageShowEvent.forTarget(this);

  Stream<Event> get onPause => Element.pauseEvent.forTarget(this);

  Stream<Event> get onPlay => Element.playEvent.forTarget(this);

  Stream<Event> get onPlaying => Element.playingEvent.forTarget(this);

  /// Stream of `popstate` events handled by this [Window].
  Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);

  Stream<Event> get onProgress => progressEvent.forTarget(this);

  Stream<Event> get onRateChange => Element.rateChangeEvent.forTarget(this);

  /// Stream of `reset` events handled by this [Window].
  Stream<Event> get onReset => Element.resetEvent.forTarget(this);

  /// Stream of `resize` events handled by this [Window].
  Stream<Event> get onResize => Element.resizeEvent.forTarget(this);

  /// Stream of `scroll` events handled by this [Window].
  Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);

  /// Stream of `search` events handled by this [Window].
  Stream<Event> get onSearch => Element.searchEvent.forTarget(this);

  Stream<Event> get onSeeked => Element.seekedEvent.forTarget(this);

  Stream<Event> get onSeeking => Element.seekingEvent.forTarget(this);

  /// Stream of `select` events handled by this [Window].
  Stream<Event> get onSelect => Element.selectEvent.forTarget(this);

  Stream<Event> get onStalled => Element.stalledEvent.forTarget(this);

  /// Stream of `storage` events handled by this [Window].
  Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);

  /// Stream of `submit` events handled by this [Window].
  Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);

  Stream<Event> get onSuspend => Element.suspendEvent.forTarget(this);

  Stream<Event> get onTimeUpdate => Element.timeUpdateEvent.forTarget(this);

  /// Stream of `touchcancel` events handled by this [Window].
  Stream<TouchEvent> get onTouchCancel =>
      Element.touchCancelEvent.forTarget(this);

  /// Stream of `touchend` events handled by this [Window].
  Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);

  /// Stream of `touchmove` events handled by this [Window].
  Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);

  /// Stream of `touchstart` events handled by this [Window].
  Stream<TouchEvent> get onTouchStart =>
      Element.touchStartEvent.forTarget(this);

  /// Stream of `transitionend` events handled by this [Window].
  Stream<TransitionEvent> get onTransitionEnd =>
      Element.transitionEndEvent.forTarget(this);

  /// Stream of `unload` events handled by this [Window].
  Stream<Event> get onUnload => unloadEvent.forTarget(this);

  Stream<Event> get onVolumeChange => Element.volumeChangeEvent.forTarget(this);

  Stream<Event> get onWaiting => Element.waitingEvent.forTarget(this);

  /// Stream of `animationend` events handled by this [Window].
  Stream<AnimationEvent> get onAnimationEnd =>
      animationEndEvent.forTarget(this);

  /// Stream of `animationiteration` events handled by this [Window].
  Stream<AnimationEvent> get onAnimationIteration =>
      animationIterationEvent.forTarget(this);

  /// Stream of `animationstart` events handled by this [Window].
  Stream<AnimationEvent> get onAnimationStart =>
      animationStartEvent.forTarget(this);

  /**
   * Static factory designed to expose `beforeunload` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<BeforeUnloadEvent> beforeUnloadEvent =
      const _BeforeUnloadEventStreamProvider('beforeunload');

  /// Stream of `beforeunload` events handled by this [Window].
  Stream<Event> get onBeforeUnload => beforeUnloadEvent.forTarget(this);

  /// Stream of `wheel` events handled by this [Window].
  Stream<WheelEvent> get onWheel => Element.wheelEvent.forTarget(this);

  /**
   * Moves this window to a specific position.
   *
   * x and y can be negative.
   *
   * ## Other resources
   *
   * * [Window.moveTo](https://developer.mozilla.org/en-US/docs/Web/API/Window.moveTo)
   *   from MDN.
   * * [Window.moveTo](http://dev.w3.org/csswg/cssom-view/#dom-window-moveto)
   *   from W3C.
   */
  void moveTo(Point p) {
    _moveTo(p.x, p.y);
  }

  @JSName('openDatabase')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Creates('SqlDatabase')
  SqlDatabase openDatabase(
      String name, String version, String displayName, int estimatedSize,
      [DatabaseCallback creationCallback]) {
    var db;
    if (creationCallback == null)
      db = _openDatabase(name, version, displayName, estimatedSize);
    else
      db = _openDatabase(
          name, version, displayName, estimatedSize, creationCallback);

    applyExtension('Database', db);

    return db;
  }

  int get pageXOffset => JS('num', '#.pageXOffset', this).round();

  int get pageYOffset => JS('num', '#.pageYOffset', this).round();

  /**
   * The distance this window has been scrolled horizontally.
   *
   * ## Other resources
   *
   * * [The Screen interface
   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollX](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)
   *   from MDN.
   */
  int get scrollX => JS('bool', '("scrollX" in #)', this)
      ? JS('num', '#.scrollX', this).round()
      : document.documentElement.scrollLeft;

  /**
   * The distance this window has been scrolled vertically.
   *
   * ## Other resources
   *
   * * [The Screen interface
   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollY](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)
   *   from MDN.
   */
  int get scrollY => JS('bool', '("scrollY" in #)', this)
      ? JS('num', '#.scrollY', this).round()
      : document.documentElement.scrollTop;
}

class _BeforeUnloadEvent extends _WrappedEvent implements BeforeUnloadEvent {
  String _returnValue;

  _BeforeUnloadEvent(Event base) : super(base);

  String get returnValue => _returnValue;

  set returnValue(String value) {
    _returnValue = value;
    // FF and IE use the value as the return value, Chrome will return this from
    // the event callback function.
    if (JS('bool', '("returnValue" in #)', wrapped)) {
      JS('void', '#.returnValue = #', wrapped, value);
    }
  }
}

class _BeforeUnloadEventStreamProvider
    implements EventStreamProvider<BeforeUnloadEvent> {
  final String _eventType;

  const _BeforeUnloadEventStreamProvider(this._eventType);

  Stream<BeforeUnloadEvent> forTarget(EventTarget e, {bool useCapture: false}) {
    // Specify the generic type for EventStream only in dart2js.
    var stream = new _EventStream<BeforeUnloadEvent>(e, _eventType, useCapture);
    var controller = new StreamController<BeforeUnloadEvent>(sync: true);

    stream.listen((event) {
      var wrapped = new _BeforeUnloadEvent(event);
      controller.add(wrapped);
    });

    return controller.stream;
  }

  String getEventType(EventTarget target) {
    return _eventType;
  }

  ElementStream<BeforeUnloadEvent> forElement(Element e,
      {bool useCapture: false}) {
    // Specify the generic type for _ElementEventStreamImpl only in dart2js.
    return new _ElementEventStreamImpl<BeforeUnloadEvent>(
        e, _eventType, useCapture);
  }

  ElementStream<BeforeUnloadEvent> _forElementList(ElementList<Element> e,
      {bool useCapture: false}) {
    // Specify the generic type for _ElementEventStreamImpl only in dart2js.
    return new _ElementListEventStreamImpl<BeforeUnloadEvent>(
        e, _eventType, useCapture);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class WindowBase64 extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory WindowBase64._() {
    throw new UnsupportedError("Not supported");
  }

  String atob(String atob);

  String btoa(String btoa);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("WindowClient")
class WindowClient extends Client {
  // To suppress missing implicit constructor warnings.
  factory WindowClient._() {
    throw new UnsupportedError("Not supported");
  }

  final bool focused;

  final String visibilityState;

  Future<WindowClient> focus() =>
      promiseToFuture<WindowClient>(JS("", "#.focus()", this));

  Future<WindowClient> navigate(String url) =>
      promiseToFuture<WindowClient>(JS("", "#.navigate(#)", this, url));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class WindowEventHandlers extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory WindowEventHandlers._() {
    throw new UnsupportedError("Not supported");
  }

  static const EventStreamProvider<Event> hashChangeEvent =
      const EventStreamProvider<Event>('hashchange');

  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  static const EventStreamProvider<Event> offlineEvent =
      const EventStreamProvider<Event>('offline');

  static const EventStreamProvider<Event> onlineEvent =
      const EventStreamProvider<Event>('online');

  static const EventStreamProvider<PopStateEvent> popStateEvent =
      const EventStreamProvider<PopStateEvent>('popstate');

  static const EventStreamProvider<StorageEvent> storageEvent =
      const EventStreamProvider<StorageEvent>('storage');

  static const EventStreamProvider<Event> unloadEvent =
      const EventStreamProvider<Event>('unload');

  Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);

  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  Stream<Event> get onOffline => offlineEvent.forTarget(this);

  Stream<Event> get onOnline => onlineEvent.forTarget(this);

  Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);

  Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);

  Stream<Event> get onUnload => unloadEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("Worker")
class Worker extends EventTarget implements AbstractWorker {
  // To suppress missing implicit constructor warnings.
  factory Worker._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [Worker].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [Worker].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  factory Worker(String scriptUrl) {
    return Worker._create_1(scriptUrl);
  }
  static Worker _create_1(scriptUrl) =>
      JS('Worker', 'new Worker(#)', scriptUrl);

  /// Checks if this type is supported on the current platform.
  static bool get supported =>
      JS('bool', '(typeof window.Worker != "undefined")');

  void postMessage(Object message, [List<Object> transfer]) native;

  void terminate() native;

  /// Stream of `error` events handled by this [Worker].
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [Worker].
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("WorkerGlobalScope")
class WorkerGlobalScope extends EventTarget
    implements _WindowTimers, WindowBase64 {
  // To suppress missing implicit constructor warnings.
  factory WorkerGlobalScope._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [WorkerGlobalScope].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  final String addressSpace;

  final CacheStorage caches;

  final Crypto crypto;

  final IdbFactory indexedDB;

  final bool isSecureContext;

  final _WorkerLocation location;

  final _WorkerNavigator navigator;

  final String origin;

  final WorkerPerformance performance;

  final WorkerGlobalScope self;

  Future fetch(/*RequestInfo*/ input, [Map init]) {
    var init_dict = null;
    if (init != null) {
      init_dict = convertDartToNative_Dictionary(init);
    }
    return promiseToFuture(JS("", "#.fetch(#, #)", this, input, init_dict));
  }

  void importScripts(String urls) native;

  // From WindowBase64

  String atob(String atob) native;

  String btoa(String btoa) native;

  // From WindowTimers

  @JSName('setInterval')
  int _setInterval_String(String handler, [int timeout, Object arguments])
      native;

  @JSName('setTimeout')
  int _setTimeout_String(String handler, [int timeout, Object arguments])
      native;

  @JSName('clearInterval')
  void _clearInterval([int handle]) native;

  @JSName('clearTimeout')
  void _clearTimeout([int handle]) native;

  @JSName('setInterval')
  int _setInterval(Object handler, [int timeout]) native;

  @JSName('setTimeout')
  int _setTimeout(Object handler, [int timeout]) native;

  /// Stream of `error` events handled by this [WorkerGlobalScope].
  Stream<Event> get onError => errorEvent.forTarget(this);

  static WorkerGlobalScope get instance => _workerSelf;
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("WorkerPerformance")
class WorkerPerformance extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory WorkerPerformance._() {
    throw new UnsupportedError("Not supported");
  }

  final MemoryInfo memory;

  final num timeOrigin;

  void clearMarks(String markName) native;

  void clearMeasures(String measureName) native;

  void clearResourceTimings() native;

  List<PerformanceEntry> getEntries() native;

  List<PerformanceEntry> getEntriesByName(String name, String entryType) native;

  List<PerformanceEntry> getEntriesByType(String entryType) native;

  void mark(String markName) native;

  void measure(String measureName, String startMark, String endMark) native;

  double now() native;

  void setResourceTimingBufferSize(int maxSize) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("WorkletAnimation")
class WorkletAnimation extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory WorkletAnimation._() {
    throw new UnsupportedError("Not supported");
  }

  factory WorkletAnimation(
      String animatorName,
      List<KeyframeEffectReadOnly> effects,
      List<Object> timelines,
      /*SerializedScriptValue*/ options) {
    var options_1 = convertDartToNative_SerializedScriptValue(options);
    return WorkletAnimation._create_1(
        animatorName, effects, timelines, options_1);
  }
  static WorkletAnimation _create_1(
          animatorName, effects, timelines, options) =>
      JS('WorkletAnimation', 'new WorkletAnimation(#,#,#,#)', animatorName,
          effects, timelines, options);

  final String playState;

  void cancel() native;

  void play() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("WorkletGlobalScope")
class WorkletGlobalScope extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory WorkletGlobalScope._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathEvaluator
@deprecated // experimental
@Native("XPathEvaluator")
class XPathEvaluator extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory XPathEvaluator._() {
    throw new UnsupportedError("Not supported");
  }

  factory XPathEvaluator() {
    return XPathEvaluator._create_1();
  }
  static XPathEvaluator _create_1() =>
      JS('XPathEvaluator', 'new XPathEvaluator()');

  XPathExpression createExpression(String expression, XPathNSResolver resolver)
      native;

  XPathNSResolver createNSResolver(Node nodeResolver) native;

  XPathResult evaluate(
      String expression, Node contextNode, XPathNSResolver resolver,
      [int type, Object inResult]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathExpression
@deprecated // experimental
@Native("XPathExpression")
class XPathExpression extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory XPathExpression._() {
    throw new UnsupportedError("Not supported");
  }

  XPathResult evaluate(Node contextNode, [int type, Object inResult]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathNSResolver
@deprecated // experimental
@Native("XPathNSResolver")
class XPathNSResolver extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory XPathNSResolver._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('lookupNamespaceURI')
  String lookupNamespaceUri(String prefix) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathResult
@deprecated // experimental
@Native("XPathResult")
class XPathResult extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory XPathResult._() {
    throw new UnsupportedError("Not supported");
  }

  static const int ANY_TYPE = 0;

  static const int ANY_UNORDERED_NODE_TYPE = 8;

  static const int BOOLEAN_TYPE = 3;

  static const int FIRST_ORDERED_NODE_TYPE = 9;

  static const int NUMBER_TYPE = 1;

  static const int ORDERED_NODE_ITERATOR_TYPE = 5;

  static const int ORDERED_NODE_SNAPSHOT_TYPE = 7;

  static const int STRING_TYPE = 2;

  static const int UNORDERED_NODE_ITERATOR_TYPE = 4;

  static const int UNORDERED_NODE_SNAPSHOT_TYPE = 6;

  final bool booleanValue;

  final bool invalidIteratorState;

  final num numberValue;

  final int resultType;

  final Node singleNodeValue;

  final int snapshotLength;

  final String stringValue;

  Node iterateNext() native;

  Node snapshotItem(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("XMLDocument")
class XmlDocument extends Document {
  // To suppress missing implicit constructor warnings.
  factory XmlDocument._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://domparsing.spec.whatwg.org/#the-xmlserializer-interface
@deprecated // stable
@Native("XMLSerializer")
class XmlSerializer extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory XmlSerializer._() {
    throw new UnsupportedError("Not supported");
  }

  factory XmlSerializer() {
    return XmlSerializer._create_1();
  }
  static XmlSerializer _create_1() =>
      JS('XmlSerializer', 'new XMLSerializer()');

  String serializeToString(Node root) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@deprecated // nonstandard
@Native("XSLTProcessor")
class XsltProcessor extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory XsltProcessor._() {
    throw new UnsupportedError("Not supported");
  }

  factory XsltProcessor() {
    return XsltProcessor._create_1();
  }
  static XsltProcessor _create_1() =>
      JS('XsltProcessor', 'new XSLTProcessor()');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.XSLTProcessor)');

  void clearParameters() native;

  String getParameter(String namespaceURI, String localName) native;

  void importStylesheet(Node style) native;

  void removeParameter(String namespaceURI, String localName) native;

  void reset() native;

  void setParameter(String namespaceURI, String localName, String value) native;

  Document transformToDocument(Node source) native;

  DocumentFragment transformToFragment(Node source, Document output) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Attr")
class _Attr extends Node {
  // To suppress missing implicit constructor warnings.
  factory _Attr._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('localName')
  final String _localName;

  final String name;

  @JSName('namespaceURI')
  final String _namespaceUri;

  String value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Bluetooth")
abstract class _Bluetooth extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _Bluetooth._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BluetoothCharacteristicProperties")
abstract class _BluetoothCharacteristicProperties extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _BluetoothCharacteristicProperties._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BluetoothDevice")
abstract class _BluetoothDevice extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory _BluetoothDevice._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BluetoothRemoteGATTCharacteristic")
abstract class _BluetoothRemoteGATTCharacteristic extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory _BluetoothRemoteGATTCharacteristic._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BluetoothRemoteGATTServer")
abstract class _BluetoothRemoteGATTServer extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _BluetoothRemoteGATTServer._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BluetoothRemoteGATTService")
abstract class _BluetoothRemoteGATTService extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _BluetoothRemoteGATTService._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BluetoothUUID")
abstract class _BluetoothUUID extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _BluetoothUUID._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("BudgetService")
class _BudgetService extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _BudgetService._() {
    throw new UnsupportedError("Not supported");
  }

  Future<BudgetState> getBudget() =>
      promiseToFuture<BudgetState>(JS("", "#.getBudget()", this));

  Future<double> getCost(String operation) =>
      promiseToFuture<double>(JS("", "#.getCost(#)", this, operation));

  Future<bool> reserve(String operation) =>
      promiseToFuture<bool>(JS("", "#.reserve(#)", this, operation));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Cache")
abstract class _Cache extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _Cache._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class _CanvasPath extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _CanvasPath._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Clipboard")
class _Clipboard extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory _Clipboard._() {
    throw new UnsupportedError("Not supported");
  }

  Future<DataTransfer> read() =>
      promiseToFuture<DataTransfer>(JS("", "#.read()", this));

  Future<String> readText() =>
      promiseToFuture<String>(JS("", "#.readText()", this));

  Future write(DataTransfer data) =>
      promiseToFuture(JS("", "#.write(#)", this, data));

  Future writeText(String data) =>
      promiseToFuture(JS("", "#.writeText(#)", this, data));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("CSSRuleList")
class _CssRuleList extends Interceptor
    with ListMixin<CssRule>, ImmutableListMixin<CssRule>
    implements JavaScriptIndexingBehavior<CssRule>, List<CssRule> {
  // To suppress missing implicit constructor warnings.
  factory _CssRuleList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  CssRule operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("CssRule", "#[#]", this, index);
  }

  void operator []=(int index, CssRule value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<CssRule> mixins.
  // CssRule is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  CssRule get first {
    if (this.length > 0) {
      return JS('CssRule', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  CssRule get last {
    int len = this.length;
    if (len > 0) {
      return JS('CssRule', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  CssRule get single {
    int len = this.length;
    if (len == 1) {
      return JS('CssRule', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  CssRule elementAt(int index) => this[index];
  // -- end List<CssRule> mixins.

  CssRule item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@SupportedBrowser(SupportedBrowser.CHROME)
@Native("DOMFileSystemSync")
abstract class _DOMFileSystemSync extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _DOMFileSystemSync._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DirectoryEntrySync")
abstract class _DirectoryEntrySync extends _EntrySync {
  // To suppress missing implicit constructor warnings.
  factory _DirectoryEntrySync._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("DirectoryReaderSync")
abstract class _DirectoryReaderSync extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _DirectoryReaderSync._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-412266927
@deprecated // stable
@Native("DocumentType")
abstract class _DocumentType extends Node implements ChildNode {
  // To suppress missing implicit constructor warnings.
  factory _DocumentType._() {
    throw new UnsupportedError("Not supported");
  }

  // From ChildNode

}

// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("ClientRect,DOMRect")
class _DomRect extends DomRectReadOnly implements Rectangle {
  // NOTE! All code below should be common with RectangleBase.
  String toString() {
    return 'Rectangle ($left, $top) $width x $height';
  }

  bool operator ==(other) {
    if (other is! Rectangle) return false;
    return left == other.left &&
        top == other.top &&
        width == other.width &&
        height == other.height;
  }

  int get hashCode => _JenkinsSmiHash.hash4(
      left.hashCode, top.hashCode, width.hashCode, height.hashCode);

  /**
   * Computes the intersection of `this` and [other].
   *
   * The intersection of two axis-aligned rectangles, if any, is always another
   * axis-aligned rectangle.
   *
   * Returns the intersection of this and `other`, or null if they don't
   * intersect.
   */
  Rectangle intersection(Rectangle other) {
    var x0 = max(left, other.left);
    var x1 = min(left + width, other.left + other.width);

    if (x0 <= x1) {
      var y0 = max(top, other.top);
      var y1 = min(top + height, other.top + other.height);

      if (y0 <= y1) {
        return new Rectangle(x0, y0, x1 - x0, y1 - y0);
      }
    }
    return null;
  }

  /**
   * Returns true if `this` intersects [other].
   */
  bool intersects(Rectangle<num> other) {
    return (left <= other.left + other.width &&
        other.left <= left + width &&
        top <= other.top + other.height &&
        other.top <= top + height);
  }

  /**
   * Returns a new rectangle which completely contains `this` and [other].
   */
  Rectangle boundingBox(Rectangle other) {
    var right = max(this.left + this.width, other.left + other.width);
    var bottom = max(this.top + this.height, other.top + other.height);

    var left = min(this.left, other.left);
    var top = min(this.top, other.top);

    return new Rectangle(left, top, right - left, bottom - top);
  }

  /**
   * Tests whether `this` entirely contains [another].
   */
  bool containsRectangle(Rectangle<num> another) {
    return left <= another.left &&
        left + width >= another.left + another.width &&
        top <= another.top &&
        top + height >= another.top + another.height;
  }

  /**
   * Tests whether [another] is inside or along the edges of `this`.
   */
  bool containsPoint(Point<num> another) {
    return another.x >= left &&
        another.x <= left + width &&
        another.y >= top &&
        another.y <= top + height;
  }

  Point get topLeft => new Point(this.left, this.top);
  Point get topRight => new Point(this.left + this.width, this.top);
  Point get bottomRight =>
      new Point(this.left + this.width, this.top + this.height);
  Point get bottomLeft => new Point(this.left, this.top + this.height);

  // To suppress missing implicit constructor warnings.
  factory _DomRect._() {
    throw new UnsupportedError("Not supported");
  }

  factory _DomRect([num x, num y, num width, num height]) {
    if (height != null) {
      return _DomRect._create_1(x, y, width, height);
    }
    if (width != null) {
      return _DomRect._create_2(x, y, width);
    }
    if (y != null) {
      return _DomRect._create_3(x, y);
    }
    if (x != null) {
      return _DomRect._create_4(x);
    }
    return _DomRect._create_5();
  }
  static _DomRect _create_1(x, y, width, height) =>
      JS('_DomRect', 'new DOMRect(#,#,#,#)', x, y, width, height);
  static _DomRect _create_2(x, y, width) =>
      JS('_DomRect', 'new DOMRect(#,#,#)', x, y, width);
  static _DomRect _create_3(x, y) => JS('_DomRect', 'new DOMRect(#,#)', x, y);
  static _DomRect _create_4(x) => JS('_DomRect', 'new DOMRect(#)', x);
  static _DomRect _create_5() => JS('_DomRect', 'new DOMRect()');

  // Shadowing definition.
  num get height => JS("num", "#.height", this);

  set height(num value) {
    JS("void", "#.height = #", this, value);
  }

  // Shadowing definition.
  num get width => JS("num", "#.width", this);

  set width(num value) {
    JS("void", "#.width = #", this, value);
  }

  // Shadowing definition.
  num get x => JS("num", "#.x", this);

  set x(num value) {
    JS("void", "#.x = #", this, value);
  }

  // Shadowing definition.
  num get y => JS("num", "#.y", this);

  set y(num value) {
    JS("void", "#.y = #", this, value);
  }
}

/**
 * This is the [Jenkins hash function][1] but using masking to keep
 * values in SMI range.
 *
 * [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
 *
 * Use:
 * Hash each value with the hash of the previous value, then get the final
 * hash by calling finish.
 *
 *     var hash = 0;
 *     for (var value in values) {
 *       hash = JenkinsSmiHash.combine(hash, value.hashCode);
 *     }
 *     hash = JenkinsSmiHash.finish(hash);
 */
class _JenkinsSmiHash {
  // TODO(11617): This class should be optimized and standardized elsewhere.

  static int combine(int hash, int value) {
    hash = 0x1fffffff & (hash + value);
    hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
    return hash ^ (hash >> 6);
  }

  static int finish(int hash) {
    hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
    hash = hash ^ (hash >> 11);
    return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
  }

  static int hash2(a, b) => finish(combine(combine(0, a), b));

  static int hash4(a, b, c, d) =>
      finish(combine(combine(combine(combine(0, a), b), c), d));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("EntrySync")
abstract class _EntrySync extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _EntrySync._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FileEntrySync")
abstract class _FileEntrySync extends _EntrySync {
  // To suppress missing implicit constructor warnings.
  factory _FileEntrySync._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FileReaderSync")
abstract class _FileReaderSync extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _FileReaderSync._() {
    throw new UnsupportedError("Not supported");
  }

  factory _FileReaderSync() {
    return _FileReaderSync._create_1();
  }
  static _FileReaderSync _create_1() =>
      JS('_FileReaderSync', 'new FileReaderSync()');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("FileWriterSync")
abstract class _FileWriterSync extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _FileWriterSync._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("GamepadList")
class _GamepadList extends Interceptor
    with ListMixin<Gamepad>, ImmutableListMixin<Gamepad>
    implements List<Gamepad>, JavaScriptIndexingBehavior<Gamepad> {
  // To suppress missing implicit constructor warnings.
  factory _GamepadList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  Gamepad operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Gamepad|Null", "#[#]", this, index);
  }

  void operator []=(int index, Gamepad value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Gamepad> mixins.
  // Gamepad is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Gamepad get first {
    if (this.length > 0) {
      return JS('Gamepad|Null', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Gamepad get last {
    int len = this.length;
    if (len > 0) {
      return JS('Gamepad|Null', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Gamepad get single {
    int len = this.length;
    if (len == 1) {
      return JS('Gamepad|Null', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Gamepad elementAt(int index) => this[index];
  // -- end List<Gamepad> mixins.

  Gamepad item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#dom-document-all
@deprecated // deprecated
@Native("HTMLAllCollection")
abstract class _HTMLAllCollection extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _HTMLAllCollection._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('item')
  Element _item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#dir
@deprecated // deprecated
@Native("HTMLDirectoryElement")
abstract class _HTMLDirectoryElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory _HTMLDirectoryElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLDirectoryElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#htmlfontelement
@deprecated // deprecated
@Native("HTMLFontElement")
abstract class _HTMLFontElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory _HTMLFontElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLFontElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#htmlframeelement
@deprecated // deprecated
@Native("HTMLFrameElement")
abstract class _HTMLFrameElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory _HTMLFrameElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLFrameElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#frameset
@deprecated // deprecated
@Native("HTMLFrameSetElement")
abstract class _HTMLFrameSetElement extends HtmlElement
    implements WindowEventHandlers {
  // To suppress missing implicit constructor warnings.
  factory _HTMLFrameSetElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLFrameSetElement.created() : super.created();
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#the-marquee-element
@deprecated // deprecated
@Native("HTMLMarqueeElement")
abstract class _HTMLMarqueeElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory _HTMLMarqueeElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLMarqueeElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Mojo")
abstract class _Mojo extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _Mojo._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MojoHandle")
abstract class _MojoHandle extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _MojoHandle._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MojoInterfaceInterceptor")
abstract class _MojoInterfaceInterceptor extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory _MojoInterfaceInterceptor._() {
    throw new UnsupportedError("Not supported");
  }

  factory _MojoInterfaceInterceptor(String interfaceName, [String scope]) {
    if (scope != null) {
      return _MojoInterfaceInterceptor._create_1(interfaceName, scope);
    }
    return _MojoInterfaceInterceptor._create_2(interfaceName);
  }
  static _MojoInterfaceInterceptor _create_1(interfaceName, scope) => JS(
      '_MojoInterfaceInterceptor',
      'new MojoInterfaceInterceptor(#,#)',
      interfaceName,
      scope);
  static _MojoInterfaceInterceptor _create_2(interfaceName) => JS(
      '_MojoInterfaceInterceptor',
      'new MojoInterfaceInterceptor(#)',
      interfaceName);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MojoInterfaceRequestEvent")
abstract class _MojoInterfaceRequestEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory _MojoInterfaceRequestEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory _MojoInterfaceRequestEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _MojoInterfaceRequestEvent._create_1(type, eventInitDict_1);
    }
    return _MojoInterfaceRequestEvent._create_2(type);
  }
  static _MojoInterfaceRequestEvent _create_1(type, eventInitDict) => JS(
      '_MojoInterfaceRequestEvent',
      'new MojoInterfaceRequestEvent(#,#)',
      type,
      eventInitDict);
  static _MojoInterfaceRequestEvent _create_2(type) => JS(
      '_MojoInterfaceRequestEvent', 'new MojoInterfaceRequestEvent(#)', type);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("MojoWatcher")
abstract class _MojoWatcher extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _MojoWatcher._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("NFC")
abstract class _NFC extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _NFC._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// http://dom.spec.whatwg.org/#namednodemap
@deprecated // deprecated
@Native("NamedNodeMap,MozNamedAttrMap")
class _NamedNodeMap extends Interceptor
    with ListMixin<Node>, ImmutableListMixin<Node>
    implements JavaScriptIndexingBehavior<Node>, List<Node> {
  // To suppress missing implicit constructor warnings.
  factory _NamedNodeMap._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  Node operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Node", "#[#]", this, index);
  }

  void operator []=(int index, Node value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Node> mixins.
  // Node is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Node get first {
    if (this.length > 0) {
      return JS('Node', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Node get last {
    int len = this.length;
    if (len > 0) {
      return JS('Node', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Node get single {
    int len = this.length;
    if (len == 1) {
      return JS('Node', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Node elementAt(int index) => this[index];
  // -- end List<Node> mixins.

  _Attr getNamedItem(String name) native;

  _Attr getNamedItemNS(String namespaceURI, String localName) native;

  _Attr item(int index) native;

  _Attr removeNamedItem(String name) native;

  _Attr removeNamedItemNS(String namespaceURI, String localName) native;

  _Attr setNamedItem(_Attr attr) native;

  _Attr setNamedItemNS(_Attr attr) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@deprecated // nonstandard
@Native("PagePopupController")
abstract class _PagePopupController extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _PagePopupController._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Omit RadioNodeList for dart2js.  The Dart Form and FieldSet APIs don't
// currently expose an API the returns RadioNodeList.  The only use of a
// RadioNodeList is to get the selected value and it will be cleaner to
// introduce a different API for that purpose.
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Report")
class _Report extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _Report._() {
    throw new UnsupportedError("Not supported");
  }

  final ReportBody body;

  final String type;

  final String url;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Request")
class _Request extends Body {
  // To suppress missing implicit constructor warnings.
  factory _Request._() {
    throw new UnsupportedError("Not supported");
  }

  factory _Request(Object input, [Map requestInitDict]) {
    if (requestInitDict != null) {
      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict);
      return _Request._create_1(input, requestInitDict_1);
    }
    return _Request._create_2(input);
  }
  static _Request _create_1(input, requestInitDict) =>
      JS('_Request', 'new Request(#,#)', input, requestInitDict);
  static _Request _create_2(input) => JS('_Request', 'new Request(#)', input);

  final String cache;

  final String credentials;

  final Headers headers;

  final String integrity;

  final String mode;

  final String redirect;

  final String referrer;

  final String referrerPolicy;

  final String url;

  _Request clone() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// https://chromiumcodereview.appspot.com/14773025/
@deprecated // experimental
@Native("ResourceProgressEvent")
abstract class _ResourceProgressEvent extends ProgressEvent {
  // To suppress missing implicit constructor warnings.
  factory _ResourceProgressEvent._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Response")
abstract class _Response extends Body {
  // To suppress missing implicit constructor warnings.
  factory _Response._() {
    throw new UnsupportedError("Not supported");
  }

  factory _Response([Object body, Map init]) {
    if (init != null) {
      var init_1 = convertDartToNative_Dictionary(init);
      return _Response._create_1(body, init_1);
    }
    if (body != null) {
      return _Response._create_2(body);
    }
    return _Response._create_3();
  }
  static _Response _create_1(body, init) =>
      JS('_Response', 'new Response(#,#)', body, init);
  static _Response _create_2(body) => JS('_Response', 'new Response(#)', body);
  static _Response _create_3() => JS('_Response', 'new Response()');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SpeechRecognitionResultList")
class _SpeechRecognitionResultList extends Interceptor
    with
        ListMixin<SpeechRecognitionResult>,
        ImmutableListMixin<SpeechRecognitionResult>
    implements
        JavaScriptIndexingBehavior<SpeechRecognitionResult>,
        List<SpeechRecognitionResult> {
  // To suppress missing implicit constructor warnings.
  factory _SpeechRecognitionResultList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  SpeechRecognitionResult operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("SpeechRecognitionResult", "#[#]", this, index);
  }

  void operator []=(int index, SpeechRecognitionResult value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<SpeechRecognitionResult> mixins.
  // SpeechRecognitionResult is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  SpeechRecognitionResult get first {
    if (this.length > 0) {
      return JS('SpeechRecognitionResult', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  SpeechRecognitionResult get last {
    int len = this.length;
    if (len > 0) {
      return JS('SpeechRecognitionResult', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  SpeechRecognitionResult get single {
    int len = this.length;
    if (len == 1) {
      return JS('SpeechRecognitionResult', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  SpeechRecognitionResult elementAt(int index) => this[index];
  // -- end List<SpeechRecognitionResult> mixins.

  SpeechRecognitionResult item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("StyleSheetList")
class _StyleSheetList extends Interceptor
    with ListMixin<StyleSheet>, ImmutableListMixin<StyleSheet>
    implements List<StyleSheet>, JavaScriptIndexingBehavior<StyleSheet> {
  // To suppress missing implicit constructor warnings.
  factory _StyleSheetList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length => JS("int", "#.length", this);

  StyleSheet operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("StyleSheet", "#[#]", this, index);
  }

  void operator []=(int index, StyleSheet value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<StyleSheet> mixins.
  // StyleSheet is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  StyleSheet get first {
    if (this.length > 0) {
      return JS('StyleSheet', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  StyleSheet get last {
    int len = this.length;
    if (len > 0) {
      return JS('StyleSheet', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  StyleSheet get single {
    int len = this.length;
    if (len == 1) {
      return JS('StyleSheet', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  StyleSheet elementAt(int index) => this[index];
  // -- end List<StyleSheet> mixins.

  CssStyleSheet __getter__(String name) native;

  StyleSheet item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("SubtleCrypto")
abstract class _SubtleCrypto extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _SubtleCrypto._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USB")
abstract class _USB extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory _USB._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBAlternateInterface")
abstract class _USBAlternateInterface extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBAlternateInterface._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBAlternateInterface(
      _USBInterface deviceInterface, int alternateSetting) {
    return _USBAlternateInterface._create_1(deviceInterface, alternateSetting);
  }
  static _USBAlternateInterface _create_1(deviceInterface, alternateSetting) =>
      JS('_USBAlternateInterface', 'new USBAlternateInterface(#,#)',
          deviceInterface, alternateSetting);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBConfiguration")
abstract class _USBConfiguration extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBConfiguration._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBConfiguration(_USBDevice device, int configurationValue) {
    return _USBConfiguration._create_1(device, configurationValue);
  }
  static _USBConfiguration _create_1(device, configurationValue) => JS(
      '_USBConfiguration',
      'new USBConfiguration(#,#)',
      device,
      configurationValue);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBConnectionEvent")
abstract class _USBConnectionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory _USBConnectionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBConnectionEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return _USBConnectionEvent._create_1(type, eventInitDict_1);
  }
  static _USBConnectionEvent _create_1(type, eventInitDict) => JS(
      '_USBConnectionEvent',
      'new USBConnectionEvent(#,#)',
      type,
      eventInitDict);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBDevice")
abstract class _USBDevice extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBDevice._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBEndpoint")
abstract class _USBEndpoint extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBEndpoint._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBEndpoint(
      _USBAlternateInterface alternate, int endpointNumber, String direction) {
    return _USBEndpoint._create_1(alternate, endpointNumber, direction);
  }
  static _USBEndpoint _create_1(alternate, endpointNumber, direction) => JS(
      '_USBEndpoint',
      'new USBEndpoint(#,#,#)',
      alternate,
      endpointNumber,
      direction);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBInTransferResult")
abstract class _USBInTransferResult extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBInTransferResult._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBInTransferResult(String status, [ByteData data]) {
    if (data != null) {
      return _USBInTransferResult._create_1(status, data);
    }
    return _USBInTransferResult._create_2(status);
  }
  static _USBInTransferResult _create_1(status, data) =>
      JS('_USBInTransferResult', 'new USBInTransferResult(#,#)', status, data);
  static _USBInTransferResult _create_2(status) =>
      JS('_USBInTransferResult', 'new USBInTransferResult(#)', status);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBInterface")
abstract class _USBInterface extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBInterface._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBInterface(_USBConfiguration configuration, int interfaceNumber) {
    return _USBInterface._create_1(configuration, interfaceNumber);
  }
  static _USBInterface _create_1(configuration, interfaceNumber) => JS(
      '_USBInterface', 'new USBInterface(#,#)', configuration, interfaceNumber);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBIsochronousInTransferPacket")
abstract class _USBIsochronousInTransferPacket extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBIsochronousInTransferPacket._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBIsochronousInTransferPacket(String status, [ByteData data]) {
    if (data != null) {
      return _USBIsochronousInTransferPacket._create_1(status, data);
    }
    return _USBIsochronousInTransferPacket._create_2(status);
  }
  static _USBIsochronousInTransferPacket _create_1(status, data) => JS(
      '_USBIsochronousInTransferPacket',
      'new USBIsochronousInTransferPacket(#,#)',
      status,
      data);
  static _USBIsochronousInTransferPacket _create_2(status) => JS(
      '_USBIsochronousInTransferPacket',
      'new USBIsochronousInTransferPacket(#)',
      status);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBIsochronousInTransferResult")
abstract class _USBIsochronousInTransferResult extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBIsochronousInTransferResult._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBIsochronousInTransferResult(
      List<_USBIsochronousInTransferPacket> packets,
      [ByteData data]) {
    if (data != null) {
      return _USBIsochronousInTransferResult._create_1(packets, data);
    }
    return _USBIsochronousInTransferResult._create_2(packets);
  }
  static _USBIsochronousInTransferResult _create_1(packets, data) => JS(
      '_USBIsochronousInTransferResult',
      'new USBIsochronousInTransferResult(#,#)',
      packets,
      data);
  static _USBIsochronousInTransferResult _create_2(packets) => JS(
      '_USBIsochronousInTransferResult',
      'new USBIsochronousInTransferResult(#)',
      packets);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBIsochronousOutTransferPacket")
abstract class _USBIsochronousOutTransferPacket extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBIsochronousOutTransferPacket._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBIsochronousOutTransferPacket(String status, [int bytesWritten]) {
    if (bytesWritten != null) {
      return _USBIsochronousOutTransferPacket._create_1(status, bytesWritten);
    }
    return _USBIsochronousOutTransferPacket._create_2(status);
  }
  static _USBIsochronousOutTransferPacket _create_1(status, bytesWritten) => JS(
      '_USBIsochronousOutTransferPacket',
      'new USBIsochronousOutTransferPacket(#,#)',
      status,
      bytesWritten);
  static _USBIsochronousOutTransferPacket _create_2(status) => JS(
      '_USBIsochronousOutTransferPacket',
      'new USBIsochronousOutTransferPacket(#)',
      status);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBIsochronousOutTransferResult")
abstract class _USBIsochronousOutTransferResult extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBIsochronousOutTransferResult._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBIsochronousOutTransferResult(
      List<_USBIsochronousOutTransferPacket> packets) {
    return _USBIsochronousOutTransferResult._create_1(packets);
  }
  static _USBIsochronousOutTransferResult _create_1(packets) => JS(
      '_USBIsochronousOutTransferResult',
      'new USBIsochronousOutTransferResult(#)',
      packets);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("USBOutTransferResult")
abstract class _USBOutTransferResult extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBOutTransferResult._() {
    throw new UnsupportedError("Not supported");
  }

  factory _USBOutTransferResult(String status, [int bytesWritten]) {
    if (bytesWritten != null) {
      return _USBOutTransferResult._create_1(status, bytesWritten);
    }
    return _USBOutTransferResult._create_2(status);
  }
  static _USBOutTransferResult _create_1(status, bytesWritten) => JS(
      '_USBOutTransferResult',
      'new USBOutTransferResult(#,#)',
      status,
      bytesWritten);
  static _USBOutTransferResult _create_2(status) =>
      JS('_USBOutTransferResult', 'new USBOutTransferResult(#)', status);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class _WindowTimers extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _WindowTimers._() {
    throw new UnsupportedError("Not supported");
  }

  int _setInterval_String(String handler, [int timeout, Object arguments]);

  int _setTimeout_String(String handler, [int timeout, Object arguments]);

  void _clearInterval([int handle]);

  void _clearTimeout([int handle]);

  int _setInterval(Object handler, [int timeout]);

  int _setTimeout(Object handler, [int timeout]);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("WorkerLocation")
abstract class _WorkerLocation extends Interceptor implements UrlUtilsReadOnly {
  // To suppress missing implicit constructor warnings.
  factory _WorkerLocation._() {
    throw new UnsupportedError("Not supported");
  }

  // From URLUtilsReadOnly

}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("WorkerNavigator")
abstract class _WorkerNavigator extends NavigatorConcurrentHardware
    implements NavigatorOnLine, NavigatorID {
  // To suppress missing implicit constructor warnings.
  factory _WorkerNavigator._() {
    throw new UnsupportedError("Not supported");
  }

  // From NavigatorID

  // From NavigatorOnLine

}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@Native("Worklet")
abstract class _Worklet extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _Worklet._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class _AttributeMap extends MapBase<String, String> {
  final Element _element;

  _AttributeMap(this._element);

  void addAll(Map<String, String> other) {
    other.forEach((k, v) {
      this[k] = v;
    });
  }

  Map<K, V> cast<K, V>() => Map.castFrom<String, String, K, V>(this);
  bool containsValue(Object value) {
    for (var v in this.values) {
      if (value == v) {
        return true;
      }
    }
    return false;
  }

  String putIfAbsent(String key, String ifAbsent()) {
    if (!containsKey(key)) {
      this[key] = ifAbsent();
    }
    return this[key];
  }

  void clear() {
    for (var key in keys) {
      remove(key);
    }
  }

  void forEach(void f(String key, String value)) {
    for (var key in keys) {
      var value = this[key];
      f(key, value);
    }
  }

  Iterable<String> get keys {
    // TODO: generate a lazy collection instead.
    var attributes = _element._attributes;
    var keys = <String>[];
    for (int i = 0, len = attributes.length; i < len; i++) {
      _Attr attr = attributes[i];
      if (_matches(attr)) {
        keys.add(attr.name);
      }
    }
    return keys;
  }

  Iterable<String> get values {
    // TODO: generate a lazy collection instead.
    var attributes = _element._attributes;
    var values = <String>[];
    for (int i = 0, len = attributes.length; i < len; i++) {
      _Attr attr = attributes[i];
      if (_matches(attr)) {
        values.add(attr.value);
      }
    }
    return values;
  }

  /**
   * Returns true if there is no {key, value} pair in the map.
   */
  bool get isEmpty {
    return length == 0;
  }

  /**
   * Returns true if there is at least one {key, value} pair in the map.
   */
  bool get isNotEmpty => !isEmpty;

  /**
   * Checks to see if the node should be included in this map.
   */
  bool _matches(_Attr node);
}

/**
 * Wrapper to expose [Element.attributes] as a typed map.
 */
class _ElementAttributeMap extends _AttributeMap {
  _ElementAttributeMap(Element element) : super(element);

  bool containsKey(Object key) {
    return _element._hasAttribute(key);
  }

  String operator [](Object key) {
    return _element.getAttribute(key);
  }

  void operator []=(String key, String value) {
    _element.setAttribute(key, value);
  }

  String remove(Object key) {
    String value = _element.getAttribute(key);
    _element._removeAttribute(key);
    return value;
  }

  /**
   * The number of {key, value} pairs in the map.
   */
  int get length {
    return keys.length;
  }

  bool _matches(_Attr node) => node._namespaceUri == null;
}

/**
 * Wrapper to expose namespaced attributes as a typed map.
 */
class _NamespacedAttributeMap extends _AttributeMap {
  final String _namespace;

  _NamespacedAttributeMap(Element element, this._namespace) : super(element);

  bool containsKey(Object key) {
    return _element._hasAttributeNS(_namespace, key);
  }

  String operator [](Object key) {
    return _element.getAttributeNS(_namespace, key);
  }

  void operator []=(String key, String value) {
    _element.setAttributeNS(_namespace, key, value);
  }

  String remove(Object key) {
    String value = this[key];
    _element._removeAttributeNS(_namespace, key);
    return value;
  }

  /**
   * The number of {key, value} pairs in the map.
   */
  int get length {
    return keys.length;
  }

  bool _matches(_Attr node) => node._namespaceUri == _namespace;
}

/**
 * Provides a Map abstraction on top of data-* attributes, similar to the
 * dataSet in the old DOM.
 */
class _DataAttributeMap extends MapBase<String, String> {
  final Map<String, String> _attributes;

  _DataAttributeMap(this._attributes);

  // interface Map

  void addAll(Map<String, String> other) {
    other.forEach((k, v) {
      this[k] = v;
    });
  }

  Map<K, V> cast<K, V>() => Map.castFrom<String, String, K, V>(this);
  // TODO: Use lazy iterator when it is available on Map.
  bool containsValue(Object value) => values.any((v) => v == value);

  bool containsKey(Object key) => _attributes.containsKey(_attr(key));

  String operator [](Object key) => _attributes[_attr(key)];

  void operator []=(String key, String value) {
    _attributes[_attr(key)] = value;
  }

  String putIfAbsent(String key, String ifAbsent()) =>
      _attributes.putIfAbsent(_attr(key), ifAbsent);

  String remove(Object key) => _attributes.remove(_attr(key));

  void clear() {
    // Needs to operate on a snapshot since we are mutating the collection.
    for (String key in keys) {
      remove(key);
    }
  }

  void forEach(void f(String key, String value)) {
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        f(_strip(key), value);
      }
    });
  }

  Iterable<String> get keys {
    final keys = <String>[];
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        keys.add(_strip(key));
      }
    });
    return keys;
  }

  Iterable<String> get values {
    final values = <String>[];
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        values.add(value);
      }
    });
    return values;
  }

  int get length => keys.length;

  // TODO: Use lazy iterator when it is available on Map.
  bool get isEmpty => length == 0;

  bool get isNotEmpty => !isEmpty;

  // Helpers.
  String _attr(String key) => 'data-${_toHyphenedName(key)}';
  bool _matches(String key) => key.startsWith('data-');
  String _strip(String key) => _toCamelCase(key.substring(5));

  /**
   * Converts a string name with hyphens into an identifier, by removing hyphens
   * and capitalizing the following letter. Optionally [startUppercase] to
   * capitalize the first letter.
   */
  String _toCamelCase(String hyphenedName, {bool startUppercase: false}) {
    var segments = hyphenedName.split('-');
    int start = startUppercase ? 0 : 1;
    for (int i = start; i < segments.length; i++) {
      var segment = segments[i];
      if (segment.length > 0) {
        // Character between 'a'..'z' mapped to 'A'..'Z'
        segments[i] = '${segment[0].toUpperCase()}${segment.substring(1)}';
      }
    }
    return segments.join('');
  }

  /** Reverse of [toCamelCase]. */
  String _toHyphenedName(String word) {
    var sb = new StringBuffer();
    for (int i = 0; i < word.length; i++) {
      var lower = word[i].toLowerCase();
      if (word[i] != lower && i > 0) sb.write('-');
      sb.write(lower);
    }
    return sb.toString();
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * An object that can be drawn to a 2D canvas rendering context.
 *
 * The image drawn to the canvas depends on the type of this object:
 *
 * * If this object is an [ImageElement], then this element's image is
 * drawn to the canvas. If this element is an animated image, then this
 * element's poster frame is drawn. If this element has no poster frame, then
 * the first frame of animation is drawn.
 *
 * * If this object is a [VideoElement], then the frame at this element's current
 * playback position is drawn to the canvas.
 *
 * * If this object is a [CanvasElement], then this element's bitmap is drawn to
 * the canvas.
 *
 * **Note:** Currently all versions of Internet Explorer do not support
 * drawing a video element to a canvas. You may also encounter problems drawing
 * a video to a canvas in Firefox if the source of the video is a data URL.
 *
 * ## See also
 *
 * * [CanvasRenderingContext2D.drawImage]
 * * [CanvasRenderingContext2D.drawImageToRect]
 * * [CanvasRenderingContext2D.drawImageScaled]
 * * [CanvasRenderingContext2D.drawImageScaledFromSource]
 *
 * ## Other resources
 *
 * * [Image sources for 2D rendering
 *   contexts](https://html.spec.whatwg.org/multipage/scripting.html#image-sources-for-2d-rendering-contexts)
 *   from WHATWG.
 * * [Drawing images](https://html.spec.whatwg.org/multipage/scripting.html#dom-context-2d-drawimage)
 *   from WHATWG.
 */
abstract class CanvasImageSource {}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Top-level container for a browser tab or window.
 *
 * In a web browser, a [WindowBase] object represents any browser window. This
 * object contains the window's state and its relation to other
 * windows, such as which window opened this window.
 *
 * **Note:** This class represents any window, while [Window] is
 * used to access the properties and content of the current window or tab.
 *
 * ## See also
 *
 * * [Window]
 *
 * ## Other resources
 *
 * * [DOM Window](https://developer.mozilla.org/en-US/docs/DOM/window) from MDN.
 * * [Window](http://www.w3.org/TR/Window/) from the W3C.
 */
abstract class WindowBase implements EventTarget {
  // Fields.

  /**
   * The current location of this window.
   *
   *     Location currentLocation = window.location;
   *     print(currentLocation.href); // 'http://www.example.com:80/'
   */
  LocationBase get location;

  /**
   * The current session history for this window.
   *
   * ## Other resources
   *
   * * [Session history and navigation
   *   specification](https://html.spec.whatwg.org/multipage/browsers.html#history)
   *   from WHATWG.
   */
  HistoryBase get history;

  /**
   * Indicates whether this window has been closed.
   *
   *     print(window.closed); // 'false'
   *     window.close();
   *     print(window.closed); // 'true'
   */
  bool get closed;

  /**
   * A reference to the window that opened this one.
   *
   *     Window thisWindow = window;
   *     WindowBase otherWindow = thisWindow.open('http://www.example.com/', 'foo');
   *     print(otherWindow.opener == thisWindow); // 'true'
   */
  WindowBase get opener;

  /**
   * A reference to the parent of this window.
   *
   * If this [WindowBase] has no parent, [parent] will return a reference to
   * the [WindowBase] itself.
   *
   *     IFrameElement myIFrame = new IFrameElement();
   *     window.document.body.elements.add(myIFrame);
   *     print(myIframe.contentWindow.parent == window) // 'true'
   *
   *     print(window.parent == window) // 'true'
   */
  WindowBase get parent;

  /**
   * A reference to the topmost window in the window hierarchy.
   *
   * If this [WindowBase] is the topmost [WindowBase], [top] will return a
   * reference to the [WindowBase] itself.
   *
   *     // Add an IFrame to the current window.
   *     IFrameElement myIFrame = new IFrameElement();
   *     window.document.body.elements.add(myIFrame);
   *
   *     // Add an IFrame inside of the other IFrame.
   *     IFrameElement innerIFrame = new IFrameElement();
   *     myIFrame.elements.add(innerIFrame);
   *
   *     print(myIframe.contentWindow.top == window) // 'true'
   *     print(innerIFrame.contentWindow.top == window) // 'true'
   *
   *     print(window.top == window) // 'true'
   */
  WindowBase get top;

  // Methods.
  /**
   * Closes the window.
   *
   * This method should only succeed if the [WindowBase] object is
   * **script-closeable** and the window calling [close] is allowed to navigate
   * the window.
   *
   * A window is script-closeable if it is either a window
   * that was opened by another window, or if it is a window with only one
   * document in its history.
   *
   * A window might not be allowed to navigate, and therefore close, another
   * window due to browser security features.
   *
   *     var other = window.open('http://www.example.com', 'foo');
   *     // Closes other window, as it is script-closeable.
   *     other.close();
   *     print(other.closed()); // 'true'
   *
   *     window.location('http://www.mysite.com', 'foo');
   *     // Does not close this window, as the history has changed.
   *     window.close();
   *     print(window.closed()); // 'false'
   *
   * See also:
   *
   * * [Window close discussion](http://www.w3.org/TR/html5/browsers.html#dom-window-close) from the W3C
   */
  void close();

  /**
   * Sends a cross-origin message.
   *
   * ## Other resources
   *
   * * [window.postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage)
   *   from MDN.
   * * [Cross-document messaging](https://html.spec.whatwg.org/multipage/comms.html#web-messaging)
   *   from WHATWG.
   */
  void postMessage(var message, String targetOrigin,
      [List<MessagePort> messagePorts]);
}

abstract class LocationBase {
  void set href(String val);
}

abstract class HistoryBase {
  void back();
  void forward();
  void go(int distance);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/** A Set that stores the CSS class names for an element. */
abstract class CssClassSet implements Set<String> {
  /**
   * Adds the class [value] to the element if it is not on it, removes it if it
   * is.
   *
   * If [shouldAdd] is true, then we always add that [value] to the element. If
   * [shouldAdd] is false then we always remove [value] from the element.
   *
   * If this corresponds to one element, returns `true` if [value] is present
   * after the operation, and returns `false` if [value] is absent after the
   * operation.
   *
   * If this corresponds to many elements, `null` is always returned.
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.  To toggle multiple classes, use
   * [toggleAll].
   */
  bool toggle(String value, [bool shouldAdd]);

  /**
   * Returns [:true:] if classes cannot be added or removed from this
   * [:CssClassSet:].
   */
  bool get frozen;

  /**
   * Determine if this element contains the class [value].
   *
   * This is the Dart equivalent of jQuery's
   * [hasClass](http://api.jquery.com/hasClass/).
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.
   */
  bool contains(Object value);

  /**
   * Add the class [value] to element.
   *
   * [add] and [addAll] are the Dart equivalent of jQuery's
   * [addClass](http://api.jquery.com/addClass/).
   *
   * If this CssClassSet corresponds to one element. Returns true if [value] was
   * added to the set, otherwise false.
   *
   * If this corresponds to many elements, `null` is always returned.
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.  To add multiple classes use
   * [addAll].
   */
  bool add(String value);

  /**
   * Remove the class [value] from element, and return true on successful
   * removal.
   *
   * [remove] and [removeAll] are the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.  To remove multiple classes, use
   * [removeAll].
   */
  bool remove(Object value);

  /**
   * Add all classes specified in [iterable] to element.
   *
   * [add] and [addAll] are the Dart equivalent of jQuery's
   * [addClass](http://api.jquery.com/addClass/).
   *
   * Each element of [iterable] must be a valid 'token' representing a single
   * class, i.e. a non-empty string containing no whitespace.
   */
  void addAll(Iterable<String> iterable);

  /**
   * Remove all classes specified in [iterable] from element.
   *
   * [remove] and [removeAll] are the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   *
   * Each element of [iterable] must be a valid 'token' representing a single
   * class, i.e. a non-empty string containing no whitespace.
   */
  void removeAll(Iterable<Object> iterable);

  /**
   * Toggles all classes specified in [iterable] on element.
   *
   * Iterate through [iterable]'s items, and add it if it is not on it, or
   * remove it if it is. This is the Dart equivalent of jQuery's
   * [toggleClass](http://api.jquery.com/toggleClass/).
   * If [shouldAdd] is true, then we always add all the classes in [iterable]
   * element. If [shouldAdd] is false then we always remove all the classes in
   * [iterable] from the element.
   *
   * Each element of [iterable] must be a valid 'token' representing a single
   * class, i.e. a non-empty string containing no whitespace.
   */
  void toggleAll(Iterable<String> iterable, [bool shouldAdd]);
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * A rectangle representing all the content of the element in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _ContentCssRect extends CssRect {
  _ContentCssRect(Element element) : super(element);

  num get height =>
      _element.offsetHeight + _addOrSubtractToBoxModel(_HEIGHT, _CONTENT);

  num get width =>
      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _CONTENT);

  /**
   * Set the height to `newHeight`.
   *
   * newHeight can be either a [num] representing the height in pixels or a
   * [Dimension] object. Values of newHeight that are less than zero are
   * converted to effectively setting the height to 0. This is equivalent to the
   * `height` function in jQuery and the calculated `height` CSS value,
   * converted to a num in pixels.
   */
  set height(dynamic newHeight) {
    if (newHeight is Dimension) {
      Dimension newHeightAsDimension = newHeight;
      if (newHeightAsDimension.value < 0) newHeight = new Dimension.px(0);
      _element.style.height = newHeight.toString();
    } else if (newHeight is num) {
      if (newHeight < 0) newHeight = 0;
      _element.style.height = '${newHeight}px';
    } else {
      throw new ArgumentError("newHeight is not a Dimension or num");
    }
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * newWidth can be either a [num] representing the width in pixels or a
   * [Dimension] object. This is equivalent to the `width` function in jQuery
   * and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   */
  set width(dynamic newWidth) {
    if (newWidth is Dimension) {
      Dimension newWidthAsDimension = newWidth;
      if (newWidthAsDimension.value < 0) newWidth = new Dimension.px(0);
      _element.style.width = newWidth.toString();
    } else if (newWidth is num) {
      if (newWidth < 0) newWidth = 0;
      _element.style.width = '${newWidth}px';
    } else {
      throw new ArgumentError("newWidth is not a Dimension or num");
    }
  }

  num get left =>
      _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _CONTENT);
  num get top =>
      _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _CONTENT);
}

/**
 * A list of element content rectangles in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _ContentCssListRect extends _ContentCssRect {
  List<Element> _elementList;

  _ContentCssListRect(List<Element> elementList) : super(elementList.first) {
    _elementList = elementList;
  }

  /**
   * Set the height to `newHeight`.
   *
   * Values of newHeight that are less than zero are converted to effectively
   * setting the height to 0. This is equivalent to the `height`
   * function in jQuery and the calculated `height` CSS value, converted to a
   * num in pixels.
   */
  set height(newHeight) {
    _elementList.forEach((e) => e.contentEdge.height = newHeight);
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * This is equivalent to the `width` function in jQuery and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   */
  set width(newWidth) {
    _elementList.forEach((e) => e.contentEdge.width = newWidth);
  }
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _PaddingCssRect extends CssRect {
  _PaddingCssRect(element) : super(element);
  num get height =>
      _element.offsetHeight + _addOrSubtractToBoxModel(_HEIGHT, _PADDING);
  num get width =>
      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _PADDING);

  num get left =>
      _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _PADDING);
  num get top =>
      _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _PADDING);
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding + border in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _BorderCssRect extends CssRect {
  _BorderCssRect(element) : super(element);
  num get height => _element.offsetHeight;
  num get width => _element.offsetWidth;

  num get left => _element.getBoundingClientRect().left;
  num get top => _element.getBoundingClientRect().top;
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding + border + margin in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _MarginCssRect extends CssRect {
  _MarginCssRect(element) : super(element);
  num get height =>
      _element.offsetHeight + _addOrSubtractToBoxModel(_HEIGHT, _MARGIN);
  num get width =>
      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _MARGIN);

  num get left =>
      _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _MARGIN);
  num get top =>
      _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _MARGIN);
}

/**
 * A class for representing CSS dimensions.
 *
 * In contrast to the more general purpose [Rectangle] class, this class's
 * values are mutable, so one can change the height of an element
 * programmatically.
 *
 * _Important_ _note_: use of these methods will perform CSS calculations that
 * can trigger a browser reflow. Therefore, use of these properties _during_ an
 * animation frame is discouraged. See also:
 * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
 */
abstract class CssRect implements Rectangle<num> {
  Element _element;

  CssRect(this._element);

  num get left;

  num get top;

  /**
   * The height of this rectangle.
   *
   * This is equivalent to the `height` function in jQuery and the calculated
   * `height` CSS value, converted to a dimensionless num in pixels. Unlike
   * [getBoundingClientRect], `height` will return the same numerical width if
   * the element is hidden or not.
   */
  num get height;

  /**
   * The width of this rectangle.
   *
   * This is equivalent to the `width` function in jQuery and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels. Unlike
   * [getBoundingClientRect], `width` will return the same numerical width if
   * the element is hidden or not.
   */
  num get width;

  /**
   * Set the height to `newHeight`.
   *
   * newHeight can be either a [num] representing the height in pixels or a
   * [Dimension] object. Values of newHeight that are less than zero are
   * converted to effectively setting the height to 0. This is equivalent to the
   * `height` function in jQuery and the calculated `height` CSS value,
   * converted to a num in pixels.
   *
   * Note that only the content height can actually be set via this method.
   */
  set height(dynamic newHeight) {
    throw new UnsupportedError("Can only set height for content rect.");
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * newWidth can be either a [num] representing the width in pixels or a
   * [Dimension] object. This is equivalent to the `width` function in jQuery
   * and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   *
   * Note that only the content width can be set via this method.
   */
  set width(dynamic newWidth) {
    throw new UnsupportedError("Can only set width for content rect.");
  }

  /**
   * Return a value that is used to modify the initial height or width
   * measurement of an element. Depending on the value (ideally an enum) passed
   * to augmentingMeasurement, we may need to add or subtract margin, padding,
   * or border values, depending on the measurement we're trying to obtain.
   */
  num _addOrSubtractToBoxModel(
      List<String> dimensions, String augmentingMeasurement) {
    // getComputedStyle always returns pixel values (hence, computed), so we're
    // always dealing with pixels in this method.
    var styles = _element.getComputedStyle();

    var val = 0;

    for (String measurement in dimensions) {
      // The border-box and default box model both exclude margin in the regular
      // height/width calculation, so add it if we want it for this measurement.
      if (augmentingMeasurement == _MARGIN) {
        val += new Dimension.css(
                styles.getPropertyValue('$augmentingMeasurement-$measurement'))
            .value;
      }

      // The border-box includes padding and border, so remove it if we want
      // just the content itself.
      if (augmentingMeasurement == _CONTENT) {
        val -= new Dimension.css(
                styles.getPropertyValue('${_PADDING}-$measurement'))
            .value;
      }

      // At this point, we don't wan't to augment with border or margin,
      // so remove border.
      if (augmentingMeasurement != _MARGIN) {
        val -= new Dimension.css(
                styles.getPropertyValue('border-${measurement}-width'))
            .value;
      }
    }
    return val;
  }

  // TODO(jacobr): these methods are duplicated from _RectangleBase in dart:math
  // Ideally we would provide a RectangleMixin class that provides this implementation.
  // In an ideal world we would exp
  /** The x-coordinate of the right edge. */
  num get right => left + width;
  /** The y-coordinate of the bottom edge. */
  num get bottom => top + height;

  String toString() {
    return 'Rectangle ($left, $top) $width x $height';
  }

  bool operator ==(other) {
    if (other is! Rectangle) return false;
    return left == other.left &&
        top == other.top &&
        right == other.right &&
        bottom == other.bottom;
  }

  int get hashCode => _JenkinsSmiHash.hash4(
      left.hashCode, top.hashCode, right.hashCode, bottom.hashCode);

  /**
   * Computes the intersection of `this` and [other].
   *
   * The intersection of two axis-aligned rectangles, if any, is always another
   * axis-aligned rectangle.
   *
   * Returns the intersection of this and `other`, or `null` if they don't
   * intersect.
   */
  Rectangle<num> intersection(Rectangle<num> other) {
    var x0 = max(left, other.left);
    var x1 = min(left + width, other.left + other.width);

    if (x0 <= x1) {
      var y0 = max(top, other.top);
      var y1 = min(top + height, other.top + other.height);

      if (y0 <= y1) {
        return new Rectangle<num>(x0, y0, x1 - x0, y1 - y0);
      }
    }
    return null;
  }

  /**
   * Returns true if `this` intersects [other].
   */
  bool intersects(Rectangle<num> other) {
    return (left <= other.left + other.width &&
        other.left <= left + width &&
        top <= other.top + other.height &&
        other.top <= top + height);
  }

  /**
   * Returns a new rectangle which completely contains `this` and [other].
   */
  Rectangle<num> boundingBox(Rectangle<num> other) {
    var right = max(this.left + this.width, other.left + other.width);
    var bottom = max(this.top + this.height, other.top + other.height);

    var left = min(this.left, other.left);
    var top = min(this.top, other.top);

    return new Rectangle<num>(left, top, right - left, bottom - top);
  }

  /**
   * Tests whether `this` entirely contains [another].
   */
  bool containsRectangle(Rectangle<num> another) {
    return left <= another.left &&
        left + width >= another.left + another.width &&
        top <= another.top &&
        top + height >= another.top + another.height;
  }

  /**
   * Tests whether [another] is inside or along the edges of `this`.
   */
  bool containsPoint(Point<num> another) {
    return another.x >= left &&
        another.x <= left + width &&
        another.y >= top &&
        another.y <= top + height;
  }

  Point<num> get topLeft => new Point<num>(this.left, this.top);
  Point<num> get topRight => new Point<num>(this.left + this.width, this.top);
  Point<num> get bottomRight =>
      new Point<num>(this.left + this.width, this.top + this.height);
  Point<num> get bottomLeft =>
      new Point<num>(this.left, this.top + this.height);
}

final _HEIGHT = ['top', 'bottom'];
final _WIDTH = ['right', 'left'];
final _CONTENT = 'content';
final _PADDING = 'padding';
final _MARGIN = 'margin';
// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * A set (union) of the CSS classes that are present in a set of elements.
 * Implemented separately from _ElementCssClassSet for performance.
 */
class _MultiElementCssClassSet extends CssClassSetImpl {
  final Iterable<Element> _elementIterable;

  // TODO(sra): Perhaps we should store the DomTokenList instead.
  final List<CssClassSetImpl> _sets;

  factory _MultiElementCssClassSet(Iterable<Element> elements) {
    return new _MultiElementCssClassSet._(elements,
        new List<CssClassSetImpl>.from(elements.map((Element e) => e.classes)));
  }

  _MultiElementCssClassSet._(this._elementIterable, this._sets);

  Set<String> readClasses() {
    var s = new LinkedHashSet<String>();
    _sets.forEach((CssClassSetImpl e) => s.addAll(e.readClasses()));
    return s;
  }

  void writeClasses(Set<String> s) {
    var classes = s.join(' ');
    for (Element e in _elementIterable) {
      e.className = classes;
    }
  }

  /**
   * Helper method used to modify the set of css classes on this element.
   *
   *   f - callback with:
   *   s - a Set of all the css class name currently on this element.
   *
   *   After f returns, the modified set is written to the
   *       className property of this element.
   */
  modify(f(Set<String> s)) {
    _sets.forEach((CssClassSetImpl e) => e.modify(f));
  }

  /**
   * Adds the class [value] to the element if it is not on it, removes it if it
   * is.
   *
   * TODO(sra): It seems wrong to collect a 'changed' flag like this when the
   * underlying toggle returns an 'is set' flag.
   */
  bool toggle(String value, [bool shouldAdd]) => _sets.fold(
      false,
      (bool changed, CssClassSetImpl e) =>
          e.toggle(value, shouldAdd) || changed);

  /**
   * Remove the class [value] from element, and return true on successful
   * removal.
   *
   * This is the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   */
  bool remove(Object value) => _sets.fold(
      false, (bool changed, CssClassSetImpl e) => e.remove(value) || changed);
}

class _ElementCssClassSet extends CssClassSetImpl {
  final Element _element;

  _ElementCssClassSet(this._element);

  Set<String> readClasses() {
    var s = new LinkedHashSet<String>();
    var classname = _element.className;

    for (String name in classname.split(' ')) {
      String trimmed = name.trim();
      if (!trimmed.isEmpty) {
        s.add(trimmed);
      }
    }
    return s;
  }

  void writeClasses(Set<String> s) {
    _element.className = s.join(' ');
  }

  int get length => _classListLength(_classListOf(_element));
  bool get isEmpty => length == 0;
  bool get isNotEmpty => length != 0;

  void clear() {
    _element.className = '';
  }

  bool contains(Object value) {
    return _contains(_element, value);
  }

  bool add(String value) {
    return _add(_element, value);
  }

  bool remove(Object value) {
    return value is String && _remove(_element, value);
  }

  bool toggle(String value, [bool shouldAdd]) {
    return _toggle(_element, value, shouldAdd);
  }

  void addAll(Iterable<String> iterable) {
    _addAll(_element, iterable);
  }

  void removeAll(Iterable<Object> iterable) {
    _removeAll(_element, iterable);
  }

  void retainAll(Iterable<Object> iterable) {
    _removeWhere(_element, iterable.toSet().contains, false);
  }

  void removeWhere(bool test(String name)) {
    _removeWhere(_element, test, true);
  }

  void retainWhere(bool test(String name)) {
    _removeWhere(_element, test, false);
  }

  static bool _contains(Element _element, Object value) {
    return value is String && _classListContains(_classListOf(_element), value);
  }

  @ForceInline()
  static bool _add(Element _element, String value) {
    DomTokenList list = _classListOf(_element);
    // Compute returned result independently of action upon the set.
    bool added = !_classListContainsBeforeAddOrRemove(list, value);
    _classListAdd(list, value);
    return added;
  }

  @ForceInline()
  static bool _remove(Element _element, String value) {
    DomTokenList list = _classListOf(_element);
    bool removed = _classListContainsBeforeAddOrRemove(list, value);
    _classListRemove(list, value);
    return removed;
  }

  static bool _toggle(Element _element, String value, bool shouldAdd) {
    // There is no value that can be passed as the second argument of
    // DomTokenList.toggle that behaves the same as passing one argument.
    // `null` is seen as false, meaning 'remove'.
    return shouldAdd == null
        ? _toggleDefault(_element, value)
        : _toggleOnOff(_element, value, shouldAdd);
  }

  static bool _toggleDefault(Element _element, String value) {
    DomTokenList list = _classListOf(_element);
    return _classListToggle1(list, value);
  }

  static bool _toggleOnOff(Element _element, String value, bool shouldAdd) {
    DomTokenList list = _classListOf(_element);
    // IE's toggle does not take a second parameter. We would prefer:
    //
    //    return _classListToggle2(list, value, shouldAdd);
    //
    if (shouldAdd) {
      _classListAdd(list, value);
      return true;
    } else {
      _classListRemove(list, value);
      return false;
    }
  }

  static void _addAll(Element _element, Iterable<String> iterable) {
    DomTokenList list = _classListOf(_element);
    for (String value in iterable) {
      _classListAdd(list, value);
    }
  }

  static void _removeAll(Element _element, Iterable<String> iterable) {
    DomTokenList list = _classListOf(_element);
    for (var value in iterable) {
      _classListRemove(list, value);
    }
  }

  static void _removeWhere(
      Element _element, bool test(String name), bool doRemove) {
    DomTokenList list = _classListOf(_element);
    int i = 0;
    while (i < _classListLength(list)) {
      String item = list.item(i);
      if (doRemove == test(item)) {
        _classListRemove(list, item);
      } else {
        ++i;
      }
    }
  }

  // A collection of static methods for DomTokenList. These methods are a
  // work-around for the lack of annotations to express the full behaviour of
  // the DomTokenList methods.

  static DomTokenList _classListOf(Element e) => JS(
      'returns:DomTokenList;creates:DomTokenList;effects:none;depends:all;',
      '#.classList',
      e);

  static int _classListLength(DomTokenList list) =>
      JS('returns:JSUInt31;effects:none;depends:all;', '#.length', list);

  static bool _classListContains(DomTokenList list, String value) =>
      JS('returns:bool;effects:none;depends:all', '#.contains(#)', list, value);

  static bool _classListContainsBeforeAddOrRemove(
          DomTokenList list, String value) =>
      // 'throws:never' is a lie, since 'contains' will throw on an illegal
      // token.  However, we always call this function immediately prior to
      // add/remove/toggle with the same token.  Often the result of 'contains'
      // is unused and the lie makes it possible for the 'contains' instruction
      // to be removed.
      JS('returns:bool;effects:none;depends:all;throws:null(1)',
          '#.contains(#)', list, value);

  static void _classListAdd(DomTokenList list, String value) {
    // list.add(value);
    JS('', '#.add(#)', list, value);
  }

  static void _classListRemove(DomTokenList list, String value) {
    // list.remove(value);
    JS('', '#.remove(#)', list, value);
  }

  static bool _classListToggle1(DomTokenList list, String value) {
    return JS('bool', '#.toggle(#)', list, value);
  }

  static bool _classListToggle2(
      DomTokenList list, String value, bool shouldAdd) {
    return JS('bool', '#.toggle(#, #)', list, value, shouldAdd);
  }
}

/**
 * Class representing a
 * [length measurement](https://developer.mozilla.org/en-US/docs/Web/CSS/length)
 * in CSS.
 */
class Dimension {
  num _value;
  String _unit;

  /** Set this CSS Dimension to a percentage `value`. */
  Dimension.percent(this._value) : _unit = '%';

  /** Set this CSS Dimension to a pixel `value`. */
  Dimension.px(this._value) : _unit = 'px';

  /** Set this CSS Dimension to a pica `value`. */
  Dimension.pc(this._value) : _unit = 'pc';

  /** Set this CSS Dimension to a point `value`. */
  Dimension.pt(this._value) : _unit = 'pt';

  /** Set this CSS Dimension to an inch `value`. */
  Dimension.inch(this._value) : _unit = 'in';

  /** Set this CSS Dimension to a centimeter `value`. */
  Dimension.cm(this._value) : _unit = 'cm';

  /** Set this CSS Dimension to a millimeter `value`. */
  Dimension.mm(this._value) : _unit = 'mm';

  /**
   * Set this CSS Dimension to the specified number of ems.
   *
   * 1em is equal to the current font size. (So 2ems is equal to double the font
   * size). This is useful for producing website layouts that scale nicely with
   * the user's desired font size.
   */
  Dimension.em(this._value) : _unit = 'em';

  /**
   * Set this CSS Dimension to the specified number of x-heights.
   *
   * One ex is equal to the x-height of a font's baseline to its mean line,
   * generally the height of the letter "x" in the font, which is usually about
   * half the font-size.
   */
  Dimension.ex(this._value) : _unit = 'ex';

  /**
   * Construct a Dimension object from the valid, simple CSS string `cssValue`
   * that represents a distance measurement.
   *
   * This constructor is intended as a convenience method for working with
   * simplistic CSS length measurements. Non-numeric values such as `auto` or
   * `inherit` or invalid CSS will cause this constructor to throw a
   * FormatError.
   */
  Dimension.css(String cssValue) {
    if (cssValue == '') cssValue = '0px';
    if (cssValue.endsWith('%')) {
      _unit = '%';
    } else {
      _unit = cssValue.substring(cssValue.length - 2);
    }
    if (cssValue.contains('.')) {
      _value =
          double.parse(cssValue.substring(0, cssValue.length - _unit.length));
    } else {
      _value = int.parse(cssValue.substring(0, cssValue.length - _unit.length));
    }
  }

  /** Print out the CSS String representation of this value. */
  String toString() {
    return '${_value}${_unit}';
  }

  /** Return a unitless, numerical value of this CSS value. */
  num get value => this._value;
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

typedef EventListener(Event event);
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * A factory to expose DOM events as Streams.
 */
class EventStreamProvider<T extends Event> {
  final String _eventType;

  const EventStreamProvider(this._eventType);

  /**
   * Gets a [Stream] for this event type, on the specified target.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent.forTarget(element, useCapture: true).listen(...);
   *
   *     // Alternate method:
   *     Element.keyDownEvent.forTarget(element).capture(...);
   *
   * Or for listening to an event which will bubble through the DOM tree:
   *
   *     MediaElement.pauseEvent.forTarget(document.body).listen(...);
   *
   * See also:
   *
   * [addEventListener](http://docs.webplatform.org/wiki/dom/methods/addEventListener)
   */
  Stream<T> forTarget(EventTarget e, {bool useCapture: false}) =>
      new _EventStream<T>(e, _eventType, useCapture);

  /**
   * Gets an [ElementEventStream] for this event type, on the specified element.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent.forElement(element, useCapture: true).listen(...);
   *
   *     // Alternate method:
   *     Element.keyDownEvent.forElement(element).capture(...);
   *
   * Or for listening to an event which will bubble through the DOM tree:
   *
   *     MediaElement.pauseEvent.forElement(document.body).listen(...);
   *
   * See also:
   *
   * [addEventListener](http://docs.webplatform.org/wiki/dom/methods/addEventListener)
   */
  ElementStream<T> forElement(Element e, {bool useCapture: false}) {
    return new _ElementEventStreamImpl<T>(e, _eventType, useCapture);
  }

  /**
   * Gets an [ElementEventStream] for this event type, on the list of elements.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent._forElementList(element, useCapture: true).listen(...);
   *
   * See also:
   *
   * [addEventListener](http://docs.webplatform.org/wiki/dom/methods/addEventListener)
   */
  ElementStream<T> _forElementList(ElementList<Element> e,
      {bool useCapture: false}) {
    return new _ElementListEventStreamImpl<T>(e, _eventType, useCapture);
  }

  /**
   * Gets the type of the event which this would listen for on the specified
   * event target.
   *
   * The target is necessary because some browsers may use different event names
   * for the same purpose and the target allows differentiating browser support.
   */
  String getEventType(EventTarget target) {
    return _eventType;
  }
}

/** A specialized Stream available to [Element]s to enable event delegation. */
abstract class ElementStream<T extends Event> implements Stream<T> {
  /**
   * Return a stream that only fires when the particular event fires for
   * elements matching the specified CSS selector.
   *
   * This is the Dart equivalent to jQuery's
   * [delegate](http://api.jquery.com/delegate/).
   */
  Stream<T> matches(String selector);

  /**
   * Adds a capturing subscription to this stream.
   *
   * If the target of the event is a descendant of the element from which this
   * stream derives then [onData] is called before the event propagates down to
   * the target. This is the opposite of bubbling behavior, where the event
   * is first processed for the event target and then bubbles upward.
   *
   * ## Other resources
   *
   * * [Event Capture](http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
   *   from the W3C DOM Events specification.
   */
  StreamSubscription<T> capture(void onData(T event));
}

/**
 * Adapter for exposing DOM events as Dart streams.
 */
class _EventStream<T extends Event> extends Stream<T> {
  final EventTarget _target;
  final String _eventType;
  final bool _useCapture;

  _EventStream(this._target, this._eventType, this._useCapture);

  // DOM events are inherently multi-subscribers.
  Stream<T> asBroadcastStream(
          {void onListen(StreamSubscription<T> subscription),
          void onCancel(StreamSubscription<T> subscription)}) =>
      this;
  bool get isBroadcast => true;

  // TODO(9757): Inlining should be smart and inline only when inlining would
  // enable scalar replacement of an immediately allocated receiver.
  @ForceInline()
  StreamSubscription<T> listen(void onData(T event),
      {Function onError, void onDone(), bool cancelOnError}) {
    return new _EventStreamSubscription<T>(
        this._target, this._eventType, onData, this._useCapture);
  }
}

bool _matchesWithAncestors(Event event, String selector) {
  var target = event.target;
  return target is Element ? target.matchesWithAncestors(selector) : false;
}

/**
 * Adapter for exposing DOM Element events as streams, while also allowing
 * event delegation.
 */
class _ElementEventStreamImpl<T extends Event> extends _EventStream<T>
    implements ElementStream<T> {
  _ElementEventStreamImpl(target, eventType, useCapture)
      : super(target, eventType, useCapture);

  Stream<T> matches(String selector) =>
      this.where((event) => _matchesWithAncestors(event, selector)).map((e) {
        e._selector = selector;
        return e;
      });

  StreamSubscription<T> capture(void onData(T event)) =>
      new _EventStreamSubscription<T>(
          this._target, this._eventType, onData, true);
}

/**
 * Adapter for exposing events on a collection of DOM Elements as streams,
 * while also allowing event delegation.
 */
class _ElementListEventStreamImpl<T extends Event> extends Stream<T>
    implements ElementStream<T> {
  final Iterable<Element> _targetList;
  final bool _useCapture;
  final String _eventType;

  _ElementListEventStreamImpl(
      this._targetList, this._eventType, this._useCapture);

  Stream<T> matches(String selector) =>
      this.where((event) => _matchesWithAncestors(event, selector)).map((e) {
        e._selector = selector;
        return e;
      });

  // Delegate all regular Stream behavior to a wrapped Stream.
  StreamSubscription<T> listen(void onData(T event),
      {Function onError, void onDone(), bool cancelOnError}) {
    var pool = new _StreamPool<T>.broadcast();
    for (var target in _targetList) {
      pool.add(new _EventStream<T>(target, _eventType, _useCapture));
    }
    return pool.stream.listen(onData,
        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
  }

  StreamSubscription<T> capture(void onData(T event)) {
    var pool = new _StreamPool<T>.broadcast();
    for (var target in _targetList) {
      pool.add(new _EventStream<T>(target, _eventType, true));
    }
    return pool.stream.listen(onData);
  }

  Stream<T> asBroadcastStream(
          {void onListen(StreamSubscription<T> subscription),
          void onCancel(StreamSubscription<T> subscription)}) =>
      this;
  bool get isBroadcast => true;
}

// We would like this to just be EventListener<T> but that typdef cannot
// use generics until dartbug/26276 is fixed.
typedef _EventListener<T extends Event>(T event);

class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
  int _pauseCount = 0;
  EventTarget _target;
  final String _eventType;
  EventListener _onData;
  final bool _useCapture;

  // TODO(leafp): It would be better to write this as
  // _onData = onData == null ? null :
  //   onData is void Function(Event)
  //     ? _wrapZone<Event>(onData)
  //     : _wrapZone<Event>((e) => onData(e as T))
  // In order to support existing tests which pass the wrong type of events but
  // use a more general listener, without causing as much slowdown for things
  // which are typed correctly.  But this currently runs afoul of restrictions
  // on is checks for compatibility with the VM.
  _EventStreamSubscription(
      this._target, this._eventType, void onData(T event), this._useCapture)
      : _onData = onData == null
            ? null
            : _wrapZone<Event>((e) => (onData as dynamic)(e)) {
    _tryResume();
  }

  Future cancel() {
    if (_canceled) return null;

    _unlisten();
    // Clear out the target to indicate this is complete.
    _target = null;
    _onData = null;
    return null;
  }

  bool get _canceled => _target == null;

  void onData(void handleData(T event)) {
    if (_canceled) {
      throw new StateError("Subscription has been canceled.");
    }
    // Remove current event listener.
    _unlisten();
    _onData = _wrapZone<Event>(handleData);
    _tryResume();
  }

  /// Has no effect.
  void onError(Function handleError) {}

  /// Has no effect.
  void onDone(void handleDone()) {}

  void pause([Future resumeSignal]) {
    if (_canceled) return;
    ++_pauseCount;
    _unlisten();

    if (resumeSignal != null) {
      resumeSignal.whenComplete(resume);
    }
  }

  bool get isPaused => _pauseCount > 0;

  void resume() {
    if (_canceled || !isPaused) return;
    --_pauseCount;
    _tryResume();
  }

  void _tryResume() {
    if (_onData != null && !isPaused) {
      _target.addEventListener(_eventType, _onData, _useCapture);
    }
  }

  void _unlisten() {
    if (_onData != null) {
      _target.removeEventListener(_eventType, _onData, _useCapture);
    }
  }

  Future<E> asFuture<E>([E futureValue]) {
    // We just need a future that will never succeed or fail.
    var completer = new Completer<E>();
    return completer.future;
  }
}

/**
 * A stream of custom events, which enables the user to "fire" (add) their own
 * custom events to a stream.
 */
abstract class CustomStream<T extends Event> implements Stream<T> {
  /**
   * Add the following custom event to the stream for dispatching to interested
   * listeners.
   */
  void add(T event);
}

class _CustomEventStreamImpl<T extends Event> extends Stream<T>
    implements CustomStream<T> {
  StreamController<T> _streamController;
  /** The type of event this stream is providing (e.g. "keydown"). */
  String _type;

  _CustomEventStreamImpl(String type) {
    _type = type;
    _streamController = new StreamController.broadcast(sync: true);
  }

  // Delegate all regular Stream behavior to our wrapped Stream.
  StreamSubscription<T> listen(void onData(T event),
      {Function onError, void onDone(), bool cancelOnError}) {
    return _streamController.stream.listen(onData,
        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
  }

  Stream<T> asBroadcastStream(
          {void onListen(StreamSubscription<T> subscription),
          void onCancel(StreamSubscription<T> subscription)}) =>
      _streamController.stream;

  bool get isBroadcast => true;

  void add(T event) {
    if (event.type == _type) _streamController.add(event);
  }
}

class _CustomKeyEventStreamImpl extends _CustomEventStreamImpl<KeyEvent>
    implements CustomStream<KeyEvent> {
  _CustomKeyEventStreamImpl(String type) : super(type);

  void add(KeyEvent event) {
    if (event.type == _type) {
      event.currentTarget.dispatchEvent(event._parent);
      _streamController.add(event);
    }
  }
}

/**
 * A pool of streams whose events are unified and emitted through a central
 * stream.
 */
// TODO (efortuna): Remove this when Issue 12218 is addressed.
class _StreamPool<T> {
  StreamController<T> _controller;

  /// Subscriptions to the streams that make up the pool.
  var _subscriptions = new Map<Stream<T>, StreamSubscription<T>>();

  /**
   * Creates a new stream pool where [stream] can be listened to more than
   * once.
   *
   * Any events from buffered streams in the pool will be emitted immediately,
   * regardless of whether [stream] has any subscribers.
   */
  _StreamPool.broadcast() {
    _controller =
        new StreamController<T>.broadcast(sync: true, onCancel: close);
  }

  /**
   * The stream through which all events from streams in the pool are emitted.
   */
  Stream<T> get stream => _controller.stream;

  /**
   * Adds [stream] as a member of this pool.
   *
   * Any events from [stream] will be emitted through [this.stream]. If
   * [stream] is sync, they'll be emitted synchronously; if [stream] is async,
   * they'll be emitted asynchronously.
   */
  void add(Stream<T> stream) {
    if (_subscriptions.containsKey(stream)) return;
    _subscriptions[stream] = stream.listen(_controller.add,
        onError: _controller.addError, onDone: () => remove(stream));
  }

  /** Removes [stream] as a member of this pool. */
  void remove(Stream<T> stream) {
    var subscription = _subscriptions.remove(stream);
    if (subscription != null) subscription.cancel();
  }

  /** Removes all streams from this pool and closes [stream]. */
  void close() {
    for (var subscription in _subscriptions.values) {
      subscription.cancel();
    }
    _subscriptions.clear();
    _controller.close();
  }
}

/**
 * A factory to expose DOM events as streams, where the DOM event name has to
 * be determined on the fly (for example, mouse wheel events).
 */
class _CustomEventStreamProvider<T extends Event>
    implements EventStreamProvider<T> {
  final _eventTypeGetter;
  const _CustomEventStreamProvider(this._eventTypeGetter);

  Stream<T> forTarget(EventTarget e, {bool useCapture: false}) {
    return new _EventStream<T>(e, _eventTypeGetter(e), useCapture);
  }

  ElementStream<T> forElement(Element e, {bool useCapture: false}) {
    return new _ElementEventStreamImpl<T>(e, _eventTypeGetter(e), useCapture);
  }

  ElementStream<T> _forElementList(ElementList<Element> e,
      {bool useCapture: false}) {
    return new _ElementListEventStreamImpl<T>(
        e, _eventTypeGetter(e), useCapture);
  }

  String getEventType(EventTarget target) {
    return _eventTypeGetter(target);
  }

  String get _eventType =>
      throw new UnsupportedError('Access type through getEventType method.');
}
// DO NOT EDIT- this file is generated from running tool/generator.sh.

// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * A Dart DOM validator generated from Caja whitelists.
 *
 * This contains a whitelist of known HTML tagNames and attributes and will only
 * accept known good values.
 *
 * See also:
 *
 * * <https://code.google.com/p/google-caja/wiki/CajaWhitelists>
 */
class _Html5NodeValidator implements NodeValidator {
  static final Set<String> _allowedElements = new Set.from([
    'A',
    'ABBR',
    'ACRONYM',
    'ADDRESS',
    'AREA',
    'ARTICLE',
    'ASIDE',
    'AUDIO',
    'B',
    'BDI',
    'BDO',
    'BIG',
    'BLOCKQUOTE',
    'BR',
    'BUTTON',
    'CANVAS',
    'CAPTION',
    'CENTER',
    'CITE',
    'CODE',
    'COL',
    'COLGROUP',
    'COMMAND',
    'DATA',
    'DATALIST',
    'DD',
    'DEL',
    'DETAILS',
    'DFN',
    'DIR',
    'DIV',
    'DL',
    'DT',
    'EM',
    'FIELDSET',
    'FIGCAPTION',
    'FIGURE',
    'FONT',
    'FOOTER',
    'FORM',
    'H1',
    'H2',
    'H3',
    'H4',
    'H5',
    'H6',
    'HEADER',
    'HGROUP',
    'HR',
    'I',
    'IFRAME',
    'IMG',
    'INPUT',
    'INS',
    'KBD',
    'LABEL',
    'LEGEND',
    'LI',
    'MAP',
    'MARK',
    'MENU',
    'METER',
    'NAV',
    'NOBR',
    'OL',
    'OPTGROUP',
    'OPTION',
    'OUTPUT',
    'P',
    'PRE',
    'PROGRESS',
    'Q',
    'S',
    'SAMP',
    'SECTION',
    'SELECT',
    'SMALL',
    'SOURCE',
    'SPAN',
    'STRIKE',
    'STRONG',
    'SUB',
    'SUMMARY',
    'SUP',
    'TABLE',
    'TBODY',
    'TD',
    'TEXTAREA',
    'TFOOT',
    'TH',
    'THEAD',
    'TIME',
    'TR',
    'TRACK',
    'TT',
    'U',
    'UL',
    'VAR',
    'VIDEO',
    'WBR',
  ]);

  static const _standardAttributes = const <String>[
    '*::class',
    '*::dir',
    '*::draggable',
    '*::hidden',
    '*::id',
    '*::inert',
    '*::itemprop',
    '*::itemref',
    '*::itemscope',
    '*::lang',
    '*::spellcheck',
    '*::title',
    '*::translate',
    'A::accesskey',
    'A::coords',
    'A::hreflang',
    'A::name',
    'A::shape',
    'A::tabindex',
    'A::target',
    'A::type',
    'AREA::accesskey',
    'AREA::alt',
    'AREA::coords',
    'AREA::nohref',
    'AREA::shape',
    'AREA::tabindex',
    'AREA::target',
    'AUDIO::controls',
    'AUDIO::loop',
    'AUDIO::mediagroup',
    'AUDIO::muted',
    'AUDIO::preload',
    'BDO::dir',
    'BODY::alink',
    'BODY::bgcolor',
    'BODY::link',
    'BODY::text',
    'BODY::vlink',
    'BR::clear',
    'BUTTON::accesskey',
    'BUTTON::disabled',
    'BUTTON::name',
    'BUTTON::tabindex',
    'BUTTON::type',
    'BUTTON::value',
    'CANVAS::height',
    'CANVAS::width',
    'CAPTION::align',
    'COL::align',
    'COL::char',
    'COL::charoff',
    'COL::span',
    'COL::valign',
    'COL::width',
    'COLGROUP::align',
    'COLGROUP::char',
    'COLGROUP::charoff',
    'COLGROUP::span',
    'COLGROUP::valign',
    'COLGROUP::width',
    'COMMAND::checked',
    'COMMAND::command',
    'COMMAND::disabled',
    'COMMAND::label',
    'COMMAND::radiogroup',
    'COMMAND::type',
    'DATA::value',
    'DEL::datetime',
    'DETAILS::open',
    'DIR::compact',
    'DIV::align',
    'DL::compact',
    'FIELDSET::disabled',
    'FONT::color',
    'FONT::face',
    'FONT::size',
    'FORM::accept',
    'FORM::autocomplete',
    'FORM::enctype',
    'FORM::method',
    'FORM::name',
    'FORM::novalidate',
    'FORM::target',
    'FRAME::name',
    'H1::align',
    'H2::align',
    'H3::align',
    'H4::align',
    'H5::align',
    'H6::align',
    'HR::align',
    'HR::noshade',
    'HR::size',
    'HR::width',
    'HTML::version',
    'IFRAME::align',
    'IFRAME::frameborder',
    'IFRAME::height',
    'IFRAME::marginheight',
    'IFRAME::marginwidth',
    'IFRAME::width',
    'IMG::align',
    'IMG::alt',
    'IMG::border',
    'IMG::height',
    'IMG::hspace',
    'IMG::ismap',
    'IMG::name',
    'IMG::usemap',
    'IMG::vspace',
    'IMG::width',
    'INPUT::accept',
    'INPUT::accesskey',
    'INPUT::align',
    'INPUT::alt',
    'INPUT::autocomplete',
    'INPUT::autofocus',
    'INPUT::checked',
    'INPUT::disabled',
    'INPUT::inputmode',
    'INPUT::ismap',
    'INPUT::list',
    'INPUT::max',
    'INPUT::maxlength',
    'INPUT::min',
    'INPUT::multiple',
    'INPUT::name',
    'INPUT::placeholder',
    'INPUT::readonly',
    'INPUT::required',
    'INPUT::size',
    'INPUT::step',
    'INPUT::tabindex',
    'INPUT::type',
    'INPUT::usemap',
    'INPUT::value',
    'INS::datetime',
    'KEYGEN::disabled',
    'KEYGEN::keytype',
    'KEYGEN::name',
    'LABEL::accesskey',
    'LABEL::for',
    'LEGEND::accesskey',
    'LEGEND::align',
    'LI::type',
    'LI::value',
    'LINK::sizes',
    'MAP::name',
    'MENU::compact',
    'MENU::label',
    'MENU::type',
    'METER::high',
    'METER::low',
    'METER::max',
    'METER::min',
    'METER::value',
    'OBJECT::typemustmatch',
    'OL::compact',
    'OL::reversed',
    'OL::start',
    'OL::type',
    'OPTGROUP::disabled',
    'OPTGROUP::label',
    'OPTION::disabled',
    'OPTION::label',
    'OPTION::selected',
    'OPTION::value',
    'OUTPUT::for',
    'OUTPUT::name',
    'P::align',
    'PRE::width',
    'PROGRESS::max',
    'PROGRESS::min',
    'PROGRESS::value',
    'SELECT::autocomplete',
    'SELECT::disabled',
    'SELECT::multiple',
    'SELECT::name',
    'SELECT::required',
    'SELECT::size',
    'SELECT::tabindex',
    'SOURCE::type',
    'TABLE::align',
    'TABLE::bgcolor',
    'TABLE::border',
    'TABLE::cellpadding',
    'TABLE::cellspacing',
    'TABLE::frame',
    'TABLE::rules',
    'TABLE::summary',
    'TABLE::width',
    'TBODY::align',
    'TBODY::char',
    'TBODY::charoff',
    'TBODY::valign',
    'TD::abbr',
    'TD::align',
    'TD::axis',
    'TD::bgcolor',
    'TD::char',
    'TD::charoff',
    'TD::colspan',
    'TD::headers',
    'TD::height',
    'TD::nowrap',
    'TD::rowspan',
    'TD::scope',
    'TD::valign',
    'TD::width',
    'TEXTAREA::accesskey',
    'TEXTAREA::autocomplete',
    'TEXTAREA::cols',
    'TEXTAREA::disabled',
    'TEXTAREA::inputmode',
    'TEXTAREA::name',
    'TEXTAREA::placeholder',
    'TEXTAREA::readonly',
    'TEXTAREA::required',
    'TEXTAREA::rows',
    'TEXTAREA::tabindex',
    'TEXTAREA::wrap',
    'TFOOT::align',
    'TFOOT::char',
    'TFOOT::charoff',
    'TFOOT::valign',
    'TH::abbr',
    'TH::align',
    'TH::axis',
    'TH::bgcolor',
    'TH::char',
    'TH::charoff',
    'TH::colspan',
    'TH::headers',
    'TH::height',
    'TH::nowrap',
    'TH::rowspan',
    'TH::scope',
    'TH::valign',
    'TH::width',
    'THEAD::align',
    'THEAD::char',
    'THEAD::charoff',
    'THEAD::valign',
    'TR::align',
    'TR::bgcolor',
    'TR::char',
    'TR::charoff',
    'TR::valign',
    'TRACK::default',
    'TRACK::kind',
    'TRACK::label',
    'TRACK::srclang',
    'UL::compact',
    'UL::type',
    'VIDEO::controls',
    'VIDEO::height',
    'VIDEO::loop',
    'VIDEO::mediagroup',
    'VIDEO::muted',
    'VIDEO::preload',
    'VIDEO::width',
  ];

  static const _uriAttributes = const <String>[
    'A::href',
    'AREA::href',
    'BLOCKQUOTE::cite',
    'BODY::background',
    'COMMAND::icon',
    'DEL::cite',
    'FORM::action',
    'IMG::src',
    'INPUT::src',
    'INS::cite',
    'Q::cite',
    'VIDEO::poster',
  ];

  final UriPolicy uriPolicy;

  static final Map<String, Function> _attributeValidators = {};

  /**
   * All known URI attributes will be validated against the UriPolicy, if
   * [uriPolicy] is null then a default UriPolicy will be used.
   */
  _Html5NodeValidator({UriPolicy uriPolicy})
      : uriPolicy = uriPolicy != null ? uriPolicy : new UriPolicy() {
    if (_attributeValidators.isEmpty) {
      for (var attr in _standardAttributes) {
        _attributeValidators[attr] = _standardAttributeValidator;
      }

      for (var attr in _uriAttributes) {
        _attributeValidators[attr] = _uriAttributeValidator;
      }
    }
  }

  bool allowsElement(Element element) {
    return _allowedElements.contains(Element._safeTagName(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    var tagName = Element._safeTagName(element);
    var validator = _attributeValidators['$tagName::$attributeName'];
    if (validator == null) {
      validator = _attributeValidators['*::$attributeName'];
    }
    if (validator == null) {
      return false;
    }
    return validator(element, attributeName, value, this);
  }

  static bool _standardAttributeValidator(Element element, String attributeName,
      String value, _Html5NodeValidator context) {
    return true;
  }

  static bool _uriAttributeValidator(Element element, String attributeName,
      String value, _Html5NodeValidator context) {
    return context.uriPolicy.allowsUri(value);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class ImmutableListMixin<E> implements List<E> {
  // From Iterable<$E>:
  Iterator<E> get iterator {
    // Note: NodeLists are not fixed size. And most probably length shouldn't
    // be cached in both iterator _and_ forEach method. For now caching it
    // for consistency.
    return new FixedSizeListIterator<E>(this);
  }

  // From List<E>:
  void add(E value) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void addAll(Iterable<E> iterable) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void sort([int compare(E a, E b)]) {
    throw new UnsupportedError("Cannot sort immutable List.");
  }

  void shuffle([Random random]) {
    throw new UnsupportedError("Cannot shuffle immutable List.");
  }

  void insert(int index, E element) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void insertAll(int index, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void setAll(int index, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }

  E removeAt(int pos) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  E removeLast() {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  bool remove(Object object) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void removeWhere(bool test(E element)) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void retainWhere(bool test(E element)) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
    throw new UnsupportedError("Cannot setRange on immutable List.");
  }

  void removeRange(int start, int end) {
    throw new UnsupportedError("Cannot removeRange on immutable List.");
  }

  void replaceRange(int start, int end, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }

  void fillRange(int start, int end, [E fillValue]) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Defines the keycode values for keys that are returned by
 * KeyboardEvent.keyCode.
 *
 * Important note: There is substantial divergence in how different browsers
 * handle keycodes and their variants in different locales/keyboard layouts. We
 * provide these constants to help make code processing keys more readable.
 */
abstract class KeyCode {
  // These constant names were borrowed from Closure's Keycode enumeration
  // class.
  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keycodes.js.source.html
  static const int WIN_KEY_FF_LINUX = 0;
  static const int MAC_ENTER = 3;
  static const int BACKSPACE = 8;
  static const int TAB = 9;
  /** NUM_CENTER is also NUMLOCK for FF and Safari on Mac. */
  static const int NUM_CENTER = 12;
  static const int ENTER = 13;
  static const int SHIFT = 16;
  static const int CTRL = 17;
  static const int ALT = 18;
  static const int PAUSE = 19;
  static const int CAPS_LOCK = 20;
  static const int ESC = 27;
  static const int SPACE = 32;
  static const int PAGE_UP = 33;
  static const int PAGE_DOWN = 34;
  static const int END = 35;
  static const int HOME = 36;
  static const int LEFT = 37;
  static const int UP = 38;
  static const int RIGHT = 39;
  static const int DOWN = 40;
  static const int NUM_NORTH_EAST = 33;
  static const int NUM_SOUTH_EAST = 34;
  static const int NUM_SOUTH_WEST = 35;
  static const int NUM_NORTH_WEST = 36;
  static const int NUM_WEST = 37;
  static const int NUM_NORTH = 38;
  static const int NUM_EAST = 39;
  static const int NUM_SOUTH = 40;
  static const int PRINT_SCREEN = 44;
  static const int INSERT = 45;
  static const int NUM_INSERT = 45;
  static const int DELETE = 46;
  static const int NUM_DELETE = 46;
  static const int ZERO = 48;
  static const int ONE = 49;
  static const int TWO = 50;
  static const int THREE = 51;
  static const int FOUR = 52;
  static const int FIVE = 53;
  static const int SIX = 54;
  static const int SEVEN = 55;
  static const int EIGHT = 56;
  static const int NINE = 57;
  static const int FF_SEMICOLON = 59;
  static const int FF_EQUALS = 61;
  /**
   * CAUTION: The question mark is for US-keyboard layouts. It varies
   * for other locales and keyboard layouts.
   */
  static const int QUESTION_MARK = 63;
  static const int A = 65;
  static const int B = 66;
  static const int C = 67;
  static const int D = 68;
  static const int E = 69;
  static const int F = 70;
  static const int G = 71;
  static const int H = 72;
  static const int I = 73;
  static const int J = 74;
  static const int K = 75;
  static const int L = 76;
  static const int M = 77;
  static const int N = 78;
  static const int O = 79;
  static const int P = 80;
  static const int Q = 81;
  static const int R = 82;
  static const int S = 83;
  static const int T = 84;
  static const int U = 85;
  static const int V = 86;
  static const int W = 87;
  static const int X = 88;
  static const int Y = 89;
  static const int Z = 90;
  static const int META = 91;
  static const int WIN_KEY_LEFT = 91;
  static const int WIN_KEY_RIGHT = 92;
  static const int CONTEXT_MENU = 93;
  static const int NUM_ZERO = 96;
  static const int NUM_ONE = 97;
  static const int NUM_TWO = 98;
  static const int NUM_THREE = 99;
  static const int NUM_FOUR = 100;
  static const int NUM_FIVE = 101;
  static const int NUM_SIX = 102;
  static const int NUM_SEVEN = 103;
  static const int NUM_EIGHT = 104;
  static const int NUM_NINE = 105;
  static const int NUM_MULTIPLY = 106;
  static const int NUM_PLUS = 107;
  static const int NUM_MINUS = 109;
  static const int NUM_PERIOD = 110;
  static const int NUM_DIVISION = 111;
  static const int F1 = 112;
  static const int F2 = 113;
  static const int F3 = 114;
  static const int F4 = 115;
  static const int F5 = 116;
  static const int F6 = 117;
  static const int F7 = 118;
  static const int F8 = 119;
  static const int F9 = 120;
  static const int F10 = 121;
  static const int F11 = 122;
  static const int F12 = 123;
  static const int NUMLOCK = 144;
  static const int SCROLL_LOCK = 145;

  // OS-specific media keys like volume controls and browser controls.
  static const int FIRST_MEDIA_KEY = 166;
  static const int LAST_MEDIA_KEY = 183;

  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SEMICOLON = 186;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int DASH = 189;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int EQUALS = 187;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int COMMA = 188;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int PERIOD = 190;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SLASH = 191;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int APOSTROPHE = 192;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int TILDE = 192;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SINGLE_QUOTE = 222;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int OPEN_SQUARE_BRACKET = 219;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int BACKSLASH = 220;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int CLOSE_SQUARE_BRACKET = 221;
  static const int WIN_KEY = 224;
  static const int MAC_FF_META = 224;
  static const int WIN_IME = 229;

  /** A sentinel value if the keycode could not be determined. */
  static const int UNKNOWN = -1;

  /**
   * Returns true if the keyCode produces a (US keyboard) character.
   * Note: This does not (yet) cover characters on non-US keyboards (Russian,
   * Hebrew, etc.).
   */
  static bool isCharacterKey(int keyCode) {
    if ((keyCode >= ZERO && keyCode <= NINE) ||
        (keyCode >= NUM_ZERO && keyCode <= NUM_MULTIPLY) ||
        (keyCode >= A && keyCode <= Z)) {
      return true;
    }

    // Safari sends zero key code for non-latin characters.
    if (Device.isWebKit && keyCode == 0) {
      return true;
    }

    return (keyCode == SPACE ||
        keyCode == QUESTION_MARK ||
        keyCode == NUM_PLUS ||
        keyCode == NUM_MINUS ||
        keyCode == NUM_PERIOD ||
        keyCode == NUM_DIVISION ||
        keyCode == SEMICOLON ||
        keyCode == FF_SEMICOLON ||
        keyCode == DASH ||
        keyCode == EQUALS ||
        keyCode == FF_EQUALS ||
        keyCode == COMMA ||
        keyCode == PERIOD ||
        keyCode == SLASH ||
        keyCode == APOSTROPHE ||
        keyCode == SINGLE_QUOTE ||
        keyCode == OPEN_SQUARE_BRACKET ||
        keyCode == BACKSLASH ||
        keyCode == CLOSE_SQUARE_BRACKET);
  }

  /**
   * Experimental helper function for converting keyCodes to keyNames for the
   * keyIdentifier attribute still used in browsers not updated with current
   * spec. This is an imperfect conversion! It will need to be refined, but
   * hopefully it can just completely go away once all the browsers update to
   * follow the DOM3 spec.
   */
  static String _convertKeyCodeToKeyName(int keyCode) {
    switch (keyCode) {
      case KeyCode.ALT:
        return _KeyName.ALT;
      case KeyCode.BACKSPACE:
        return _KeyName.BACKSPACE;
      case KeyCode.CAPS_LOCK:
        return _KeyName.CAPS_LOCK;
      case KeyCode.CTRL:
        return _KeyName.CONTROL;
      case KeyCode.DELETE:
        return _KeyName.DEL;
      case KeyCode.DOWN:
        return _KeyName.DOWN;
      case KeyCode.END:
        return _KeyName.END;
      case KeyCode.ENTER:
        return _KeyName.ENTER;
      case KeyCode.ESC:
        return _KeyName.ESC;
      case KeyCode.F1:
        return _KeyName.F1;
      case KeyCode.F2:
        return _KeyName.F2;
      case KeyCode.F3:
        return _KeyName.F3;
      case KeyCode.F4:
        return _KeyName.F4;
      case KeyCode.F5:
        return _KeyName.F5;
      case KeyCode.F6:
        return _KeyName.F6;
      case KeyCode.F7:
        return _KeyName.F7;
      case KeyCode.F8:
        return _KeyName.F8;
      case KeyCode.F9:
        return _KeyName.F9;
      case KeyCode.F10:
        return _KeyName.F10;
      case KeyCode.F11:
        return _KeyName.F11;
      case KeyCode.F12:
        return _KeyName.F12;
      case KeyCode.HOME:
        return _KeyName.HOME;
      case KeyCode.INSERT:
        return _KeyName.INSERT;
      case KeyCode.LEFT:
        return _KeyName.LEFT;
      case KeyCode.META:
        return _KeyName.META;
      case KeyCode.NUMLOCK:
        return _KeyName.NUM_LOCK;
      case KeyCode.PAGE_DOWN:
        return _KeyName.PAGE_DOWN;
      case KeyCode.PAGE_UP:
        return _KeyName.PAGE_UP;
      case KeyCode.PAUSE:
        return _KeyName.PAUSE;
      case KeyCode.PRINT_SCREEN:
        return _KeyName.PRINT_SCREEN;
      case KeyCode.RIGHT:
        return _KeyName.RIGHT;
      case KeyCode.SCROLL_LOCK:
        return _KeyName.SCROLL;
      case KeyCode.SHIFT:
        return _KeyName.SHIFT;
      case KeyCode.SPACE:
        return _KeyName.SPACEBAR;
      case KeyCode.TAB:
        return _KeyName.TAB;
      case KeyCode.UP:
        return _KeyName.UP;
      case KeyCode.WIN_IME:
      case KeyCode.WIN_KEY:
      case KeyCode.WIN_KEY_LEFT:
      case KeyCode.WIN_KEY_RIGHT:
        return _KeyName.WIN;
      default:
        return _KeyName.UNIDENTIFIED;
    }
    return _KeyName.UNIDENTIFIED;
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Defines the standard key locations returned by
 * KeyboardEvent.getKeyLocation.
 */
abstract class KeyLocation {
  /**
   * The event key is not distinguished as the left or right version
   * of the key, and did not originate from the numeric keypad (or did not
   * originate with a virtual key corresponding to the numeric keypad).
   */
  static const int STANDARD = 0;

  /**
   * The event key is in the left key location.
   */
  static const int LEFT = 1;

  /**
   * The event key is in the right key location.
   */
  static const int RIGHT = 2;

  /**
   * The event key originated on the numeric keypad or with a virtual key
   * corresponding to the numeric keypad.
   */
  static const int NUMPAD = 3;

  /**
   * The event key originated on a mobile device, either on a physical
   * keypad or a virtual keyboard.
   */
  static const int MOBILE = 4;

  /**
   * The event key originated on a game controller or a joystick on a mobile
   * device.
   */
  static const int JOYSTICK = 5;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Defines the standard keyboard identifier names for keys that are returned
 * by KeyboardEvent.getKeyboardIdentifier when the key does not have a direct
 * unicode mapping.
 */
abstract class _KeyName {
  /** The Accept (Commit, OK) key */
  static const String ACCEPT = "Accept";

  /** The Add key */
  static const String ADD = "Add";

  /** The Again key */
  static const String AGAIN = "Again";

  /** The All Candidates key */
  static const String ALL_CANDIDATES = "AllCandidates";

  /** The Alphanumeric key */
  static const String ALPHANUMERIC = "Alphanumeric";

  /** The Alt (Menu) key */
  static const String ALT = "Alt";

  /** The Alt-Graph key */
  static const String ALT_GRAPH = "AltGraph";

  /** The Application key */
  static const String APPS = "Apps";

  /** The ATTN key */
  static const String ATTN = "Attn";

  /** The Browser Back key */
  static const String BROWSER_BACK = "BrowserBack";

  /** The Browser Favorites key */
  static const String BROWSER_FAVORTIES = "BrowserFavorites";

  /** The Browser Forward key */
  static const String BROWSER_FORWARD = "BrowserForward";

  /** The Browser Home key */
  static const String BROWSER_NAME = "BrowserHome";

  /** The Browser Refresh key */
  static const String BROWSER_REFRESH = "BrowserRefresh";

  /** The Browser Search key */
  static const String BROWSER_SEARCH = "BrowserSearch";

  /** The Browser Stop key */
  static const String BROWSER_STOP = "BrowserStop";

  /** The Camera key */
  static const String CAMERA = "Camera";

  /** The Caps Lock (Capital) key */
  static const String CAPS_LOCK = "CapsLock";

  /** The Clear key */
  static const String CLEAR = "Clear";

  /** The Code Input key */
  static const String CODE_INPUT = "CodeInput";

  /** The Compose key */
  static const String COMPOSE = "Compose";

  /** The Control (Ctrl) key */
  static const String CONTROL = "Control";

  /** The Crsel key */
  static const String CRSEL = "Crsel";

  /** The Convert key */
  static const String CONVERT = "Convert";

  /** The Copy key */
  static const String COPY = "Copy";

  /** The Cut key */
  static const String CUT = "Cut";

  /** The Decimal key */
  static const String DECIMAL = "Decimal";

  /** The Divide key */
  static const String DIVIDE = "Divide";

  /** The Down Arrow key */
  static const String DOWN = "Down";

  /** The diagonal Down-Left Arrow key */
  static const String DOWN_LEFT = "DownLeft";

  /** The diagonal Down-Right Arrow key */
  static const String DOWN_RIGHT = "DownRight";

  /** The Eject key */
  static const String EJECT = "Eject";

  /** The End key */
  static const String END = "End";

  /**
   * The Enter key. Note: This key value must also be used for the Return
   *  (Macintosh numpad) key
   */
  static const String ENTER = "Enter";

  /** The Erase EOF key */
  static const String ERASE_EOF = "EraseEof";

  /** The Execute key */
  static const String EXECUTE = "Execute";

  /** The Exsel key */
  static const String EXSEL = "Exsel";

  /** The Function switch key */
  static const String FN = "Fn";

  /** The F1 key */
  static const String F1 = "F1";

  /** The F2 key */
  static const String F2 = "F2";

  /** The F3 key */
  static const String F3 = "F3";

  /** The F4 key */
  static const String F4 = "F4";

  /** The F5 key */
  static const String F5 = "F5";

  /** The F6 key */
  static const String F6 = "F6";

  /** The F7 key */
  static const String F7 = "F7";

  /** The F8 key */
  static const String F8 = "F8";

  /** The F9 key */
  static const String F9 = "F9";

  /** The F10 key */
  static const String F10 = "F10";

  /** The F11 key */
  static const String F11 = "F11";

  /** The F12 key */
  static const String F12 = "F12";

  /** The F13 key */
  static const String F13 = "F13";

  /** The F14 key */
  static const String F14 = "F14";

  /** The F15 key */
  static const String F15 = "F15";

  /** The F16 key */
  static const String F16 = "F16";

  /** The F17 key */
  static const String F17 = "F17";

  /** The F18 key */
  static const String F18 = "F18";

  /** The F19 key */
  static const String F19 = "F19";

  /** The F20 key */
  static const String F20 = "F20";

  /** The F21 key */
  static const String F21 = "F21";

  /** The F22 key */
  static const String F22 = "F22";

  /** The F23 key */
  static const String F23 = "F23";

  /** The F24 key */
  static const String F24 = "F24";

  /** The Final Mode (Final) key used on some asian keyboards */
  static const String FINAL_MODE = "FinalMode";

  /** The Find key */
  static const String FIND = "Find";

  /** The Full-Width Characters key */
  static const String FULL_WIDTH = "FullWidth";

  /** The Half-Width Characters key */
  static const String HALF_WIDTH = "HalfWidth";

  /** The Hangul (Korean characters) Mode key */
  static const String HANGUL_MODE = "HangulMode";

  /** The Hanja (Korean characters) Mode key */
  static const String HANJA_MODE = "HanjaMode";

  /** The Help key */
  static const String HELP = "Help";

  /** The Hiragana (Japanese Kana characters) key */
  static const String HIRAGANA = "Hiragana";

  /** The Home key */
  static const String HOME = "Home";

  /** The Insert (Ins) key */
  static const String INSERT = "Insert";

  /** The Japanese-Hiragana key */
  static const String JAPANESE_HIRAGANA = "JapaneseHiragana";

  /** The Japanese-Katakana key */
  static const String JAPANESE_KATAKANA = "JapaneseKatakana";

  /** The Japanese-Romaji key */
  static const String JAPANESE_ROMAJI = "JapaneseRomaji";

  /** The Junja Mode key */
  static const String JUNJA_MODE = "JunjaMode";

  /** The Kana Mode (Kana Lock) key */
  static const String KANA_MODE = "KanaMode";

  /**
   * The Kanji (Japanese name for ideographic characters of Chinese origin)
   * Mode key
   */
  static const String KANJI_MODE = "KanjiMode";

  /** The Katakana (Japanese Kana characters) key */
  static const String KATAKANA = "Katakana";

  /** The Start Application One key */
  static const String LAUNCH_APPLICATION_1 = "LaunchApplication1";

  /** The Start Application Two key */
  static const String LAUNCH_APPLICATION_2 = "LaunchApplication2";

  /** The Start Mail key */
  static const String LAUNCH_MAIL = "LaunchMail";

  /** The Left Arrow key */
  static const String LEFT = "Left";

  /** The Menu key */
  static const String MENU = "Menu";

  /**
   * The Meta key. Note: This key value shall be also used for the Apple
   * Command key
   */
  static const String META = "Meta";

  /** The Media Next Track key */
  static const String MEDIA_NEXT_TRACK = "MediaNextTrack";

  /** The Media Play Pause key */
  static const String MEDIA_PAUSE_PLAY = "MediaPlayPause";

  /** The Media Previous Track key */
  static const String MEDIA_PREVIOUS_TRACK = "MediaPreviousTrack";

  /** The Media Stop key */
  static const String MEDIA_STOP = "MediaStop";

  /** The Mode Change key */
  static const String MODE_CHANGE = "ModeChange";

  /** The Next Candidate function key */
  static const String NEXT_CANDIDATE = "NextCandidate";

  /** The Nonconvert (Don't Convert) key */
  static const String NON_CONVERT = "Nonconvert";

  /** The Number Lock key */
  static const String NUM_LOCK = "NumLock";

  /** The Page Down (Next) key */
  static const String PAGE_DOWN = "PageDown";

  /** The Page Up key */
  static const String PAGE_UP = "PageUp";

  /** The Paste key */
  static const String PASTE = "Paste";

  /** The Pause key */
  static const String PAUSE = "Pause";

  /** The Play key */
  static const String PLAY = "Play";

  /**
   * The Power key. Note: Some devices may not expose this key to the
   * operating environment
   */
  static const String POWER = "Power";

  /** The Previous Candidate function key */
  static const String PREVIOUS_CANDIDATE = "PreviousCandidate";

  /** The Print Screen (PrintScrn, SnapShot) key */
  static const String PRINT_SCREEN = "PrintScreen";

  /** The Process key */
  static const String PROCESS = "Process";

  /** The Props key */
  static const String PROPS = "Props";

  /** The Right Arrow key */
  static const String RIGHT = "Right";

  /** The Roman Characters function key */
  static const String ROMAN_CHARACTERS = "RomanCharacters";

  /** The Scroll Lock key */
  static const String SCROLL = "Scroll";

  /** The Select key */
  static const String SELECT = "Select";

  /** The Select Media key */
  static const String SELECT_MEDIA = "SelectMedia";

  /** The Separator key */
  static const String SEPARATOR = "Separator";

  /** The Shift key */
  static const String SHIFT = "Shift";

  /** The Soft1 key */
  static const String SOFT_1 = "Soft1";

  /** The Soft2 key */
  static const String SOFT_2 = "Soft2";

  /** The Soft3 key */
  static const String SOFT_3 = "Soft3";

  /** The Soft4 key */
  static const String SOFT_4 = "Soft4";

  /** The Stop key */
  static const String STOP = "Stop";

  /** The Subtract key */
  static const String SUBTRACT = "Subtract";

  /** The Symbol Lock key */
  static const String SYMBOL_LOCK = "SymbolLock";

  /** The Up Arrow key */
  static const String UP = "Up";

  /** The diagonal Up-Left Arrow key */
  static const String UP_LEFT = "UpLeft";

  /** The diagonal Up-Right Arrow key */
  static const String UP_RIGHT = "UpRight";

  /** The Undo key */
  static const String UNDO = "Undo";

  /** The Volume Down key */
  static const String VOLUME_DOWN = "VolumeDown";

  /** The Volume Mute key */
  static const String VOLUMN_MUTE = "VolumeMute";

  /** The Volume Up key */
  static const String VOLUMN_UP = "VolumeUp";

  /** The Windows Logo key */
  static const String WIN = "Win";

  /** The Zoom key */
  static const String ZOOM = "Zoom";

  /**
   * The Backspace (Back) key. Note: This key value shall be also used for the
   * key labeled 'delete' MacOS keyboards when not modified by the 'Fn' key
   */
  static const String BACKSPACE = "Backspace";

  /** The Horizontal Tabulation (Tab) key */
  static const String TAB = "Tab";

  /** The Cancel key */
  static const String CANCEL = "Cancel";

  /** The Escape (Esc) key */
  static const String ESC = "Esc";

  /** The Space (Spacebar) key:   */
  static const String SPACEBAR = "Spacebar";

  /**
   * The Delete (Del) Key. Note: This key value shall be also used for the key
   * labeled 'delete' MacOS keyboards when modified by the 'Fn' key
   */
  static const String DEL = "Del";

  /** The Combining Grave Accent (Greek Varia, Dead Grave) key */
  static const String DEAD_GRAVE = "DeadGrave";

  /**
   * The Combining Acute Accent (Stress Mark, Greek Oxia, Tonos, Dead Eacute)
   * key
   */
  static const String DEAD_EACUTE = "DeadEacute";

  /** The Combining Circumflex Accent (Hat, Dead Circumflex) key */
  static const String DEAD_CIRCUMFLEX = "DeadCircumflex";

  /** The Combining Tilde (Dead Tilde) key */
  static const String DEAD_TILDE = "DeadTilde";

  /** The Combining Macron (Long, Dead Macron) key */
  static const String DEAD_MACRON = "DeadMacron";

  /** The Combining Breve (Short, Dead Breve) key */
  static const String DEAD_BREVE = "DeadBreve";

  /** The Combining Dot Above (Derivative, Dead Above Dot) key */
  static const String DEAD_ABOVE_DOT = "DeadAboveDot";

  /**
   * The Combining Diaeresis (Double Dot Abode, Umlaut, Greek Dialytika,
   * Double Derivative, Dead Diaeresis) key
   */
  static const String DEAD_UMLAUT = "DeadUmlaut";

  /** The Combining Ring Above (Dead Above Ring) key */
  static const String DEAD_ABOVE_RING = "DeadAboveRing";

  /** The Combining Double Acute Accent (Dead Doubleacute) key */
  static const String DEAD_DOUBLEACUTE = "DeadDoubleacute";

  /** The Combining Caron (Hacek, V Above, Dead Caron) key */
  static const String DEAD_CARON = "DeadCaron";

  /** The Combining Cedilla (Dead Cedilla) key */
  static const String DEAD_CEDILLA = "DeadCedilla";

  /** The Combining Ogonek (Nasal Hook, Dead Ogonek) key */
  static const String DEAD_OGONEK = "DeadOgonek";

  /**
   * The Combining Greek Ypogegrammeni (Greek Non-Spacing Iota Below, Iota
   * Subscript, Dead Iota) key
   */
  static const String DEAD_IOTA = "DeadIota";

  /**
   * The Combining Katakana-Hiragana Voiced Sound Mark (Dead Voiced Sound) key
   */
  static const String DEAD_VOICED_SOUND = "DeadVoicedSound";

  /**
   * The Combining Katakana-Hiragana Semi-Voiced Sound Mark (Dead Semivoiced
   * Sound) key
   */
  static const String DEC_SEMIVOICED_SOUND = "DeadSemivoicedSound";

  /**
   * Key value used when an implementation is unable to identify another key
   * value, due to either hardware, platform, or software constraints
   */
  static const String UNIDENTIFIED = "Unidentified";
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Internal class that does the actual calculations to determine keyCode and
 * charCode for keydown, keypress, and keyup events for all browsers.
 */
class _KeyboardEventHandler extends EventStreamProvider<KeyEvent> {
  // This code inspired by Closure's KeyHandling library.
  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keyhandler.js.source.html

  /**
   * The set of keys that have been pressed down without seeing their
   * corresponding keyup event.
   */
  final List<KeyEvent> _keyDownList = <KeyEvent>[];

  /** The type of KeyEvent we are tracking (keyup, keydown, keypress). */
  final String _type;

  /** The element we are watching for events to happen on. */
  final EventTarget _target;

  // The distance to shift from upper case alphabet Roman letters to lower case.
  static final int _ROMAN_ALPHABET_OFFSET = "a".codeUnits[0] - "A".codeUnits[0];

  /** Custom Stream (Controller) to produce KeyEvents for the stream. */
  _CustomKeyEventStreamImpl _stream;

  static const _EVENT_TYPE = 'KeyEvent';

  /**
   * An enumeration of key identifiers currently part of the W3C draft for DOM3
   * and their mappings to keyCodes.
   * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set
   */
  static const Map<String, int> _keyIdentifier = const {
    'Up': KeyCode.UP,
    'Down': KeyCode.DOWN,
    'Left': KeyCode.LEFT,
    'Right': KeyCode.RIGHT,
    'Enter': KeyCode.ENTER,
    'F1': KeyCode.F1,
    'F2': KeyCode.F2,
    'F3': KeyCode.F3,
    'F4': KeyCode.F4,
    'F5': KeyCode.F5,
    'F6': KeyCode.F6,
    'F7': KeyCode.F7,
    'F8': KeyCode.F8,
    'F9': KeyCode.F9,
    'F10': KeyCode.F10,
    'F11': KeyCode.F11,
    'F12': KeyCode.F12,
    'U+007F': KeyCode.DELETE,
    'Home': KeyCode.HOME,
    'End': KeyCode.END,
    'PageUp': KeyCode.PAGE_UP,
    'PageDown': KeyCode.PAGE_DOWN,
    'Insert': KeyCode.INSERT
  };

  /** Return a stream for KeyEvents for the specified target. */
  // Note: this actually functions like a factory constructor.
  CustomStream<KeyEvent> forTarget(EventTarget e, {bool useCapture: false}) {
    var handler =
        new _KeyboardEventHandler.initializeAllEventListeners(_type, e);
    return handler._stream;
  }

  /**
   * General constructor, performs basic initialization for our improved
   * KeyboardEvent controller.
   */
  _KeyboardEventHandler(this._type)
      : _stream = new _CustomKeyEventStreamImpl('event'),
        _target = null,
        super(_EVENT_TYPE);

  /**
   * Hook up all event listeners under the covers so we can estimate keycodes
   * and charcodes when they are not provided.
   */
  _KeyboardEventHandler.initializeAllEventListeners(this._type, this._target)
      : super(_EVENT_TYPE) {
    Element.keyDownEvent
        .forTarget(_target, useCapture: true)
        .listen(processKeyDown);
    Element.keyPressEvent
        .forTarget(_target, useCapture: true)
        .listen(processKeyPress);
    Element.keyUpEvent
        .forTarget(_target, useCapture: true)
        .listen(processKeyUp);
    _stream = new _CustomKeyEventStreamImpl(_type);
  }

  /** Determine if caps lock is one of the currently depressed keys. */
  bool get _capsLockOn =>
      _keyDownList.any((var element) => element.keyCode == KeyCode.CAPS_LOCK);

  /**
   * Given the previously recorded keydown key codes, see if we can determine
   * the keycode of this keypress [event]. (Generally browsers only provide
   * charCode information for keypress events, but with a little
   * reverse-engineering, we can also determine the keyCode.) Returns
   * KeyCode.UNKNOWN if the keycode could not be determined.
   */
  int _determineKeyCodeForKeypress(KeyboardEvent event) {
    // Note: This function is a work in progress. We'll expand this function
    // once we get more information about other keyboards.
    for (var prevEvent in _keyDownList) {
      if (prevEvent._shadowCharCode == event.charCode) {
        return prevEvent.keyCode;
      }
      if ((event.shiftKey || _capsLockOn) &&
          event.charCode >= "A".codeUnits[0] &&
          event.charCode <= "Z".codeUnits[0] &&
          event.charCode + _ROMAN_ALPHABET_OFFSET ==
              prevEvent._shadowCharCode) {
        return prevEvent.keyCode;
      }
    }
    return KeyCode.UNKNOWN;
  }

  /**
   * Given the character code returned from a keyDown [event], try to ascertain
   * and return the corresponding charCode for the character that was pressed.
   * This information is not shown to the user, but used to help polyfill
   * keypress events.
   */
  int _findCharCodeKeyDown(KeyboardEvent event) {
    if (event.location == 3) {
      // Numpad keys.
      switch (event.keyCode) {
        case KeyCode.NUM_ZERO:
          // Even though this function returns _charCodes_, for some cases the
          // KeyCode == the charCode we want, in which case we use the keycode
          // constant for readability.
          return KeyCode.ZERO;
        case KeyCode.NUM_ONE:
          return KeyCode.ONE;
        case KeyCode.NUM_TWO:
          return KeyCode.TWO;
        case KeyCode.NUM_THREE:
          return KeyCode.THREE;
        case KeyCode.NUM_FOUR:
          return KeyCode.FOUR;
        case KeyCode.NUM_FIVE:
          return KeyCode.FIVE;
        case KeyCode.NUM_SIX:
          return KeyCode.SIX;
        case KeyCode.NUM_SEVEN:
          return KeyCode.SEVEN;
        case KeyCode.NUM_EIGHT:
          return KeyCode.EIGHT;
        case KeyCode.NUM_NINE:
          return KeyCode.NINE;
        case KeyCode.NUM_MULTIPLY:
          return 42; // Char code for *
        case KeyCode.NUM_PLUS:
          return 43; // +
        case KeyCode.NUM_MINUS:
          return 45; // -
        case KeyCode.NUM_PERIOD:
          return 46; // .
        case KeyCode.NUM_DIVISION:
          return 47; // /
      }
    } else if (event.keyCode >= 65 && event.keyCode <= 90) {
      // Set the "char code" for key down as the lower case letter. Again, this
      // will not show up for the user, but will be helpful in estimating
      // keyCode locations and other information during the keyPress event.
      return event.keyCode + _ROMAN_ALPHABET_OFFSET;
    }
    switch (event.keyCode) {
      case KeyCode.SEMICOLON:
        return KeyCode.FF_SEMICOLON;
      case KeyCode.EQUALS:
        return KeyCode.FF_EQUALS;
      case KeyCode.COMMA:
        return 44; // Ascii value for ,
      case KeyCode.DASH:
        return 45; // -
      case KeyCode.PERIOD:
        return 46; // .
      case KeyCode.SLASH:
        return 47; // /
      case KeyCode.APOSTROPHE:
        return 96; // `
      case KeyCode.OPEN_SQUARE_BRACKET:
        return 91; // [
      case KeyCode.BACKSLASH:
        return 92; // \
      case KeyCode.CLOSE_SQUARE_BRACKET:
        return 93; // ]
      case KeyCode.SINGLE_QUOTE:
        return 39; // '
    }
    return event.keyCode;
  }

  /**
   * Returns true if the key fires a keypress event in the current browser.
   */
  bool _firesKeyPressEvent(KeyEvent event) {
    if (!Device.isIE && !Device.isWebKit) {
      return true;
    }

    if (Device.userAgent.contains('Mac') && event.altKey) {
      return KeyCode.isCharacterKey(event.keyCode);
    }

    // Alt but not AltGr which is represented as Alt+Ctrl.
    if (event.altKey && !event.ctrlKey) {
      return false;
    }

    // Saves Ctrl or Alt + key for IE and WebKit, which won't fire keypress.
    if (!event.shiftKey &&
        (_keyDownList.last.keyCode == KeyCode.CTRL ||
            _keyDownList.last.keyCode == KeyCode.ALT ||
            Device.userAgent.contains('Mac') &&
                _keyDownList.last.keyCode == KeyCode.META)) {
      return false;
    }

    // Some keys with Ctrl/Shift do not issue keypress in WebKit.
    if (Device.isWebKit &&
        event.ctrlKey &&
        event.shiftKey &&
        (event.keyCode == KeyCode.BACKSLASH ||
            event.keyCode == KeyCode.OPEN_SQUARE_BRACKET ||
            event.keyCode == KeyCode.CLOSE_SQUARE_BRACKET ||
            event.keyCode == KeyCode.TILDE ||
            event.keyCode == KeyCode.SEMICOLON ||
            event.keyCode == KeyCode.DASH ||
            event.keyCode == KeyCode.EQUALS ||
            event.keyCode == KeyCode.COMMA ||
            event.keyCode == KeyCode.PERIOD ||
            event.keyCode == KeyCode.SLASH ||
            event.keyCode == KeyCode.APOSTROPHE ||
            event.keyCode == KeyCode.SINGLE_QUOTE)) {
      return false;
    }

    switch (event.keyCode) {
      case KeyCode.ENTER:
        // IE9 does not fire keypress on ENTER.
        return !Device.isIE;
      case KeyCode.ESC:
        return !Device.isWebKit;
    }

    return KeyCode.isCharacterKey(event.keyCode);
  }

  /**
   * Normalize the keycodes to the IE KeyCodes (this is what Chrome, IE, and
   * Opera all use).
   */
  int _normalizeKeyCodes(KeyboardEvent event) {
    // Note: This may change once we get input about non-US keyboards.
    if (Device.isFirefox) {
      switch (event.keyCode) {
        case KeyCode.FF_EQUALS:
          return KeyCode.EQUALS;
        case KeyCode.FF_SEMICOLON:
          return KeyCode.SEMICOLON;
        case KeyCode.MAC_FF_META:
          return KeyCode.META;
        case KeyCode.WIN_KEY_FF_LINUX:
          return KeyCode.WIN_KEY;
      }
    }
    return event.keyCode;
  }

  /** Handle keydown events. */
  void processKeyDown(KeyboardEvent e) {
    // Ctrl-Tab and Alt-Tab can cause the focus to be moved to another window
    // before we've caught a key-up event.  If the last-key was one of these
    // we reset the state.
    if (_keyDownList.length > 0 &&
        (_keyDownList.last.keyCode == KeyCode.CTRL && !e.ctrlKey ||
            _keyDownList.last.keyCode == KeyCode.ALT && !e.altKey ||
            Device.userAgent.contains('Mac') &&
                _keyDownList.last.keyCode == KeyCode.META &&
                !e.metaKey)) {
      _keyDownList.clear();
    }

    var event = new KeyEvent.wrap(e);
    event._shadowKeyCode = _normalizeKeyCodes(event);
    // Technically a "keydown" event doesn't have a charCode. This is
    // calculated nonetheless to provide us with more information in giving
    // as much information as possible on keypress about keycode and also
    // charCode.
    event._shadowCharCode = _findCharCodeKeyDown(event);
    if (_keyDownList.length > 0 &&
        event.keyCode != _keyDownList.last.keyCode &&
        !_firesKeyPressEvent(event)) {
      // Some browsers have quirks not firing keypress events where all other
      // browsers do. This makes them more consistent.
      processKeyPress(e);
    }
    _keyDownList.add(event);
    _stream.add(event);
  }

  /** Handle keypress events. */
  void processKeyPress(KeyboardEvent event) {
    var e = new KeyEvent.wrap(event);
    // IE reports the character code in the keyCode field for keypress events.
    // There are two exceptions however, Enter and Escape.
    if (Device.isIE) {
      if (e.keyCode == KeyCode.ENTER || e.keyCode == KeyCode.ESC) {
        e._shadowCharCode = 0;
      } else {
        e._shadowCharCode = e.keyCode;
      }
    } else if (Device.isOpera) {
      // Opera reports the character code in the keyCode field.
      e._shadowCharCode = KeyCode.isCharacterKey(e.keyCode) ? e.keyCode : 0;
    }
    // Now we guesstimate about what the keycode is that was actually
    // pressed, given previous keydown information.
    e._shadowKeyCode = _determineKeyCodeForKeypress(e);

    // Correct the key value for certain browser-specific quirks.
    if (e._shadowKeyIdentifier != null &&
        _keyIdentifier.containsKey(e._shadowKeyIdentifier)) {
      // This is needed for Safari Windows because it currently doesn't give a
      // keyCode/which for non printable keys.
      e._shadowKeyCode = _keyIdentifier[e._shadowKeyIdentifier];
    }
    e._shadowAltKey = _keyDownList.any((var element) => element.altKey);
    _stream.add(e);
  }

  /** Handle keyup events. */
  void processKeyUp(KeyboardEvent event) {
    var e = new KeyEvent.wrap(event);
    KeyboardEvent toRemove = null;
    for (var key in _keyDownList) {
      if (key.keyCode == e.keyCode) {
        toRemove = key;
      }
    }
    if (toRemove != null) {
      _keyDownList.removeWhere((element) => element == toRemove);
    } else if (_keyDownList.length > 0) {
      // This happens when we've reached some international keyboard case we
      // haven't accounted for or we haven't correctly eliminated all browser
      // inconsistencies. Filing bugs on when this is reached is welcome!
      _keyDownList.removeLast();
    }
    _stream.add(e);
  }
}

/**
 * Records KeyboardEvents that occur on a particular element, and provides a
 * stream of outgoing KeyEvents with cross-browser consistent keyCode and
 * charCode values despite the fact that a multitude of browsers that have
 * varying keyboard default behavior.
 *
 * Example usage:
 *
 *     KeyboardEventStream.onKeyDown(document.body).listen(
 *         keydownHandlerTest);
 *
 * This class is very much a work in progress, and we'd love to get information
 * on how we can make this class work with as many international keyboards as
 * possible. Bugs welcome!
 */
class KeyboardEventStream {
  /** Named constructor to produce a stream for onKeyPress events. */
  static CustomStream<KeyEvent> onKeyPress(EventTarget target) =>
      new _KeyboardEventHandler('keypress').forTarget(target);

  /** Named constructor to produce a stream for onKeyUp events. */
  static CustomStream<KeyEvent> onKeyUp(EventTarget target) =>
      new _KeyboardEventHandler('keyup').forTarget(target);

  /** Named constructor to produce a stream for onKeyDown events. */
  static CustomStream<KeyEvent> onKeyDown(EventTarget target) =>
      new _KeyboardEventHandler('keydown').forTarget(target);
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Class which helps construct standard node validation policies.
 *
 * By default this will not accept anything, but the 'allow*' functions can be
 * used to expand what types of elements or attributes are allowed.
 *
 * All allow functions are additive- elements will be accepted if they are
 * accepted by any specific rule.
 *
 * It is important to remember that sanitization is not just intended to prevent
 * cross-site scripting attacks, but also to prevent information from being
 * displayed in unexpected ways. For example something displaying basic
 * formatted text may not expect `<video>` tags to appear. In this case an
 * empty NodeValidatorBuilder with just [allowTextElements] might be
 * appropriate.
 */
class NodeValidatorBuilder implements NodeValidator {
  final List<NodeValidator> _validators = <NodeValidator>[];

  NodeValidatorBuilder() {}

  /**
   * Creates a new NodeValidatorBuilder which accepts common constructs.
   *
   * By default this will accept HTML5 elements and attributes with the default
   * [UriPolicy] and templating elements.
   *
   * Notable syntax which is filtered:
   *
   * * Only known-good HTML5 elements and attributes are allowed.
   * * All URLs must be same-origin, use [allowNavigation] and [allowImages] to
   * specify additional URI policies.
   * * Inline-styles are not allowed.
   * * Custom element tags are disallowed, use [allowCustomElement].
   * * Custom tags extensions are disallowed, use [allowTagExtension].
   * * SVG Elements are not allowed, use [allowSvg].
   *
   * For scenarios where the HTML should only contain formatted text
   * [allowTextElements] is more appropriate.
   *
   * Use [allowSvg] to allow SVG elements.
   */
  NodeValidatorBuilder.common() {
    allowHtml5();
    allowTemplating();
  }

  /**
   * Allows navigation elements- Form and Anchor tags, along with common
   * attributes.
   *
   * The UriPolicy can be used to restrict the locations the navigation elements
   * are allowed to direct to. By default this will use the default [UriPolicy].
   */
  void allowNavigation([UriPolicy uriPolicy]) {
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }
    add(new _SimpleNodeValidator.allowNavigation(uriPolicy));
  }

  /**
   * Allows image elements.
   *
   * The UriPolicy can be used to restrict the locations the images may be
   * loaded from. By default this will use the default [UriPolicy].
   */
  void allowImages([UriPolicy uriPolicy]) {
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }
    add(new _SimpleNodeValidator.allowImages(uriPolicy));
  }

  /**
   * Allow basic text elements.
   *
   * This allows a subset of HTML5 elements, specifically just these tags and
   * no attributes.
   *
   * * B
   * * BLOCKQUOTE
   * * BR
   * * EM
   * * H1
   * * H2
   * * H3
   * * H4
   * * H5
   * * H6
   * * HR
   * * I
   * * LI
   * * OL
   * * P
   * * SPAN
   * * UL
   */
  void allowTextElements() {
    add(new _SimpleNodeValidator.allowTextElements());
  }

  /**
   * Allow inline styles on elements.
   *
   * If [tagName] is not specified then this allows inline styles on all
   * elements. Otherwise tagName limits the styles to the specified elements.
   */
  void allowInlineStyles({String tagName}) {
    if (tagName == null) {
      tagName = '*';
    } else {
      tagName = tagName.toUpperCase();
    }
    add(new _SimpleNodeValidator(null, allowedAttributes: ['$tagName::style']));
  }

  /**
   * Allow common safe HTML5 elements and attributes.
   *
   * This list is based off of the Caja whitelists at:
   * https://code.google.com/p/google-caja/wiki/CajaWhitelists.
   *
   * Common things which are not allowed are script elements, style attributes
   * and any script handlers.
   */
  void allowHtml5({UriPolicy uriPolicy}) {
    add(new _Html5NodeValidator(uriPolicy: uriPolicy));
  }

  /**
   * Allow SVG elements and attributes except for known bad ones.
   */
  void allowSvg() {
    add(new _SvgNodeValidator());
  }

  /**
   * Allow custom elements with the specified tag name and specified attributes.
   *
   * This will allow the elements as custom tags (such as <x-foo></x-foo>),
   * but will not allow tag extensions. Use [allowTagExtension] to allow
   * tag extensions.
   */
  void allowCustomElement(String tagName,
      {UriPolicy uriPolicy,
      Iterable<String> attributes,
      Iterable<String> uriAttributes}) {
    var tagNameUpper = tagName.toUpperCase();
    var attrs = attributes
        ?.map<String>((name) => '$tagNameUpper::${name.toLowerCase()}');
    var uriAttrs = uriAttributes
        ?.map<String>((name) => '$tagNameUpper::${name.toLowerCase()}');
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }

    add(new _CustomElementNodeValidator(
        uriPolicy, [tagNameUpper], attrs, uriAttrs, false, true));
  }

  /**
   * Allow custom tag extensions with the specified type name and specified
   * attributes.
   *
   * This will allow tag extensions (such as <div is="x-foo"></div>),
   * but will not allow custom tags. Use [allowCustomElement] to allow
   * custom tags.
   */
  void allowTagExtension(String tagName, String baseName,
      {UriPolicy uriPolicy,
      Iterable<String> attributes,
      Iterable<String> uriAttributes}) {
    var baseNameUpper = baseName.toUpperCase();
    var tagNameUpper = tagName.toUpperCase();
    var attrs = attributes
        ?.map<String>((name) => '$baseNameUpper::${name.toLowerCase()}');
    var uriAttrs = uriAttributes
        ?.map<String>((name) => '$baseNameUpper::${name.toLowerCase()}');
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }

    add(new _CustomElementNodeValidator(uriPolicy,
        [tagNameUpper, baseNameUpper], attrs, uriAttrs, true, false));
  }

  void allowElement(String tagName,
      {UriPolicy uriPolicy,
      Iterable<String> attributes,
      Iterable<String> uriAttributes}) {
    allowCustomElement(tagName,
        uriPolicy: uriPolicy,
        attributes: attributes,
        uriAttributes: uriAttributes);
  }

  /**
   * Allow templating elements (such as <template> and template-related
   * attributes.
   *
   * This still requires other validators to allow regular attributes to be
   * bound (such as [allowHtml5]).
   */
  void allowTemplating() {
    add(new _TemplatingNodeValidator());
  }

  /**
   * Add an additional validator to the current list of validators.
   *
   * Elements and attributes will be accepted if they are accepted by any
   * validators.
   */
  void add(NodeValidator validator) {
    _validators.add(validator);
  }

  bool allowsElement(Element element) {
    return _validators.any((v) => v.allowsElement(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    return _validators
        .any((v) => v.allowsAttribute(element, attributeName, value));
  }
}

class _SimpleNodeValidator implements NodeValidator {
  final Set<String> allowedElements = new Set<String>();
  final Set<String> allowedAttributes = new Set<String>();
  final Set<String> allowedUriAttributes = new Set<String>();
  final UriPolicy uriPolicy;

  factory _SimpleNodeValidator.allowNavigation(UriPolicy uriPolicy) {
    return new _SimpleNodeValidator(uriPolicy, allowedElements: const [
      'A',
      'FORM'
    ], allowedAttributes: const [
      'A::accesskey',
      'A::coords',
      'A::hreflang',
      'A::name',
      'A::shape',
      'A::tabindex',
      'A::target',
      'A::type',
      'FORM::accept',
      'FORM::autocomplete',
      'FORM::enctype',
      'FORM::method',
      'FORM::name',
      'FORM::novalidate',
      'FORM::target',
    ], allowedUriAttributes: const [
      'A::href',
      'FORM::action',
    ]);
  }

  factory _SimpleNodeValidator.allowImages(UriPolicy uriPolicy) {
    return new _SimpleNodeValidator(uriPolicy, allowedElements: const [
      'IMG'
    ], allowedAttributes: const [
      'IMG::align',
      'IMG::alt',
      'IMG::border',
      'IMG::height',
      'IMG::hspace',
      'IMG::ismap',
      'IMG::name',
      'IMG::usemap',
      'IMG::vspace',
      'IMG::width',
    ], allowedUriAttributes: const [
      'IMG::src',
    ]);
  }

  factory _SimpleNodeValidator.allowTextElements() {
    return new _SimpleNodeValidator(null, allowedElements: const [
      'B',
      'BLOCKQUOTE',
      'BR',
      'EM',
      'H1',
      'H2',
      'H3',
      'H4',
      'H5',
      'H6',
      'HR',
      'I',
      'LI',
      'OL',
      'P',
      'SPAN',
      'UL',
    ]);
  }

  /**
   * Elements must be uppercased tag names. For example `'IMG'`.
   * Attributes must be uppercased tag name followed by :: followed by
   * lowercase attribute name. For example `'IMG:src'`.
   */
  _SimpleNodeValidator(this.uriPolicy,
      {Iterable<String> allowedElements,
      Iterable<String> allowedAttributes,
      Iterable<String> allowedUriAttributes}) {
    this.allowedElements.addAll(allowedElements ?? const []);
    allowedAttributes = allowedAttributes ?? const [];
    allowedUriAttributes = allowedUriAttributes ?? const [];
    var legalAttributes = allowedAttributes
        .where((x) => !_Html5NodeValidator._uriAttributes.contains(x));
    var extraUriAttributes = allowedAttributes
        .where((x) => _Html5NodeValidator._uriAttributes.contains(x));
    this.allowedAttributes.addAll(legalAttributes);
    this.allowedUriAttributes.addAll(allowedUriAttributes);
    this.allowedUriAttributes.addAll(extraUriAttributes);
  }

  bool allowsElement(Element element) {
    return allowedElements.contains(Element._safeTagName(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    var tagName = Element._safeTagName(element);
    if (allowedUriAttributes.contains('$tagName::$attributeName')) {
      return uriPolicy.allowsUri(value);
    } else if (allowedUriAttributes.contains('*::$attributeName')) {
      return uriPolicy.allowsUri(value);
    } else if (allowedAttributes.contains('$tagName::$attributeName')) {
      return true;
    } else if (allowedAttributes.contains('*::$attributeName')) {
      return true;
    } else if (allowedAttributes.contains('$tagName::*')) {
      return true;
    } else if (allowedAttributes.contains('*::*')) {
      return true;
    }
    return false;
  }
}

class _CustomElementNodeValidator extends _SimpleNodeValidator {
  final bool allowTypeExtension;
  final bool allowCustomTag;

  _CustomElementNodeValidator(
      UriPolicy uriPolicy,
      Iterable<String> allowedElements,
      Iterable<String> allowedAttributes,
      Iterable<String> allowedUriAttributes,
      bool allowTypeExtension,
      bool allowCustomTag)
      : this.allowTypeExtension = allowTypeExtension == true,
        this.allowCustomTag = allowCustomTag == true,
        super(uriPolicy,
            allowedElements: allowedElements,
            allowedAttributes: allowedAttributes,
            allowedUriAttributes: allowedUriAttributes);

  bool allowsElement(Element element) {
    if (allowTypeExtension) {
      var isAttr = element.attributes['is'];
      if (isAttr != null) {
        return allowedElements.contains(isAttr.toUpperCase()) &&
            allowedElements.contains(Element._safeTagName(element));
      }
    }
    return allowCustomTag &&
        allowedElements.contains(Element._safeTagName(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (allowsElement(element)) {
      if (allowTypeExtension &&
          attributeName == 'is' &&
          allowedElements.contains(value.toUpperCase())) {
        return true;
      }
      return super.allowsAttribute(element, attributeName, value);
    }
    return false;
  }
}

class _TemplatingNodeValidator extends _SimpleNodeValidator {
  static const _TEMPLATE_ATTRS = const <String>[
    'bind',
    'if',
    'ref',
    'repeat',
    'syntax'
  ];

  final Set<String> _templateAttrs;

  _TemplatingNodeValidator()
      : _templateAttrs = new Set<String>.from(_TEMPLATE_ATTRS),
        super(null,
            allowedElements: ['TEMPLATE'],
            allowedAttributes:
                _TEMPLATE_ATTRS.map((attr) => 'TEMPLATE::$attr')) {}

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (super.allowsAttribute(element, attributeName, value)) {
      return true;
    }

    if (attributeName == 'template' && value == "") {
      return true;
    }

    if (element.attributes['template'] == "") {
      return _templateAttrs.contains(attributeName);
    }
    return false;
  }
}

class _SvgNodeValidator implements NodeValidator {
  bool allowsElement(Element element) {
    if (element is svg.ScriptElement) {
      return false;
    }
    // Firefox 37 has issues with creating foreign elements inside a
    // foreignobject tag as SvgElement. We don't want foreignobject contents
    // anyway, so just remove the whole tree outright. And we can't rely
    // on IE recognizing the SvgForeignObject type, so go by tagName. Bug 23144
    if (element is svg.SvgElement &&
        Element._safeTagName(element) == 'foreignObject') {
      return false;
    }
    if (element is svg.SvgElement) {
      return true;
    }
    return false;
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (attributeName == 'is' || attributeName.startsWith('on')) {
      return false;
    }
    return allowsElement(element);
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Contains the set of standard values returned by HTMLDocument.getReadyState.
 */
abstract class ReadyState {
  /**
   * Indicates the document is still loading and parsing.
   */
  static const String LOADING = "loading";

  /**
   * Indicates the document is finished parsing but is still loading
   * subresources.
   */
  static const String INTERACTIVE = "interactive";

  /**
   * Indicates the document and all subresources have been loaded.
   */
  static const String COMPLETE = "complete";
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * A list which just wraps another list, for either intercepting list calls or
 * retyping the list (for example, from List<A> to List<B> where B extends A).
 */
class _WrappedList<E extends Node> extends ListBase<E>
    implements NodeListWrapper {
  final List<Node> _list;

  _WrappedList(this._list);

  // Iterable APIs

  Iterator<E> get iterator => new _WrappedIterator<E>(_list.iterator);

  int get length => _list.length;

  // Collection APIs

  void add(E element) {
    _list.add(element);
  }

  bool remove(Object element) => _list.remove(element);

  void clear() {
    _list.clear();
  }

  // List APIs

  E operator [](int index) => _list[index];

  void operator []=(int index, E value) {
    _list[index] = value;
  }

  set length(int newLength) {
    _list.length = newLength;
  }

  void sort([int compare(E a, E b)]) {
    // Implicit downcast on argument from Node to E-extends-Node.
    _list.sort((Node a, Node b) => compare(a, b));
  }

  int indexOf(Object element, [int start = 0]) => _list.indexOf(element, start);

  int lastIndexOf(Object element, [int start]) =>
      _list.lastIndexOf(element, start);

  void insert(int index, E element) => _list.insert(index, element);

  E removeAt(int index) => _list.removeAt(index);

  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
    _list.setRange(start, end, iterable, skipCount);
  }

  void removeRange(int start, int end) {
    _list.removeRange(start, end);
  }

  void replaceRange(int start, int end, Iterable<E> iterable) {
    _list.replaceRange(start, end, iterable);
  }

  void fillRange(int start, int end, [E fillValue]) {
    _list.fillRange(start, end, fillValue);
  }

  List<Node> get rawList => _list;
}

/**
 * Iterator wrapper for _WrappedList.
 */
class _WrappedIterator<E extends Node> implements Iterator<E> {
  Iterator<Node> _iterator;

  _WrappedIterator(this._iterator);

  bool moveNext() {
    return _iterator.moveNext();
  }

  E get current => _iterator.current;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

class _HttpRequestUtils {
  // Helper for factory HttpRequest.get
  static HttpRequest get(
      String url, onComplete(HttpRequest request), bool withCredentials) {
    final request = new HttpRequest();
    request.open('GET', url, async: true);

    request.withCredentials = withCredentials;

    request.onReadyStateChange.listen((e) {
      if (request.readyState == HttpRequest.DONE) {
        onComplete(request);
      }
    });

    request.send();

    return request;
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Iterator for arrays with fixed size.
class FixedSizeListIterator<T> implements Iterator<T> {
  final List<T> _array;
  final int _length; // Cache array length for faster access.
  int _position;
  T _current;

  FixedSizeListIterator(List<T> array)
      : _array = array,
        _position = -1,
        _length = array.length;

  bool moveNext() {
    int nextPosition = _position + 1;
    if (nextPosition < _length) {
      _current = _array[nextPosition];
      _position = nextPosition;
      return true;
    }
    _current = null;
    _position = _length;
    return false;
  }

  T get current => _current;
}

// Iterator for arrays with variable size.
class _VariableSizeListIterator<T> implements Iterator<T> {
  final List<T> _array;
  int _position;
  T _current;

  _VariableSizeListIterator(List<T> array)
      : _array = array,
        _position = -1;

  bool moveNext() {
    int nextPosition = _position + 1;
    if (nextPosition < _array.length) {
      _current = _array[nextPosition];
      _position = nextPosition;
      return true;
    }
    _current = null;
    _position = _array.length;
    return false;
  }

  T get current => _current;
}
// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

class Console {
  const Console._safe();
  static const Console _safeConsole = const Console._safe();

  bool get _isConsoleDefined => JS('bool', 'typeof console != "undefined"');

  MemoryInfo get memory =>
      _isConsoleDefined ? JS('MemoryInfo', 'window.console.memory') : null;

  void assertCondition(bool condition, Object arg) => _isConsoleDefined
      ? JS('void', 'window.console.assertCondition(#, #)', condition, arg)
      : null;

  void clear(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.clear(#)', arg) : null;

  void count(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.count(#)', arg) : null;

  void debug(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.debug(#)', arg) : null;

  void dir(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.dir(#)', arg) : null;

  void dirxml(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.dirxml(#)', arg) : null;

  void error(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.error(#)', arg) : null;

  void group(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.group(#)', arg) : null;

  void groupCollapsed(Object arg) => _isConsoleDefined
      ? JS('void', 'window.console.groupCollapsed(#)', arg)
      : null;

  void groupEnd() =>
      _isConsoleDefined ? JS('void', 'window.console.groupEnd()') : null;

  void info(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.info(#)', arg) : null;

  void log(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.log(#)', arg) : null;

  void markTimeline(Object arg) => _isConsoleDefined
      ? JS('void', 'window.console.markTimeline(#)', arg)
      : null;

  void profile(String title) =>
      _isConsoleDefined ? JS('void', 'window.console.profile(#)', title) : null;

  void profileEnd(String title) => _isConsoleDefined
      ? JS('void', 'window.console.profileEnd(#)', title)
      : null;

  void table(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.table(#)', arg) : null;

  void time(String title) =>
      _isConsoleDefined ? JS('void', 'window.console.time(#)', title) : null;

  void timeEnd(String title) =>
      _isConsoleDefined ? JS('void', 'window.console.timeEnd(#)', title) : null;

  void timeStamp(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.timeStamp(#)', arg) : null;

  void trace(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.trace(#)', arg) : null;

  void warn(Object arg) =>
      _isConsoleDefined ? JS('void', 'window.console.warn(#)', arg) : null;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Conversions for Window.  These check if the window is the local
// window, and if it's not, wraps or unwraps it with a secure wrapper.
// We need to test for EventTarget here as well as it's a base type.
// We omit an unwrapper for Window as no methods take a non-local
// window as a parameter.

WindowBase _convertNativeToDart_Window(win) {
  if (win == null) return null;
  return _DOMWindowCrossFrame._createSafe(win);
}

EventTarget _convertNativeToDart_EventTarget(e) {
  if (e == null) {
    return null;
  }
  // Assume it's a Window if it contains the postMessage property.  It may be
  // from a different frame - without a patched prototype - so we cannot
  // rely on Dart type checking.
  if (JS('bool', r'"postMessage" in #', e)) {
    var window = _DOMWindowCrossFrame._createSafe(e);
    // If it's a native window.
    if (window is EventTarget) {
      return window;
    }
    return null;
  } else
    return e;
}

EventTarget _convertDartToNative_EventTarget(e) {
  if (e is _DOMWindowCrossFrame) {
    return e._window;
  } else {
    return e;
  }
}

_convertNativeToDart_XHR_Response(o) {
  if (o is Document) {
    return o;
  }
  return convertNativeToDart_SerializedScriptValue(o);
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

_callConstructor(constructor, interceptor) {
  return (receiver) {
    setNativeSubclassDispatchRecord(receiver, interceptor);

    // Mirrors uses the constructor property to cache lookups, so we need it to
    // be set correctly, including on IE where it is not automatically picked
    // up from the __proto__.
    JS('', '#.constructor = #.__proto__.constructor', receiver, receiver);
    return JS('', '#(#)', constructor, receiver);
  };
}

_callAttached(receiver) {
  return receiver.attached();
}

_callDetached(receiver) {
  return receiver.detached();
}

_callAttributeChanged(receiver, name, oldValue, newValue) {
  return receiver.attributeChanged(name, oldValue, newValue);
}

_makeCallbackMethod(callback) {
  return JS(
      '',
      '''((function(invokeCallback) {
             return function() {
               return invokeCallback(this);
             };
          })(#))''',
      convertDartClosureToJS(callback, 1));
}

_makeCallbackMethod3(callback) {
  return JS(
      '',
      '''((function(invokeCallback) {
             return function(arg1, arg2, arg3) {
               return invokeCallback(this, arg1, arg2, arg3);
             };
          })(#))''',
      convertDartClosureToJS(callback, 4));
}

/// Checks whether the given [element] correctly extends from the native class
/// with the given [baseClassName]. This method will throw if the base class
/// doesn't match, except when the element extends from `template` and it's base
/// class is `HTMLUnknownElement`. This exclusion is needed to support extension
/// of template elements (used heavily in Polymer 1.0) on IE11 when using the
/// webcomponents-lite.js polyfill.
void _checkExtendsNativeClassOrTemplate(
    Element element, String extendsTag, String baseClassName) {
  if (!JS('bool', '(# instanceof window[#])', element, baseClassName) &&
      !((extendsTag == 'template' &&
          JS('bool', '(# instanceof window["HTMLUnknownElement"])',
              element)))) {
    throw new UnsupportedError('extendsTag does not match base native class');
  }
}

Function _registerCustomElement(context, document, String tag, [Map options]) {
  // Function follows the same pattern as the following JavaScript code for
  // registering a custom element.
  //
  //    var proto = Object.create(HTMLElement.prototype, {
  //        createdCallback: {
  //          value: function() {
  //            window.console.log('here');
  //          }
  //        }
  //    });
  //    document.registerElement('x-foo', { prototype: proto });
  //    ...
  //    var e = document.createElement('x-foo');

  var extendsTagName = '';
  Type type;
  if (options != null) {
    extendsTagName = options['extends'];
    type = options['prototype'];
  }

  var interceptorClass = findInterceptorConstructorForType(type);
  if (interceptorClass == null) {
    throw new ArgumentError(type);
  }

  var interceptor = JS('=Object', '#.prototype', interceptorClass);

  var constructor = findConstructorForNativeSubclassType(type, 'created');
  if (constructor == null) {
    throw new ArgumentError("$type has no constructor called 'created'");
  }

  // Workaround for 13190- use an article element to ensure that HTMLElement's
  // interceptor is resolved correctly.
  getNativeInterceptor(new Element.tag('article'));

  String baseClassName = findDispatchTagForInterceptorClass(interceptorClass);
  if (baseClassName == null) {
    throw new ArgumentError(type);
  }

  if (extendsTagName == null) {
    if (baseClassName != 'HTMLElement') {
      throw new UnsupportedError('Class must provide extendsTag if base '
          'native class is not HtmlElement');
    }
  } else {
    var element = document.createElement(extendsTagName);
    _checkExtendsNativeClassOrTemplate(element, extendsTagName, baseClassName);
  }

  var baseConstructor = JS('=Object', '#[#]', context, baseClassName);

  var properties = JS('=Object', '{}');

  JS(
      'void',
      '#.createdCallback = #',
      properties,
      JS('=Object', '{value: #}',
          _makeCallbackMethod(_callConstructor(constructor, interceptor))));
  JS('void', '#.attachedCallback = #', properties,
      JS('=Object', '{value: #}', _makeCallbackMethod(_callAttached)));
  JS('void', '#.detachedCallback = #', properties,
      JS('=Object', '{value: #}', _makeCallbackMethod(_callDetached)));
  JS('void', '#.attributeChangedCallback = #', properties,
      JS('=Object', '{value: #}', _makeCallbackMethod3(_callAttributeChanged)));

  var baseProto = JS('=Object', '#.prototype', baseConstructor);
  var proto = JS('=Object', 'Object.create(#, #)', baseProto, properties);

  setNativeSubclassDispatchRecord(proto, interceptor);

  var opts = JS('=Object', '{prototype: #}', proto);

  if (extendsTagName != null) {
    JS('=Object', '#.extends = #', opts, extendsTagName);
  }

  return JS(
      'JavaScriptFunction', '#.registerElement(#, #)', document, tag, opts);
}

//// Called by Element.created to do validation & initialization.
void _initializeCustomElement(Element e) {
  // TODO(blois): Add validation that this is only in response to an upgrade.
}

/// Dart2JS implementation of ElementUpgrader
class _JSElementUpgrader implements ElementUpgrader {
  var _interceptor;
  var _constructor;
  var _nativeType;

  _JSElementUpgrader(Document document, Type type, String extendsTag) {
    var interceptorClass = findInterceptorConstructorForType(type);
    if (interceptorClass == null) {
      throw new ArgumentError(type);
    }

    _constructor = findConstructorForNativeSubclassType(type, 'created');
    if (_constructor == null) {
      throw new ArgumentError("$type has no constructor called 'created'");
    }

    // Workaround for 13190- use an article element to ensure that HTMLElement's
    // interceptor is resolved correctly.
    getNativeInterceptor(new Element.tag('article'));

    var baseClassName = findDispatchTagForInterceptorClass(interceptorClass);
    if (baseClassName == null) {
      throw new ArgumentError(type);
    }

    if (extendsTag == null) {
      if (baseClassName != 'HTMLElement') {
        throw new UnsupportedError('Class must provide extendsTag if base '
            'native class is not HtmlElement');
      }
      _nativeType = HtmlElement;
    } else {
      var element = document.createElement(extendsTag);
      _checkExtendsNativeClassOrTemplate(element, extendsTag, baseClassName);
      _nativeType = element.runtimeType;
    }

    _interceptor = JS('=Object', '#.prototype', interceptorClass);
  }

  Element upgrade(Element element) {
    // Only exact type matches are supported- cannot be a subclass.
    if (element.runtimeType != _nativeType) {
      // Some browsers may represent non-upgraded elements <x-foo> as
      // UnknownElement and not a plain HtmlElement.
      if (_nativeType != HtmlElement || element.runtimeType != UnknownElement) {
        throw new ArgumentError('element is not subclass of $_nativeType');
      }
    }

    setNativeSubclassDispatchRecord(element, _interceptor);
    JS('', '#(#)', _constructor, element);
    return element;
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// TODO(vsm): Unify with Dartium version.
class _DOMWindowCrossFrame implements WindowBase {
  // Private window.  Note, this is a window in another frame, so it
  // cannot be typed as "Window" as its prototype is not patched
  // properly.  Its fields and methods can only be accessed via JavaScript.
  final _window;

  // Fields.
  HistoryBase get history =>
      _HistoryCrossFrame._createSafe(JS('HistoryBase', '#.history', _window));
  LocationBase get location => _LocationCrossFrame._createSafe(
      JS('LocationBase', '#.location', _window));

  // TODO(vsm): Add frames to navigate subframes.  See 2312.

  bool get closed => JS('bool', '#.closed', _window);

  WindowBase get opener => _createSafe(JS('WindowBase', '#.opener', _window));

  WindowBase get parent => _createSafe(JS('WindowBase', '#.parent', _window));

  WindowBase get top => _createSafe(JS('WindowBase', '#.top', _window));

  // Methods.
  void close() => JS('void', '#.close()', _window);

  void postMessage(var message, String targetOrigin,
      [List messagePorts = null]) {
    if (messagePorts == null) {
      JS('void', '#.postMessage(#,#)', _window,
          convertDartToNative_SerializedScriptValue(message), targetOrigin);
    } else {
      JS(
          'void',
          '#.postMessage(#,#,#)',
          _window,
          convertDartToNative_SerializedScriptValue(message),
          targetOrigin,
          messagePorts);
    }
  }

  // Implementation support.
  _DOMWindowCrossFrame(this._window);

  static WindowBase _createSafe(w) {
    if (identical(w, window)) {
      return w;
    } else {
      // TODO(vsm): Cache or implement equality.
      registerGlobalObject(w);
      return new _DOMWindowCrossFrame(w);
    }
  }

  // TODO(efortuna): Remove this method. dartbug.com/16814
  Events get on => throw new UnsupportedError(
      'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void _addEventListener(String type, EventListener listener,
          [bool useCapture]) =>
      throw new UnsupportedError(
          'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void addEventListener(String type, EventListener listener,
          [bool useCapture]) =>
      throw new UnsupportedError(
          'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  bool dispatchEvent(Event event) => throw new UnsupportedError(
      'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void _removeEventListener(String type, EventListener listener,
          [bool useCapture]) =>
      throw new UnsupportedError(
          'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void removeEventListener(String type, EventListener listener,
          [bool useCapture]) =>
      throw new UnsupportedError(
          'You can only attach EventListeners to your own window.');
}

class _LocationCrossFrame implements LocationBase {
  // Private location.  Note, this is a location object in another frame, so it
  // cannot be typed as "Location" as its prototype is not patched
  // properly.  Its fields and methods can only be accessed via JavaScript.
  var _location;

  set href(String val) => _setHref(_location, val);
  static void _setHref(location, val) {
    JS('void', '#.href = #', location, val);
  }

  // Implementation support.
  _LocationCrossFrame(this._location);

  static LocationBase _createSafe(location) {
    if (identical(location, window.location)) {
      return location;
    } else {
      // TODO(vsm): Cache or implement equality.
      return new _LocationCrossFrame(location);
    }
  }
}

class _HistoryCrossFrame implements HistoryBase {
  // Private history.  Note, this is a history object in another frame, so it
  // cannot be typed as "History" as its prototype is not patched
  // properly.  Its fields and methods can only be accessed via JavaScript.
  var _history;

  void back() => JS('void', '#.back()', _history);

  void forward() => JS('void', '#.forward()', _history);

  void go(int distance) => JS('void', '#.go(#)', _history, distance);

  // Implementation support.
  _HistoryCrossFrame(this._history);

  static HistoryBase _createSafe(h) {
    if (identical(h, window.history)) {
      return h;
    } else {
      // TODO(vsm): Cache or implement equality.
      return new _HistoryCrossFrame(h);
    }
  }
}

/**
 * A custom KeyboardEvent that attempts to eliminate cross-browser
 * inconsistencies, and also provide both keyCode and charCode information
 * for all key events (when such information can be determined).
 *
 * KeyEvent tries to provide a higher level, more polished keyboard event
 * information on top of the "raw" [KeyboardEvent].
 *
 * The mechanics of using KeyEvents is a little different from the underlying
 * [KeyboardEvent]. To use KeyEvents, you need to create a stream and then add
 * KeyEvents to the stream, rather than using the [EventTarget.dispatchEvent].
 * Here's an example usage:
 *
 *     // Initialize a stream for the KeyEvents:
 *     var stream = KeyEvent.keyPressEvent.forTarget(document.body);
 *     // Start listening to the stream of KeyEvents.
 *     stream.listen((keyEvent) =>
 *         window.console.log('KeyPress event detected ${keyEvent.charCode}'));
 *     ...
 *     // Add a new KeyEvent of someone pressing the 'A' key to the stream so
 *     // listeners can know a KeyEvent happened.
 *     stream.add(new KeyEvent('keypress', keyCode: 65, charCode: 97));
 *
 * This class is very much a work in progress, and we'd love to get information
 * on how we can make this class work with as many international keyboards as
 * possible. Bugs welcome!
 */
class KeyEvent extends _WrappedEvent implements KeyboardEvent {
  /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */
  KeyboardEvent _parent;

  /** The "fixed" value of whether the alt key is being pressed. */
  bool _shadowAltKey;

  /** Calculated value of what the estimated charCode is for this event. */
  int _shadowCharCode;

  /** Calculated value of what the estimated keyCode is for this event. */
  int _shadowKeyCode;

  /** Calculated value of what the estimated keyCode is for this event. */
  int get keyCode => _shadowKeyCode;

  /** Calculated value of what the estimated charCode is for this event. */
  int get charCode => this.type == 'keypress' ? _shadowCharCode : 0;

  /** Calculated value of whether the alt key is pressed is for this event. */
  bool get altKey => _shadowAltKey;

  /** Calculated value of what the estimated keyCode is for this event. */
  int get which => keyCode;

  /** Accessor to the underlying keyCode value is the parent event. */
  int get _realKeyCode => JS('int', '#.keyCode', _parent);

  /** Accessor to the underlying charCode value is the parent event. */
  int get _realCharCode => JS('int', '#.charCode', _parent);

  /** Accessor to the underlying altKey value is the parent event. */
  bool get _realAltKey => JS('bool', '#.altKey', _parent);

  /** Shadows on top of the parent's currentTarget. */
  EventTarget _currentTarget;

  final InputDeviceCapabilities sourceCapabilities;

  /**
   * The value we want to use for this object's dispatch. Created here so it is
   * only invoked once.
   */
  static final _keyboardEventDispatchRecord = _makeRecord();

  /** Helper to statically create the dispatch record. */
  static _makeRecord() {
    var interceptor = JS_INTERCEPTOR_CONSTANT(KeyboardEvent);
    return makeLeafDispatchRecord(interceptor);
  }

  /** Construct a KeyEvent with [parent] as the event we're emulating. */
  KeyEvent.wrap(KeyboardEvent parent) : super(parent) {
    _parent = parent;
    _shadowAltKey = _realAltKey;
    _shadowCharCode = _realCharCode;
    _shadowKeyCode = _realKeyCode;
    _currentTarget = _parent.currentTarget;
  }

  /** Programmatically create a new KeyEvent (and KeyboardEvent). */
  factory KeyEvent(String type,
      {Window view,
      bool canBubble: true,
      bool cancelable: true,
      int keyCode: 0,
      int charCode: 0,
      int location: 1,
      bool ctrlKey: false,
      bool altKey: false,
      bool shiftKey: false,
      bool metaKey: false,
      EventTarget currentTarget}) {
    if (view == null) {
      view = window;
    }

    var eventObj;

    // Currently this works on everything but Safari. Safari throws an
    // "Attempting to change access mechanism for an unconfigurable property"
    // TypeError when trying to do the Object.defineProperty hack, so we avoid
    // this branch if possible.
    // Also, if we want this branch to work in FF, we also need to modify
    // _initKeyboardEvent to also take charCode and keyCode values to
    // initialize initKeyEvent.

    eventObj = new Event.eventType('KeyboardEvent', type,
        canBubble: canBubble, cancelable: cancelable);

    // Chromium Hack
    JS(
        'void',
        "Object.defineProperty(#, 'keyCode', {"
        "  get : function() { return this.keyCodeVal; } })",
        eventObj);
    JS(
        'void',
        "Object.defineProperty(#, 'which', {"
        "  get : function() { return this.keyCodeVal; } })",
        eventObj);
    JS(
        'void',
        "Object.defineProperty(#, 'charCode', {"
        "  get : function() { return this.charCodeVal; } })",
        eventObj);

    var keyIdentifier = _convertToHexString(charCode, keyCode);
    eventObj._initKeyboardEvent(type, canBubble, cancelable, view,
        keyIdentifier, location, ctrlKey, altKey, shiftKey, metaKey);
    JS('void', '#.keyCodeVal = #', eventObj, keyCode);
    JS('void', '#.charCodeVal = #', eventObj, charCode);

    // Tell dart2js that it smells like a KeyboardEvent!
    setDispatchProperty(eventObj, _keyboardEventDispatchRecord);

    var keyEvent = new KeyEvent.wrap(eventObj);
    if (keyEvent._currentTarget == null) {
      keyEvent._currentTarget = currentTarget == null ? window : currentTarget;
    }
    return keyEvent;
  }

  // Currently known to work on all browsers but IE.
  static bool get canUseDispatchEvent => JS(
      'bool',
      '(typeof document.body.dispatchEvent == "function")'
      '&& document.body.dispatchEvent.length > 0');

  /** The currently registered target for this event. */
  EventTarget get currentTarget => _currentTarget;

  // This is an experimental method to be sure.
  static String _convertToHexString(int charCode, int keyCode) {
    if (charCode != -1) {
      var hex = charCode.toRadixString(16); // Convert to hexadecimal.
      StringBuffer sb = new StringBuffer('U+');
      for (int i = 0; i < 4 - hex.length; i++) sb.write('0');
      sb.write(hex);
      return sb.toString();
    } else {
      return KeyCode._convertKeyCodeToKeyName(keyCode);
    }
  }

  // TODO(efortuna): If KeyEvent is sufficiently successful that we want to make
  // it the default keyboard event handling, move these methods over to Element.
  /** Accessor to provide a stream of KeyEvents on the desired target. */
  static EventStreamProvider<KeyEvent> keyDownEvent =
      new _KeyboardEventHandler('keydown');
  /** Accessor to provide a stream of KeyEvents on the desired target. */
  static EventStreamProvider<KeyEvent> keyUpEvent =
      new _KeyboardEventHandler('keyup');
  /** Accessor to provide a stream of KeyEvents on the desired target. */
  static EventStreamProvider<KeyEvent> keyPressEvent =
      new _KeyboardEventHandler('keypress');

  String get code => _parent.code;
  /** True if the ctrl key is pressed during this event. */
  bool get ctrlKey => _parent.ctrlKey;
  int get detail => _parent.detail;
  bool get isComposing => _parent.isComposing;
  String get key => _parent.key;
  /**
   * Accessor to the part of the keyboard that the key was pressed from (one of
   * KeyLocation.STANDARD, KeyLocation.RIGHT, KeyLocation.LEFT,
   * KeyLocation.NUMPAD, KeyLocation.MOBILE, KeyLocation.JOYSTICK).
   */
  int get location => _parent.location;
  /** True if the Meta (or Mac command) key is pressed during this event. */
  bool get metaKey => _parent.metaKey;
  /** True if the shift key was pressed during this event. */
  bool get shiftKey => _parent.shiftKey;
  Window get view => _parent.view;
  void _initUIEvent(
      String type, bool canBubble, bool cancelable, Window view, int detail) {
    throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
  }

  String get _shadowKeyIdentifier => JS('String', '#.keyIdentifier', _parent);

  int get _charCode => charCode;
  int get _keyCode => keyCode;
  int get _which => which;

  String get _keyIdentifier {
    throw new UnsupportedError("keyIdentifier is unsupported.");
  }

  void _initKeyboardEvent(
      String type,
      bool canBubble,
      bool cancelable,
      Window view,
      String keyIdentifier,
      int location,
      bool ctrlKey,
      bool altKey,
      bool shiftKey,
      bool metaKey) {
    throw new UnsupportedError(
        "Cannot initialize a KeyboardEvent from a KeyEvent.");
  }

  bool getModifierState(String keyArgument) => throw new UnimplementedError();

  bool get repeat => throw new UnimplementedError();
  bool get isComposed => throw new UnimplementedError();
  dynamic get _get_view => throw new UnimplementedError();
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

class Platform {
  /**
   * Returns true if dart:typed_data types are supported on this
   * browser.  If false, using these types will generate a runtime
   * error.
   */
  static final supportsTypedData = JS('bool', '!!(window.ArrayBuffer)');

  /**
   * Returns true if SIMD types in dart:typed_data types are supported
   * on this browser.  If false, using these types will generate a runtime
   * error.
   */
  static final supportsSimd = false;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Helper class to implement custom events which wrap DOM events.
 */
class _WrappedEvent implements Event {
  final Event wrapped;

  /** The CSS selector involved with event delegation. */
  String _selector;

  _WrappedEvent(this.wrapped);

  bool get bubbles => wrapped.bubbles;

  bool get cancelable => wrapped.cancelable;

  bool get composed => wrapped.composed;

  EventTarget get currentTarget => wrapped.currentTarget;

  bool get defaultPrevented => wrapped.defaultPrevented;

  int get eventPhase => wrapped.eventPhase;

  bool get isTrusted => wrapped.isTrusted;

  EventTarget get target => wrapped.target;

  double get timeStamp => wrapped.timeStamp;

  String get type => wrapped.type;

  void _initEvent(String type, [bool bubbles, bool cancelable]) {
    throw new UnsupportedError('Cannot initialize this Event.');
  }

  void preventDefault() {
    wrapped.preventDefault();
  }

  void stopImmediatePropagation() {
    wrapped.stopImmediatePropagation();
  }

  void stopPropagation() {
    wrapped.stopPropagation();
  }

  List<EventTarget> composedPath() => wrapped.composedPath();

  /**
   * A pointer to the element whose CSS selector matched within which an event
   * was fired. If this Event was not associated with any Event delegation,
   * accessing this value will throw an [UnsupportedError].
   */
  Element get matchingTarget {
    if (_selector == null) {
      throw new UnsupportedError('Cannot call matchingTarget if this Event did'
          ' not arise as a result of event delegation.');
    }
    Element currentTarget = this.currentTarget;
    Element target = this.target;
    var matchedTarget;
    do {
      if (target.matches(_selector)) return target;
      target = target.parent;
    } while (target != null && target != currentTarget.parent);
    throw new StateError('No selector matched for populating matchedTarget.');
  }

  /**
   * This event's path, taking into account shadow DOM.
   *
   * ## Other resources
   *
   * * [Shadow DOM extensions to
   *   Event](http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event)
   *   from W3C.
   */
  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event
  List<Node> get path => wrapped.path;

  dynamic get _get_currentTarget => wrapped._get_currentTarget;

  dynamic get _get_target => wrapped._get_target;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

void Function(T) _wrapZone<T>(void Function(T) callback) {
  // For performance reasons avoid wrapping if we are in the root zone.
  if (Zone.current == Zone.root) return callback;
  if (callback == null) return null;
  return Zone.current.bindUnaryCallbackGuarded(callback);
}

void Function(T1, T2) _wrapBinaryZone<T1, T2>(void Function(T1, T2) callback) {
  // For performance reasons avoid wrapping if we are in the root zone.
  if (Zone.current == Zone.root) return callback;
  if (callback == null) return null;
  return Zone.current.bindBinaryCallbackGuarded(callback);
}

/**
 * Finds the first descendant element of this document that matches the
 * specified group of selectors.
 *
 * Unless your webpage contains multiple documents, the top-level
 * [querySelector]
 * method behaves the same as this method, so you should use it instead to
 * save typing a few characters.
 *
 * [selectors] should be a string using CSS selector syntax.
 *
 *     var element1 = document.querySelector('.className');
 *     var element2 = document.querySelector('#id');
 *
 * For details about CSS selector syntax, see the
 * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
 */
Element querySelector(String selectors) => document.querySelector(selectors);

/**
 * Finds all descendant elements of this document that match the specified
 * group of selectors.
 *
 * Unless your webpage contains multiple documents, the top-level
 * [querySelectorAll]
 * method behaves the same as this method, so you should use it instead to
 * save typing a few characters.
 *
 * [selectors] should be a string using CSS selector syntax.
 *
 *     var items = document.querySelectorAll('.itemClassName');
 *
 * For details about CSS selector syntax, see the
 * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
 */
ElementList<T> querySelectorAll<T extends Element>(String selectors) =>
    document.querySelectorAll(selectors);

/// A utility for changing the Dart wrapper type for elements.
abstract class ElementUpgrader {
  /// Upgrade the specified element to be of the Dart type this was created for.
  ///
  /// After upgrading the element passed in is invalid and the returned value
  /// should be used instead.
  Element upgrade(Element element);
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Interface used to validate that only accepted elements and attributes are
 * allowed while parsing HTML strings into DOM nodes.
 *
 * In general, customization of validation behavior should be done via the
 * [NodeValidatorBuilder] class to mitigate the chances of incorrectly
 * implementing validation rules.
 */
abstract class NodeValidator {
  /**
   * Construct a default NodeValidator which only accepts whitelisted HTML5
   * elements and attributes.
   *
   * If a uriPolicy is not specified then the default uriPolicy will be used.
   */
  factory NodeValidator({UriPolicy uriPolicy}) =>
      new _Html5NodeValidator(uriPolicy: uriPolicy);

  factory NodeValidator.throws(NodeValidator base) =>
      new _ThrowsNodeValidator(base);

  /**
   * Returns true if the tagName is an accepted type.
   */
  bool allowsElement(Element element);

  /**
   * Returns true if the attribute is allowed.
   *
   * The attributeName parameter will always be in lowercase.
   *
   * See [allowsElement] for format of tagName.
   */
  bool allowsAttribute(Element element, String attributeName, String value);
}

/**
 * Performs sanitization of a node tree after construction to ensure that it
 * does not contain any disallowed elements or attributes.
 *
 * In general custom implementations of this class should not be necessary and
 * all validation customization should be done in custom NodeValidators, but
 * custom implementations of this class can be created to perform more complex
 * tree sanitization.
 */
abstract class NodeTreeSanitizer {
  /**
   * Constructs a default tree sanitizer which will remove all elements and
   * attributes which are not allowed by the provided validator.
   */
  factory NodeTreeSanitizer(NodeValidator validator) =>
      new _ValidatingTreeSanitizer(validator);

  /**
   * Called with the root of the tree which is to be sanitized.
   *
   * This method needs to walk the entire tree and either remove elements and
   * attributes which are not recognized as safe or throw an exception which
   * will mark the entire tree as unsafe.
   */
  void sanitizeTree(Node node);

  /**
   * A sanitizer for trees that we trust. It does no validation and allows
   * any elements. It is also more efficient, since it can pass the text
   * directly through to the underlying APIs without creating a document
   * fragment to be sanitized.
   */
  static const trusted = const _TrustedHtmlTreeSanitizer();
}

/**
 * A sanitizer for trees that we trust. It does no validation and allows
 * any elements.
 */
class _TrustedHtmlTreeSanitizer implements NodeTreeSanitizer {
  const _TrustedHtmlTreeSanitizer();

  sanitizeTree(Node node) {}
}

/**
 * Defines the policy for what types of uris are allowed for particular
 * attribute values.
 *
 * This can be used to provide custom rules such as allowing all http:// URIs
 * for image attributes but only same-origin URIs for anchor tags.
 */
abstract class UriPolicy {
  /**
   * Constructs the default UriPolicy which is to only allow Uris to the same
   * origin as the application was launched from.
   *
   * This will block all ftp: mailto: URIs. It will also block accessing
   * https://example.com if the app is running from http://example.com.
   */
  factory UriPolicy() => new _SameOriginUriPolicy();

  /**
   * Checks if the uri is allowed on the specified attribute.
   *
   * The uri provided may or may not be a relative path.
   */
  bool allowsUri(String uri);
}

/**
 * Allows URIs to the same origin as the current application was loaded from
 * (such as https://example.com:80).
 */
class _SameOriginUriPolicy implements UriPolicy {
  final AnchorElement _hiddenAnchor = new AnchorElement();
  final Location _loc = window.location;

  bool allowsUri(String uri) {
    _hiddenAnchor.href = uri;
    // IE leaves an empty hostname for same-origin URIs.
    return (_hiddenAnchor.hostname == _loc.hostname &&
            _hiddenAnchor.port == _loc.port &&
            _hiddenAnchor.protocol == _loc.protocol) ||
        (_hiddenAnchor.hostname == '' &&
            _hiddenAnchor.port == '' &&
            (_hiddenAnchor.protocol == ':' || _hiddenAnchor.protocol == ''));
  }
}

class _ThrowsNodeValidator implements NodeValidator {
  final NodeValidator validator;

  _ThrowsNodeValidator(this.validator) {}

  bool allowsElement(Element element) {
    if (!validator.allowsElement(element)) {
      throw new ArgumentError(Element._safeTagName(element));
    }
    return true;
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (!validator.allowsAttribute(element, attributeName, value)) {
      throw new ArgumentError(
          '${Element._safeTagName(element)}[$attributeName="$value"]');
    }
  }
}

/**
 * Standard tree sanitizer which validates a node tree against the provided
 * validator and removes any nodes or attributes which are not allowed.
 */
class _ValidatingTreeSanitizer implements NodeTreeSanitizer {
  NodeValidator validator;
  _ValidatingTreeSanitizer(this.validator) {}

  void sanitizeTree(Node node) {
    void walk(Node node, Node parent) {
      sanitizeNode(node, parent);

      var child = node.lastChild;
      while (null != child) {
        var nextChild;
        try {
          // Child may be removed during the walk, and we may not
          // even be able to get its previousNode.
          nextChild = child.previousNode;
        } catch (e) {
          // Child appears bad, remove it. We want to check the rest of the
          // children of node and, but we have no way of getting to the next
          // child, so start again from the last child.
          _removeNode(child, node);
          child = null;
          nextChild = node.lastChild;
        }
        if (child != null) walk(child, node);
        child = nextChild;
      }
    }

    walk(node, null);
  }

  /// Aggressively try to remove node.
  void _removeNode(Node node, Node parent) {
    // If we have the parent, it's presumably already passed more sanitization
    // or is the fragment, so ask it to remove the child. And if that fails
    // try to set the outer html.
    if (parent == null) {
      node.remove();
    } else {
      parent._removeChild(node);
    }
  }

  /// Sanitize the element, assuming we can't trust anything about it.
  void _sanitizeUntrustedElement(/* Element */ element, Node parent) {
    // If the _hasCorruptedAttributes does not successfully return false,
    // then we consider it corrupted and remove.
    // TODO(alanknight): This is a workaround because on Firefox
    // embed/object
    // tags typeof is "function", not "object". We don't recognize them, and
    // can't call methods. This does mean that you can't explicitly allow an
    // embed tag. The only thing that will let it through is a null
    // sanitizer that doesn't traverse the tree at all. But sanitizing while
    // allowing embeds seems quite unlikely. This is also the reason that we
    // can't declare the type of element, as an embed won't pass any type
    // check in dart2js.
    var corrupted = true;
    var attrs;
    var isAttr;
    try {
      // If getting/indexing attributes throws, count that as corrupt.
      attrs = element.attributes;
      isAttr = attrs['is'];
      var corruptedTest1 = Element._hasCorruptedAttributes(element);

      // On IE, erratically, the hasCorruptedAttributes test can return false,
      // even though it clearly is corrupted. A separate copy of the test
      // inlining just the basic check seems to help.
      corrupted = corruptedTest1
          ? true
          : Element._hasCorruptedAttributesAdditionalCheck(element);
    } catch (e) {}
    var elementText = 'element unprintable';
    try {
      elementText = element.toString();
    } catch (e) {}
    try {
      var elementTagName = Element._safeTagName(element);
      _sanitizeElement(element, parent, corrupted, elementText, elementTagName,
          attrs, isAttr);
    } on ArgumentError {
      // Thrown by _ThrowsNodeValidator
      rethrow;
    } catch (e) {
      // Unexpected exception sanitizing -> remove
      _removeNode(element, parent);
      window.console.warn('Removing corrupted element $elementText');
    }
  }

  /// Having done basic sanity checking on the element, and computed the
  /// important attributes we want to check, remove it if it's not valid
  /// or not allowed, either as a whole or particular attributes.
  void _sanitizeElement(Element element, Node parent, bool corrupted,
      String text, String tag, Map attrs, String isAttr) {
    if (false != corrupted) {
      _removeNode(element, parent);
      window.console
          .warn('Removing element due to corrupted attributes on <$text>');
      return;
    }
    if (!validator.allowsElement(element)) {
      _removeNode(element, parent);
      window.console.warn('Removing disallowed element <$tag> from $parent');
      return;
    }

    if (isAttr != null) {
      if (!validator.allowsAttribute(element, 'is', isAttr)) {
        _removeNode(element, parent);
        window.console.warn('Removing disallowed type extension '
            '<$tag is="$isAttr">');
        return;
      }
    }

    // TODO(blois): Need to be able to get all attributes, irrespective of
    // XMLNS.
    var keys = attrs.keys.toList();
    for (var i = attrs.length - 1; i >= 0; --i) {
      var name = keys[i];
      if (!validator.allowsAttribute(
          element, name.toLowerCase(), attrs[name])) {
        window.console.warn('Removing disallowed attribute '
            '<$tag $name="${attrs[name]}">');
        attrs.remove(name);
      }
    }

    if (element is TemplateElement) {
      TemplateElement template = element;
      sanitizeTree(template.content);
    }
  }

  /// Sanitize the node and its children recursively.
  void sanitizeNode(Node node, Node parent) {
    switch (node.nodeType) {
      case Node.ELEMENT_NODE:
        _sanitizeUntrustedElement(node, parent);
        break;
      case Node.COMMENT_NODE:
      case Node.DOCUMENT_FRAGMENT_NODE:
      case Node.TEXT_NODE:
      case Node.CDATA_SECTION_NODE:
        break;
      default:
        _removeNode(node, parent);
    }
  }
}
