// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.

/// HTML elements and other resources for web-based applications that need to
/// interact with the browser and the DOM (Document Object Model).
///
/// > [!Note]
/// > New projects should prefer to use
/// > [package:web](https://pub.dev/packages/web). For existing projects, see
/// > our [migration guide](https://dart.dev/go/package-web).
///
/// 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://dart.dev/web.
///
/// {@category Web (Legacy)}
/// {@canonicalFor dart:_internal.HttpStatus}
@Deprecated('Use package:web and dart:js_interop instead.')
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:_foreign_helper' show JS, JS_INTERCEPTOR_CONSTANT;
import 'dart:js_util' as js_util;

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

export 'dart:_internal' show HttpStatus;
export 'dart:html_common' show promiseToFuture;
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');

/// Convert a JS Promise to a Future<Map<String, dynamic>>.
///
/// On a successful result the native JS result will be converted to a Dart Map.
/// See [convertNativeToDart_Dictionary]. On a rejected promise the error is
/// forwarded without change.
Future<Map<String, dynamic>?> promiseToFutureAsMap(jsPromise) =>
    promiseToFuture(jsPromise).then(convertNativeToDart_Dictionary);

// 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? get nonce native;
  set nonce(String? value) native;
}

/**
 * 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 JavaScriptObject 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()');

  num? get x native;

  num? get y native;

  num? get z 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("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? get activeDescendant native;

  set activeDescendant(AccessibleNode? value) native;

  bool? get atomic native;

  set atomic(bool? value) native;

  String? get autocomplete native;

  set autocomplete(String? value) native;

  bool? get busy native;

  set busy(bool? value) native;

  String? get checked native;

  set checked(String? value) native;

  int? get colCount native;

  set colCount(int? value) native;

  int? get colIndex native;

  set colIndex(int? value) native;

  int? get colSpan native;

  set colSpan(int? value) native;

  AccessibleNodeList? get controls native;

  set controls(AccessibleNodeList? value) native;

  String? get current native;

  set current(String? value) native;

  AccessibleNodeList? get describedBy native;

  set describedBy(AccessibleNodeList? value) native;

  AccessibleNode? get details native;

  set details(AccessibleNode? value) native;

  bool? get disabled native;

  set disabled(bool? value) native;

  AccessibleNode? get errorMessage native;

  set errorMessage(AccessibleNode? value) native;

  bool? get expanded native;

  set expanded(bool? value) native;

  AccessibleNodeList? get flowTo native;

  set flowTo(AccessibleNodeList? value) native;

  String? get hasPopUp native;

  set hasPopUp(String? value) native;

  bool? get hidden native;

  set hidden(bool? value) native;

  String? get invalid native;

  set invalid(String? value) native;

  String? get keyShortcuts native;

  set keyShortcuts(String? value) native;

  String? get label native;

  set label(String? value) native;

  AccessibleNodeList? get labeledBy native;

  set labeledBy(AccessibleNodeList? value) native;

  int? get level native;

  set level(int? value) native;

  String? get live native;

  set live(String? value) native;

  bool? get modal native;

  set modal(bool? value) native;

  bool? get multiline native;

  set multiline(bool? value) native;

  bool? get multiselectable native;

  set multiselectable(bool? value) native;

  String? get orientation native;

  set orientation(String? value) native;

  AccessibleNodeList? get owns native;

  set owns(AccessibleNodeList? value) native;

  String? get placeholder native;

  set placeholder(String? value) native;

  int? get posInSet native;

  set posInSet(int? value) native;

  String? get pressed native;

  set pressed(String? value) native;

  bool? get readOnly native;

  set readOnly(bool? value) native;

  String? get relevant native;

  set relevant(String? value) native;

  bool? get required native;

  set required(bool? value) native;

  String? get role native;

  set role(String? value) native;

  String? get roleDescription native;

  set roleDescription(String? value) native;

  int? get rowCount native;

  set rowCount(int? value) native;

  int? get rowIndex native;

  set rowIndex(int? value) native;

  int? get rowSpan native;

  set rowSpan(int? value) native;

  bool? get selected native;

  set selected(bool? value) native;

  int? get setSize native;

  set setSize(int? value) native;

  String? get sort native;

  set sort(String? value) native;

  num? get valueMax native;

  set valueMax(num? value) native;

  num? get valueMin native;

  set valueMin(num? value) native;

  num? get valueNow native;

  set valueNow(num? value) native;

  String? get valueText native;

  set valueText(String? value) native;

  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 JavaScriptObject {
  // 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? get length native;

  set length(int? value) native;

  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()');

  num? get illuminance native;
}
// 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<AnchorElement>(
      '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? get download native;

  set download(String? value) native;

  String get hreflang native;

  set hreflang(String value) native;

  String? get referrerPolicy native;

  set referrerPolicy(String? value) native;

  String get rel native;

  set rel(String value) native;

  String get target native;

  set target(String value) native;

  String get type native;

  set type(String value) native;

  // From HTMLHyperlinkElementUtils

  String? get hash native;

  set hash(String? value) native;

  String? get host native;

  set host(String? value) native;

  String? get hostname native;

  set hostname(String? value) native;

  String? get href native;

  set href(String? value) native;

  String? get origin native;

  String? get password native;

  set password(String? value) native;

  String? get pathname native;

  set pathname(String? value) native;

  String? get port native;

  set port(String? value) native;

  String? get protocol native;

  set protocol(String? value) native;

  String? get search native;

  set search(String? value) native;

  String? get username native;

  set username(String? value) native;

  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? get currentTime native;

  set currentTime(num? value) native;

  AnimationEffectReadOnly? get effect native;

  set effect(AnimationEffectReadOnly? value) native;

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

  String? get id native;

  set id(String? value) native;

  String? get playState native;

  num? get playbackRate native;

  set playbackRate(num? value) native;

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

  num? get startTime native;

  set startTime(num? value) native;

  AnimationTimeline? get timeline native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory AnimationEffectReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  AnimationEffectTimingReadOnly? get timing native;

  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 native;

  set delay(num? value) native;

  // Shadowing definition.

  String? get direction native;

  set direction(String? value) native;

  // Shadowing definition.

  @Returns('num|String|Null')
  Object? get duration native;

  set duration(Object? value) native;

  // Shadowing definition.

  String? get easing native;

  set easing(String? value) native;

  // Shadowing definition.

  num? get endDelay native;

  set endDelay(num? value) native;

  // Shadowing definition.

  String? get fill native;

  set fill(String? value) native;

  // Shadowing definition.

  num? get iterationStart native;

  set iterationStart(num? value) native;

  // Shadowing definition.

  num? get iterations native;

  set iterations(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("AnimationEffectTimingReadOnly")
class AnimationEffectTimingReadOnly extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory AnimationEffectTimingReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  num? get delay native;

  String? get direction native;

  Object? get duration native;

  String? get easing native;

  num? get endDelay native;

  String? get fill native;

  num? get iterationStart native;

  num? get iterations 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("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);

  String? get animationName native;

  num? get elapsedTime 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("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);

  num? get currentTime native;

  num? get timelineTime 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("AnimationTimeline")
class AnimationTimeline extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory AnimationTimeline._() {
    throw new UnsupportedError("Not supported");
  }

  num? get currentTime 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("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;

  int? get status native;

  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,
  );

  String? get message native;

  String? get reason native;

  int? get status native;

  String? get url native;
}
// 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<AreaElement>(
    '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 get alt native;

  set alt(String value) native;

  String get coords native;

  set coords(String value) native;

  String? get download native;

  set download(String? value) native;

  String? get referrerPolicy native;

  set referrerPolicy(String? value) native;

  String get rel native;

  set rel(String value) native;

  String get shape native;

  set shape(String value) native;

  String get target native;

  set target(String value) native;

  // From HTMLHyperlinkElementUtils

  String? get hash native;

  set hash(String? value) native;

  String? get host native;

  set host(String? value) native;

  String? get hostname native;

  set hostname(String? value) native;

  String? get href native;

  set href(String? value) native;

  String? get origin native;

  String? get password native;

  set password(String? value) native;

  String? get pathname native;

  set pathname(String? value) native;

  String? get port native;

  set port(String? value) native;

  String? get protocol native;

  set protocol(String? value) native;

  String? get search native;

  set search(String? value) native;

  String? get username native;

  set username(String? value) native;

  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");
  }

  ByteBuffer? get authenticatorData native;

  ByteBuffer? get signature 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("AuthenticatorAttestationResponse")
class AuthenticatorAttestationResponse extends AuthenticatorResponse {
  // To suppress missing implicit constructor warnings.
  factory AuthenticatorAttestationResponse._() {
    throw new UnsupportedError("Not supported");
  }

  ByteBuffer? get attestationObject 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("AuthenticatorResponse")
class AuthenticatorResponse extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory AuthenticatorResponse._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('clientDataJSON')
  ByteBuffer? get clientDataJson 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("HTMLBRElement")
class BRElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory BRElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory BRElement() => JS<BRElement>(
    '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,
  );

  String? get state 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("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);

  String? get 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("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,
  );

  List<BackgroundFetchSettledFetch>? get fetches 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("BackgroundFetchFetch")
class BackgroundFetchFetch extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory BackgroundFetchFetch._() {
    throw new UnsupportedError("Not supported");
  }

  _Request? get request 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("BackgroundFetchManager")
class BackgroundFetchManager extends JavaScriptObject {
  // 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(
        "creates:BackgroundFetchRegistration;",
        "#.fetch(#, #, #)",
        this,
        id,
        requests,
        options_dict,
      ),
    );
  }

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

  Future<List<dynamic>> getIds() =>
      promiseToFuture<List<dynamic>>(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");
  }

  int? get downloadTotal native;

  int? get downloaded native;

  String? get id native;

  String? get title native;

  int? get totalDownloadSize native;

  int? get uploadTotal native;

  int? get uploaded native;

  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,
  );

  _Response? get 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("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,
  );

  List<BackgroundFetchSettledFetch>? get fetches native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory BarProp._() {
    throw new UnsupportedError("Not supported");
  }

  bool? get visible 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("BarcodeDetector")
class BarcodeDetector extends JavaScriptObject {
  // 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<dynamic>> detect(/*ImageBitmapSource*/ image) =>
      promiseToFuture<List<dynamic>>(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<BaseElement>(
    '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 get href native;

  set href(String value) native;

  String get target native;

  set target(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.

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

  bool? get charging native;

  num? get chargingTime native;

  num? get dischargingTime native;

  num? get level 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("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);

  List<String>? get platforms native;

  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 native;

  set returnValue(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.

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

  int get size native;

  String get type native;

  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);

  Blob? get data native;

  num? get timecode 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("BluetoothRemoteGATTDescriptor")
class BluetoothRemoteGattDescriptor extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory BluetoothRemoteGattDescriptor._() {
    throw new UnsupportedError("Not supported");
  }

  _BluetoothRemoteGATTCharacteristic? get characteristic native;

  String? get uuid native;

  ByteData? get value native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory Body._() {
    throw new UnsupportedError("Not supported");
  }

  bool? get bodyUsed native;

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

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

  Future<FormData> formData() =>
      promiseToFuture<FormData>(JS("creates:FormData;", "#.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<BodyElement>(
    '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);

  String? get name native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory BudgetState._() {
    throw new UnsupportedError("Not supported");
  }

  num? get budgetAt native;

  int? get time 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("HTMLButtonElement")
class ButtonElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ButtonElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory ButtonElement() => JS<ButtonElement>(
    '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 get autofocus native;

  set autofocus(bool value) native;

  bool get disabled native;

  set disabled(bool value) native;

  FormElement? get form native;

  String? get formAction native;

  set formAction(String? value) native;

  String? get formEnctype native;

  set formEnctype(String? value) native;

  String? get formMethod native;

  set formMethod(String? value) native;

  bool get formNoValidate native;

  set formNoValidate(bool value) native;

  String get formTarget native;

  set formTarget(String value) native;

  @Unstable()
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node>? get labels native;

  String get name native;

  set name(String value) native;

  String get type native;

  set type(String value) native;

  String get validationMessage native;

  ValidityState get validity native;

  String get value native;

  set value(String value) native;

  bool get willValidate 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.

// 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 JavaScriptObject {
  // 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("creates:_Response;", "#.match(#, #)", this, request, options_dict),
    );
  }

  Future open(String cacheName) =>
      promiseToFuture(JS("creates:_Cache;", "#.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,
  );

  List? get methodData native;

  List? get modifiers native;

  String? get paymentRequestOrigin native;

  String? get topLevelOrigin native;

  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");
  }

  CanvasElement? get canvas native;

  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<CanvasElement>(
      '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? get height native;

  set height(int? value) native;

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

  int? get width native;

  set width(int? value) native;

  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;

  @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 as gl.RenderingContext?;
  }

  /**
   * 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);

  @JSName('toBlob')
  void _toBlob(BlobCallback callback, [String? type, Object? arguments]) native;

  Future<Blob> toBlob([String? type, Object? arguments]) {
    var completer = new Completer<Blob>();
    _toBlob(
      (value) {
        completer.complete(value);
      },
      type,
      arguments,
    );
    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.

/**
 * An opaque canvas object representing a gradient.
 *
 * Created by calling the methods
 * [CanvasRenderingContext2D.createLinearGradient] or
 * [CanvasRenderingContext2D.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 JavaScriptObject {
  // 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 [CanvasRenderingContext2D.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 JavaScriptObject {
  // 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 JavaScriptObject
    implements CanvasRenderingContext {
  // To suppress missing implicit constructor warnings.
  factory CanvasRenderingContext2D._() {
    throw new UnsupportedError("Not supported");
  }

  CanvasElement get canvas native;

  Matrix? get currentTransform native;

  set currentTransform(Matrix? value) native;

  String? get direction native;

  set direction(String? value) native;

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

  set fillStyle(Object? value) native;

  String? get filter native;

  set filter(String? value) native;

  String get font native;

  set font(String value) native;

  num get globalAlpha native;

  set globalAlpha(num value) native;

  String get globalCompositeOperation native;

  set globalCompositeOperation(String value) native;

  /**
   * 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? get imageSmoothingEnabled native;

  set imageSmoothingEnabled(bool? value) native;

  String? get imageSmoothingQuality native;

  set imageSmoothingQuality(String? value) native;

  String get lineCap native;

  set lineCap(String value) native;

  String get lineJoin native;

  set lineJoin(String value) native;

  num get lineWidth native;

  set lineWidth(num value) native;

  num get miterLimit native;

  set miterLimit(num value) native;

  num get shadowBlur native;

  set shadowBlur(num value) native;

  String get shadowColor native;

  set shadowColor(String value) native;

  num get shadowOffsetX native;

  set shadowOffsetX(num value) native;

  num get shadowOffsetY native;

  set shadowOffsetY(num value) native;

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

  set strokeStyle(Object? value) native;

  String get textAlign native;

  set textAlign(String value) native;

  String get textBaseline native;

  set textBaseline(String value) native;

  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
   * [sourceHeight] 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);
    }
    return [];
  }

  @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 ChildNode, NonDocumentTypeChildNode {
  // To suppress missing implicit constructor warnings.
  factory CharacterData._() {
    throw new UnsupportedError("Not supported");
  }

  String? get data native;

  set data(String? value) native;

  int? get length native;

  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

  Element? get nextElementSibling native;

  Element? get previousElementSibling 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 ChildNode extends JavaScriptObject {
  // 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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory Client._() {
    throw new UnsupportedError("Not supported");
  }

  String? get frameType native;

  String? get id native;

  String? get type native;

  String? get url native;

  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 JavaScriptObject {
  // 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<dynamic>> matchAll([Map? options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture<List<dynamic>>(
      JS("", "#.matchAll(#)", this, options_dict),
    );
  }

  Future<WindowClient> openWindow(String url) => promiseToFuture<WindowClient>(
    JS("creates:WindowClient;", "#.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);

  DataTransfer? get clipboardData 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("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);

  int? get code native;

  String? get reason native;

  bool? get wasClean 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("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") as 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);

  String? get data native;

  @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") as ContentElement;
  /**
   * 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? get select native;

  set select(String? value) native;

  @Returns('NodeList')
  @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 JavaScriptObject {
  // 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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory Coordinates._() {
    throw new UnsupportedError("Not supported");
  }

  num? get accuracy native;

  num? get altitude native;

  num? get altitudeAccuracy native;

  num? get heading native;

  num? get latitude native;

  num? get longitude native;

  num? get speed 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("Credential")
class Credential extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory Credential._() {
    throw new UnsupportedError("Not supported");
  }

  String? get id native;

  String? get 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("CredentialUserData")
class CredentialUserData extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory CredentialUserData._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('iconURL')
  String? get iconUrl native;

  String? get 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("CredentialsContainer")
class CredentialsContainer extends JavaScriptObject {
  // 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("creates:Credential;", "#.create(#)", this, options_dict),
    );
  }

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

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

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

  Future store(Credential credential) => promiseToFuture(
    JS("creates:Credential;", "#.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 JavaScriptObject {
  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)');

  _SubtleCrypto? get subtle native;

  @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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory CryptoKey._() {
    throw new UnsupportedError("Not supported");
  }

  @Creates('Null')
  Object? get algorithm native;

  bool? get extractable native;

  String? get type native;

  Object? get usages 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("CSS")
class Css extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory Css._() {
    throw new UnsupportedError("Not supported");
  }

  static _Worklet? get paintWorklet native;

  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? get encoding native;

  set encoding(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.

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

  String? get conditionText 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("CSSFontFaceRule")
class CssFontFaceRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssFontFaceRule._() {
    throw new UnsupportedError("Not supported");
  }

  CssStyleDeclaration? get style 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("CSSGroupingRule")
class CssGroupingRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssGroupingRule._() {
    throw new UnsupportedError("Not supported");
  }

  @Returns('_CssRuleList')
  @Creates('_CssRuleList')
  List<CssRule>? get cssRules native;

  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");
  }

  num? get intrinsicHeight native;

  num? get intrinsicRatio native;

  num? get intrinsicWidth 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("CSSImportRule")
class CssImportRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssImportRule._() {
    throw new UnsupportedError("Not supported");
  }

  String? get href native;

  MediaList? get media native;

  CssStyleSheet? get styleSheet 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("CSSKeyframeRule,MozCSSKeyframeRule,WebKitCSSKeyframeRule")
class CssKeyframeRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssKeyframeRule._() {
    throw new UnsupportedError("Not supported");
  }

  String? get keyText native;

  set keyText(String? value) native;

  CssStyleDeclaration? get style 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("CSSKeyframesRule,MozCSSKeyframesRule,WebKitCSSKeyframesRule")
class CssKeyframesRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssKeyframesRule._() {
    throw new UnsupportedError("Not supported");
  }

  @Returns('_CssRuleList')
  @Creates('_CssRuleList')
  List<CssRule>? get cssRules native;

  String? get name native;

  set name(String? value) native;

  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? get value native;

  set value(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.

@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? get matrix native;

  set matrix(DomMatrix? 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("CSSMediaRule")
class CssMediaRule extends CssConditionRule {
  // To suppress missing implicit constructor warnings.
  factory CssMediaRule._() {
    throw new UnsupportedError("Not supported");
  }

  MediaList? get media 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("CSSNamespaceRule")
class CssNamespaceRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssNamespaceRule._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('namespaceURI')
  String? get namespaceUri native;

  String? get 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.

@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? get selectorText native;

  set selectorText(String? value) native;

  CssStyleDeclaration? get style 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("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? get length native;

  set length(CssNumericValue? 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("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? get x native;

  set x(CssNumericValue? value) native;

  CssNumericValue? get y native;

  set y(CssNumericValue? 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("CSSResourceValue")
class CssResourceValue extends CssStyleValue {
  // To suppress missing implicit constructor warnings.
  factory CssResourceValue._() {
    throw new UnsupportedError("Not supported");
  }

  String? get state 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("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? get angle native;

  set angle(CssNumericValue? value) native;

  num? get x native;

  set x(num? value) native;

  num? get y native;

  set y(num? value) native;

  num? get z native;

  set z(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("CSSRule")
class CssRule extends JavaScriptObject {
  // 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? get cssText native;

  set cssText(String? value) native;

  CssRule? get parentRule native;

  CssStyleSheet? get parentStyleSheet native;

  int? get 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("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? get x native;

  set x(num? value) native;

  num? get y native;

  set y(num? value) native;

  num? get z native;

  set z(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("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? get ax native;

  set ax(CssNumericValue? value) native;

  CssNumericValue? get ay native;

  set ay(CssNumericValue? value) 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.

// 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 JavaScriptObject
    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) {
    return _getPropertyValueHelper(propertyName);
  }

  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? get cssFloat native;

  set cssFloat(String? value) native;

  String? get cssText native;

  set cssText(String? value) native;

  int get length native;

  CssRule? get parentRule native;

  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 get _background native;

  @JSName('background')
  set _background(String value) native;

  /** 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 get _backgroundAttachment native;

  @JSName('backgroundAttachment')
  set _backgroundAttachment(String value) native;

  /** 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 get _backgroundColor native;

  @JSName('backgroundColor')
  set _backgroundColor(String value) native;

  /** 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 get _backgroundImage native;

  @JSName('backgroundImage')
  set _backgroundImage(String value) native;

  /** 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 get _backgroundPosition native;

  @JSName('backgroundPosition')
  set _backgroundPosition(String value) native;

  /** 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 get _backgroundRepeat native;

  @JSName('backgroundRepeat')
  set _backgroundRepeat(String value) native;

  /** 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 get _border native;

  @JSName('border')
  set _border(String value) native;

  /** 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 get _borderBottom native;

  @JSName('borderBottom')
  set _borderBottom(String value) native;

  /** 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 get _borderBottomColor native;

  @JSName('borderBottomColor')
  set _borderBottomColor(String value) native;

  /** 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 get _borderBottomStyle native;

  @JSName('borderBottomStyle')
  set _borderBottomStyle(String value) native;

  /** 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 get _borderBottomWidth native;

  @JSName('borderBottomWidth')
  set _borderBottomWidth(String value) native;

  /** 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 get _borderCollapse native;

  @JSName('borderCollapse')
  set _borderCollapse(String value) native;

  /** 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 get _borderColor native;

  @JSName('borderColor')
  set _borderColor(String value) native;

  /** 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 get _borderLeft native;

  @JSName('borderLeft')
  set _borderLeft(String value) native;

  /** 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 get _borderLeftColor native;

  @JSName('borderLeftColor')
  set _borderLeftColor(String value) native;

  /** 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 get _borderLeftStyle native;

  @JSName('borderLeftStyle')
  set _borderLeftStyle(String value) native;

  /** 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 get _borderLeftWidth native;

  @JSName('borderLeftWidth')
  set _borderLeftWidth(String value) native;

  /** 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 get _borderRight native;

  @JSName('borderRight')
  set _borderRight(String value) native;

  /** 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 get _borderRightColor native;

  @JSName('borderRightColor')
  set _borderRightColor(String value) native;

  /** 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 get _borderRightStyle native;

  @JSName('borderRightStyle')
  set _borderRightStyle(String value) native;

  /** 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 get _borderRightWidth native;

  @JSName('borderRightWidth')
  set _borderRightWidth(String value) native;

  /** 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 get _borderSpacing native;

  @JSName('borderSpacing')
  set _borderSpacing(String value) native;

  /** 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 get _borderStyle native;

  @JSName('borderStyle')
  set _borderStyle(String value) native;

  /** 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 get _borderTop native;

  @JSName('borderTop')
  set _borderTop(String value) native;

  /** 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 get _borderTopColor native;

  @JSName('borderTopColor')
  set _borderTopColor(String value) native;

  /** 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 get _borderTopStyle native;

  @JSName('borderTopStyle')
  set _borderTopStyle(String value) native;

  /** 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 get _borderTopWidth native;

  @JSName('borderTopWidth')
  set _borderTopWidth(String value) native;

  /** 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 get _borderWidth native;

  @JSName('borderWidth')
  set _borderWidth(String value) native;

  /** 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 get _bottom native;

  @JSName('bottom')
  set _bottom(String value) native;

  /** 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 get _captionSide native;

  @JSName('captionSide')
  set _captionSide(String value) native;

  /** 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 get _clear native;

  @JSName('clear')
  set _clear(String value) native;

  /** 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 get _clip native;

  @JSName('clip')
  set _clip(String value) native;

  /** 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 get _color native;

  @JSName('color')
  set _color(String value) native;

  /** 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 get _content native;

  @JSName('content')
  set _content(String value) native;

  /** 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 get _cursor native;

  @JSName('cursor')
  set _cursor(String value) native;

  /** 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 get _direction native;

  @JSName('direction')
  set _direction(String value) native;

  /** 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 get _display native;

  @JSName('display')
  set _display(String value) native;

  /** 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 get _emptyCells native;

  @JSName('emptyCells')
  set _emptyCells(String value) native;

  /** 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 get _font native;

  @JSName('font')
  set _font(String value) native;

  /** 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 get _fontFamily native;

  @JSName('fontFamily')
  set _fontFamily(String value) native;

  /** 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 get _fontSize native;

  @JSName('fontSize')
  set _fontSize(String value) native;

  /** 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 get _fontStyle native;

  @JSName('fontStyle')
  set _fontStyle(String value) native;

  /** 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 get _fontVariant native;

  @JSName('fontVariant')
  set _fontVariant(String value) native;

  /** 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 get _fontWeight native;

  @JSName('fontWeight')
  set _fontWeight(String value) native;

  /** 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 get _height native;

  @JSName('height')
  set _height(String value) native;

  /** 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 get _left native;

  @JSName('left')
  set _left(String value) native;

  /** 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 get _letterSpacing native;

  @JSName('letterSpacing')
  set _letterSpacing(String value) native;

  /** 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 get _lineHeight native;

  @JSName('lineHeight')
  set _lineHeight(String value) native;

  /** 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 get _listStyle native;

  @JSName('listStyle')
  set _listStyle(String value) native;

  /** 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 get _listStyleImage native;

  @JSName('listStyleImage')
  set _listStyleImage(String value) native;

  /** 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 get _listStylePosition native;

  @JSName('listStylePosition')
  set _listStylePosition(String value) native;

  /** 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 get _listStyleType native;

  @JSName('listStyleType')
  set _listStyleType(String value) native;

  /** 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 get _margin native;

  @JSName('margin')
  set _margin(String value) native;

  /** 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 get _marginBottom native;

  @JSName('marginBottom')
  set _marginBottom(String value) native;

  /** 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 get _marginLeft native;

  @JSName('marginLeft')
  set _marginLeft(String value) native;

  /** 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 get _marginRight native;

  @JSName('marginRight')
  set _marginRight(String value) native;

  /** 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 get _marginTop native;

  @JSName('marginTop')
  set _marginTop(String value) native;

  /** 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 get _maxHeight native;

  @JSName('maxHeight')
  set _maxHeight(String value) native;

  /** 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 get _maxWidth native;

  @JSName('maxWidth')
  set _maxWidth(String value) native;

  /** 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 get _minHeight native;

  @JSName('minHeight')
  set _minHeight(String value) native;

  /** 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 get _minWidth native;

  @JSName('minWidth')
  set _minWidth(String value) native;

  /** 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 get _outline native;

  @JSName('outline')
  set _outline(String value) native;

  /** 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 get _outlineColor native;

  @JSName('outlineColor')
  set _outlineColor(String value) native;

  /** 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 get _outlineStyle native;

  @JSName('outlineStyle')
  set _outlineStyle(String value) native;

  /** 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 get _outlineWidth native;

  @JSName('outlineWidth')
  set _outlineWidth(String value) native;

  /** 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 get _overflow native;

  @JSName('overflow')
  set _overflow(String value) native;

  /** 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 get _padding native;

  @JSName('padding')
  set _padding(String value) native;

  /** 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 get _paddingBottom native;

  @JSName('paddingBottom')
  set _paddingBottom(String value) native;

  /** 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 get _paddingLeft native;

  @JSName('paddingLeft')
  set _paddingLeft(String value) native;

  /** 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 get _paddingRight native;

  @JSName('paddingRight')
  set _paddingRight(String value) native;

  /** 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 get _paddingTop native;

  @JSName('paddingTop')
  set _paddingTop(String value) native;

  /** 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 get _pageBreakAfter native;

  @JSName('pageBreakAfter')
  set _pageBreakAfter(String value) native;

  /** 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 get _pageBreakBefore native;

  @JSName('pageBreakBefore')
  set _pageBreakBefore(String value) native;

  /** 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 get _pageBreakInside native;

  @JSName('pageBreakInside')
  set _pageBreakInside(String value) native;

  /** 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 get _position native;

  @JSName('position')
  set _position(String value) native;

  /** 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 get _quotes native;

  @JSName('quotes')
  set _quotes(String value) native;

  /** 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 get _right native;

  @JSName('right')
  set _right(String value) native;

  /** 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 get _tableLayout native;

  @JSName('tableLayout')
  set _tableLayout(String value) native;

  /** 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 get _textAlign native;

  @JSName('textAlign')
  set _textAlign(String value) native;

  /** 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 get _textDecoration native;

  @JSName('textDecoration')
  set _textDecoration(String value) native;

  /** 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 get _textIndent native;

  @JSName('textIndent')
  set _textIndent(String value) native;

  /** 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 get _textTransform native;

  @JSName('textTransform')
  set _textTransform(String value) native;

  /** 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 get _top native;

  @JSName('top')
  set _top(String value) native;

  /** 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 get _unicodeBidi native;

  @JSName('unicodeBidi')
  set _unicodeBidi(String value) native;

  /** 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 get _verticalAlign native;

  @JSName('verticalAlign')
  set _verticalAlign(String value) native;

  /** 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 get _visibility native;

  @JSName('visibility')
  set _visibility(String value) native;

  /** 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 get _whiteSpace native;

  @JSName('whiteSpace')
  set _whiteSpace(String value) native;

  /** 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 get _width native;

  @JSName('width')
  set _width(String value) native;

  /** 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 get _wordSpacing native;

  @JSName('wordSpacing')
  set _wordSpacing(String value) native;

  /** 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 get _zIndex native;

  @JSName('zIndex')
  set _zIndex(String value) native;
}

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

  _CssStyleDeclarationSet(this._elementIterable)
    : _elementCssStyleDeclarationSetIterable = new List.of(
        _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 reasonable 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 mixin 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 "gap" */
  String get gap => getPropertyValue('gap');

  /** Sets the value of "gap" */
  set gap(String value) {
    setProperty('gap', 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 "row-gap" */
  String get rowGap => getPropertyValue('row-gap');

  /** Sets the value of "row-gap" */
  set rowGap(String value) {
    setProperty('row-gap', 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 get selectorText native;

  set selectorText(String value) native;

  CssStyleDeclaration get style 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("CSSStyleSheet")
class CssStyleSheet extends StyleSheet {
  // To suppress missing implicit constructor warnings.
  factory CssStyleSheet._() {
    throw new UnsupportedError("Not supported");
  }

  @Returns('_CssRuleList')
  @Creates('_CssRuleList')
  List<CssRule> get cssRules native;

  CssRule? get ownerRule native;

  @Returns('_CssRuleList')
  @Creates('_CssRuleList')
  List<CssRule>? get rules native;

  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 JavaScriptObject {
  // 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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory CssTransformComponent._() {
    throw new UnsupportedError("Not supported");
  }

  bool? get is2D native;

  set is2D(bool? 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("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);

  bool? get is2D native;

  int? get length native;

  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? get x native;

  set x(CssNumericValue? value) native;

  CssNumericValue? get y native;

  set y(CssNumericValue? value) native;

  CssNumericValue? get z native;

  set z(CssNumericValue? 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("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);

  String? get type native;

  String? get unit native;

  set unit(String? value) native;

  num? get value native;

  set value(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("CSSUnparsedValue")
class CssUnparsedValue extends CssStyleValue {
  // To suppress missing implicit constructor warnings.
  factory CssUnparsedValue._() {
    throw new UnsupportedError("Not supported");
  }

  int? get length native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory CssVariableReferenceValue._() {
    throw new UnsupportedError("Not supported");
  }

  CssUnparsedValue? get fallback native;

  String? get variable 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("CSSViewportRule")
class CssViewportRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssViewportRule._() {
    throw new UnsupportedError("Not supported");
  }

  CssStyleDeclaration? get style 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("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);

  String? get 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.

// 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 JavaScriptObject {
  // 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') as 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')
  dynamic get _get__detail native;

  @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<DListElement>(
    '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? get value native;

  set value(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.

@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") as DataListElement;
  /**
   * 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')
  @Creates('HtmlCollection')
  List<Node>? get 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("DataTransfer")
class DataTransfer extends JavaScriptObject {
  // 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? get dropEffect native;

  set dropEffect(String? value) native;

  String? get effectAllowed native;

  set effectAllowed(String? value) native;

  @Returns('FileList')
  @Creates('FileList')
  List<File>? get files native;

  DataTransferItemList? get items native;

  List<String>? get types native;

  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) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. 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 JavaScriptObject {
  Entry getAsEntry() {
    Entry entry = _webkitGetAsEntry() as Entry;

    if (entry.isFile!) {
      applyExtension('FileEntry', entry);
      applyExtension('webkitFileSystemFileEntry', entry);
      applyExtension('FileSystemFileEntry', entry);
    } else if (entry.isDirectory!) {
      applyExtension('DirectoryEntry', entry);
      applyExtension('webkitFileSystemDirectoryEntry', entry);
      applyExtension('FileSystemDirectoryEntry', entry);
    } else {
      applyExtension('Entry', entry);
      applyExtension('webkitFileSystemEntry', entry);
      applyExtension('FileSystemEntry', entry);
    }

    return entry;
  }

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

  String? get kind native;

  String? get type native;

  File? getAsFile() native;

  @JSName('webkitGetAsEntry')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  Entry? _webkitGetAsEntry() 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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory DataTransferItemList._() {
    throw new UnsupportedError("Not supported");
  }

  int? get length native;

  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 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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");
  }

  int? get lineNumber native;

  String? get message native;

  String? get sourceFile 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.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") as DetailsElement;
  /**
   * 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? get open native;

  set open(bool? 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("DetectedBarcode")
class DetectedBarcode extends JavaScriptObject {
  // 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()');

  Rectangle? get boundingBox native;

  List? get cornerPoints native;

  String? get rawValue 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("DetectedFace")
class DetectedFace extends JavaScriptObject {
  // 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()');

  Rectangle? get boundingBox native;

  List? get landmarks 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("DetectedText")
class DetectedText extends JavaScriptObject {
  // 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()');

  Rectangle? get boundingBox native;

  List? get cornerPoints native;

  String? get rawValue 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("DeviceAcceleration")
class DeviceAcceleration extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory DeviceAcceleration._() {
    throw new UnsupportedError("Not supported");
  }

  num? get x native;

  num? get y native;

  num? get z 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("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);

  DeviceAcceleration? get acceleration native;

  DeviceAcceleration? get accelerationIncludingGravity native;

  num? get interval native;

  DeviceRotationRate? get rotationRate 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("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);

  bool? get absolute native;

  num? get alpha native;

  num? get beta native;

  num? get gamma 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("DeviceRotationRate")
class DeviceRotationRate extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory DeviceRotationRate._() {
    throw new UnsupportedError("Not supported");
  }

  num? get alpha native;

  num? get beta native;

  num? get gamma 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("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? get open native;

  set open(bool? value) native;

  String? get returnValue native;

  set returnValue(String? value) native;

  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,webkitFileSystemDirectoryEntry,FileSystemDirectoryEntry",
)
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);
    applyExtension('WebKitDirectoryReader', reader);
    applyExtension('webkitFileSystemDirectoryReader', reader);
    applyExtension('FileSystemDirectoryReader', 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);
        applyExtension('webkitFileSystemFileEntry', value);
        applyExtension('FileSystemFileEntry', 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,WebKitDirectoryReader,webkitFileSystemDirectoryReader,FileSystemDirectoryReader",
)
class DirectoryReader extends JavaScriptObject {
  // 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(
      (values) {
        values.forEach((value) {
          applyExtension('Entry', value);
          applyExtension('webkitFileSystemEntry', value);
          applyExtension('FileSystemEntry', value);
          Entry entry = value as Entry;
          if (entry.isFile!) {
            applyExtension('FileEntry', entry);
            applyExtension('webkitFileSystemFileEntry', entry);
            applyExtension('FileSystemFileEntry', entry);
          } else if (entry.isDirectory!) {
            applyExtension('DirectoryEntry', entry);
            applyExtension('webkitFileSystemDirectoryEntry', entry);
            applyExtension('FileSystemDirectoryEntry', entry);
          }
        });
        completer.complete(new List<Entry>.from(values));
      },
      (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 is 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<DivElement>(
    '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()');

  String? get addressSpace native;

  @JSName('body')
  HtmlElement? get _body native;

  @JSName('body')
  set _body(HtmlElement? value) native;

  String? get contentType native;

  String? get cookie native;

  set cookie(String? value) native;

  ScriptElement? get currentScript native;

  WindowBase? get window => _convertNativeToDart_Window(this._get_window);
  @JSName('defaultView')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  @Creates('Window|=Object|Null')
  @Returns('Window|=Object|Null')
  dynamic get _get_window native;

  Element? get documentElement native;

  String? get domain native;

  bool? get fullscreenEnabled native;

  @JSName('head')
  HeadElement? get _head native;

  bool? get hidden native;

  DomImplementation? get implementation native;

  @JSName('lastModified')
  String? get _lastModified native;

  String? get origin native;

  @JSName('preferredStylesheetSet')
  String? get _preferredStylesheetSet native;

  String? get readyState native;

  @JSName('referrer')
  String get _referrer native;

  SvgSvgElement? get rootElement native;

  Element? get rootScroller native;

  set rootScroller(Element? value) native;

  Element? get scrollingElement native;

  @JSName('selectedStylesheetSet')
  String? get _selectedStylesheetSet native;

  @JSName('selectedStylesheetSet')
  set _selectedStylesheetSet(String? value) native;

  String? get suborigin native;

  DocumentTimeline? get timeline native;

  @JSName('title')
  String get _title native;

  @JSName('title')
  set _title(String value) native;

  @JSName('visibilityState')
  String? get _visibilityState native;

  @JSName('webkitFullscreenElement')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  Element? get _webkitFullscreenElement native;

  @JSName('webkitFullscreenEnabled')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  bool? get _webkitFullscreenEnabled native;

  @JSName('webkitHidden')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  bool? get _webkitHidden native;

  @JSName('webkitVisibilityState')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  String? get _webkitVisibilityState native;

  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;

  @JSName('webkitExitFullscreen')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void _webkitExitFullscreen() native;

  // From DocumentOrShadowRoot

  Element? get activeElement native;

  Element? get fullscreenElement native;

  Element? get pointerLockElement native;

  @JSName('styleSheets')
  @Returns('_StyleSheetList')
  @Creates('_StyleSheetList')
  List<StyleSheet>? get _styleSheets native;

  @JSName('elementFromPoint')
  Element? _elementFromPoint(int x, int y) native;

  List<Element> elementsFromPoint(int x, int y) native;

  // From FontFaceSource

  FontFaceSet? get fonts native;

  // From NonElementParentNode

  Element? getElementById(String elementId) native;

  // From ParentNode

  @JSName('childElementCount')
  int get _childElementCount native;

  @JSName('children')
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  List<Node>? get _children native;

  @JSName('firstElementChild')
  Element? get _firstElementChild native;

  @JSName('lastElementChild')
  Element? get _lastElementChild native;

  /**
   * 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].
  @DomName('Document.ondblclick')
  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));

  @pragma('dart2js:tryInline') // 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 ParentNode, NonElementParentNode {
  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));

  // innerHtml is marked as nullable, even though it is guaranteed to return a
  // non-nullable, because ShadowRoot.innerHtml overrides it and can be
  // incompatible.
  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')
  int get _childElementCount native;

  @JSName('firstElementChild')
  Element? get _firstElementChild native;

  @JSName('lastElementChild')
  Element? get _lastElementChild native;

  /**
   * 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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory DocumentOrShadowRoot._() {
    throw new UnsupportedError("Not supported");
  }

  Element? get activeElement native;

  Element? get fullscreenElement native;

  Element? get pointerLockElement native;

  @Returns('_StyleSheetList')
  @Creates('_StyleSheetList')
  List<StyleSheet>? get styleSheets native;

  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 JavaScriptObject {
  // 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);

  String? get message native;

  String? get 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.

@Unstable()
@Native("DOMException")
class DomException extends JavaScriptObject {
  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';
  static const String ENCODING = 'EncodingError';
  static const String NOT_READABLE = 'NotReadableError';
  static const String UNKNOWN = 'UnknownError';
  static const String CONSTRAINT = 'ConstraintError';
  static const String TRANSACTION_INACTIVE = 'TransactionInactiveError';
  static const String READ_ONLY = 'ReadOnlyError';
  static const String VERSION = 'VersionError';
  static const String OPERATION = 'OperationError';
  static const String NOT_ALLOWED = 'NotAllowedError';
  // 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 as String;
  }

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

  String? get message native;

  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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 native;

  set a(num? value) native;

  // Shadowing definition.

  num? get b native;

  set b(num? value) native;

  // Shadowing definition.

  num? get c native;

  set c(num? value) native;

  // Shadowing definition.

  num? get d native;

  set d(num? value) native;

  // Shadowing definition.

  num? get e native;

  set e(num? value) native;

  // Shadowing definition.

  num? get f native;

  set f(num? value) native;

  // Shadowing definition.

  num? get m11 native;

  set m11(num? value) native;

  // Shadowing definition.

  num? get m12 native;

  set m12(num? value) native;

  // Shadowing definition.

  num? get m13 native;

  set m13(num? value) native;

  // Shadowing definition.

  num? get m14 native;

  set m14(num? value) native;

  // Shadowing definition.

  num? get m21 native;

  set m21(num? value) native;

  // Shadowing definition.

  num? get m22 native;

  set m22(num? value) native;

  // Shadowing definition.

  num? get m23 native;

  set m23(num? value) native;

  // Shadowing definition.

  num? get m24 native;

  set m24(num? value) native;

  // Shadowing definition.

  num? get m31 native;

  set m31(num? value) native;

  // Shadowing definition.

  num? get m32 native;

  set m32(num? value) native;

  // Shadowing definition.

  num? get m33 native;

  set m33(num? value) native;

  // Shadowing definition.

  num? get m34 native;

  set m34(num? value) native;

  // Shadowing definition.

  num? get m41 native;

  set m41(num? value) native;

  // Shadowing definition.

  num? get m42 native;

  set m42(num? value) native;

  // Shadowing definition.

  num? get m43 native;

  set m43(num? value) native;

  // Shadowing definition.

  num? get m44 native;

  set m44(num? value) native;

  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 JavaScriptObject {
  // 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 native;

  num? get b native;

  num? get c native;

  num? get d native;

  num? get e native;

  num? get f native;

  bool? get is2D native;

  bool? get isIdentity native;

  num? get m11 native;

  num? get m12 native;

  num? get m13 native;

  num? get m14 native;

  num? get m21 native;

  num? get m22 native;

  num? get m23 native;

  num? get m24 native;

  num? get m31 native;

  num? get m32 native;

  num? get m33 native;

  num? get m34 native;

  num? get m41 native;

  num? get m42 native;

  num? get m43 native;

  num? get m44 native;

  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 JavaScriptObject {
  // 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 native;

  set w(num? value) native;

  // Shadowing definition.

  num? get x native;

  set x(num? value) native;

  // Shadowing definition.

  num? get y native;

  set y(num? value) native;

  // Shadowing definition.

  num? get z native;

  set z(num? value) native;

  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 JavaScriptObject {
  // 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 native;

  num? get x native;

  num? get y native;

  num? get z native;

  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 JavaScriptObject {
  // 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()');

  DomPoint? get p1 native;

  DomPoint? get p2 native;

  DomPoint? get p3 native;

  DomPoint? get p4 native;

  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 JavaScriptObject
    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 IndexError.withLength(index, length, indexable: 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 newLength) {
    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 JavaScriptObject implements Rectangle {
  // NOTE! All code below should be common with RectangleBase.
  String toString() {
    return 'Rectangle ($left, $top) $width x $height';
  }

  bool operator ==(other) =>
      other is Rectangle &&
      left == other.left &&
      top == other.top &&
      width == other.width &&
      height == other.height;

  int get hashCode => Object.hash(left, top, width, height);

  /**
   * 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()');

  // The following getter is incompatible with some browsers but
  // must be made non-nullable to match the overridden method.

  @JSName('bottom')
  num? get _bottom native;

  num get bottom => _bottom!;

  // The following getter is incompatible with some browsers but
  // must be made non-nullable to match the overridden method.

  @JSName('height')
  num? get _height native;

  num get height => _height!;

  // The following getter is incompatible with some browsers but
  // must be made non-nullable to match the overridden method.

  @JSName('left')
  num? get _left native;

  num get left => _left!;

  // The following getter is incompatible with some browsers but
  // must be made non-nullable to match the overridden method.

  @JSName('right')
  num? get _right native;

  num get right => _right!;

  // The following getter is incompatible with some browsers but
  // must be made non-nullable to match the overridden method.

  @JSName('top')
  num? get _top native;

  num get top => _top!;

  // The following getter is incompatible with some browsers but
  // must be made non-nullable to match the overridden method.

  @JSName('width')
  num? get _width native;

  num get width => _width!;

  num? get x native;

  num? get y native;

  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 JavaScriptObject
    with ListMixin<String>, ImmutableListMixin<String>
    implements List<String>, JavaScriptIndexingBehavior<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 IndexError.withLength(index, length, indexable: 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 newLength) {
    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 JavaScriptObject {
  // 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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory DomTokenList._() {
    throw new UnsupportedError("Not supported");
  }

  int get length native;

  String? get value native;

  set value(String? value) native;

  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 as HtmlCollection,
      _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] as Element;
  }

  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) {
    _addAll(_element, iterable);
  }

  static void _addAll(Element _element, 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) {
    Iterable<Element> 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) {
    return _remove(_element, object);
  }

  static bool _remove(Element _element, 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 insertAll(int index, Iterable<Element> iterable) {
    throw new UnimplementedError();
  }

  void setAll(int index, Iterable<Element> iterable) {
    throw new UnimplementedError();
  }

  void clear() {
    _element._clearChildren();
  }

  Element removeAt(int index) {
    final result = this[index];
    // TODO(41258): Remove null check after unfork/strong mode.
    if (result != null) {
      _element._removeChild(result);
    }
    return result;
  }

  Element removeLast() {
    final result = this.last;
    _element._removeChild(result);
    return result;
  }

  Element get first => _first(_element);

  @pragma('dart2js:noInline')
  static Element _first(Element _element) {
    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 [Element]s 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 [Element.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 [Element.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 [Element.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 [Element.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].
  @DomName('Element.ondblclick')
  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] as E;

  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 as E;

  E get last => _nodeList.last as E;

  E get single => _nodeList.single as E;

  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].
  @DomName('Element.ondblclick')
  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
        ParentNode,
        ChildNode,
        NonDocumentTypeChildNode,
        GlobalEventHandlers {
  /**
   * 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 as Element;
  }

  /**
   * 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? typeExtension]) =>
      _ElementFactoryProvider.createElement_tag(tag, typeExtension);

  /// 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]!;
    }
  }

  @pragma('dart2js:tryInline')
  String? getAttribute(String name) {
    // TODO(41258): Delete this assertion after forcing strong mode.
    // Protect [name] against string conversion to "null" or "undefined".
    assert(name != null, 'Attribute name cannot be null');
    return _getAttribute(name);
  }

  @pragma('dart2js:tryInline')
  String? getAttributeNS(String? namespaceURI, String name) {
    // TODO(41258): Delete this assertion after forcing strong mode.
    // Protect [name] against string conversion to "null" or "undefined".
    // [namespaceURI] does not need protecting, both `null` and `undefined` map to `null`.
    assert(name != null, 'Attribute name cannot be null');
    return _getAttributeNS(namespaceURI, name);
  }

  @pragma('dart2js:tryInline')
  bool hasAttribute(String name) {
    // TODO(41258): Delete this assertion after forcing strong mode.
    // Protect [name] against string conversion to "null" or "undefined".
    assert(name != null, 'Attribute name cannot be null');
    return _hasAttribute(name);
  }

  @pragma('dart2js:tryInline')
  bool hasAttributeNS(String? namespaceURI, String name) {
    // TODO(41258): Delete this assertion after forcing strong mode.
    // Protect [name] against string conversion to "null" or "undefined".
    // [namespaceURI] does not need protecting, both `null` and `undefined` map to `null`.
    assert(name != null, 'Attribute name cannot be null');
    return _hasAttributeNS(namespaceURI, name);
  }

  @pragma('dart2js:tryInline')
  void removeAttribute(String name) {
    // TODO(41258): Delete this assertion after forcing strong mode.
    // Protect [name] against string conversion to "null" or "undefined".
    assert(name != null, 'Attribute name cannot be null');
    _removeAttribute(name);
  }

  @pragma('dart2js:tryInline')
  void removeAttributeNS(String? namespaceURI, String name) {
    // TODO(41258): Delete this assertion after forcing strong mode.
    // Protect [name] against string conversion to "null" or "undefined".
    assert(name != null, 'Attribute name cannot be null');
    _removeAttributeNS(namespaceURI, name);
  }

  @pragma('dart2js:tryInline')
  void setAttribute(String name, Object value) {
    // TODO(41258): Delete these assertions after forcing strong mode.
    // Protect [name] against string conversion to "null" or "undefined".
    assert(name != null, 'Attribute name cannot be null');
    // TODO(sra): assert(value != null, 'Attribute value cannot be null.');
    _setAttribute(name, value);
  }

  @pragma('dart2js:tryInline')
  void setAttributeNS(String? namespaceURI, String name, Object value) {
    // TODO(41258): Delete these assertions after forcing strong mode.
    // Protect [name] against string conversion to "null" or "undefined".
    assert(name != null, 'Attribute name cannot be null');
    // TODO(sra): assert(value != null, 'Attribute value cannot be null.');
    _setAttributeNS(namespaceURI, name, value);
  }

  /**
   * 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);

  List<Node> get _children =>
  // Element.children always returns the same list-like object which is a
  // live view on the underlying DOM tree. So we can GVN it and remove it if
  // unused.
  JS(
    'returns:HtmlCollection;creates:HtmlCollection;'
        'depends:none;effects:none;gvn:true',
    '#.children',
    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));

  @JSName('setApplyScroll')
  void _setApplyScroll(
    ScrollStateCallback scrollStateCallback,
    String nativeScrollBehavior,
  ) native;

  Future<ScrollState> setApplyScroll(String nativeScrollBehavior) {
    var completer = new Completer<ScrollState>();
    _setApplyScroll((value) {
      completer.complete(value);
    }, nativeScrollBehavior);
    return completer.future;
  }

  @JSName('setDistributeScroll')
  void _setDistributeScroll(
    ScrollStateCallback scrollStateCallback,
    String nativeScrollBehavior,
  ) native;

  Future<ScrollState> setDistributeScroll(String nativeScrollBehavior) {
    var completer = new Completer<ScrollState>();
    _setDistributeScroll((value) {
      completer.complete(value);
    }, nativeScrollBehavior);
    return completer.future;
  }

  /**
   * 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.
   *
   * Any data attributes in the markup will be converted to camel-cased keys
   * in the map based on [these conversion
   * rules](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset).
   *
   * 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:
   *
   * * [HTML data-* attributes naming
       restrictions](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-*)
   * * [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:
   *
   * * [Cascade and Inheritance](https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/Cascade_and_inheritance)
   *   from MDN.
   * * [Pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements)
   *   from MDN.
   */
  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.
   *
   * Warning: This API is part of multiple custom element APIs that are no [longer supported](https://github.com/dart-lang/sdk/issues/49536).
   */
  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.
   *
   * Warning: This API is part of multiple custom element APIs that are no [longer supported](https://github.com/dart-lang/sdk/issues/49536).
   * 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] parameter 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 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](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView)
   *   from MDN.
   * * [scrollIntoViewIfNeeded](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoViewIfNeeded)
   *   from MDN.
   */
  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) {
      // TODO(srujzs): This method shouldn't be calling out to
      // `scrollIntoViewIfNeeded`. Remove this and make `scrollIntoView` match
      // the browser definition. If you intend to use `scrollIntoViewIfNeeded`,
      // use the `Element.scrollIntoViewIfNeeded` method.
      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.
   *
   * ```dart
   *     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 as Element?;
    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') as BaseElement;
      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") as BodyElement;
    }

    Element contextElement;
    if (this is BodyElement) {
      contextElement = _parseDocument!.body!;
    } else {
      contextElement = _parseDocument!.createElement(tagName);
      _parseDocument!.body!.append(contextElement);
    }
    DocumentFragment fragment;
    if (Range.supportsCreateContextualFragment &&
        _canBeUsedToCreateContextualFragment) {
      _parseRange!.selectNodeContents(contextElement);
      // createContextualFragment expects a non-nullable html string.
      // If null is passed, it gets converted to 'null' instead.
      fragment = _parseRange!.createContextualFragment(html ?? 'null');
    } 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;

  @JSName('innerText')
  String get innerText native;
  set innerText(String value) native;

  /**
   * 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;
	 }
         // If something has corrupted the traversal we want to detect
         // these on not only the children (tested below) but on the node itself
         // in case it was bypassed.
         if (element["id"] == 'lastChild' || element["name"] == 'lastChild' ||
             element["id"] == 'previousSibling' || element["name"] == 'previousSibling' ||
             element["id"] == 'children' || element["name"] == 'children') {
           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"] == 'previousSibling'  || child["name"] == 'previousSibling' ||
               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 element) {
    String result = 'element tag unavailable';
    try {
      if (element.tagName is String) {
        result = element.tagName;
      }
    } catch (e) {}
    return result;
  }

  Element? get offsetParent native;

  int get offsetHeight => JS<num>('num', '#.offsetHeight', this).round();

  int get offsetLeft => JS<num>('num', '#.offsetLeft', this).round();

  int get offsetTop => JS<num>('num', '#.offsetTop', this).round();

  int get offsetWidth => JS<num>('num', '#.offsetWidth', this).round();

  int get scrollHeight => JS<num>('num', '#.scrollHeight', this).round();
  int get scrollLeft => JS<num>('num', '#.scrollLeft', this).round();

  set scrollLeft(int value) {
    JS("void", "#.scrollLeft = #", this, value.round());
  }

  int get scrollTop => JS<num>('num', '#.scrollTop', this).round();

  set scrollTop(int value) {
    JS("void", "#.scrollTop = #", this, value.round());
  }

  int get scrollWidth => JS<num>('num', '#.scrollWidth', this).round();

  /**
   * Displays this element fullscreen.
   *
   * ## Other resources
   *
   * * [Fullscreen
   *   API](https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API)
   *   from MDN.
   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  Future<void> requestFullscreen([Map? options]) {
    var retValue;
    if (options != null) {
      retValue = JS(
        '',
        '(#.requestFullscreen||#.webkitRequestFullscreen).call(#, #)',
        this,
        this,
        this,
        convertDartToNative_Dictionary(options),
      );
    } else {
      retValue = JS(
        '',
        '(#.requestFullscreen||#.webkitRequestFullscreen).call(#)',
        this,
        this,
        this,
      );
    }
    if (retValue != null) return promiseToFuture(retValue);
    return Future<void>.value();
  }

  // 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.
   */
  @DomName('Element.dblclickEvent')
  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 get contentEditable native;

  set contentEditable(String value) native;

  String? get dir native;

  set dir(String? value) native;

  /**
   * 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 get draggable native;

  set draggable(bool value) native;

  /**
   * 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 get hidden native;

  set hidden(bool value) native;

  bool? get inert native;

  set inert(bool? value) native;

  String? get inputMode native;

  set inputMode(String? value) native;

  bool? get isContentEditable native;

  String? get lang native;

  set lang(String? value) native;

  bool? get spellcheck native;

  set spellcheck(bool? value) native;

  CssStyleDeclaration get style native;

  int? get tabIndex native;

  set tabIndex(int? value) native;

  String? get title native;

  set title(String? value) native;

  /**
   * 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? get translate native;

  set translate(bool? value) native;

  void blur() native;

  void click() native;

  void focus() native;

  AccessibleNode? get accessibleNode native;

  SlotElement? get assignedSlot native;

  @JSName('attributes')
  _NamedNodeMap? get _attributes native;

  String get className native;

  set className(String value) native;

  int get clientHeight native;

  int? get clientLeft native;

  int? get clientTop native;

  int get clientWidth native;

  String? get computedName native;

  String? get computedRole native;

  String get id native;

  set id(String value) native;

  @JSName('innerHTML')
  String? get _innerHtml native;

  @JSName('innerHTML')
  set _innerHtml(String? value) native;

  @JSName('localName')
  String? get _localName native;

  @JSName('namespaceURI')
  String? get _namespaceUri native;

  @JSName('outerHTML')
  String? get outerHtml native;

  @JSName('scrollHeight')
  int? get _scrollHeight native;

  @JSName('scrollLeft')
  num get _scrollLeft native;

  @JSName('scrollLeft')
  set _scrollLeft(num value) native;

  @JSName('scrollTop')
  num get _scrollTop native;

  @JSName('scrollTop')
  set _scrollTop(num value) native;

  @JSName('scrollWidth')
  int? get _scrollWidth native;

  String? get slot native;

  set slot(String? value) native;

  StylePropertyMap? get styleMap native;

  String get tagName native;

  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;

  @JSName('getAttribute')
  String? _getAttribute(String name) native;

  @JSName('getAttributeNS')
  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')
  @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;

  /**
   * Nonstandard version of `scrollIntoView` that scrolls the current element
   * into the visible area of the browser window if it's not already within the
   * visible area of the browser window. If the element is already within the
   * visible area of the browser window, then no scrolling takes place.
   *
   * ## Other resources
   *
   * * [Element.scrollIntoViewIfNeeded](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoViewIfNeeded)
   *   from MDN.
   */
  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;

  @JSName('setAttribute')
  void _setAttribute(String name, Object value) native;

  @JSName('setAttributeNS')
  void _setAttributeNS(String? namespaceURI, String name, Object value) native;

  void setPointerCapture(int pointerId) native;

  // From ChildNode

  void after(Object nodes) native;

  void before(Object nodes) native;

  // From NonDocumentTypeChildNode

  Element? get nextElementSibling native;

  Element? get previousElementSibling native;

  // From ParentNode

  @JSName('childElementCount')
  int get _childElementCount native;

  @JSName('firstElementChild')
  Element? get _firstElementChild native;

  @JSName('lastElementChild')
  Element? get _lastElementChild native;

  /**
   * 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].
  @DomName('Element.ondblclick')
  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") as EmbedElement;
  /**
   * 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 get height native;

  set height(String value) native;

  String? get name native;

  set name(String? value) native;

  String get src native;

  set src(String value) native;

  String get type native;

  set type(String value) native;

  String get width native;

  set width(String value) native;

  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,webkitFileSystemEntry,FileSystemEntry")
class Entry extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory Entry._() {
    throw new UnsupportedError("Not supported");
  }

  FileSystem? get filesystem native;

  String? get fullPath native;

  bool? get isDirectory native;

  bool? get isFile native;

  String? get name native;

  @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) {
        applyExtension('Entry', value);
        applyExtension('webkitFileSystemEntry', value);
        applyExtension('FileSystemEntry', 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);

  int? get colno native;

  @Creates('Null')
  Object? get error native;

  String? get filename native;

  int? get lineno native;

  String? get message 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("Event,InputEvent,SubmitEvent")
class Event extends JavaScriptObject {
  // 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? get _selector native;
  set _selector(String? value) native;

  /**
   * 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 as Element?;
    Element? target = this.target as Element?;
    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>('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;

  bool? get bubbles native;

  bool? get cancelable native;

  bool? get composed native;

  EventTarget? get currentTarget =>
      _convertNativeToDart_EventTarget(this._get_currentTarget);
  @JSName('currentTarget')
  @Creates('Null')
  @Returns('EventTarget|=Object|Null')
  dynamic get _get_currentTarget native;

  bool get defaultPrevented native;

  int get eventPhase native;

  bool? get isTrusted native;

  EventTarget? get target => _convertNativeToDart_EventTarget(this._get_target);
  @JSName('target')
  @Creates('Node')
  @Returns('EventTarget|=Object')
  dynamic get _get_target native;

  num? get timeStamp native;

  String get type native;

  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;

  int? get readyState native;

  String? get url native;

  bool? get withCredentials native;

  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 JavaScriptObject {
  // 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
  Object? get data native;

  String? get lastEventId native;

  String? get origin native;

  List<MessagePort>? get ports native;

  @Creates('Client|ServiceWorker|MessagePort')
  @Returns('Client|ServiceWorker|MessagePort|Null')
  Object? get source 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("External")
class External extends JavaScriptObject {
  // 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 JavaScriptObject {
  // 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<dynamic>> detect(/*ImageBitmapSource*/ image) =>
      promiseToFuture<List<dynamic>>(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);

  String? get protocol native;

  String? get provider native;

  // From CredentialUserData

  @JSName('iconURL')
  String? get iconUrl native;

  String? get 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("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);

  String? get clientId native;

  bool? get isReload native;

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

  _Request? get request native;

  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<FieldSetElement>(
    '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? get disabled native;

  set disabled(bool? value) native;

  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  List<Node>? get elements native;

  FormElement? get form native;

  String get name native;

  set name(String value) native;

  String get type native;

  String get validationMessage native;

  ValidityState get validity native;

  bool get willValidate 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("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);

  int? get lastModified native;

  DateTime get lastModifiedDate =>
      convertNativeToDart_DateTime(this._get_lastModifiedDate);
  @JSName('lastModifiedDate')
  @Creates('Null')
  dynamic get _get_lastModifiedDate native;

  String get name native;

  @JSName('webkitRelativePath')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  String? get relativePath 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 _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,webkitFileSystemFileEntry,FileSystemFileEntry")
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 JavaScriptObject
    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 IndexError.withLength(index, length, indexable: 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 newLength) {
    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;

  DomException? get error native;

  int get readyState native;

  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,WebKitFileSystem,webkitFileSystem,FileSystem")
class FileSystem extends JavaScriptObject {
  // 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)');

  String? get name native;

  DirectoryEntry? get 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.

// 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;

  DomException? get error native;

  int? get length native;

  int? get position native;

  int? get readyState native;

  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')
  dynamic get _get_relatedTarget 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("FontFace")
class FontFace extends JavaScriptObject {
  // 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? get display native;

  set display(String? value) native;

  String? get family native;

  set family(String? value) native;

  String? get featureSettings native;

  set featureSettings(String? value) native;

  Future<FontFace> get loaded =>
      promiseToFuture<FontFace>(JS("creates:FontFace;", "#.loaded", this));

  String? get status native;

  String? get stretch native;

  set stretch(String? value) native;

  String? get style native;

  set style(String? value) native;

  String? get unicodeRange native;

  set unicodeRange(String? value) native;

  String? get variant native;

  set variant(String? value) native;

  String? get weight native;

  set weight(String? value) native;

  Future<FontFace> load() =>
      promiseToFuture<FontFace>(JS("creates:FontFace;", "#.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');

  String? get status native;

  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);

  List<FontFace>? get fontfaces 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("FontFaceSource")
class FontFaceSource extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory FontFaceSource._() {
    throw new UnsupportedError("Not supported");
  }

  FontFaceSet? get fonts 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("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,
  );

  String? get origin native;

  _Request? get request native;

  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 JavaScriptObject {
  // 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<FormElement>(
    '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? get acceptCharset native;

  set acceptCharset(String? value) native;

  String? get action native;

  set action(String? value) native;

  String? get autocomplete native;

  set autocomplete(String? value) native;

  String? get encoding native;

  set encoding(String? value) native;

  String? get enctype native;

  set enctype(String? value) native;

  int? get length native;

  String? get method native;

  set method(String? value) native;

  String? get name native;

  set name(String? value) native;

  bool? get noValidate native;

  set noValidate(bool? value) native;

  String? get target native;

  set target(String? value) native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory Gamepad._() {
    throw new UnsupportedError("Not supported");
  }

  List<num>? get axes native;

  @Creates('JSExtendableArray|GamepadButton')
  @Returns('JSExtendableArray')
  List<GamepadButton>? get buttons native;

  bool? get connected native;

  int? get displayId native;

  String? get hand native;

  String? get id native;

  int? get index native;

  String? get mapping native;

  GamepadPose? get pose native;

  int? get 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("GamepadButton")
class GamepadButton extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory GamepadButton._() {
    throw new UnsupportedError("Not supported");
  }

  bool? get pressed native;

  bool? get touched native;

  num? get 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("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);

  Gamepad? get gamepad 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("GamepadPose")
class GamepadPose extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory GamepadPose._() {
    throw new UnsupportedError("Not supported");
  }

  Float32List? get angularAcceleration native;

  Float32List? get angularVelocity native;

  bool? get hasOrientation native;

  bool? get hasPosition native;

  Float32List? get linearAcceleration native;

  Float32List? get linearVelocity native;

  Float32List? get orientation native;

  Float32List? get position 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("Geolocation")
class Geolocation extends JavaScriptObject {
  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;
    StreamController<Geoposition> controller =
        new StreamController<Geoposition>(
          sync: true,
          onCancel: () {
            final id = watchId;
            if (id != null) _clearWatch(id);
          },
        );
    controller.onListen = () {
      assert(watchId == null);
      watchId = _watchPosition(
        (position) {
          controller.add(_ensurePosition(position));
        },
        (error) {
          controller.addError(error);
        },
        options,
      );
    };

    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;

  @Creates('Geoposition')
  @Creates('PositionError')
  void _getCurrentPosition(
    _PositionCallback successCallback, [
    _PositionErrorCallback? errorCallback,
    Map? options,
  ]) {
    if (options != null) {
      var successCallback_1 = convertDartClosureToJS(successCallback, 1);
      var options_2 = convertDartToNative_Dictionary(options);
      _getCurrentPosition_1(successCallback_1, errorCallback, options_2);
      return;
    }
    if (errorCallback != null) {
      var successCallback_1 = convertDartClosureToJS(successCallback, 1);
      _getCurrentPosition_2(successCallback_1, errorCallback);
      return;
    }
    var successCallback_1 = convertDartClosureToJS(successCallback, 1);
    _getCurrentPosition_3(successCallback_1);
    return;
  }

  @JSName('getCurrentPosition')
  @Creates('Geoposition')
  @Creates('PositionError')
  void _getCurrentPosition_1(
    successCallback,
    _PositionErrorCallback? errorCallback,
    options,
  ) native;
  @JSName('getCurrentPosition')
  @Creates('Geoposition')
  @Creates('PositionError')
  void _getCurrentPosition_2(
    successCallback,
    _PositionErrorCallback? errorCallback,
  ) native;
  @JSName('getCurrentPosition')
  @Creates('Geoposition')
  @Creates('PositionError')
  void _getCurrentPosition_3(successCallback) native;

  @Creates('Geoposition')
  @Creates('PositionError')
  int _watchPosition(
    _PositionCallback successCallback, [
    _PositionErrorCallback? errorCallback,
    Map? options,
  ]) {
    if (options != null) {
      var successCallback_1 = convertDartClosureToJS(successCallback, 1);
      var options_2 = convertDartToNative_Dictionary(options);
      return _watchPosition_1(successCallback_1, errorCallback, options_2);
    }
    if (errorCallback != null) {
      var successCallback_1 = convertDartClosureToJS(successCallback, 1);
      return _watchPosition_2(successCallback_1, errorCallback);
    }
    var successCallback_1 = convertDartClosureToJS(successCallback, 1);
    return _watchPosition_3(successCallback_1);
  }

  @JSName('watchPosition')
  @Creates('Geoposition')
  @Creates('PositionError')
  int _watchPosition_1(
    successCallback,
    _PositionErrorCallback? errorCallback,
    options,
  ) native;
  @JSName('watchPosition')
  @Creates('Geoposition')
  @Creates('PositionError')
  int _watchPosition_2(
    successCallback,
    _PositionErrorCallback? errorCallback,
  ) native;
  @JSName('watchPosition')
  @Creates('Geoposition')
  @Creates('PositionError')
  int _watchPosition_3(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,GeolocationPosition")
class Geoposition extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory Geoposition._() {
    throw new UnsupportedError("Not supported");
  }

  Coordinates? get coords native;

  int? get 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.

// 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');

  @DomName('GlobalEventHandlers.dblclickEvent')
  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);

  @DomName('GlobalEventHandlers.ondblclick')
  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()');

  num? get x native;

  num? get y native;

  num? get z 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 `<hr>` tag.
 */
@Native("HTMLHRElement")
class HRElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory HRElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory HRElement() => JS<HRElement>(
    '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 get color native;

  set color(String value) 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.

@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')
  String? get newUrl native;

  @JSName('oldURL')
  String? get oldUrl 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("HTMLHeadElement")
class HeadElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory HeadElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory HeadElement() => JS<HeadElement>(
    '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 JavaScriptObject {
  // 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<HeadingElement>(
    'returns:HeadingElement;creates:HeadingElement;new:true',
    '#.createElement(#)',
    document,
    "h1",
  );

  factory HeadingElement.h2() => JS<HeadingElement>(
    'returns:HeadingElement;creates:HeadingElement;new:true',
    '#.createElement(#)',
    document,
    "h2",
  );

  factory HeadingElement.h3() => JS<HeadingElement>(
    'returns:HeadingElement;creates:HeadingElement;new:true',
    '#.createElement(#)',
    document,
    "h3",
  );

  factory HeadingElement.h4() => JS<HeadingElement>(
    'returns:HeadingElement;creates:HeadingElement;new:true',
    '#.createElement(#)',
    document,
    "h4",
  );

  factory HeadingElement.h5() => JS<HeadingElement>(
    'returns:HeadingElement;creates:HeadingElement;new:true',
    '#.createElement(#)',
    document,
    "h5",
  );

  factory HeadingElement.h6() => JS<HeadingElement>(
    '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 JavaScriptObject 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");
  }

  int get length native;

  String? get scrollRestoration native;

  set scrollRestoration(String? value) native;

  dynamic get state =>
      convertNativeToDart_SerializedScriptValue(this._get_state);
  @JSName('state')
  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  dynamic get _get_state native;

  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 JavaScriptObject
    with ListMixin<Node>, ImmutableListMixin<Node>
    implements List<Node>, JavaScriptIndexingBehavior<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 IndexError.withLength(index, length, indexable: 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 newLength) {
    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? get body native;
  set body(BodyElement? value) native;

  /// 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
   *
   * * [Fullscreen
   *   API](https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API)
   *   from MDN.
   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void exitFullscreen() {
    _webkitExitFullscreen();
  }

  /**
   * 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");
  }

  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<HtmlHtmlElement>(
    '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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory HtmlHyperlinkElementUtils._() {
    throw new UnsupportedError("Not supported");
  }

  String? get hash native;

  set hash(String? value) native;

  String? get host native;

  set host(String? value) native;

  String? get hostname native;

  set hostname(String? value) native;

  String? get href native;

  set href(String? value) native;

  String? get origin native;

  String? get password native;

  set password(String? value) native;

  String? get pathname native;

  set pathname(String? value) native;

  String? get port native;

  set port(String? value) native;

  String? get protocol native;

  set protocol(String? value) native;

  String? get search native;

  set search(String? value) native;

  String? get username native;

  set username(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.

@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.
  *
  * **Note:** You should avoid directly using `HttpRequest` to make HTTP
  * requests. You can use `HttpRequest` indirectly through the
  * [`BrowserClient`](https://pub.dev/documentation/http/latest/browser_client/BrowserClient-class.html)
  * adapter in [`package:http`](https://pub.dev/packages/http).
  *
  * Using a higher-level library, like
  * [`package:http`](https://pub.dev/packages/http), allows you to switch
  * implementations with minimal changes to your code. For example,
  * `package:http`
  * [`Client`](https://pub.dev/documentation/http/latest/http/Client-class.html)
  * has implementations for the browser and implementations that use
  * platform native HTTP clients on Android and iOS.
  *
  * 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) {
  *       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.
  *
  * ## Other resources
  *
  * * [Fetch data dynamically](https://dart.dev/tutorials/web/fetch-data/),
  * a tutorial shows how to load data from a static file or from a server.
  * * [Dart article on using HttpRequests](https://dart.dev/guides/libraries/library-tour#using-http-resources-with-httprequest)
  * * [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].
   *
   * 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((String 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 [getAllResponseHeaders].
   *
   * 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 status = xhr.status!;
      var accepted = status >= 200 && status < 300;
      var fileUri = status == 0; // file:// URIs have status of 0.
      var notModified = 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 = status > 307 && 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 as FutureOr<String>?);
      }, 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 asynchronously, with no user or password
   * authentication information. If `async` is false, the request will be sent
   * 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>
   */

  int get readyState native;

  /**
   * 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',
  )
  dynamic get _get_response native;

  /**
   * The response in String form or empty String on failure.
   */

  String? get responseText native;

  /**
   * [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 get responseType native;

  set responseType(String value) native;

  @JSName('responseURL')
  String? get responseUrl native;

  @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.
   */
  Document? get responseXml native;

  /**
   * 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)
   */

  int? get status native;

  /**
   * The request response string (such as \"OK\").
   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
   */

  String? get statusText native;

  /**
   * Length of time in milliseconds before a request is automatically
   * terminated.
   *
   * When the time has passed, an [HttpRequestEventTarget.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? get timeout native;

  set timeout(int? value) native;

  /**
   * [EventTarget] that can hold listeners to track the progress of the request.
   */
  @Unstable()
  HttpRequestUpload get upload native;

  /**
   * 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? get withCredentials native;

  set withCredentials(bool? value) native;

  /**
   * 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<IFrameElement>(
    '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? get allow native;

  set allow(String? value) native;

  bool? get allowFullscreen native;

  set allowFullscreen(bool? value) native;

  bool? get allowPaymentRequest native;

  set allowPaymentRequest(bool? value) native;

  WindowBase? get contentWindow =>
      _convertNativeToDart_Window(this._get_contentWindow);
  @JSName('contentWindow')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  dynamic get _get_contentWindow native;

  String? get csp native;

  set csp(String? value) native;

  String? get height native;

  set height(String? value) native;

  String? get name native;

  set name(String? value) native;

  String? get referrerPolicy native;

  set referrerPolicy(String? value) native;

  DomTokenList? get sandbox native;

  String? get src native;

  set src(String? value) native;

  String? get srcdoc native;

  set srcdoc(String? value) native;

  String? get width native;

  set width(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.

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

  bool? get didTimeout native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory ImageBitmap._() {
    throw new UnsupportedError("Not supported");
  }

  int? get height native;

  int? get width native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory ImageBitmapRenderingContext._() {
    throw new UnsupportedError("Not supported");
  }

  CanvasElement? get canvas native;

  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 JavaScriptObject {
  // 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);

  MediaStreamTrack? get track native;

  Future<PhotoCapabilities> getPhotoCapabilities() =>
      promiseToFuture<PhotoCapabilities>(
        JS("creates:PhotoCapabilities;", "#.getPhotoCapabilities()", this),
      );

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

  Future<ImageBitmap> grabFrame() => promiseToFuture<ImageBitmap>(
    JS("creates:ImageBitmap;", "#.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("creates:Blob;", "#.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 JavaScriptObject {
  // 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')
  Uint8ClampedList get data native;

  int get height native;

  int get width 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("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<ImageElement>(
      '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? get alt native;

  set alt(String? value) native;

  String? get async native;

  set async(String? value) native;

  bool? get complete native;

  String? get crossOrigin native;

  set crossOrigin(String? value) native;

  String? get currentSrc native;

  int? get height native;

  set height(int? value) native;

  bool? get isMap native;

  set isMap(bool? value) native;

  int get naturalHeight native;

  int get naturalWidth native;

  String? get referrerPolicy native;

  set referrerPolicy(String? value) native;

  String? get sizes native;

  set sizes(String? value) native;

  String? get src native;

  set src(String? value) native;

  String? get srcset native;

  set srcset(String? value) native;

  String? get useMap native;

  set useMap(String? value) native;

  int? get width native;

  set width(int? value) native;

  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 JavaScriptObject {
  // 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()');

  bool? get firesTouchEvents 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("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") as InputElement;
    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? get accept native;

  set accept(String? value) native;

  String? get alt native;

  set alt(String? value) native;

  String? get autocapitalize native;

  set autocapitalize(String? value) native;

  String get autocomplete native;

  set autocomplete(String value) native;

  bool get autofocus native;

  set autofocus(bool value) native;

  String? get capture native;

  set capture(String? value) native;

  bool? get checked native;

  set checked(bool? value) native;

  bool? get defaultChecked native;

  set defaultChecked(bool? value) native;

  String? get defaultValue native;

  set defaultValue(String? value) native;

  String? get dirName native;

  set dirName(String? value) native;

  bool? get disabled native;

  set disabled(bool? value) native;

  @Returns('FileList|Null')
  @Creates('FileList')
  List<File>? get files native;

  set files(List<File>? value) native;

  FormElement? get form native;

  String get formAction native;

  set formAction(String value) native;

  String get formEnctype native;

  set formEnctype(String value) native;

  String get formMethod native;

  set formMethod(String value) native;

  bool get formNoValidate native;

  set formNoValidate(bool value) native;

  String get formTarget native;

  set formTarget(String value) native;

  int? get height native;

  set height(int? value) native;

  bool? get incremental native;

  set incremental(bool? value) native;

  bool? get indeterminate native;

  set indeterminate(bool? value) native;

  @Returns('NodeList')
  @Creates('NodeList')
  List<Node>? get labels native;

  HtmlElement? get list native;

  String? get max native;

  set max(String? value) native;

  int? get maxLength native;

  set maxLength(int? value) native;

  String? get min native;

  set min(String? value) native;

  int? get minLength native;

  set minLength(int? value) native;

  bool? get multiple native;

  set multiple(bool? value) native;

  String? get name native;

  set name(String? value) native;

  String get pattern native;

  set pattern(String value) native;

  String get placeholder native;

  set placeholder(String value) native;

  bool? get readOnly native;

  set readOnly(bool? value) native;

  bool get required native;

  set required(bool value) native;

  String? get selectionDirection native;

  set selectionDirection(String? value) native;

  int? get selectionEnd native;

  set selectionEnd(int? value) native;

  int? get selectionStart native;

  set selectionStart(int? value) native;

  int? get size native;

  set size(int? value) native;

  String? get src native;

  set src(String? value) native;

  String? get step native;

  set step(String? value) native;

  String? get type native;

  set type(String? value) native;

  String get validationMessage native;

  ValidityState get validity native;

  String? get value native;

  set value(String? value) native;

  DateTime get valueAsDate =>
      convertNativeToDart_DateTime(this._get_valueAsDate);
  @JSName('valueAsDate')
  @Creates('Null')
  dynamic get _get_valueAsDate native;

  set valueAsDate(DateTime? value) {
    this._set_valueAsDate = convertDartToNative_DateTime(value!);
  }

  set _set_valueAsDate(/*dynamic*/ value) {
    JS("void", "#.valueAsDate = #", this, value);
  }

  num? get valueAsNumber native;

  set valueAsNumber(num? value) native;

  @JSName('webkitEntries')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  List<Entry>? get entries native;

  @JSName('webkitdirectory')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  bool? get directory native;

  @JSName('webkitdirectory')
  set directory(bool? value) native;

  int? get width native;

  set width(int? value) native;

  bool get willValidate native;

  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:
// https://w3c.github.io/html/sec-forms.html#the-input-element.

/**
 * Exposes the functionality common between all InputElement types.
 */
abstract class InputElementBase implements Element {
  bool get autofocus;
  set autofocus(bool value);

  bool? get disabled;
  set disabled(bool? value);

  bool? get incremental;
  set incremental(bool? value);

  bool? get indeterminate;
  set indeterminate(bool? value);

  String? get name;
  set name(String? value);

  String? get value;
  set value(String? value);

  List<Node>? get labels;

  String get validationMessage;

  ValidityState get validity;

  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 get autocomplete;
  set autocomplete(String value);

  int? get maxLength;
  set maxLength(int? value);

  String get pattern;
  set pattern(String value);

  String get placeholder;
  set placeholder(String value);

  bool? get readOnly;
  set readOnly(bool? value);

  bool get required;
  set required(bool value);

  int? get size;
  set size(int? value);

  void select();

  String? get selectionDirection;
  set selectionDirection(String? value);

  int? get selectionEnd;
  set selectionEnd(int? value);

  int? get selectionStart;
  set selectionStart(int? value);

  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? get dirName;
  set dirName(String? value);

  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? get dirName;
  set dirName(String? value);

  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 get autocomplete;
  set autocomplete(String value);

  bool get autofocus;
  set autofocus(bool value);

  Element? get list;

  int? get maxLength;
  set maxLength(int? value);

  bool? get multiple;
  set multiple(bool? value);

  String get pattern;
  set pattern(String value);

  String get placeholder;
  set placeholder(String value);

  bool? get readOnly;
  set readOnly(bool? value);

  bool get required;
  set required(bool value);

  int? get size;
  set size(int? value);

  /// 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? get max;
  set max(String? value);

  String? get min;
  set min(String? value);

  String? get step;
  set step(String? value);

  num? get valueAsNumber;
  set valueAsNumber(num? value);

  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 get valueAsDate;
  set valueAsDate(DateTime value);

  bool? get readOnly;
  set readOnly(bool? value);

  bool get required;
  set required(bool value);

  /// 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 get valueAsDate;
  set valueAsDate(DateTime value);

  bool? get readOnly;
  set readOnly(bool? value);

  bool get required;
  set required(bool value);

  /// 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 get valueAsDate;
  set valueAsDate(DateTime value);

  bool? get readOnly;
  set readOnly(bool? value);

  bool get required;
  set required(bool value);

  /// 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 get valueAsDate;
  set valueAsDate(DateTime value);

  bool? get readOnly;
  set readOnly(bool? value);

  bool get required;
  set required(bool value);

  /// 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? get readOnly;
  set readOnly(bool? value);

  bool get required;
  set required(bool value);

  /// 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 get placeholder;
  set placeholder(String value);

  bool? get readOnly;
  set readOnly(bool? value);

  bool get required;
  set required(bool value);

  /// 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? get checked;
  set checked(bool? value);

  bool get required;
  set required(bool value);
}

/**
 * A control that when used with other [RadioButtonInputElement] 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? get checked;
  set checked(bool? value);

  bool get required;
  set required(bool value);
}

/**
 * A control for picking files from the user's computer.
 */
abstract class FileUploadInputElement implements InputElementBase {
  factory FileUploadInputElement() => new InputElement(type: 'file');

  String? get accept;
  set accept(String? value);

  bool? get multiple;
  set multiple(bool? value);

  bool get required;
  set required(bool value);

  List<File>? files;
}

/**
 * A button, which when clicked, submits the form.
 */
abstract class SubmitButtonInputElement implements InputElementBase {
  factory SubmitButtonInputElement() => new InputElement(type: 'submit');

  String get formAction;
  set formAction(String value);

  String get formEnctype;
  set formEnctype(String value);

  String get formMethod;
  set formMethod(String value);

  bool get formNoValidate;
  set formNoValidate(bool value);

  String get formTarget;
  set formTarget(String value);
}

/**
 * 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? get alt;
  set alt(String? value);

  String get formAction;
  set formAction(String value);

  String get formEnctype;
  set formEnctype(String value);

  String get formMethod;
  set formMethod(String value);

  bool get formNoValidate;
  set formNoValidate(bool value);

  String get formTarget;
  set formTarget(String value);

  int? get height;
  set height(int? value);

  String? get src;
  set src(String? value);

  int? get width;
  set width(int? value);
}

/**
 * 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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory IntersectionObserver._() {
    throw new UnsupportedError("Not supported");
  }

  factory IntersectionObserver(
    IntersectionObserverCallback callback, [
    Map? options,
  ]) {
    if (options != null) {
      var callback_1 = convertDartClosureToJS(callback, 2);
      var options_2 = convertDartToNative_Dictionary(options);
      return IntersectionObserver._create_1(callback_1, options_2);
    }
    var callback_1 = convertDartClosureToJS(callback, 2);
    return IntersectionObserver._create_2(callback_1);
  }
  static IntersectionObserver _create_1(callback, options) => JS(
    'IntersectionObserver',
    'new IntersectionObserver(#,#)',
    callback,
    options,
  );
  static IntersectionObserver _create_2(callback) =>
      JS('IntersectionObserver', 'new IntersectionObserver(#)', callback);

  Element? get root native;

  String? get rootMargin native;

  List<num>? get thresholds native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory IntersectionObserverEntry._() {
    throw new UnsupportedError("Not supported");
  }

  DomRectReadOnly? get boundingClientRect native;

  num? get intersectionRatio native;

  DomRectReadOnly? get intersectionRect native;

  bool? get isIntersecting native;

  DomRectReadOnly? get rootBounds native;

  Element? get target native;

  num? get time 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("InterventionReport")
class InterventionReport extends ReportBody {
  // To suppress missing implicit constructor warnings.
  factory InterventionReport._() {
    throw new UnsupportedError("Not supported");
  }

  int? get lineNumber native;

  String? get message native;

  String? get sourceFile 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 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") as 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,
      );
    }
  }

  int get keyCode native;

  int get charCode native;

  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;

  bool get altKey native;

  @JSName('charCode')
  int get _charCode native;

  String? get code native;

  bool get ctrlKey native;

  bool? get isComposing native;

  String? get key native;

  @JSName('keyCode')
  int get _keyCode native;

  int get location native;

  bool get metaKey native;

  bool? get repeat native;

  bool get shiftKey native;

  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<LIElement>(
    '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 get value native;

  set value(int 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("HTMLLabelElement")
class LabelElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory LabelElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory LabelElement() => JS<LabelElement>(
    '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();

  HtmlElement? get control native;

  FormElement? get form native;

  String get htmlFor native;

  set htmlFor(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.

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

  factory LegendElement() => JS<LegendElement>(
    '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();

  FormElement? get form 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("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<LinkElement>(
    '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? get as native;

  set as(String? value) native;

  String? get crossOrigin native;

  set crossOrigin(String? value) native;

  bool? get disabled native;

  set disabled(bool? value) native;

  String get href native;

  set href(String value) native;

  String get hreflang native;

  set hreflang(String value) native;

  Document? get import native;

  String? get integrity native;

  set integrity(String? value) native;

  String get media native;

  set media(String value) native;

  String? get referrerPolicy native;

  set referrerPolicy(String? value) native;

  String get rel native;

  set rel(String value) native;

  DomTokenList? get relList native;

  String? get scope native;

  set scope(String? value) native;

  StyleSheet? get sheet native;

  DomTokenList? get sizes native;

  String get type native;

  set type(String value) native;

  /// 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 JavaScriptObject implements LocationBase {
  // To suppress missing implicit constructor warnings.
  factory Location._() {
    throw new UnsupportedError("Not supported");
  }

  @Returns('DomStringList')
  @Creates('DomStringList')
  List<String>? get ancestorOrigins native;

  String get hash native;

  set hash(String value) native;

  String get host native;

  set host(String value) native;

  String? get hostname native;

  set hostname(String? value) native;

  String get href native;

  set href(String value) native;

  String? get pathname native;

  set pathname(String? value) native;

  String get port native;

  set port(String value) native;

  String get protocol native;

  set protocol(String value) native;

  String? get search native;

  set search(String? value) native;

  TrustedUrl? get trustedHref native;

  set trustedHref(TrustedUrl? value) native;

  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()');

  num? get x native;

  num? get y native;

  num? get z 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("HTMLMapElement")
class MapElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MapElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory MapElement() => JS<MapElement>(
    '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')
  @Creates('HtmlCollection')
  List<Node> get areas native;

  String get name native;

  set name(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.

@Native("MathMLElement")
class MathMLElement extends Element {
  // To suppress missing implicit constructor warnings.
  factory MathMLElement._() {
    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.
   */
  MathMLElement.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("MediaCapabilities")
class MediaCapabilities extends JavaScriptObject {
  // 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(
        "creates:MediaCapabilitiesInfo;",
        "#.decodingInfo(#)",
        this,
        configuration_dict,
      ),
    );
  }

  Future<MediaCapabilitiesInfo> encodingInfo(Map configuration) {
    var configuration_dict = convertDartToNative_Dictionary(configuration);
    return promiseToFuture<MediaCapabilitiesInfo>(
      JS(
        "creates:MediaCapabilitiesInfo;",
        "#.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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory MediaCapabilitiesInfo._() {
    throw new UnsupportedError("Not supported");
  }

  bool? get powerEfficient native;

  bool? get smooth native;

  bool? get supported 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("MediaDeviceInfo")
class MediaDeviceInfo extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory MediaDeviceInfo._() {
    throw new UnsupportedError("Not supported");
  }

  String? get deviceId native;

  String? get groupId native;

  String? get kind native;

  String? get label 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("MediaDevices")
class MediaDevices extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaDevices._() {
    throw new UnsupportedError("Not supported");
  }

  Future<List<dynamic>> enumerateDevices() =>
      promiseToFuture<List<dynamic>>(JS("", "#.enumerateDevices()", this));

  Map getSupportedConstraints() {
    return convertNativeToDart_Dictionary(_getSupportedConstraints_1())!;
  }

  @JSName('getSupportedConstraints')
  _getSupportedConstraints_1() native;

  Future<MediaStream> getUserMedia([Map? constraints]) {
    var constraints_dict = null;
    if (constraints != null) {
      constraints_dict = convertDartToNative_Dictionary(constraints);
    }
    return promiseToFuture<MediaStream>(
      JS("creates:MediaStream;", "#.getUserMedia(#)", this, constraints_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.

@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;

  AudioTrackList? get audioTracks native;

  bool get autoplay native;

  set autoplay(bool value) native;

  TimeRanges get buffered native;

  bool get controls native;

  set controls(bool value) native;

  DomTokenList? get controlsList native;

  String? get crossOrigin native;

  set crossOrigin(String? value) native;

  String get currentSrc native;

  num get currentTime native;

  set currentTime(num value) native;

  bool? get defaultMuted native;

  set defaultMuted(bool? value) native;

  num get defaultPlaybackRate native;

  set defaultPlaybackRate(num value) native;

  bool get disableRemotePlayback native;

  set disableRemotePlayback(bool value) native;

  num get duration native;

  bool get ended native;

  MediaError? get error native;

  bool get loop native;

  set loop(bool value) native;

  MediaKeys? get mediaKeys native;

  bool get muted native;

  set muted(bool value) native;

  int? get networkState native;

  bool get paused native;

  num get playbackRate native;

  set playbackRate(num value) native;

  TimeRanges get played native;

  String get preload native;

  set preload(String value) native;

  int get readyState native;

  RemotePlayback? get remote native;

  TimeRanges get seekable native;

  bool get seeking native;

  String? get sinkId native;

  String get src native;

  set src(String value) native;

  MediaStream? get srcObject native;

  set srcObject(MediaStream? value) native;

  TextTrackList? get textTracks native;

  VideoTrackList? get videoTracks native;

  num get volume native;

  set volume(num value) native;

  @JSName('webkitAudioDecodedByteCount')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  int? get audioDecodedByteCount native;

  @JSName('webkitVideoDecodedByteCount')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  int? get videoDecodedByteCount native;

  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);

  ByteBuffer? get initData native;

  String? get initDataType 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("MediaError")
class MediaError extends JavaScriptObject {
  // 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;

  int get code native;

  String? get message 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("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,
  );

  ByteBuffer? get message native;

  String? get messageType 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("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));

  num? get expiration native;

  MediaKeyStatusMap? get keyStatuses native;

  String? get sessionId native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyStatusMap._() {
    throw new UnsupportedError("Not supported");
  }

  int? get size native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory MediaKeySystemAccess._() {
    throw new UnsupportedError("Not supported");
  }

  String? get keySystem native;

  Future createMediaKeys() =>
      promiseToFuture(JS("creates:MediaKeys;", "#.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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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);

  String? get minHdcpVersion 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("MediaList")
class MediaList extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory MediaList._() {
    throw new UnsupportedError("Not supported");
  }

  int? get length native;

  String? get mediaText native;

  set mediaText(String? value) native;

  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 JavaScriptObject {
  // 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? get album native;

  set album(String? value) native;

  String? get artist native;

  set artist(String? value) native;

  List? get artwork native;

  set artwork(List? value) native;

  String? get title native;

  set title(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.

@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');

  bool get matches native;

  String get media native;

  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);

  bool? get matches native;

  String? get media 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("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);

  int? get audioBitsPerSecond native;

  String? get mimeType native;

  String? get state native;

  MediaStream? get stream native;

  int? get videoBitsPerSecond native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory MediaSession._() {
    throw new UnsupportedError("Not supported");
  }

  MediaMetadata? get metadata native;

  set metadata(MediaMetadata? value) native;

  String? get playbackState native;

  set playbackState(String? value) native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory MediaSettingsRange._() {
    throw new UnsupportedError("Not supported");
  }

  num? get max native;

  num? get min native;

  num? get step 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, '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)');

  SourceBufferList? get activeSourceBuffers native;

  num? get duration native;

  set duration(num? value) native;

  String? get readyState native;

  SourceBufferList? get sourceBuffers native;

  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);

  bool? get active native;

  String? get id native;

  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');

  MediaStream? get stream 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("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? get contentHint native;

  set contentHint(String? value) native;

  bool? get enabled native;

  set enabled(bool? value) native;

  String? get id native;

  String? get kind native;

  String? get label native;

  bool? get muted native;

  String? get readyState native;

  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');

  MediaStreamTrack? get track 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("MemoryInfo")
class MemoryInfo extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory MemoryInfo._() {
    throw new UnsupportedError("Not supported");
  }

  int? get jsHeapSizeLimit native;

  int? get totalJSHeapSize native;

  int? get usedJSHeapSize 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 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<MenuElement>(
    '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 JavaScriptObject {
  // 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()');

  MessagePort get port1 native;

  MessagePort get port2 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.

@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") as 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
  dynamic get _get_data native;

  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()
  String get lastEventId native;

  String get origin native;

  @Unstable()
  @Creates('JSExtendableArray')
  List<MessagePort> get ports native;

  EventTarget? get source => _convertNativeToDart_EventTarget(this._get_source);
  @JSName('source')
  @Creates('Null')
  @Returns('EventTarget|=Object')
  dynamic get _get_source native;

  String? get suborigin native;

  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<MetaElement>(
    '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 get content native;

  set content(String value) native;

  String? get httpEquiv native;

  set httpEquiv(String? value) native;

  String get name native;

  set name(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.

@Native("Metadata")
class Metadata extends JavaScriptObject {
  // 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')
  dynamic get _get_modificationTime native;

  int? get size 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 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") as MeterElement;
  /**
   * 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? get high native;

  set high(num? value) native;

  @Unstable()
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node>? get labels native;

  num? get low native;

  set low(num? value) native;

  num? get max native;

  set max(num? value) native;

  num? get min native;

  set min(num? value) native;

  num? get optimum native;

  set optimum(num? value) native;

  num? get value native;

  set value(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("MIDIAccess")
class MidiAccess extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MidiAccess._() {
    throw new UnsupportedError("Not supported");
  }

  MidiInputMap? get inputs native;

  MidiOutputMap? get outputs native;

  bool? get sysexEnabled 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("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);

  MidiPort? get port 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("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 JavaScriptObject 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);

  Uint8List? get 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("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 JavaScriptObject 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");
  }

  String? get connection native;

  String? get id native;

  String? get manufacturer native;

  String? get name native;

  String? get state native;

  String? get type native;

  String? get version native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory MimeType._() {
    throw new UnsupportedError("Not supported");
  }

  String? get description native;

  Plugin? get enabledPlugin native;

  String? get suffixes native;

  String? get 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("MimeTypeArray")
class MimeTypeArray extends JavaScriptObject
    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 IndexError.withLength(index, length, indexable: 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 newLength) {
    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 get cite native;

  set cite(String value) native;

  String get dateTime native;

  set dateTime(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 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') as 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);

  bool get altKey native;

  int get button native;

  int? get buttons native;

  @JSName('clientX')
  num get _clientX native;

  @JSName('clientY')
  num get _clientY native;

  bool get ctrlKey native;

  /**
   * 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
  Node? get fromElement native;

  @JSName('layerX')
  int? get _layerX native;

  @JSName('layerY')
  int? get _layerY native;

  bool get metaKey native;

  @JSName('movementX')
  int? get _movementX native;

  @JSName('movementY')
  int? get _movementY native;

  @JSName('pageX')
  num? get _pageX native;

  @JSName('pageY')
  num? get _pageY native;

  String? get region native;

  EventTarget? get relatedTarget =>
      _convertNativeToDart_EventTarget(this._get_relatedTarget);
  @JSName('relatedTarget')
  @Creates('Node')
  @Returns('EventTarget|=Object|Null')
  dynamic get _get_relatedTarget native;

  @JSName('screenX')
  num get _screenX native;

  @JSName('screenY')
  num get _screenY native;

  bool get shiftKey native;

  /**
   * 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
  Node? get toElement native;

  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 as num, y as num);
    } else {
      // Firefox does not support offsetX.
      if (!(this.target is Element)) {
        throw new UnsupportedError('offsetX is only supported on elements');
      }
      Element target = this.target as Element;
      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;

  int? get attrChange native;

  String? get attrName native;

  String? get newValue native;

  String? get prevValue native;

  Node? get relatedNode native;

  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 JavaScriptObject {
  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory MutationRecord._() {
    throw new UnsupportedError("Not supported");
  }

  @Returns('NodeList')
  @Creates('NodeList')
  List<Node>? get addedNodes native;

  String? get attributeName native;

  String? get attributeNamespace native;

  Node? get nextSibling native;

  String? get oldValue native;

  Node? get previousSibling native;

  @Returns('NodeList')
  @Creates('NodeList')
  List<Node>? get removedNodes native;

  Node? get target native;

  String? get 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("NavigationPreloadManager")
class NavigationPreloadManager extends JavaScriptObject {
  // 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,
        NavigatorID,
        NavigatorLanguage,
        NavigatorOnLine,
        NavigatorAutomationInformation {
  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");
  }

  _BudgetService? get budget native;

  _Clipboard? get clipboard native;

  NetworkInformation? get connection native;

  CredentialsContainer? get credentials native;

  num? get deviceMemory native;

  String? get doNotTrack native;

  @Unstable()
  Geolocation get geolocation native;

  int? get maxTouchPoints native;

  MediaCapabilities? get mediaCapabilities native;

  MediaDevices? get mediaDevices native;

  MediaSession? get mediaSession native;

  MimeTypeArray? get mimeTypes native;

  _NFC? get nfc native;

  Permissions? get permissions native;

  Presentation? get presentation native;

  @Unstable()
  String? get productSub native;

  ServiceWorkerContainer? get serviceWorker native;

  StorageManager? get storage native;

  @Unstable()
  String get vendor native;

  @Unstable()
  String get vendorSub native;

  VR? get vr native;

  @JSName('webkitPersistentStorage')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  DeprecatedStorageQuota? get persistentStorage native;

  @JSName('webkitTemporaryStorage')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  DeprecatedStorageQuota? get temporaryStorage native;

  void cancelKeyboardLock() native;

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

  @JSName('getGamepads')
  @Returns('_GamepadList')
  @Creates('_GamepadList')
  List<Gamepad?> _getGamepads() native;

  Future<RelatedApplication> getInstalledRelatedApps() =>
      promiseToFuture<RelatedApplication>(
        JS("creates:RelatedApplication;", "#.getInstalledRelatedApps()", this),
      );

  Future getVRDisplays() =>
      promiseToFuture(JS("creates:VRDisplay;", "#.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(
      "creates:MediaKeySystemAccess;",
      "#.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

  bool? get webdriver native;

  // From NavigatorCookies

  @Unstable()
  bool? get cookieEnabled native;

  // From NavigatorID

  String get appCodeName native;

  String get appName native;

  String get appVersion native;

  bool? get dartEnabled native;

  String? get platform native;

  @Unstable()
  String get product native;

  String get userAgent native;

  // From NavigatorLanguage

  List<String>? get languages native;

  // From NavigatorOnLine

  @Unstable()
  bool? get onLine 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("NavigatorAutomationInformation")
class NavigatorAutomationInformation extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory NavigatorAutomationInformation._() {
    throw new UnsupportedError("Not supported");
  }

  bool? get webdriver 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("NavigatorConcurrentHardware")
class NavigatorConcurrentHardware extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory NavigatorConcurrentHardware._() {
    throw new UnsupportedError("Not supported");
  }

  int? get hardwareConcurrency 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("NavigatorCookies")
class NavigatorCookies extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory NavigatorCookies._() {
    throw new UnsupportedError("Not supported");
  }

  bool? get cookieEnabled 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 NavigatorID extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory NavigatorID._() {
    throw new UnsupportedError("Not supported");
  }

  String get appCodeName native;

  String get appName native;

  String get appVersion native;

  bool? get dartEnabled native;

  String? get platform native;

  String get product native;

  String get userAgent 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 NavigatorLanguage extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory NavigatorLanguage._() {
    throw new UnsupportedError("Not supported");
  }

  String? get language native;

  List<String>? get languages 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 NavigatorOnLine extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory NavigatorOnLine._() {
    throw new UnsupportedError("Not supported");
  }

  bool? get onLine 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("NavigatorUserMediaError")
class NavigatorUserMediaError extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory NavigatorUserMediaError._() {
    throw new UnsupportedError("Not supported");
  }

  String? get constraintName native;

  String? get message native;

  String? get 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.

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');

  num? get downlink native;

  num? get downlinkMax native;

  String? get effectiveType native;

  int? get rtt native;

  String? get type 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.

/**
 * 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 newLength) {
    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!;
      parent._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 child.
   *
   * See also:
   *
   * * [insertBefore]
   */
  void insertAllBefore(Iterable<Node> newNodes, Node child) {
    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!, child);
      }
    } else {
      for (var node in newNodes) {
        this.insertBefore(node, child);
      }
    }
  }

  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')
  List<Node> get childNodes native;

  // 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')
  String? get baseUri native;

  /**
   * The first child of this node.
   *
   * ## Other resources
   *
   * * [Node.firstChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.firstChild)
   *   from MDN.
   */

  Node? get firstChild native;

  bool? get isConnected native;

  /**
   * The last child of this node.
   *
   * ## Other resources
   *
   * * [Node.lastChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.lastChild)
   *   from MDN.
   */

  Node? get lastChild native;

  @JSName('nextSibling')
  /**
   * The next sibling node.
   *
   * ## Other resources
   *
   * * [Node.nextSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling)
   *   from MDN.
   */
  Node? get nextNode native;

  /**
   * 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].
   */

  String? get nodeName native;

  /**
   * 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.
   */

  int get nodeType native;

  /**
   * 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].
   */

  String? get nodeValue native;

  /**
   * 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.
   */

  Document? get ownerDocument native;

  @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.
   */
  Element? get parent native;

  /**
   * The parent node of this node.
   *
   * ## Other resources
   *
   * * [Node.parentNode](https://developer.mozilla.org/en-US/docs/Web/API/Node.parentNode)
   *   from MDN.
   */

  Node? get parentNode native;

  @JSName('previousSibling')
  /**
   * The previous sibling node.
   *
   * ## Other resources
   *
   * * [Node.previousSibling](https://developer.mozilla.org/en-US/docs/Web/API/Node.previousSibling)
   *   from MDN.
   */
  Node? get previousNode native;

  @JSName('textContent')
  /**
   * All text within this node and its descendants.
   *
   * ## Other resources
   *
   * * [Node.textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent)
   *   from MDN.
   */
  String? get text native;

  @JSName('textContent')
  set text(String? value) native;

  @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 descendants 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 the given node into this node directly before child.
   * If child is `null`, then the given node is inserted at the end
   * of this node's child nodes.
   *
   * ## 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 JavaScriptObject {
  // 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 JavaScriptObject {
  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");
  }

  bool? get pointerBeforeReferenceNode native;

  Node? get referenceNode native;

  Node get root native;

  int get whatToShow native;

  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 JavaScriptObject
    with ListMixin<Node>, ImmutableListMixin<Node>
    implements List<Node>, JavaScriptIndexingBehavior<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 IndexError.withLength(index, length, indexable: 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 newLength) {
    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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory NonDocumentTypeChildNode._() {
    throw new UnsupportedError("Not supported");
  }

  Element? get nextElementSibling native;

  Element? get previousElementSibling 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("NonElementParentNode")
class NonElementParentNode extends JavaScriptObject {
  // 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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory NoncedElement._() {
    throw new UnsupportedError("Not supported");
  }

  String? get nonce native;

  set nonce(String? value) 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("Notification")
class Notification extends EventTarget {
  factory Notification(
    String title, {
    String? dir,
    String? body,
    String? lang,
    String? tag,
    String? icon,
  }) {
    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)');

  List? get actions native;

  String? get badge native;

  String? get body native;

  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  Object? get data native;

  String? get dir native;

  String? get icon native;

  String? get image native;

  String? get lang native;

  static int? get maxActions native;

  static String? get permission native;

  bool? get renotify native;

  bool? get requireInteraction native;

  bool? get silent native;

  String? get tag native;

  int? get timestamp native;

  String? get title native;

  List<int>? get vibrate native;

  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,
  );

  String? get action native;

  Notification? get notification native;

  String? get reply 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 _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<OListElement>(
    '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? get reversed native;

  set reversed(bool? value) native;

  int get start native;

  set start(int value) native;

  String get type native;

  set type(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.

@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") as ObjectElement;
  /**
   * 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')
  dynamic get _get_contentWindow native;

  String get data native;

  set data(String value) native;

  FormElement? get form native;

  String get height native;

  set height(String value) native;

  String get name native;

  set name(String value) native;

  String get type native;

  set type(String value) native;

  String get useMap native;

  set useMap(String value) native;

  String get validationMessage native;

  ValidityState get validity native;

  String get width native;

  set width(String value) native;

  bool get willValidate native;

  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? get height native;

  set height(int? value) native;

  int? get width native;

  set width(int? value) native;

  Future<Blob> convertToBlob([Map? options]) {
    var options_dict = null;
    if (options != null) {
      options_dict = convertDartToNative_Dictionary(options);
    }
    return promiseToFuture<Blob>(
      JS("creates:Blob;", "#.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 JavaScriptObject
    implements _CanvasPath {
  // To suppress missing implicit constructor warnings.
  factory OffscreenCanvasRenderingContext2D._() {
    throw new UnsupportedError("Not supported");
  }

  OffscreenCanvas? get canvas native;

  String? get direction native;

  set direction(String? value) native;

  Object? get fillStyle native;

  set fillStyle(Object? value) native;

  String? get filter native;

  set filter(String? value) native;

  String? get font native;

  set font(String? value) native;

  num? get globalAlpha native;

  set globalAlpha(num? value) native;

  String? get globalCompositeOperation native;

  set globalCompositeOperation(String? value) native;

  bool? get imageSmoothingEnabled native;

  set imageSmoothingEnabled(bool? value) native;

  String? get imageSmoothingQuality native;

  set imageSmoothingQuality(String? value) native;

  String? get lineCap native;

  set lineCap(String? value) native;

  num? get lineDashOffset native;

  set lineDashOffset(num? value) native;

  String? get lineJoin native;

  set lineJoin(String? value) native;

  num? get lineWidth native;

  set lineWidth(num? value) native;

  num? get miterLimit native;

  set miterLimit(num? value) native;

  num? get shadowBlur native;

  set shadowBlur(num? value) native;

  String? get shadowColor native;

  set shadowColor(String? value) native;

  num? get shadowOffsetX native;

  set shadowOffsetX(num? value) native;

  num? get shadowOffsetY native;

  set shadowOffsetY(num? value) native;

  Object? get strokeStyle native;

  set strokeStyle(Object? value) native;

  String? get textAlign native;

  set textAlign(String? value) native;

  String? get textBaseline native;

  set textBaseline(String? value) native;

  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<OptGroupElement>(
    '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 get disabled native;

  set disabled(bool value) native;

  String get label native;

  set label(String value) 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("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 get defaultSelected native;

  set defaultSelected(bool value) native;

  bool get disabled native;

  set disabled(bool value) native;

  FormElement? get form native;

  int get index native;

  String? get label native;

  set label(String? value) native;

  bool get selected native;

  set selected(bool value) native;

  String get value native;

  set value(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.

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

  List<num>? get quaternion native;

  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") as OutputElement;
  /**
   * 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? get defaultValue native;

  set defaultValue(String? value) native;

  FormElement? get form native;

  DomTokenList? get htmlFor native;

  @Unstable()
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node>? get labels native;

  String? get name native;

  set name(String? value) native;

  String? get type native;

  String? get validationMessage native;

  ValidityState? get validity native;

  String? get value native;

  set value(String? value) native;

  bool? get willValidate 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("OverconstrainedError")
class OverconstrainedError extends JavaScriptObject {
  // 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,
  );

  String? get constraint native;

  String? get message native;

  String? get 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("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);

  bool? get persisted 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("PaintRenderingContext2D")
class PaintRenderingContext2D extends JavaScriptObject implements _CanvasPath {
  // To suppress missing implicit constructor warnings.
  factory PaintRenderingContext2D._() {
    throw new UnsupportedError("Not supported");
  }

  Matrix? get currentTransform native;

  set currentTransform(Matrix? value) native;

  Object? get fillStyle native;

  set fillStyle(Object? value) native;

  String? get filter native;

  set filter(String? value) native;

  num? get globalAlpha native;

  set globalAlpha(num? value) native;

  String? get globalCompositeOperation native;

  set globalCompositeOperation(String? value) native;

  bool? get imageSmoothingEnabled native;

  set imageSmoothingEnabled(bool? value) native;

  String? get imageSmoothingQuality native;

  set imageSmoothingQuality(String? value) native;

  String? get lineCap native;

  set lineCap(String? value) native;

  num? get lineDashOffset native;

  set lineDashOffset(num? value) native;

  String? get lineJoin native;

  set lineJoin(String? value) native;

  num? get lineWidth native;

  set lineWidth(num? value) native;

  num? get miterLimit native;

  set miterLimit(num? value) native;

  num? get shadowBlur native;

  set shadowBlur(num? value) native;

  String? get shadowColor native;

  set shadowColor(String? value) native;

  num? get shadowOffsetX native;

  set shadowOffsetX(num? value) native;

  num? get shadowOffsetY native;

  set shadowOffsetY(num? value) native;

  Object? get strokeStyle native;

  set strokeStyle(Object? value) native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory PaintSize._() {
    throw new UnsupportedError("Not supported");
  }

  num? get height native;

  num? get width 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("PaintWorkletGlobalScope")
class PaintWorkletGlobalScope extends WorkletGlobalScope {
  // To suppress missing implicit constructor warnings.
  factory PaintWorkletGlobalScope._() {
    throw new UnsupportedError("Not supported");
  }

  num? get devicePixelRatio native;

  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<ParagraphElement>(
    '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<ParamElement>(
    '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 get name native;

  set name(String value) native;

  String get value native;

  set value(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.

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

  int get _childElementCount native;

  List<Node>? get _children native;

  Element? get _firstElementChild native;

  Element? get _lastElementChild native;

  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? get additionalData native;

  set additionalData(Object? value) native;

  String? get idName native;

  set idName(String? value) native;

  String? get password native;

  String? get passwordName native;

  set passwordName(String? value) native;

  // From CredentialUserData

  @JSName('iconURL')
  String? get iconUrl native;

  String? get 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("Path2D")
class Path2D extends JavaScriptObject 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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory PaymentAddress._() {
    throw new UnsupportedError("Not supported");
  }

  List<String>? get addressLine native;

  String? get city native;

  String? get country native;

  String? get dependentLocality native;

  String? get languageCode native;

  String? get organization native;

  String? get phone native;

  String? get postalCode native;

  String? get recipient native;

  String? get region native;

  String? get sortingCode 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("PaymentInstruments")
class PaymentInstruments extends JavaScriptObject {
  // 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<dynamic>> keys() =>
      promiseToFuture<List<dynamic>>(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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory PaymentManager._() {
    throw new UnsupportedError("Not supported");
  }

  PaymentInstruments? get instruments native;

  String? get userHint native;

  set userHint(String? value) native;
}
// 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");
  }

  String? get id native;

  PaymentAddress? get shippingAddress native;

  String? get shippingOption native;

  String? get shippingType native;

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

  Future<bool> canMakePayment() =>
      promiseToFuture<bool>(JS("", "#.canMakePayment()", this));

  Future<PaymentResponse> show() => promiseToFuture<PaymentResponse>(
    JS("creates:PaymentResponse;", "#.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,
  );

  String? get instrumentKey native;

  List? get methodData native;

  List? get modifiers native;

  String? get paymentRequestId native;

  String? get paymentRequestOrigin native;

  String? get topLevelOrigin native;

  Object? get total native;

  Future<WindowClient> openWindow(String url) => promiseToFuture<WindowClient>(
    JS("creates:WindowClient;", "#.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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory PaymentResponse._() {
    throw new UnsupportedError("Not supported");
  }

  Object? get details native;

  String? get methodName native;

  String? get payerEmail native;

  String? get payerName native;

  String? get payerPhone native;

  String? get requestId native;

  PaymentAddress? get shippingAddress native;

  String? get shippingOption native;

  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)');

  MemoryInfo? get memory native;

  PerformanceNavigation get navigation native;

  num? get timeOrigin native;

  PerformanceTiming get timing native;

  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;

  PerformanceEntry? mark(String markName, [Map? markOptions]) {
    if (markOptions != null) {
      var markOptions_1 = convertDartToNative_Dictionary(markOptions);
      return _mark_1(markName, markOptions_1);
    }
    return _mark_2(markName);
  }

  @JSName('mark')
  PerformanceEntry? _mark_1(markName, markOptions) native;
  @JSName('mark')
  PerformanceEntry? _mark_2(markName) native;

  PerformanceMeasure? measure(
    String measureName, [
    measureOptions_OR_startMark,
    String? endMark,
  ]) {
    if (measureOptions_OR_startMark == null && endMark == null) {
      return _measure_1(measureName);
    }
    if ((measureOptions_OR_startMark is String ||
            measureOptions_OR_startMark == null) &&
        endMark == null) {
      return _measure_2(measureName, measureOptions_OR_startMark);
    }
    if ((measureOptions_OR_startMark is String ||
        measureOptions_OR_startMark == null)) {
      return _measure_3(measureName, measureOptions_OR_startMark, endMark);
    }
    if ((measureOptions_OR_startMark is Map) && endMark == null) {
      var measureOptions_1 = convertDartToNative_Dictionary(
        measureOptions_OR_startMark,
      );
      return _measure_4(measureName, measureOptions_1);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('measure')
  PerformanceMeasure? _measure_1(measureName) native;
  @JSName('measure')
  PerformanceMeasure? _measure_2(measureName, String? startMark) native;
  @JSName('measure')
  PerformanceMeasure? _measure_3(
    measureName,
    String? startMark,
    endMark,
  ) native;
  @JSName('measure')
  PerformanceMeasure? _measure_4(measureName, measureOptions) 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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory PerformanceEntry._() {
    throw new UnsupportedError("Not supported");
  }

  num get duration native;

  String get entryType native;

  String get name native;

  num get startTime 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("PerformanceLongTaskTiming")
class PerformanceLongTaskTiming extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory PerformanceLongTaskTiming._() {
    throw new UnsupportedError("Not supported");
  }

  List<TaskAttributionTiming>? get attribution 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("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 JavaScriptObject {
  // 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;

  int? get redirectCount native;

  int? get 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("PerformanceNavigationTiming")
class PerformanceNavigationTiming extends PerformanceResourceTiming {
  // To suppress missing implicit constructor warnings.
  factory PerformanceNavigationTiming._() {
    throw new UnsupportedError("Not supported");
  }

  num? get domComplete native;

  num? get domContentLoadedEventEnd native;

  num? get domContentLoadedEventStart native;

  num? get domInteractive native;

  num? get loadEventEnd native;

  num? get loadEventStart native;

  int? get redirectCount native;

  String? get type native;

  num? get unloadEventEnd native;

  num? get unloadEventStart 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("PerformanceObserver")
class PerformanceObserver extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory PerformanceObserver._() {
    throw new UnsupportedError("Not supported");
  }

  factory PerformanceObserver(PerformanceObserverCallback callback) {
    var callback_1 = convertDartClosureToJS(callback, 2);
    return PerformanceObserver._create_1(callback_1);
  }
  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 JavaScriptObject {
  // 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");
  }

  num get connectEnd native;

  num get connectStart native;

  int? get decodedBodySize native;

  num? get domainLookupEnd native;

  num? get domainLookupStart native;

  int? get encodedBodySize native;

  num? get fetchStart native;

  String? get initiatorType native;

  String? get nextHopProtocol native;

  num? get redirectEnd native;

  num? get redirectStart native;

  num? get requestStart native;

  num? get responseEnd native;

  num? get responseStart native;

  num? get secureConnectionStart native;

  List<PerformanceServerTiming>? get serverTiming native;

  int? get transferSize native;

  num? get workerStart 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("PerformanceServerTiming")
class PerformanceServerTiming extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory PerformanceServerTiming._() {
    throw new UnsupportedError("Not supported");
  }

  String? get description native;

  num? get duration native;

  String? get 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("PerformanceTiming")
class PerformanceTiming extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory PerformanceTiming._() {
    throw new UnsupportedError("Not supported");
  }

  int get connectEnd native;

  int get connectStart native;

  int get domComplete native;

  int get domContentLoadedEventEnd native;

  int get domContentLoadedEventStart native;

  int get domInteractive native;

  int get domLoading native;

  int get domainLookupEnd native;

  int get domainLookupStart native;

  int get fetchStart native;

  int get loadEventEnd native;

  int get loadEventStart native;

  int get navigationStart native;

  int get redirectEnd native;

  int get redirectStart native;

  int get requestStart native;

  int get responseEnd native;

  int get responseStart native;

  int get secureConnectionStart native;

  int get unloadEventEnd native;

  int get unloadEventStart 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("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');

  String? get state 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("Permissions")
class Permissions extends JavaScriptObject {
  // 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("creates:PermissionStatus;", "#.query(#)", this, permission_dict),
    );
  }

  Future<PermissionStatus> request(Map permissions) {
    var permissions_dict = convertDartToNative_Dictionary(permissions);
    return promiseToFuture<PermissionStatus>(
      JS("creates:PermissionStatus;", "#.request(#)", this, permissions_dict),
    );
  }

  Future<PermissionStatus> requestAll(List<Map> permissions) =>
      promiseToFuture<PermissionStatus>(
        JS("creates:PermissionStatus;", "#.requestAll(#)", this, permissions),
      );

  Future<PermissionStatus> revoke(Map permission) {
    var permission_dict = convertDartToNative_Dictionary(permission);
    return promiseToFuture<PermissionStatus>(
      JS("creates:PermissionStatus;", "#.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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory PhotoCapabilities._() {
    throw new UnsupportedError("Not supported");
  }

  List? get fillLightMode native;

  MediaSettingsRange? get imageHeight native;

  MediaSettingsRange? get imageWidth native;

  String? get redEyeReduction 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("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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory Plugin._() {
    throw new UnsupportedError("Not supported");
  }

  String? get description native;

  String? get filename native;

  int? get length native;

  String? get name native;

  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 JavaScriptObject
    with ListMixin<Plugin>, ImmutableListMixin<Plugin>
    implements List<Plugin>, JavaScriptIndexingBehavior<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 IndexError.withLength(index, length, indexable: 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 newLength) {
    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) 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("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);

  num? get height native;

  bool? get isPrimary native;

  int? get pointerId native;

  String? get pointerType native;

  num? get pressure native;

  num? get tangentialPressure native;

  int? get tiltX native;

  int? get tiltY native;

  int? get twist native;

  num? get width native;

  List<PointerEvent> getCoalescedEvents() native;

  /**
   * PointerEvent used for both touch and mouse.  To check if touch is supported
   * call the property TouchEvent.supported
   */
  static bool get supported {
    try {
      return PointerEvent('pointerover') is PointerEvent;
    } catch (_) {}
    return false;
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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
  dynamic get _get_state 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.

@Unstable()
typedef void _PositionCallback(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,GeolocationPositionError")
class PositionError extends JavaScriptObject {
  // 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;

  int? get code native;

  String? get message 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.

@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<PreElement>(
    '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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory Presentation._() {
    throw new UnsupportedError("Not supported");
  }

  PresentationRequest? get defaultRequest native;

  set defaultRequest(PresentationRequest? value) native;

  PresentationReceiver? get receiver 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("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');

  bool? get value 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("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? get binaryType native;

  set binaryType(String? value) native;

  String? get id native;

  String? get state native;

  String? get url native;

  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,
      );

  PresentationConnection? get connection 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("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,
  );

  String? get message native;

  String? get reason 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("PresentationConnectionList")
class PresentationConnectionList extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory PresentationConnectionList._() {
    throw new UnsupportedError("Not supported");
  }

  List<PresentationConnection>? get connections 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("PresentationReceiver")
class PresentationReceiver extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory PresentationReceiver._() {
    throw new UnsupportedError("Not supported");
  }

  Future<PresentationConnectionList> get connectionList =>
      promiseToFuture<PresentationConnectionList>(
        JS("creates:PresentationConnectionList;", "#.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("creates:PresentationAvailability;", "#.getAvailability()", this),
      );

  Future<PresentationConnection> reconnect(String id) =>
      promiseToFuture<PresentationConnection>(
        JS("creates:PresentationConnection;", "#.reconnect(#)", this, id),
      );

  Future<PresentationConnection> start() =>
      promiseToFuture<PresentationConnection>(
        JS("creates:PresentationConnection;", "#.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");
  }

  StyleSheet? get sheet native;

  String? get 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.

@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") as ProgressElement;
  /**
   * 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')
  @Creates('NodeList')
  List<Node>? get labels native;

  num get max native;

  set max(num value) native;

  num get position native;

  num get value native;

  set value(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("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);

  bool get lengthComputable native;

  int? get loaded native;

  int? get total 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("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));

  Object? get reason 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("PublicKeyCredential")
class PublicKeyCredential extends Credential {
  // To suppress missing implicit constructor warnings.
  factory PublicKeyCredential._() {
    throw new UnsupportedError("Not supported");
  }

  ByteBuffer? get rawId native;

  AuthenticatorResponse? get 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("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);

  PushMessageData? get 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("PushManager")
class PushManager extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory PushManager._() {
    throw new UnsupportedError("Not supported");
  }

  static List<String>? get supportedContentEncodings native;

  Future<PushSubscription> getSubscription() =>
      promiseToFuture<PushSubscription>(
        JS("creates:PushSubscription;", "#.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("creates:PushSubscription;", "#.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 JavaScriptObject {
  // 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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory PushSubscription._() {
    throw new UnsupportedError("Not supported");
  }

  String? get endpoint native;

  int? get expirationTime native;

  PushSubscriptionOptions? get options native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory PushSubscriptionOptions._() {
    throw new UnsupportedError("Not supported");
  }

  ByteBuffer? get applicationServerKey native;

  bool? get userVisibleOnly 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("HTMLQuoteElement")
class QuoteElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory QuoteElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory QuoteElement() => JS<QuoteElement>(
    '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 get cite native;

  set cite(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 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 JavaScriptObject {
  factory Range() => document.createRange();

  factory Range.fromPoint(Point point) =>
      document._caretRangeFromPoint(point.x.toInt(), point.y.toInt());
  // 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;

  bool get collapsed native;

  Node get commonAncestorContainer native;

  Node get endContainer native;

  int get endOffset native;

  Node get startContainer native;

  int get startOffset native;

  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')
  @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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory RelatedApplication._() {
    throw new UnsupportedError("Not supported");
  }

  String? get id native;

  String? get platform native;

  String? get 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("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");
  }

  String? get state native;

  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 JavaScriptObject {
  // 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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory ReportingObserver._() {
    throw new UnsupportedError("Not supported");
  }

  factory ReportingObserver(ReportingObserverCallback callback) {
    var callback_1 = convertDartClosureToJS(callback, 2);
    return ReportingObserver._create_1(callback_1);
  }
  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory ResizeObserver._() {
    throw new UnsupportedError("Not supported");
  }

  factory ResizeObserver(ResizeObserverCallback callback) {
    var callback_1 = convertDartClosureToJS(callback, 2);
    return ResizeObserver._create_1(callback_1);
  }
  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 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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory ResizeObserverEntry._() {
    throw new UnsupportedError("Not supported");
  }

  DomRectReadOnly? get contentRect native;

  Element? get 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.

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

  int? get expires native;

  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? get binaryType native;

  set binaryType(String? value) native;

  int? get bufferedAmount native;

  int? get bufferedAmountLowThreshold native;

  set bufferedAmountLowThreshold(int? value) native;

  int? get id native;

  String? get label native;

  int? get maxRetransmitTime native;

  int? get maxRetransmits native;

  bool? get negotiated native;

  bool? get ordered native;

  String? get protocol native;

  String? get readyState native;

  bool? get reliable native;

  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,
  );

  RtcDataChannel? get channel 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("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')
  bool? get canInsertDtmf native;

  int? get duration native;

  int? get interToneGap native;

  String? get toneBuffer native;

  MediaStreamTrack? get track native;

  @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,
  );

  String? get tone 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("RTCIceCandidate,mozRTCIceCandidate")
class RtcIceCandidate extends JavaScriptObject {
  factory RtcIceCandidate(Map dictionary) {
    var constructorName = JS('', 'window[#]', 'RTCIceCandidate');
    return JS(
      'RtcIceCandidate',
      'new #(#)',
      constructorName,
      convertDartToNative_SerializedScriptValue(dictionary),
    );
  }
  // To suppress missing implicit constructor warnings.
  factory RtcIceCandidate._() {
    throw new UnsupportedError("Not supported");
  }

  String? get candidate native;

  set candidate(String? value) native;

  int? get sdpMLineIndex native;

  set sdpMLineIndex(int? value) native;

  String? get sdpMid native;

  set sdpMid(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.

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

  String? get id native;

  DateTime get timestamp => convertNativeToDart_DateTime(this._get_timestamp);
  @JSName('timestamp')
  dynamic get _get_timestamp native;

  String? get type native;

  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[#]',
      '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 `connectionstatechange` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  static const EventStreamProvider<Event> connectionStateChangeEvent =
      const EventStreamProvider<Event>('connectionstatechange');

  /**
   * 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');

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

  String? get connectionState native;

  String? get iceConnectionState native;

  String? get iceGatheringState native;

  RtcSessionDescription? get localDescription native;

  RtcSessionDescription? get remoteDescription native;

  String? get signalingState native;

  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(
        "creates:RtcSessionDescription;",
        "#.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(
        "creates:RtcSessionDescription;",
        "#.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("creates:RtcStatsReport;", "#.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 `connectionstatechange` events handled by this [RtcPeerConnection].
  Stream<Event> get onConnectionStateChange =>
      connectionStateChangeEvent.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);

  /// Stream of `track` events handled by this [RtcPeerConnection].
  Stream<RtcTrackEvent> get onTrack => trackEvent.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);

  RtcIceCandidate? get candidate 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("RTCRtpContributingSource")
class RtcRtpContributingSource extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory RtcRtpContributingSource._() {
    throw new UnsupportedError("Not supported");
  }

  int? get source native;

  num? get 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("RTCRtpReceiver")
class RtcRtpReceiver extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory RtcRtpReceiver._() {
    throw new UnsupportedError("Not supported");
  }

  MediaStreamTrack? get track native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory RtcRtpSender._() {
    throw new UnsupportedError("Not supported");
  }

  MediaStreamTrack? get track 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("RTCSessionDescription,mozRTCSessionDescription")
class RtcSessionDescription extends JavaScriptObject {
  factory RtcSessionDescription(Map dictionary) {
    var constructorName = JS('', 'window[#]', 'RTCSessionDescription');
    return JS(
      'RtcSessionDescription',
      'new #(#)',
      constructorName,
      convertDartToNative_SerializedScriptValue(dictionary),
    );
  }
  // To suppress missing implicit constructor warnings.
  factory RtcSessionDescription._() {
    throw new UnsupportedError("Not supported");
  }

  String? get sdp native;

  set sdp(String? value) native;

  String? get type native;

  set type(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.

@Native("RTCStatsReport")
class RtcStatsReport extends JavaScriptObject 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 JavaScriptObject {
  // 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);

  RtcRtpReceiver? get receiver native;

  List<MediaStream>? get streams native;

  MediaStreamTrack? get track 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("Screen")
class Screen extends JavaScriptObject {
  Rectangle get available =>
      new Rectangle(_availLeft!, _availTop!, _availWidth!, _availHeight!);
  // To suppress missing implicit constructor warnings.
  factory Screen._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('availHeight')
  int? get _availHeight native;

  @JSName('availLeft')
  int? get _availLeft native;

  @JSName('availTop')
  int? get _availTop native;

  @JSName('availWidth')
  int? get _availWidth native;

  int? get colorDepth native;

  int? get height native;

  bool? get keepAwake native;

  set keepAwake(bool? value) native;

  ScreenOrientation? get orientation native;

  int? get pixelDepth native;

  int? get width 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("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');

  int? get angle native;

  String? get type native;

  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<ScriptElement>(
    '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? get async native;

  set async(bool? value) native;

  String get charset native;

  set charset(String value) native;

  String? get crossOrigin native;

  set crossOrigin(String? value) native;

  bool? get defer native;

  set defer(bool? value) native;

  String? get integrity native;

  set integrity(String? value) native;

  bool? get noModule native;

  set noModule(bool? value) native;

  String get src native;

  set src(String value) native;

  String get type native;

  set type(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.

@Native("ScrollState")
class ScrollState extends JavaScriptObject {
  // 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()');

  num? get deltaGranularity native;

  num? get deltaX native;

  num? get deltaY native;

  bool? get fromUserInput native;

  bool? get inInertialPhase native;

  bool? get isBeginning native;

  bool? get isDirectManipulation native;

  bool? get isEnding native;

  int? get positionX native;

  int? get positionY native;

  num? get velocityX native;

  num? get velocityY native;

  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()');

  String? get orientation native;

  Element? get scrollSource native;

  Object? get timeRange 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("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')
  String? get blockedUri native;

  int? get columnNumber native;

  String? get disposition native;

  @JSName('documentURI')
  String? get documentUri native;

  String? get effectiveDirective native;

  int? get lineNumber native;

  String? get originalPolicy native;

  String? get referrer native;

  String? get sample native;

  String? get sourceFile native;

  int? get statusCode native;

  String? get violatedDirective 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("HTMLSelectElement")
class SelectElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory SelectElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory SelectElement() => JS<SelectElement>(
    '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 get autofocus native;

  set autofocus(bool value) native;

  bool get disabled native;

  set disabled(bool value) native;

  FormElement? get form native;

  @Unstable()
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node>? get labels native;

  int? get length native;

  set length(int? value) native;

  bool? get multiple native;

  set multiple(bool? value) native;

  String? get name native;

  set name(String? value) native;

  bool? get required native;

  set required(bool? value) native;

  int? get selectedIndex native;

  set selectedIndex(int? value) native;

  int? get size native;

  set size(int? value) native;

  String get type native;

  String get validationMessage native;

  ValidityState get validity native;

  String? get value native;

  set value(String? value) native;

  bool get willValidate native;

  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 {
      var i = this.selectedIndex!;
      return i < 0 ? [] : [this.options[i]];
    }
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. 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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory Selection._() {
    throw new UnsupportedError("Not supported");
  }

  Node? get anchorNode native;

  int? get anchorOffset native;

  Node? get baseNode native;

  int? get baseOffset native;

  Node? get extentNode native;

  int? get extentOffset native;

  Node? get focusNode native;

  int? get focusOffset native;

  bool? get isCollapsed native;

  int? get rangeCount native;

  String? get type native;

  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');

  bool? get activated native;

  bool? get hasReading native;

  num? get timestamp native;

  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);

  DomException? get 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("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')
  String? get scriptUrl native;

  String? get state 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;

  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');

  ServiceWorker? get controller native;

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

  Future<ServiceWorkerRegistration> getRegistration([String? documentURL]) =>
      promiseToFuture<ServiceWorkerRegistration>(
        JS(
          "creates:ServiceWorkerRegistration;",
          "#.getRegistration(#)",
          this,
          documentURL,
        ),
      );

  Future<List<dynamic>> getRegistrations() =>
      promiseToFuture<List<dynamic>>(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(
        "creates:ServiceWorkerRegistration;",
        "#.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');

  Clients? get clients native;

  ServiceWorkerRegistration? get registration native;

  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");
  }

  ServiceWorker? get active native;

  BackgroundFetchManager? get backgroundFetch native;

  ServiceWorker? get installing native;

  NavigationPreloadManager? get navigationPreload native;

  PaymentManager? get paymentManager native;

  PushManager? get pushManager native;

  String? get scope native;

  SyncManager? get sync native;

  ServiceWorker? get waiting native;

  Future<List<dynamic>> getNotifications([Map? filter]) {
    var filter_dict = null;
    if (filter != null) {
      filter_dict = convertDartToNative_Dictionary(filter);
    }
    return promiseToFuture<List<dynamic>>(
      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") as ShadowElement;
  /**
   * 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')
  @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");
  }

  bool? get delegatesFocus native;

  Element? get host native;

  @JSName('innerHTML')
  String? get innerHtml native;

  @JSName('innerHTML')
  set innerHtml(String? value) native;

  String? get mode native;

  ShadowRoot? get olderShadowRoot native;

  // From DocumentOrShadowRoot

  Element? get activeElement native;

  Element? get fullscreenElement native;

  Element? get pointerLockElement native;

  @Returns('_StyleSheetList')
  @Creates('_StyleSheetList')
  List<StyleSheet>? get styleSheets native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory SharedArrayBuffer._() {
    throw new UnsupportedError("Not supported");
  }

  factory SharedArrayBuffer([int? length]) {
    if (length != null) {
      return SharedArrayBuffer._create_1(length);
    }
    return SharedArrayBuffer._create_2();
  }
  static SharedArrayBuffer _create_1(length) =>
      JS('SharedArrayBuffer', 'new SharedArrayBuffer(#)', length);
  static SharedArrayBuffer _create_2() =>
      JS('SharedArrayBuffer', 'new SharedArrayBuffer()');

  int? get byteLength native;

  SharedArrayBuffer slice([int? begin, int? end]) 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("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);

  MessagePort? get port 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("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;

  String? get name native;

  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? get name native;

  set name(String? value) native;

  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? get appendWindowEnd native;

  set appendWindowEnd(num? value) native;

  num? get appendWindowStart native;

  set appendWindowStart(num? value) native;

  AudioTrackList? get audioTracks native;

  TimeRanges? get buffered native;

  String? get mode native;

  set mode(String? value) native;

  num? get timestampOffset native;

  set timestampOffset(num? value) native;

  TrackDefaultList? get trackDefaults native;

  set trackDefaults(TrackDefaultList? value) native;

  bool? get updating native;

  VideoTrackList? get videoTracks native;

  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 List<SourceBuffer>, JavaScriptIndexingBehavior<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 IndexError.withLength(index, length, indexable: 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 newLength) {
    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<SourceElement>(
    '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 get media native;

  set media(String value) native;

  String? get sizes native;

  set sizes(String? value) native;

  String get src native;

  set src(String value) native;

  String? get srcset native;

  set srcset(String? value) native;

  String get type native;

  set type(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.

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

  factory SpanElement() => JS<SpanElement>(
    '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 JavaScriptObject {
  // 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? get src native;

  set src(String? value) native;

  num? get weight native;

  set weight(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("SpeechGrammarList")
class SpeechGrammarList extends JavaScriptObject
    with ListMixin<SpeechGrammar>, ImmutableListMixin<SpeechGrammar>
    implements List<SpeechGrammar>, JavaScriptIndexingBehavior<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 IndexError.withLength(index, length, indexable: 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 newLength) {
    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,webkitSpeechRecognition")
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? get audioTrack native;

  set audioTrack(MediaStreamTrack? value) native;

  bool? get continuous native;

  set continuous(bool? value) native;

  SpeechGrammarList? get grammars native;

  set grammars(SpeechGrammarList? value) native;

  bool? get interimResults native;

  set interimResults(bool? value) native;

  String? get lang native;

  set lang(String? value) native;

  int? get maxAlternatives native;

  set maxAlternatives(int? value) native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionAlternative._() {
    throw new UnsupportedError("Not supported");
  }

  num? get confidence native;

  String? get transcript 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, '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);

  String? get error native;

  String? get message 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, '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);

  Document? get emma native;

  Document? get interpretation native;

  int? get resultIndex native;

  @Returns('_SpeechRecognitionResultList|Null')
  @Creates('_SpeechRecognitionResultList')
  List<SpeechRecognitionResult>? get results 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, '25')
@Native("SpeechRecognitionResult")
class SpeechRecognitionResult extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionResult._() {
    throw new UnsupportedError("Not supported");
  }

  bool? get isFinal native;

  int? get length native;

  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");
  }

  bool? get paused native;

  bool? get pending native;

  bool? get speaking native;

  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");
  }

  int? get charIndex native;

  num? get elapsedTime native;

  String? get name native;

  SpeechSynthesisUtterance? get 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("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? get lang native;

  set lang(String? value) native;

  num? get pitch native;

  set pitch(num? value) native;

  num? get rate native;

  set rate(num? value) native;

  String? get text native;

  set text(String? value) native;

  SpeechSynthesisVoice? get voice native;

  set voice(SpeechSynthesisVoice? value) native;

  num? get volume native;

  set volume(num? value) native;

  /// 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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesisVoice._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('default')
  bool? get defaultValue native;

  String? get lang native;

  bool? get localService native;

  String? get name native;

  @JSName('voiceURI')
  String? get voiceUri 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("StaticRange")
class StaticRange extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory StaticRange._() {
    throw new UnsupportedError("Not supported");
  }

  bool? get collapsed native;

  Node? get endContainer native;

  int? get endOffset native;

  Node? get startContainer native;

  int? get startOffset 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.

/**
 * 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](https://api.dart.dev/dart-core/Map-class.html) APIs
 * such as containsValue(), clear(), and length:
 *
 *     assert(window.localStorage.containsValue('does not exist') == false);
 *     window.localStorage.clear();
 *     assert(window.localStorage.length == 0);
 *
 */
@Unstable()
@Native("Storage")
class Storage extends JavaScriptObject 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 as String) != null;

  String? operator [](Object? key) => _getItem(key as String);

  void operator []=(String key, String value) {
    _setItem(key, value);
  }

  String putIfAbsent(String key, String ifAbsent()) {
    if (!containsKey(key)) this[key] = ifAbsent();
    return this[key] as String;
  }

  String? remove(Object? key) {
    final value = this[key];
    _removeItem(key as String);
    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')
  int get _length native;

  @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") as 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);

  String? get key native;

  String? get newValue native;

  String? get oldValue native;

  Storage? get storageArea native;

  String? get url native;

  @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 JavaScriptObject {
  // 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<StyleElement>(
    '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 get disabled native;

  set disabled(bool value) native;

  String get media native;

  set media(String value) native;

  StyleSheet? get sheet native;

  String? get type native;

  set type(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.

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

  String? get type native;

  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 JavaScriptObject {
  // 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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory StyleSheet._() {
    throw new UnsupportedError("Not supported");
  }

  bool? get disabled native;

  set disabled(bool? value) native;

  String? get href native;

  MediaList? get media native;

  Node? get ownerNode native;

  StyleSheet? get parentStyleSheet native;

  String? get title native;

  String? get 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("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);

  bool? get lastChance native;

  String? get tag 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("SyncManager")
class SyncManager extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory SyncManager._() {
    throw new UnsupportedError("Not supported");
  }

  Future<List<dynamic>> getTags() =>
      promiseToFuture<List<dynamic>>(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<TableCaptionElement>(
    '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<TableCellElement>(
    '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();

  int get cellIndex native;

  int get colSpan native;

  set colSpan(int value) native;

  String get headers native;

  set headers(String? value) native;

  int get rowSpan native;

  set rowSpan(int 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("HTMLTableColElement")
class TableColElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TableColElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory TableColElement() => JS<TableColElement>(
    '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 get span native;

  set span(int value) 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("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 as TableSectionElement;
  }

  @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<TableElement>(
    '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? get caption native;

  set caption(TableCaptionElement? value) native;

  @JSName('rows')
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  List<Node> get _rows native;

  @JSName('tBodies')
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  List<Node> get _tBodies native;

  TableSectionElement? get tFoot native;

  set tFoot(TableSectionElement? value) native;

  TableSectionElement? get tHead native;

  set tHead(TableSectionElement? value) native;

  @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) as TableCellElement;

  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<TableRowElement>(
    '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')
  @Creates('HtmlCollection')
  List<Node> get _cells native;

  int get rowIndex native;

  int get sectionRowIndex native;

  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) as TableRowElement;

  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')
  @Creates('HtmlCollection')
  List<Node> get _rows native;

  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");
  }

  String? get containerId native;

  String? get containerName native;

  String? get containerSrc native;

  String? get containerType native;

  @JSName('scriptURL')
  String? get scriptUrl 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.

@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") as TemplateElement;
  /**
   * 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');

  DocumentFragment? get content native;

  /**
   * An override to place the contents into content rather than as child nodes.
   *
   * See also:
   *
   * * <https://w3c.github.io/DOM-Parsing/#the-innerhtml-mixin>
   */
  void setInnerHtml(
    String? html, {
    NodeValidator? validator,
    NodeTreeSanitizer? treeSanitizer,
  }) {
    text = null;
    content!.nodes.clear();
    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");
  }

  SlotElement? get assignedSlot native;

  String get wholeText native;

  @Returns('NodeList')
  @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<TextAreaElement>(
    '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? get autocapitalize native;

  set autocapitalize(String? value) native;

  bool get autofocus native;

  set autofocus(bool value) native;

  int get cols native;

  set cols(int value) native;

  String? get defaultValue native;

  set defaultValue(String? value) native;

  String? get dirName native;

  set dirName(String? value) native;

  bool get disabled native;

  set disabled(bool value) native;

  FormElement? get form native;

  @Unstable()
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node>? get labels native;

  int get maxLength native;

  set maxLength(int value) native;

  int get minLength native;

  set minLength(int value) native;

  String get name native;

  set name(String value) native;

  String get placeholder native;

  set placeholder(String value) native;

  bool get readOnly native;

  set readOnly(bool value) native;

  bool get required native;

  set required(bool value) native;

  int get rows native;

  set rows(int value) native;

  String? get selectionDirection native;

  set selectionDirection(String? value) native;

  int? get selectionEnd native;

  set selectionEnd(int? value) native;

  int? get selectionStart native;

  set selectionStart(int? value) native;

  int? get textLength native;

  String? get type native;

  String? get validationMessage native;

  ValidityState? get validity native;

  String? get value native;

  set value(String? value) native;

  bool? get willValidate native;

  String get wrap native;

  set wrap(String value) native;

  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 JavaScriptObject {
  // 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<dynamic>> detect(/*ImageBitmapSource*/ image) =>
      promiseToFuture<List<dynamic>>(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") as TextEvent;
    e._initTextEvent(type, canBubble, cancelable, view, data);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory TextEvent._() {
    throw new UnsupportedError("Not supported");
  }

  String? get data native;

  @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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory TextMetrics._() {
    throw new UnsupportedError("Not supported");
  }

  num? get actualBoundingBoxAscent native;

  num? get actualBoundingBoxDescent native;

  num? get actualBoundingBoxLeft native;

  num? get actualBoundingBoxRight native;

  num? get alphabeticBaseline native;

  num? get emHeightAscent native;

  num? get emHeightDescent native;

  num? get fontBoundingBoxAscent native;

  num? get fontBoundingBoxDescent native;

  num? get hangingBaseline native;

  num? get ideographicBaseline native;

  num? get width 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("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');

  TextTrackCueList? get activeCues native;

  TextTrackCueList? get cues native;

  String get id native;

  String get kind native;

  String get label native;

  String get language native;

  String? get mode native;

  set mode(String? value) native;

  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? get endTime native;

  set endTime(num? value) native;

  String? get id native;

  set id(String? value) native;

  bool? get pauseOnExit native;

  set pauseOnExit(bool? value) native;

  num? get startTime native;

  set startTime(num? value) native;

  TextTrack? get track native;

  /// 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 JavaScriptObject
    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 IndexError.withLength(index, length, indexable: 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 newLength) {
    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 IndexError.withLength(index, length, indexable: 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 newLength) {
    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? get dateTime native;

  set dateTime(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.

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

  int get length native;

  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<TitleElement>(
    '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 JavaScriptObject {
  // 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')
  num? get _clientX native;

  @JSName('clientY')
  num? get _clientY native;

  num? get force native;

  int? get identifier native;

  @JSName('pageX')
  num? get _pageX native;

  @JSName('pageY')
  num? get _pageY native;

  @JSName('radiusX')
  num? get _radiusX native;

  @JSName('radiusY')
  num? get _radiusY native;

  String? get region native;

  num? get rotationAngle native;

  @JSName('screenX')
  num? get _screenX native;

  @JSName('screenY')
  num? get _screenY native;

  EventTarget? get target => _convertNativeToDart_EventTarget(this._get_target);
  @JSName('target')
  @Creates('Element|Document')
  @Returns('Element|Document')
  dynamic get _get_target native;

  // 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>('num', '#.clientX', this).round();
  int get __clientY => JS<num>('num', '#.clientY', this).round();
  int get __screenX => JS<num>('num', '#.screenX', this).round();
  int get __screenY => JS<num>('num', '#.screenY', this).round();
  int get __pageX => JS<num>('num', '#.pageX', this).round();
  int get __pageY => JS<num>('num', '#.pageY', this).round();
  int get __radiusX => JS<num>('num', '#.radiusX', this).round();
  int get __radiusY => JS<num>('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);

  bool? get altKey native;

  TouchList? get changedTouches native;

  bool? get ctrlKey native;

  bool? get metaKey native;

  bool? get shiftKey native;

  TouchList? get targetTouches native;

  TouchList? get touches native;

  /**
   * Checks if touch events supported on the current platform.
   */
  static bool get supported {
    try {
      return TouchEvent('touches') is TouchEvent;
    } catch (_) {}

    return 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.

@Native("TouchList")
class TouchList extends JavaScriptObject
    with ListMixin<Touch>, ImmutableListMixin<Touch>
    implements List<Touch>, JavaScriptIndexingBehavior<Touch> {
  // 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 IndexError.withLength(index, length, indexable: 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 newLength) {
    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 JavaScriptObject {
  // 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,
  );

  String? get byteStreamTrackID native;

  Object? get kinds native;

  String? get label native;

  String? get language native;

  String? get 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("TrackDefaultList")
class TrackDefaultList extends JavaScriptObject {
  // 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()');

  int? get length native;

  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") as TrackElement;
  /**
   * 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? get defaultValue native;

  @JSName('default')
  set defaultValue(bool? value) native;

  String? get kind native;

  set kind(String? value) native;

  String? get label native;

  set label(String? value) native;

  int? get readyState native;

  String? get src native;

  set src(String? value) native;

  String? get srclang native;

  set srclang(String? value) native;

  TextTrack? get track 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("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')
  Object? get track 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("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);

  num? get elapsedTime native;

  String? get propertyName native;

  String? get pseudoElement 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.

@Unstable()
@Native("TreeWalker")
class TreeWalker extends JavaScriptObject {
  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 get currentNode native;

  set currentNode(Node value) native;

  NodeFilter? get filter native;

  Node get root native;

  int get whatToShow native;

  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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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") as 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);

  int? get detail native;

  InputDeviceCapabilities? get sourceCapabilities native;

  WindowBase? get view => _convertNativeToDart_Window(this._get_view);
  @JSName('view')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  dynamic get _get_view native;

  @JSName('which')
  @Unstable()
  int? get _which native;

  @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<UListElement>(
    '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 JavaScriptObject {
  // 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 JavaScriptObject {
  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? get hash native;

  set hash(String? value) native;

  String? get host native;

  set host(String? value) native;

  String? get hostname native;

  set hostname(String? value) native;

  String? get href native;

  set href(String? value) native;

  String? get origin native;

  String? get password native;

  set password(String? value) native;

  String? get pathname native;

  set pathname(String? value) native;

  String? get port native;

  set port(String? value) native;

  String? get protocol native;

  set protocol(String? value) native;

  String? get search native;

  set search(String? value) native;

  UrlSearchParams? get searchParams native;

  String? get username native;

  set username(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.

@Native("URLSearchParams")
class UrlSearchParams extends JavaScriptObject {
  // 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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory UrlUtilsReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  String? get hash native;

  String? get host native;

  String? get hostname native;

  String? get href native;

  String? get origin native;

  String? get pathname native;

  String? get port native;

  String? get protocol native;

  String? get search 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("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 JavaScriptObject {
  // 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");
  }

  String? get deviceName native;

  bool? get isExternal native;

  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);

  VRDevice? get device 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("VRDisplay")
class VRDisplay extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory VRDisplay._() {
    throw new UnsupportedError("Not supported");
  }

  VRDisplayCapabilities? get capabilities native;

  num? get depthFar native;

  set depthFar(num? value) native;

  num? get depthNear native;

  set depthNear(num? value) native;

  int? get displayId native;

  String? get displayName native;

  bool? get isPresenting native;

  VRStageParameters? get stageParameters native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory VRDisplayCapabilities._() {
    throw new UnsupportedError("Not supported");
  }

  bool? get canPresent native;

  bool? get hasExternalDisplay native;

  bool? get hasPosition native;

  int? get maxLayers 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("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);

  VRDisplay? get display native;

  String? get reason 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("VREyeParameters")
class VREyeParameters extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory VREyeParameters._() {
    throw new UnsupportedError("Not supported");
  }

  Float32List? get offset native;

  int? get renderHeight native;

  int? get renderWidth 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("VRFrameData")
class VRFrameData extends JavaScriptObject {
  // 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()');

  Float32List? get leftProjectionMatrix native;

  Float32List? get leftViewMatrix native;

  VRPose? get pose native;

  Float32List? get rightProjectionMatrix native;

  Float32List? get rightViewMatrix 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("VRFrameOfReference")
class VRFrameOfReference extends VRCoordinateSystem {
  // To suppress missing implicit constructor warnings.
  factory VRFrameOfReference._() {
    throw new UnsupportedError("Not supported");
  }

  VRStageBounds? get bounds native;

  num? get emulatedHeight 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("VRPose")
class VRPose extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory VRPose._() {
    throw new UnsupportedError("Not supported");
  }

  Float32List? get angularAcceleration native;

  Float32List? get angularVelocity native;

  Float32List? get linearAcceleration native;

  Float32List? get linearVelocity native;

  Float32List? get orientation native;

  Float32List? get position 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("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? get depthFar native;

  set depthFar(num? value) native;

  num? get depthNear native;

  set depthNear(num? value) native;

  VRDevice? get device native;

  bool? get exclusive native;

  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(
        "creates:VRFrameOfReference;",
        "#.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);

  VRSession? get session 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("VRStageBounds")
class VRStageBounds extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory VRStageBounds._() {
    throw new UnsupportedError("Not supported");
  }

  List<VRStageBoundsPoint>? get geometry 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("VRStageBoundsPoint")
class VRStageBoundsPoint extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory VRStageBoundsPoint._() {
    throw new UnsupportedError("Not supported");
  }

  num? get x native;

  num? get z 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("VRStageParameters")
class VRStageParameters extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory VRStageParameters._() {
    throw new UnsupportedError("Not supported");
  }

  Float32List? get sittingToStandingTransform native;

  num? get sizeX native;

  num? get sizeZ 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("ValidityState")
class ValidityState extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory ValidityState._() {
    throw new UnsupportedError("Not supported");
  }

  bool? get badInput native;

  bool? get customError native;

  bool? get patternMismatch native;

  bool? get rangeOverflow native;

  bool? get rangeUnderflow native;

  bool? get stepMismatch native;

  bool? get tooLong native;

  bool? get tooShort native;

  bool? get typeMismatch native;

  bool? get valid native;

  bool? get valueMissing 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("HTMLVideoElement")
class VideoElement extends MediaElement implements CanvasImageSource {
  // To suppress missing implicit constructor warnings.
  factory VideoElement._() {
    throw new UnsupportedError("Not supported");
  }

  factory VideoElement() => JS<VideoElement>(
    '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 get height native;

  set height(int value) native;

  String get poster native;

  set poster(String value) native;

  int get videoHeight native;

  int get videoWidth native;

  @JSName('webkitDecodedFrameCount')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  int? get decodedFrameCount native;

  @JSName('webkitDroppedFrameCount')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  int? get droppedFrameCount native;

  int get width native;

  set width(int value) native;

  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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory VideoPlaybackQuality._() {
    throw new UnsupportedError("Not supported");
  }

  int? get corruptedVideoFrames native;

  num? get creationTime native;

  int? get droppedVideoFrames native;

  int? get totalVideoFrames 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("VideoTrack")
class VideoTrack extends JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory VideoTrack._() {
    throw new UnsupportedError("Not supported");
  }

  String? get id native;

  String? get kind native;

  String? get label native;

  String? get language native;

  bool? get selected native;

  set selected(bool? value) native;

  SourceBuffer? get sourceBuffer 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("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');

  int? get length native;

  int? get selectedIndex native;

  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');

  num? get height native;

  num? get offsetLeft native;

  num? get offsetTop native;

  num? get pageLeft native;

  num? get pageTop native;

  num? get scale native;

  num? get width native;

  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? get align native;

  set align(String? value) native;

  @Creates('Null')
  @Returns('num|String')
  Object? get line native;

  set line(Object? value) native;

  @Creates('Null')
  @Returns('num|String')
  Object? get position native;

  set position(Object? value) native;

  VttRegion? get region native;

  set region(VttRegion? value) native;

  num? get size native;

  set size(num? value) native;

  bool? get snapToLines native;

  set snapToLines(bool? value) native;

  String? get text native;

  set text(String? value) native;

  String? get vertical native;

  set vertical(String? value) native;

  @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 JavaScriptObject {
  // 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? get id native;

  set id(String? value) native;

  int? get lines native;

  set lines(int? value) native;

  num? get regionAnchorX native;

  set regionAnchorX(num? value) native;

  num? get regionAnchorY native;

  set regionAnchorY(num? value) native;

  String? get scroll native;

  set scroll(String? value) native;

  num? get viewportAnchorX native;

  set viewportAnchorX(num? value) native;

  num? get viewportAnchorY native;

  set viewportAnchorY(num? value) native;

  num? get width native;

  set width(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.

/**
 * 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 [Event]s.
 *
 * 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? get binaryType native;

  set binaryType(String? value) native;

  int? get bufferedAmount native;

  String? get extensions native;

  String? get protocol native;

  int get readyState native;

  String? get url native;

  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')
  num? get _deltaX native;

  @JSName('deltaY')
  num? get _deltaY native;

  num? get deltaZ native;

  /**
   * 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 {
    // deltaY may be missing or undefined.
    num? value = JS('', '#.deltaY', this);
    if (value != null) return value;
    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 {
    // deltaX may be missing or undefined.
    num? value = JS('', '#.deltaX', this);
    if (value != null) return value;
    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
        GlobalEventHandlers,
        WindowBase64,
        WindowEventHandlers,
        _WindowTimers,
        WindowBase {
  /**
   * 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.
   */
  WindowBase open(String url, String name, [String? options]) {
    final win =
        options == null ? _open2(url, name) : _open3(url, name, options);
    return _DOMWindowCrossFrame._createSafe(win);
  }

  // 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.
   */
  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>(
      '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 [dart: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;

  _Worklet? get animationWorklet native;

  /**
   * 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.
   */

  ApplicationCache? get applicationCache native;

  _Worklet? get audioWorklet native;

  CacheStorage? get caches native;

  bool? get closed native;

  CookieStore? get cookieStore native;

  /**
   * Entrypoint for the browser's cryptographic functions.
   *
   * ## Other resources
   *
   * * [Web cryptography API](http://www.w3.org/TR/WebCryptoAPI/) from W3C.
   */

  Crypto? get crypto native;

  CustomElementRegistry? get customElements native;

  /// *Deprecated*.

  String? get defaultStatus native;

  set defaultStatus(String? value) native;

  /// *Deprecated*.

  String? get defaultstatus native;

  set defaultstatus(String? value) native;

  /**
   * 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.
   */

  num get devicePixelRatio native;

  External? get external native;

  /**
   * 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.
   */

  History get history native;

  /**
   * The height of the viewport including scrollbars.
   *
   * ## Other resources
   *
   * * [Window.innerHeight](https://developer.mozilla.org/en-US/docs/Web/API/Window/innerHeight)
   *   from MDN.
   */

  int? get innerHeight native;

  /**
   * The width of the viewport including scrollbars.
   *
   * ## Other resources
   *
   * * [Window.innerWidth](https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth)
   *   from MDN.
   */

  int? get innerWidth native;

  bool? get isSecureContext native;

  /**
   * 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.
   */

  Storage get localStorage native;

  /**
   * 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.
   */

  BarProp? get locationbar native;

  /**
   * 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.
   */

  BarProp? get menubar native;

  /**
   * The name of this window.
   *
   * ## Other resources
   *
   * * [Window.name](https://developer.mozilla.org/en-US/docs/Web/API/Window/name)
   *   from MDN.
   */

  String? get name native;

  set name(String? value) native;

  /**
   * The user agent accessing this window.
   *
   * ## Other resources
   *
   * * [The navigator
   *   object](https://html.spec.whatwg.org/multipage/webappapis.html#the-navigator-object)
   *   from WHATWG.
   */

  Navigator get navigator native;

  /**
   * Whether objects are drawn offscreen before being displayed.
   *
   * ## Other resources
   *
   * * [offscreenBuffering](https://webplatform.github.io/docs/dom/HTMLElement/offscreenBuffering/)
   *   from WebPlatform.org.
   */

  bool? get offscreenBuffering native;

  WindowBase? get opener => _convertNativeToDart_Window(this._get_opener);
  @JSName('opener')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  dynamic get _get_opener native;

  set opener(WindowBase? value) native;

  int? get orientation native;

  String? get origin native;

  /**
   * The height of this window including all user interface elements.
   *
   * ## Other resources
   *
   * * [Window.outerHeight](https://developer.mozilla.org/en-US/docs/Web/API/Window/outerHeight)
   *   from MDN.
   */

  int get outerHeight native;

  /**
   * The width of the window including all user interface elements.
   *
   * ## Other resources
   *
   * * [Window.outerWidth](https://developer.mozilla.org/en-US/docs/Web/API/Window/outerWidth)
   *   from MDN.
   */

  int get outerWidth native;

  @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.
   */
  num get _pageXOffset native;

  @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.
   */
  num get _pageYOffset native;

  WindowBase? get parent => _convertNativeToDart_Window(this._get_parent);
  @JSName('parent')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  dynamic get _get_parent native;

  /**
   * Timing and navigation data for this window.
   *
   * ## Other resources
   *
   * * [Measuring page load speed with navigation
   *   timing](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)
  Performance get performance native;

  /**
   * Information about the screen displaying this window.
   *
   * ## Other resources
   *
   * * [The Screen interface specification](http://www.w3.org/TR/cssom-view/#screen)
   *   from W3C.
   */

  Screen? get screen native;

  /**
   * 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.
   */

  int? get screenLeft native;

  /**
   * 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.
   */

  int? get screenTop native;

  /**
   * 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.
   */

  int? get screenX native;

  /**
   * 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.
   */

  int? get screenY native;

  /**
   * This window's scroll bars.
   *
   * ## Other resources
   *
   * * [Browser interface
   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
   *   from WHATWG.
   */

  BarProp? get scrollbars native;

  /**
   * 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')
  dynamic get _get_self native;

  /**
   * 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.
   */

  Storage get sessionStorage native;

  /**
   * 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.
   */

  SpeechSynthesis? get speechSynthesis native;

  /// *Deprecated*.

  String? get status native;

  set status(String? value) native;

  /**
   * This window's status bar.
   *
   * ## Other resources
   *
   * * [Browser interface
   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
   *   from WHATWG.
   */

  BarProp? get statusbar native;

  /**
   * Access to CSS media queries.
   *
   * ## Other resources
   *
   * * [StyleMedia class
   *   reference](https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/StyleMedia/)
   *   from Safari Developer Library.
   */

  StyleMedia? get styleMedia native;

  /**
   * This window's tool bar.
   *
   * ## Other resources
   *
   * * [Browser interface
   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
   *   from WHATWG.
   */

  BarProp? get toolbar native;

  WindowBase? get top => _convertNativeToDart_Window(this._get_top);
  @JSName('top')
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  dynamic get _get_top native;

  VisualViewport? get visualViewport native;

  /**
   * 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')
  dynamic get _get_window native;

  @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("creates:_Response;", "#.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')
  @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;

  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 callback_1 = convertDartClosureToJS(callback, 1);
      var options_2 = convertDartToNative_Dictionary(options);
      return _requestIdleCallback_1(callback_1, options_2);
    }
    var callback_1 = convertDartClosureToJS(callback, 1);
    return _requestIdleCallback_2(callback_1);
  }

  @JSName('requestIdleCallback')
  int _requestIdleCallback_1(callback, options) native;
  @JSName('requestIdleCallback')
  int _requestIdleCallback_2(callback) native;

  /**
   * Resizes this window by an offset.
   *
   * ## Other resources
   *
   * * [Window.resizeBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/resizeBy)
   *   from MDN.
   */
  void resizeBy(int x, int y) native;

  /**
   * Resizes this window to a specific width and height.
   *
   * ## Other resources
   *
   * * [Window.resizeTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/resizeTo)
   *   from MDN.
   */
  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](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
   *   from MDN.
   */
  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](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
   *   from MDN.
   */
  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](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
   *   from MDN.
   */
  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](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
   *   from MDN.
   */
  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](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
   *   from MDN.
   */
  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](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
   *   from MDN.
   */
  void _scroll_5(int? x, int? y, scrollOptions) native;

  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
   *   from MDN.
   */
  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](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
   *   from MDN.
   */
  void _scrollBy_1() native;
  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
   *   from MDN.
   */
  void _scrollBy_2(options) native;
  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
   *   from MDN.
   */
  void _scrollBy_3(num? x, num? y) native;
  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
   *   from MDN.
   */
  void _scrollBy_4(int? x, int? y) native;
  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
   *   from MDN.
   */
  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](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
   *   from MDN.
   */
  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](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
   *   from MDN.
   */
  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](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
   *   from MDN.
   */
  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](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
   *   from MDN.
   */
  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](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
   *   from MDN.
   */
  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](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
   *   from MDN.
   */
  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('WebKitFileSystem', value);
        applyExtension('webkitFileSystem', value);
        applyExtension('FileSystem', value);
        applyExtension('DirectoryEntry', value.root);
        applyExtension('webkitFileSystemDirectoryEntry', value.root);
        applyExtension('FileSystemDirectoryEntry', 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].
  @DomName('Window.ondblclick')
  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 EventStreamProvider('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.toInt(), p.y.toInt());
  }

  int get pageXOffset => JS<num>('num', '#.pageXOffset', this).round();

  int get pageYOffset => JS<num>('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>('bool', '("scrollX" in #)', this)
          ? JS<num>('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>('bool', '("scrollY" in #)', this)
          ? JS<num>('num', '#.scrollY', this).round()
          : document.documentElement!.scrollTop;
}

class NullWindowException implements Exception {
  @override
  String toString() {
    return 'Attempting to use a null window opened in Window.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.

abstract class WindowBase64 extends JavaScriptObject {
  // 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");
  }

  bool? get focused native;

  String? get visibilityState native;

  Future<WindowClient> focus() => promiseToFuture<WindowClient>(
    JS("creates:WindowClient;", "#.focus()", this),
  );

  Future<WindowClient> navigate(String url) => promiseToFuture<WindowClient>(
    JS("creates:WindowClient;", "#.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(/*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;

  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 WindowBase64, _WindowTimers {
  // 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');

  String? get addressSpace native;

  CacheStorage? get caches native;

  Crypto? get crypto native;

  IdbFactory? get indexedDB native;

  bool? get isSecureContext native;

  _WorkerLocation get location native;

  _WorkerNavigator get navigator native;

  String? get origin native;

  WorkerPerformance? get performance native;

  WorkerGlobalScope get self native;

  Future fetch(/*RequestInfo*/ input, [Map? init]) {
    var init_dict = null;
    if (init != null) {
      init_dict = convertDartToNative_Dictionary(init);
    }
    return promiseToFuture(
      JS("creates:_Response;", "#.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");
  }

  MemoryInfo? get memory native;

  num? get timeOrigin native;

  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 JavaScriptObject {
  // 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,
  );

  String? get playState native;

  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 JavaScriptObject {
  // 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.

@Native("XPathEvaluator")
class XPathEvaluator extends JavaScriptObject {
  // 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.

@Native("XPathExpression")
class XPathExpression extends JavaScriptObject {
  // 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.

@Native("XPathNSResolver")
class XPathNSResolver extends JavaScriptObject {
  // 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.

@Native("XPathResult")
class XPathResult extends JavaScriptObject {
  // 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;

  bool? get booleanValue native;

  bool? get invalidIteratorState native;

  num? get numberValue native;

  int? get resultType native;

  Node? get singleNodeValue native;

  int? get snapshotLength native;

  String? get stringValue native;

  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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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')
  String? get _localName native;

  String? get name native;

  @JSName('namespaceURI')
  String? get _namespaceUri native;

  String? get value native;

  set value(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.

@Native("Bluetooth")
abstract class _Bluetooth extends JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory _BudgetService._() {
    throw new UnsupportedError("Not supported");
  }

  Future<BudgetState> getBudget() => promiseToFuture<BudgetState>(
    JS("creates:BudgetState;", "#.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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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("creates:DataTransfer;", "#.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 JavaScriptObject
    with ListMixin<CssRule>, ImmutableListMixin<CssRule>
    implements List<CssRule>, JavaScriptIndexingBehavior<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 IndexError.withLength(index, length, indexable: 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 newLength) {
    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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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) =>
      other is Rectangle &&
      left == other.left &&
      top == other.top &&
      width == other.width &&
      height == other.height;

  int get hashCode => Object.hash(left, top, width, height);

  /**
   * 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.

  // The following getter is incompatible with some browsers but
  // must be made non-nullable to match the overridden method.

  @JSName('height')
  num? get _height native;

  num get height => _height!;

  set height(num value) native;

  // Shadowing definition.

  // The following getter is incompatible with some browsers but
  // must be made non-nullable to match the overridden method.

  @JSName('width')
  num? get _width native;

  num get width => _width!;

  set width(num value) native;

  // Shadowing definition.

  num? get x native;

  set x(num? value) native;

  // Shadowing definition.

  num? get y native;

  set y(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("EntrySync")
abstract class _EntrySync extends JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject
    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 IndexError.withLength(index, length, indexable: 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 newLength) {
    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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject
    with ListMixin<Node>, ImmutableListMixin<Node>
    implements List<Node>, JavaScriptIndexingBehavior<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 IndexError.withLength(index, length, indexable: 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 newLength) {
    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 JavaScriptObject {
  // 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 JavaScriptObject {
  // To suppress missing implicit constructor warnings.
  factory _Report._() {
    throw new UnsupportedError("Not supported");
  }

  ReportBody? get body native;

  String? get type native;

  String? get 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("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);

  String? get cache native;

  String? get credentials native;

  Headers? get headers native;

  String? get integrity native;

  String? get mode native;

  String? get redirect native;

  String? get referrer native;

  String? get referrerPolicy native;

  String? get url native;

  _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 JavaScriptObject
    with
        ListMixin<SpeechRecognitionResult>,
        ImmutableListMixin<SpeechRecognitionResult>
    implements
        List<SpeechRecognitionResult>,
        JavaScriptIndexingBehavior<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 IndexError.withLength(index, length, indexable: 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 newLength) {
    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 JavaScriptObject
    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 IndexError.withLength(index, length, indexable: 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 newLength) {
    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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject {
  // 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 JavaScriptObject
    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 NavigatorID, NavigatorOnLine {
  // 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 JavaScriptObject {
  // 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] as String;
  }

  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 as String);
    }
  }

  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] as _Attr;
      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] as _Attr;
      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 key is String && _element._hasAttribute(key);
  }

  String? operator [](Object? key) {
    return _element.getAttribute(key as String);
  }

  void operator []=(String key, String value) {
    _element.setAttribute(key, value);
  }

  @pragma('dart2js:tryInline')
  String? remove(Object? key) => key is String ? _remove(_element, key) : null;

  /**
   * The number of {key, value} pairs in the map.
   */
  int get length {
    return keys.length;
  }

  bool _matches(_Attr node) => node._namespaceUri == null;

  // Inline this because almost all call sites of [remove] do not use [value],
  // and the annotations on the `getAttribute` call allow it to be removed.
  @pragma('dart2js:tryInline')
  static String? _remove(Element element, String key) {
    String? value = JS(
      // throws:null(1) is not accurate since [key] could be malformed, but
      // [key] is checked again by `removeAttributeNS`.
      'returns:String|Null;depends:all;effects:none;throws:null(1)',
      '#.getAttribute(#)',
      element,
      key,
    );
    JS('', '#.removeAttribute(#)', element, key);
    return value;
  }
}

/**
 * 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 key is String && _element._hasAttributeNS(_namespace, key);
  }

  String? operator [](Object? key) {
    return _element.getAttributeNS(_namespace, key as String);
  }

  void operator []=(String key, String value) {
    _element.setAttributeNS(_namespace, key, value);
  }

  @pragma('dart2js:tryInline')
  String? remove(Object? key) =>
      key is String ? _remove(_namespace, _element, key) : null;

  /**
   * The number of {key, value} pairs in the map.
   */
  int get length {
    return keys.length;
  }

  bool _matches(_Attr node) => node._namespaceUri == _namespace;

  // Inline this because almost all call sites of [remove] do not use the
  // returned [value], and the annotations on the `getAttributeNS` call allow it
  // to be removed.
  @pragma('dart2js:tryInline')
  static String? _remove(String? namespace, Element element, String key) {
    String? value = JS(
      // throws:null(1) is not accurate since [key] could be malformed, but
      // [key] is checked again by `removeAttributeNS`.
      'returns:String|Null;depends:all;effects:none;throws:null(1)',
      '#.getAttributeNS(#, #)',
      element,
      namespace,
      key,
    );
    JS('', '#.removeAttributeNS(#, #)', element, namespace, key);
    return value;
  }
}

/**
 * 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 as String));

  String? operator [](Object? key) => _attributes[_attr(key as String)];

  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 as String));

  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'
   *
   * MDN does not have compatibility info on this attribute, and therefore is
   * marked nullable.
   */
  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'
   *
   *     var newLocation = window.location
   *         ..href = 'http://www.mysite.com';
   *     window.location = newLocation;
   *     // 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 CssClassSet corresponds to many elements, `false` 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 CssClassSet corresponds to many elements, `false` 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)
    : _elementList = elementList,
      super(elementList.first);

  /**
   * 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
   * [Element.getBoundingClientRect], `height` will return the same numerical
   * height 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
   * [Element.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();

    num 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) =>
      other is Rectangle &&
      left == other.left &&
      top == other.top &&
      right == other.right &&
      bottom == other.bottom;

  int get hashCode => Object.hash(left, top, right, bottom);

  /**
   * 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);
  }

  @pragma('dart2js:tryInline')
  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;
  }

  @pragma('dart2js:tryInline')
  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 ?? false) {
      _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<Object?> iterable) {
    DomTokenList list = _classListOf(_element);
    for (Object? value in iterable) {
      _classListRemove(list, value as String);
    }
  }

  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
  // workaround 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) : _unit = '', _value = 0 {
    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:
   *
   * * [EventTarget.addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)
   *   from MDN.
   */
  Stream<T> forTarget(EventTarget? e, {bool useCapture = false}) =>
      new _EventStream<T>(e, _eventType, useCapture);

  /**
   * Gets a [Stream] 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:
   *
   * * [EventTarget.addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)
   *   from MDN.
   */
  ElementStream<T> forElement(Element e, {bool useCapture = false}) {
    return new _ElementEventStreamImpl<T>(e, _eventType, useCapture);
  }

  /**
   * Gets a [Stream] 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:
   *
   * * [EventTarget.addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)
   *   from MDN.
   */
  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.
  @pragma('dart2js:tryInline')
  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;
}

class _EventStreamSubscription<T extends Event>
    implements StreamSubscription<T> {
  int _pauseCount = 0;
  EventTarget? _target;
  final String _eventType;
  EventListener? _onData;
  final bool _useCapture;

  _EventStreamSubscription(
    this._target,
    this._eventType,
    void onData(T event)?,
    this._useCapture,
  ) : _onData =
          onData == null
              ? null
              // If removed, we would need an `is` check on a function type which
              // is ultimately more expensive.
              // ignore: avoid_dynamic_calls
              : _wrapZone<Event>((e) => (onData as dynamic)(e)) {
    _tryResume();
  }

  Future cancel() {
    if (_canceled) return nullFuture;

    _unlisten();
    // Clear out the target to indicate this is complete.
    _target = null;
    _onData = null;
    return nullFuture;
  }

  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 =
        handleData == null
            ? null
            // If removed, we would need an `is` check on a function type which is
            // ultimately more expensive.
            // ignore: avoid_dynamic_calls
            : _wrapZone<Event>((e) => (handleData as dynamic)(e));
    _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 ?? 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 mixin 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.
  // https://github.com/google/closure-library/blob/master/closure/goog/events/keycodes.js
  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; // Note that it's the same value as META.
  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:
      // Covered by `KeyCode.META` above.
      // 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_FAVORITES = "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.
  // https://github.com/google/closure-library/blob/master/closure/goog/events/keyhandler.js

  /**
   * 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.
   * https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/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)
    : _stream = new _CustomKeyEventStreamImpl(_type),
      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);
  }

  /** 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] as E;

  void operator []=(int index, E value) {
    _list[index] = value;
  }

  set length(int newLength) {
    _list.length = newLength;
  }

  void sort([int compare(E a, E b)?]) {
    if (compare == null) {
      _list.sort();
    } else {
      _list.sort((Node a, Node b) => compare(a as E, b as E));
    }
  }

  int indexOf(Object? element, [int start = 0]) =>
      _list.indexOf(element as Node, start);

  int lastIndexOf(Object? element, [int? start]) =>
      _list.lastIndexOf(element as Node, start);

  void insert(int index, E element) => _list.insert(index, element);

  E removeAt(int index) => _list.removeAt(index) as E;

  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 as E;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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 as T;
}

// 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 as T;
}
// 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;

  // Even though many of the following JS methods can take in multiple
  // arguments, we historically and currently limit the number of variable
  // arguments to 1. Depending on the need, these methods may be updated to
  // allow for more.

  // We rename assert to assertCondition here.
  void assertCondition([bool? condition, Object? arg]) =>
      _isConsoleDefined
          ? JS('void', 'window.console.assert(#, #)', condition, arg)
          : null;

  // clear no longer takes in an argument, but we keep this as optional to
  // maintain backwards compatibility.
  void clear([Object? arg]) =>
      _isConsoleDefined ? JS('void', 'window.console.clear(#)', arg) : null;

  // count takes in a String instead, but we keep this as an Object for
  // backwards compatibility.
  void count([Object? arg]) =>
      _isConsoleDefined ? JS('void', 'window.console.count(#)', arg) : null;

  void countReset([String? arg]) =>
      _isConsoleDefined
          ? JS('void', 'window.console.countReset(#)', arg)
          : null;

  void debug(Object? arg) =>
      _isConsoleDefined ? JS('void', 'window.console.debug(#)', arg) : null;

  void dir([Object? item, Object? options]) =>
      _isConsoleDefined
          ? JS('void', 'window.console.dir(#, #)', item, options)
          : 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 table([Object? tabularData, List<String>? properties]) =>
      _isConsoleDefined
          ? JS('void', 'window.console.table(#, #)', tabularData, properties)
          : null;

  void time([String? label]) =>
      _isConsoleDefined ? JS('void', 'window.console.time(#)', label) : null;

  void timeEnd([String? label]) =>
      _isConsoleDefined ? JS('void', 'window.console.timeEnd(#)', label) : null;

  void timeLog([String? label, Object? arg]) =>
      _isConsoleDefined
          ? JS('void', 'window.console.timeLog(#, #)', label, 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;

  // The following are non-standard methods.
  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 timeStamp([Object? arg]) =>
      _isConsoleDefined ? JS('void', 'window.console.timeStamp(#)', arg) : null;

  // The following is deprecated and should be removed once we drop support for
  // older Safari browsers.
  void markTimeline(Object? arg) =>
      _isConsoleDefined
          ? JS('void', 'window.console.markTimeline(#)', 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;
}

_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.

/// 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');
  }
}

/// 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 Object? __window;

  Object get _window {
    // Note that we use a local variable here to avoid a null-assertion. This is
    // needed as [__window] can be a cross-origin iframe. dart2js emits
    // null-assertions using a field access like .toString, and since accessing
    // properties on a cross-origin iframe (with the exception of postMessage)
    // is a SecurityError, the null-assertion could trigger a SecurityError.
    // This avoids the need to type [__window] as dynamic.
    final w = __window;
    if (w == null) throw new NullWindowException();
    return w;
  }

  // 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]) {
    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;

  InputDeviceCapabilities? get sourceCapabilities =>
      JS('InputDeviceCapabilities', '#.sourceCapabilities', this);

  /**
   * 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)
    : _parent = parent,
      _shadowAltKey = false,
      _shadowCharCode = 0,
      _shadowKeyCode = 0,
      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;
    }

    KeyboardEvent 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,
            )
            as KeyboardEvent;

    // 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;
  WindowBase? 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 bool 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 as double;

  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 as Element?;
    Element? target = this.target as Element?;
    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 trees](https://dom.spec.whatwg.org/#shadow-trees)
   */
  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event
  List<Node> get path => wrapped.path as List<Node>;

  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"]',
      );
    }
    return true;
  }
}

/**
 * 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;

  /// Number of tree modifications this instance has made.
  int numTreeModifications = 0;
  _ValidatingTreeSanitizer(this.validator) {}

  void sanitizeTree(Node node) {
    void walk(Node node, Node? parent) {
      sanitizeNode(node, parent);

      var child = node.lastChild;
      while (null != child) {
        Node? nextChild;
        try {
          // Child may be removed during the walk, and we may not even be able
          // to get its previousNode. But it's also possible that previousNode
          // (i.e. previousSibling) is being spoofed, so double-check it.
          nextChild = child.previousNode;
          if (nextChild != null && nextChild.nextNode != child) {
            throw StateError("Corrupt HTML");
          }
        } 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 the tree until no new modifications are added to the tree.
    var previousTreeModifications;
    do {
      previousTreeModifications = numTreeModifications;
      walk(node, null);
    } while (previousTreeModifications != numTreeModifications);
  }

  /// 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.
    numTreeModifications++;
    if (parent == null || parent != node.parentNode) {
      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.
      // Don't remove dynamic calls in sanitizing code.
      // ignore: avoid_dynamic_calls
      attrs = element.attributes;
      // Don't remove dynamic calls in sanitizing code.
      // ignore: avoid_dynamic_calls
      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,
        // Don't remove dynamic calls in sanitizing code.
        // ignore: avoid_dynamic_calls
        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);
    }
  }
}
