text:
using extensions::Extension;
using extensions::ExtensionIdList;
using extensions::ExtensionList;

namespace {

// Returns true if an |extension| is in an |extension_list|.
bool IsInExtensionList(const Extension* extension,
                       const extensions::ExtensionList& extension_list) {
  for (size_t i = 0; i < extension_list.size(); i++) {
    if (extension_list[i].get() == extension)
      return true;
  }
  return false;
}

}  // namespace

ExtensionToolbarModel::ExtensionToolbarModel(ExtensionService* service)
    : service_(service),
      prefs_(service->profile()->GetPrefs()),
      extensions_initialized_(false),
      weak_ptr_factory_(this) {
  DCHECK(service_);

  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
                 content::Source<Profile>(service_->profile()));
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
                 content::Source<Profile>(service_->profile()));
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY,
                 content::Source<Profile>(service_->profile()));
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
                 content::Source<Profile>(service_->profile()));
  registrar_.Add(
      this, chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
      content::Source<extensions::ExtensionPrefs>(service_->extension_prefs()));

  visible_icon_count_ = prefs_->GetInteger(prefs::kExtensionToolbarSize);

  pref_change_registrar_.Init(prefs_);
  pref_change_callback_ =
      base::Bind(&ExtensionToolbarModel::OnExtensionToolbarPrefChange,
                 base::Unretained(this));
  pref_change_registrar_.Add(prefs::kExtensionToolbar, pref_change_callback_);
}

ExtensionToolbarModel::~ExtensionToolbarModel() {
}

void ExtensionToolbarModel::AddObserver(Observer* observer) {
  observers_.AddObserver(observer);
}

void ExtensionToolbarModel::RemoveObserver(Observer* observer) {
  observers_.RemoveObserver(observer);
}

void ExtensionToolbarModel::MoveBrowserAction(const Extension* extension,
                                              int index) {
  ExtensionList::iterator pos = std::find(toolbar_items_.begin(),
      toolbar_items_.end(), extension);
  if (pos == toolbar_items_.end()) {
    NOTREACHED();
    return;
  }
  toolbar_items_.erase(pos);

  ExtensionIdList::iterator pos_id;
  pos_id = std::find(last_known_positions_.begin(),
                     last_known_positions_.end(), extension->id());
  if (pos_id != last_known_positions_.end())
    last_known_positions_.erase(pos_id);

  int i = 0;
  bool inserted = false;
  for (ExtensionList::iterator iter = toolbar_items_.begin();
       iter != toolbar_items_.end();
       ++iter, ++i) {
    if (i == index) {
      pos_id = std::find(last_known_positions_.begin(),
                         last_known_positions_.end(), (*iter)->id());
      last_known_positions_.insert(pos_id, extension->id());

      toolbar_items_.insert(iter, make_scoped_refptr(extension));
      inserted = true;
      break;
    }
  }

  if (!inserted) {
    DCHECK_EQ(index, static_cast<int>(toolbar_items_.size()));
    index = toolbar_items_.size();

    toolbar_items_.push_back(make_scoped_refptr(extension));
    last_known_positions_.push_back(extension->id());
  }

  FOR_EACH_OBSERVER(Observer, observers_, BrowserActionMoved(extension, index));

  UpdatePrefs();
}

ExtensionToolbarModel::Action ExtensionToolbarModel::ExecuteBrowserAction(
    const Extension* extension,
    Browser* browser,
    GURL* popup_url_out) {
  content::WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  if (!web_contents)
    return ACTION_NONE;

  int tab_id = ExtensionTabUtil::GetTabId(web_contents);
  if (tab_id < 0)
    return ACTION_NONE;

  ExtensionAction* browser_action =
      extensions::ExtensionActionManager::Get(service_->profile())->
      GetBrowserAction(*extension);

  // For browser actions, visibility == enabledness.
  if (!browser_action->GetIsVisible(tab_id))
    return ACTION_NONE;

  extensions::TabHelper::FromWebContents(web_contents)->
      active_tab_permission_granter()->GrantIfRequested(extension);

  if (browser_action->HasPopup(tab_id)) {
    if (popup_url_out)
      *popup_url_out = browser_action->GetPopupUrl(tab_id);
    return ACTION_SHOW_POPUP;
  }

  service_->browser_event_router()->BrowserActionExecuted(
      *browser_action, browser);
  return ACTION_NONE;
}

void ExtensionToolbarModel::SetVisibleIconCount(int count) {
  visible_icon_count_ =
      count == static_cast<int>(toolbar_items_.size()) ? -1 : count;
  prefs_->SetInteger(prefs::kExtensionToolbarSize, visible_icon_count_);
}

void ExtensionToolbarModel::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  if (type == chrome::NOTIFICATION_EXTENSIONS_READY) {
    InitializeExtensionList();
    return;
  }

  if (!service_->is_ready())
    return;

  const Extension* extension = NULL;
  if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) {
    extension = content::Details<extensions::UnloadedExtensionInfo>(
        details)->extension;
  } else if (type ==
      chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED) {
    extension = service_->GetExtensionById(
        *content::Details<const std::string>(details).ptr(), true);
  } else {
    extension = content::Details<const Extension>(details).ptr();
  }
  if (type == chrome::NOTIFICATION_EXTENSION_LOADED) {
    // We don't want to add the same extension twice. It may have already been
    // added by EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED below, if the user
    // hides the browser action and then disables and enables the extension.
    for (size_t i = 0; i < toolbar_items_.size(); i++) {
      if (toolbar_items_[i].get() == extension)
        return;  // Already exists.
    }
    if (extensions::ExtensionActionAPI::GetBrowserActionVisibility(
            service_->extension_prefs(), extension->id())) {
      AddExtension(extension);
    }
  } else if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) {
    RemoveExtension(extension);
  } else if (type == chrome::NOTIFICATION_EXTENSION_UNINSTALLED) {
    UninstalledExtension(extension);
  } else if (type ==
      chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED) {
    if (extensions::ExtensionActionAPI::GetBrowserActionVisibility(
            service_->extension_prefs(), extension->id())) {
      AddExtension(extension);
    } else {
      RemoveExtension(extension);
    }
  } else {
    NOTREACHED() << "Received unexpected notification";
  }
}

size_t ExtensionToolbarModel::FindNewPositionFromLastKnownGood(
    const Extension* extension) {
  // See if we have last known good position for this extension.
  size_t new_index = 0;
  // Loop through the ID list of known positions, to count the number of visible
  // browser action icons preceding |extension|.
  for (ExtensionIdList::const_iterator iter_id = last_known_positions_.begin();
       iter_id < last_known_positions_.end(); ++iter_id) {
    if ((*iter_id) == extension->id())
      return new_index;  // We've found the right position.
    // Found an id, need to see if it is visible.
    for (ExtensionList::const_iterator iter_ext = toolbar_items_.begin();
         iter_ext < toolbar_items_.end(); ++iter_ext) {
      if ((*iter_ext)->id().compare(*iter_id) == 0) {
        // This extension is visible, update the index value.
        ++new_index;
        break;
      }
    }
  }

  return -1;
}

void ExtensionToolbarModel::AddExtension(const Extension* extension) {
  // We only care about extensions with browser actions.
  if (!extensions::ExtensionActionManager::Get(service_->profile())->
      GetBrowserAction(*extension)) {
    return;
  }

  size_t new_index = -1;

  // See if we have a last known good position for this extension.
  ExtensionIdList::iterator last_pos = std::find(last_known_positions_.begin(),
                                                 last_known_positions_.end(),
                                                 extension->id());
  if (last_pos != last_known_positions_.end()) {
    new_index = FindNewPositionFromLastKnownGood(extension);
    if (new_index != toolbar_items_.size()) {
      toolbar_items_.insert(toolbar_items_.begin() + new_index,
                            make_scoped_refptr(extension));
    } else {
      toolbar_items_.push_back(make_scoped_refptr(extension));
    }
  } else {
    // This is a never before seen extension, that was added to the end. Make
    // sure to reflect that.
    toolbar_items_.push_back(make_scoped_refptr(extension));
    last_known_positions_.push_back(extension->id());
    new_index = toolbar_items_.size() - 1;
    UpdatePrefs();
  }

  FOR_EACH_OBSERVER(Observer, observers_,
                    BrowserActionAdded(extension, new_index));
}

void ExtensionToolbarModel::RemoveExtension(const Extension* extension) {
  ExtensionList::iterator pos =
      std::find(toolbar_items_.begin(), toolbar_items_.end(), extension);
  if (pos == toolbar_items_.end())
    return;

  toolbar_items_.erase(pos);
  FOR_EACH_OBSERVER(Observer, observers_,
                    BrowserActionRemoved(extension));

  UpdatePrefs();
}

void ExtensionToolbarModel::UninstalledExtension(const Extension* extension) {
  // Remove the extension id from the ordered list, if it exists (the extension
  // might not be represented in the list because it might not have an icon).
  ExtensionIdList::iterator pos =
      std::find(last_known_positions_.begin(),
                last_known_positions_.end(), extension->id());

  if (pos != last_known_positions_.end()) {
    last_known_positions_.erase(pos);
    UpdatePrefs();
  }
}

// Combine the currently enabled extensions that have browser actions (which
// we get from the ExtensionService) with the ordering we get from the
// pref service. For robustness we use a somewhat inefficient process:
// 1. Create a vector of extensions sorted by their pref values. This vector may
// have holes.
// 2. Create a vector of extensions that did not have a pref value.
// 3. Remove holes from the sorted vector and append the unsorted vector.
void ExtensionToolbarModel::InitializeExtensionList() {
  DCHECK(service_->is_ready());

  last_known_positions_ = service_->extension_prefs()->GetToolbarOrder();
  Populate(last_known_positions_);

  extensions_initialized_ = true;
  FOR_EACH_OBSERVER(Observer, observers_, ModelLoaded());
}

void ExtensionToolbarModel::Populate(
    const extensions::ExtensionIdList& positions) {
  // Items that have explicit positions.
  ExtensionList sorted;
  sorted.resize(positions.size(), NULL);
  // The items that don't have explicit positions.
  ExtensionList unsorted;

  extensions::ExtensionActionManager* extension_action_manager =
      extensions::ExtensionActionManager::Get(service_->profile());

  // Create the lists.
  for (ExtensionSet::const_iterator it = service_->extensions()->begin();
       it != service_->extensions()->end(); ++it) {
    const Extension* extension = it->get();
    if (!extension_action_manager->GetBrowserAction(*extension))
      continue;
    if (!extensions::ExtensionActionAPI::GetBrowserActionVisibility(
            service_->extension_prefs(), extension->id())) {
      continue;
    }

    extensions::ExtensionIdList::const_iterator pos =
        std::find(positions.begin(), positions.end(), extension->id());
    if (pos != positions.end())
      sorted[pos - positions.begin()] = extension;
    else
      unsorted.push_back(make_scoped_refptr(extension));
  }

  // Erase current icons.
  for (size_t i = 0; i < toolbar_items_.size(); i++) {
    FOR_EACH_OBSERVER(
        Observer, observers_, BrowserActionRemoved(toolbar_items_[i].get()));
  }
  toolbar_items_.clear();

  // Merge the lists.
  toolbar_items_.reserve(sorted.size() + unsorted.size());
  for (ExtensionList::const_iterator iter = sorted.begin();
       iter != sorted.end(); ++iter) {
    // It's possible for the extension order to contain items that aren't
    // actually loaded on this machine.  For example, when extension sync is on,
    // we sync the extension order as-is but double-check with the user before
    // syncing NPAPI-containing extensions, so if one of those is not actually
    // synced, we'll get a NULL in the list.  This sort of case can also happen
    // if some error prevents an extension from loading.
    if (iter->get() != NULL)
      toolbar_items_.push_back(*iter);
  }
  toolbar_items_.insert(toolbar_items_.end(), unsorted.begin(),
                        unsorted.end());

  // Inform observers.
  for (size_t i = 0; i < toolbar_items_.size(); i++) {
    FOR_EACH_OBSERVER(
        Observer, observers_, BrowserActionAdded(toolbar_items_[i].get(), i));
  }
}

void ExtensionToolbarModel::FillExtensionList(
    const extensions::ExtensionIdList& order) {
  toolbar_items_.clear();
  toolbar_items_.reserve(order.size());
  for (size_t i = 0; i < order.size(); ++i) {
    const extensions::Extension* extension =
        service_->GetExtensionById(order[i], false);
    if (extension)
      AddExtension(extension);
  }
}

void ExtensionToolbarModel::UpdatePrefs() {
  if (!service_->extension_prefs())
    return;

  // Don't observe change caused by self.
  pref_change_registrar_.Remove(prefs::kExtensionToolbar);
  service_->extension_prefs()->SetToolbarOrder(last_known_positions_);
  pref_change_registrar_.Add(prefs::kExtensionToolbar, pref_change_callback_);
}

int ExtensionToolbarModel::IncognitoIndexToOriginal(int incognito_index) {
  int original_index = 0, i = 0;
  for (ExtensionList::iterator iter = toolbar_items_.begin();
       iter != toolbar_items_.end();
       ++iter, ++original_index) {
    if (service_->IsIncognitoEnabled((*iter)->id())) {
      if (incognito_index == i)
        break;
      ++i;
    }
  }
  return original_index;
}

int ExtensionToolbarModel::OriginalIndexToIncognito(int original_index) {
  int incognito_index = 0, i = 0;
  for (ExtensionList::iterator iter = toolbar_items_.begin();
       iter != toolbar_items_.end();
       ++iter, ++i) {
    if (original_index == i)
      break;
    if (service_->IsIncognitoEnabled((*iter)->id()))
      ++incognito_index;
  }
  return incognito_index;
}

void ExtensionToolbarModel::OnExtensionToolbarPrefChange() {
  // If extensions are not ready, defer to later Populate() call.
  if (!extensions_initialized_)
    return;

  // Recalculate |last_known_positions_| to be |pref_positions| followed by
  // ones that are only in |last_known_positions_|.
  extensions::ExtensionIdList pref_positions =
      service_->extension_prefs()->GetToolbarOrder();
  size_t pref_position_size = pref_positions.size();
  for (size_t i = 0; i < last_known_positions_.size(); ++i) {
    if (std::find(pref_positions.begin(), pref_positions.end(),
                  last_known_positions_[i]) == pref_positions.end()) {
      pref_positions.push_back(last_known_positions_[i]);
    }
  }
  last_known_positions_.swap(pref_positions);

  // Re-populate.
  Populate(last_known_positions_);

  if (last_known_positions_.size() > pref_position_size) {
    // Need to update pref because we have extra icons. But can't call
    // UpdatePrefs() directly within observation closure.
    base::MessageLoop::current()->PostTask(
        FROM_HERE,
        base::Bind(&ExtensionToolbarModel::UpdatePrefs,
                   weak_ptr_factory_.GetWeakPtr()));
  }
}


text:
import { Event, DetailedErrorCode } from "./cast.framework.events";

export as namespace messages
export type UserAction =
    | "LIKE"
    | "DISLIKE"
    | "FOLLOW"
    | "UNFOLLOW"
    | "FLAG"
    | "SKIP_AD";

export type UserActionContext =
    | "UNKNOWN_CONTEXT"
    | "ALBUM"
    | "ARTIST"
    | "PLAYLIST"
    | "EPISODE"
    | "SERIES"
    | "MOVIE"
    | "CHANNEL"
    | "TEAM"
    | "PLAYER"
    | "COACH";

export type TextTrackType =
    | "SUBTITLES"
    | "CAPTIONS"
    | "DESCRIPTIONS"
    | "CHAPTERS"
    | "METADATA";

export type TextTrackWindowType = "NONE" | "NORMAL" | "ROUNDED_CORNERS";

export type TrackType = "TEXT" | "AUDIO" | "VIDEO";

export type TextTrackFontGenericFamily =
    | "SANS_SERIF"
    | "MONOSPACED_SANS_SERIF"
    | "SERIF"
    | "MONOSPACED_SERIF"
    | "CASUAL"
    | "CURSIVE"
    | "SMALL_CAPITALS";

export type TextTrackFontStyle = "NORMAL" | "BOLD" | "BOLD_ITALIC" | "ITALIC";

export type TextTrackEdgeType =
    | "NONE"
    | "OUTLINE"
    | "DROP_SHADOW"
    | "RAISED"
    | "DEPRESSED";

export type Command =
    | "PAUSE"
    | "SEEK"
    | "STREAM_VOLUME"
    | "STREAM_MUTE"
    | "ALL_BASIC_MEDIA"
    | "QUEUE_NEXT"
    | "QUEUE_PREV"
    | "QUEUE_SHUFFLE"
    | "SKIP_AD";

export type SeekResumeState = "PLAYBACK_START" | "PLAYBACK_PAUSE";

export type StreamingProtocolType =
    | "UNKNOWN"
    | "MPEG_DASH"
    | "HLS"
    | "SMOOTH_STREAMING";

export type StreamType = "BUFFERED" | "LIVE" | "NONE";

export type FocusState = "IN_FOCUS" | "NOT_IN_FOCUS";

export type ExtendedPlayerState = "LOADING";

export type ErrorType =
    | "INVALID_PLAYER_STATE"
    | "LOAD_FAILED"
    | "LOAD_CANCELLED"
    | "INVALID_REQUEST"
    | "ERROR";

export type ErrorReason =
    | "INVALID_COMMAND"
    | "INVALID_PARAMS"
    | "INVALID_MEDIA_SESSION_ID"
    | "SKIP_LIMIT_REACHED"
    | "NOT_SUPPORTED"
    | "LANGUAGE_NOT_SUPPORTED"
    | "END_OF_QUEUE"
    | "APP_ERROR"
    | "AUTHENTICATION_EXPIRED"
    | "PREMIUM_ACCOUNT_REQUIRED"
    | "CONCURRENT_STREAM_LIMIT"
    | "PARENTAL_CONTROL_RESTRICTED"
    | "NOT_AVAILABLE_IN_REGION"
    | "CONTENT_ALREADY_PLAYING"
    | "INVALID_REQUEST"
    | "GENERIC_LOAD_ERROR";

export type RepeatMode =
    | "REPEAT_OFF"
    | "REPEAT_ALL"
    | "REPEAT_SINGLE"
    | "REPEAT_ALL_AND_SHUFFLE";

export type IdleReason = "CANCELLED" | "INTERRUPTED" | "FINISHED" | "ERROR";

export type HlsSegmentFormat = "AAC" | "AC3" | "MP3" | "TS" | "TS_AAC";

export type HdrType = "SDR" | "HDR" | "DV";

export type PlayStringId =
    | "FREE_TRIAL_ABOUT_TO_EXPIRE"
    | "SUBSCRIPTION_ABOUT_TO_EXPIRE"
    | "STREAM_HIJACKED";

export type GetStatusOptions = "NO_METADATA" | "NO_QUEUE_ITEMS";

export type MessageType =
    | "MEDIA_STATUS"
    | "CLOUD_STATUS"
    | "QUEUE_CHANGE"
    | "QUEUE_ITEMS"
    | "QUEUE_ITEM_IDS"
    | "GET_STATUS"
    | "LOAD"
    | "PAUSE"
    | "STOP"
    | "PLAY"
    | "SKIP_AD"
    | "PLAY_AGAIN"
    | "SEEK"
    | "SET_PLAYBACK_RATE"
    | "SET_VOLUME"
    | "EDIT_TRACKS_INFO"
    | "EDIT_AUDIO_TRACKS"
    | "PRECACHE"
    | "PRELOAD"
    | "QUEUE_LOAD"
    | "QUEUE_INSERT"
    | "QUEUE_UPDATE"
    | "QUEUE_REMOVE"
    | "QUEUE_REORDER"
    | "QUEUE_NEXT"
    | "QUEUE_PREV"
    | "QUEUE_GET_ITEM_RANGE"
    | "QUEUE_GET_ITEMS"
    | "QUEUE_GET_ITEM_IDS"
    | "QUEUE_SHUFFLE"
    | "SET_CREDENTIALS"
    | "LOAD_BY_ENTITY"
    | "USER_ACTION"
    | "DISPLAY_STATUS"
    | "FOCUS_STATE"
    | "CUSTOM_COMMAND";

export type PlayerState = "IDLE" | "PLAYING" | "PAUSED" | "BUFFERING";

export type QueueChangeType =
    | "INSERT"
    | "REMOVE"
    | "ITEMS_CHANGE"
    | "UPDATE"
    | "NO_CHANGE";

export type QueueType =
    | "ALBUM"
    | "PLAYLIST"
    | "AUDIOBOOK"
    | "RADIO_STATION"
    | "PODCAST_SERIES"
    | "TV_SERIES"
    | "VIDEO_PLAYLIST"
    | "LIVE_TV"
    | "MOVIE";

export type MetadataType =
    | "GENERIC"
    | "MOVIE"
    | "TV_SHOW"
    | "MUSIC_TRACK"
    | "PHOTO";

/**
 * RefreshCredentials request data.
 */
export interface RefreshCredentialsRequestData {
    [key: string]: any;
}

/**
 * Media event SET_VOLUME request data.
 */
export interface VolumeRequestData extends RequestData {
    /**
     * The media stream volume
     */
    volume?: Volume;
}

/**
 * Represents the volume of a media session stream.
 */
export interface Volume {
    /**
     * Value from 0 to 1 that represents the current stream volume level.
     */
    level?: number;

    /**
     * Whether the stream is muted.
     */
    muted?: boolean;
}

/**
 * Video information such as video resolution and High Dynamic Range (HDR).
 */
export class VideoInformation {
    constructor(width: number, height: number, hdrType: HdrType);

    width: number;

    height: number;

    hdrType: HdrType;
}

/**
 * VAST ad request configuration.
 */
export interface VastAdsRequest {
    /**
     * Specifies a VAST document to be used as the ads response instead of making a
     * request via an ad tag url.
     * This can be useful for debugging and other situations where a VAST response is
     * already available.
     */
    adsResponse?: string;

    /**
     * URL for VAST file.
     */
    adTagUrl?: string;
}

/**
 * UserAction request data.
 */
export interface UserActionRequestData {
    /**
     * Optional request source.
     * It contain the assistent query that initiate the request.
     */
    source?: string;

    /**
     * User action to be handled by the application.
     */
    userAction?: UserAction;

    /**
     * Optional context information for the user action.
     */
    userActionContext?: UserActionContext;
}

/**
 * A TV episode media description.
 */
export interface TvShowMediaMetadata {
    /**
     * TV episode number. A positive integer.
     */
    episode?: number;

    /**
     * @deprecated use episode instead
     */
    episodeNumber?: number;

    /**
     * @deprecated use episode instead
     */
    episodeTitle?: string;

    /**
     * Content images. Examples would include cover art or a thumbnail of
     * the currently playing media.
     */
    images?: Image[];

    /**
     * ISO 8601 date when the episode originally aired; e.g. 2014-02-10.
     */
    originalAirdate?: string;

    /**
     * @deprecated use originalAirdate instead.
     */
    releaseYear?: number;

    /**
     * TV episode season. A positive integer.
     */
    season?: number;

    /**
     * @deprecated use season instead.
     */
    seasonNumber?: number;

    /**
     * TV series title.
     */
    seriesTitle?: string;

    /**
     * TV episode title.
     */
    title?: string;
}
/**
 * Describes track metadata information.
 */
export class Track {
    constructor(trackId: number, trackType: TrackType);

    /**
     * Custom data set by the receiver application.
     */
    customData?: string;

    /**
     * Language tag as per RFC 5646 (If subtype is "SUBTITLES" it is mandatory).
     */
    language?: string;

    /**
     * A descriptive; human readable name for the track. For example "Spanish".
     */
    name?: string;

    /**
     * For text tracks; the type of text track.
     */
    subtype?: string;

    /**
     * It can be the url of the track or any other identifier that allows the receiver
     * to find the content (when the track is not inband or included in the manifest).
     * For example it can be the url of a vtt file.
     */
    trackContentId?: string;

    /**
     * It represents the MIME type of the track content. For example if the track
     * is a vtt file it will be 'text/vtt'. This field is needed for out of band tracks;
     *  so it is usually provided if a trackContentId has also been provided.
     * It is not mandatory if the receiver has a way to identify the content from
     * the trackContentId; but recommended.
     * The track content type; if provided; must be consistent with the track type.
     */
    trackContentType?: string;

    /**
     * Unique identifier of the track within the context of a MediaInformation object.
     */
    trackId?: number;

    /**
     * The type of track.
     */
    type: TrackType;
}
/**
 * Describes style information for a text track.
 */
export interface TextTrackStyle {
    /**
     * The background 32 bit RGBA color. The alpha channel should be used for transparent backgrounds.
     */
    backgroundColor?: string;

    /**
     * Custom data set by the receiver application.
     */
    customData?: any;

    /**
     * RGBA color for the edge; this value will be ignored if edgeType is NONE.
     */
    edgeColor?: string;

    edgeType?: TextTrackEdgeType;

    /**
     * If the font is not available in the receiver the fontGenericFamily will be used.
     */
    fontFamily?: string;

    /**
     * The text track generic family.
     */
    fontGenericFamily?: TextTrackFontGenericFamily;

    /**
     * The font scaling factor for the text track (the default is 1).
     */
    fontScale?: number;

    /**
     * The text track font style.
     */
    fontStyle?: TextTrackFontStyle;

    /**
     * The foreground 32 bit RGBA color.
     */
    foregroundColor?: string;

    /**
     * 32 bit RGBA color for the window. This value will be ignored if windowType is NONE.
     */
    windowColor?: string;

    /**
     * Rounded corner radius absolute value in pixels (px). This value will be ignored
     * if windowType is not ROUNDED_CORNERS.
     */
    windowRoundedCornerRadius?: number;

    /**
     * The window concept is defined in CEA-608 and CEA-708. In WebVTT is called a region.
     */
    windowType?: TextTrackWindowType;
}

/**
 * Media event playback rate request data.
 */
export interface SetPlaybackRateRequestData extends RequestData {
    /**
     * New playback rate (>0).
     */
    playbackRate?: number;

    /**
     * New playback rate relative to current playback rate.
     * New rate will be the result of multiplying the current rate with the value.
     * For example a value of 1.1 will increase rate by 10%.
     * (Only used if the playbackRate value is not provided).
     */
    relativePlaybackRate?: number;
}

/**
 * SetCredentials request data.
 */
export interface SetCredentialsRequestData {
    /**
     * Credentials to use by receiver.
     */
    credentials?: string;

    /**
     * If it is a response for refresh credentials; it will indicate the request id
     * of the refresh credentials request.
     */
    forRequestId?: number;

    /**
     * Optional request source. It contain the assistent query that initiate the request.
     */
    source?: string;
}

/**
 * Media event SEEK request data.
 */
export interface SeekRequestData extends RequestData {
    /**
     * Seconds since beginning of content.
     */
    currentTime?: number;

    /**
     * Seconds relative to the current playback position. If this field is defined;
     * the currentTime field will be ignored.
     */
    relativeTime?: number;

    /**
     * The playback state after a SEEK request.
     */
    resumeState?: SeekResumeState;
}

/**
 * Provides seekable range in seconds.
 */
export class SeekableRange {
    constructor(start?: number, end?: number);

    /**
     * End of the seekable range in seconds.
     */
    end?: number;

    /**
     * Start of the seekable range in seconds.
     */
    start?: number;
}

/**
 * Media event request data.
 */
export class RequestData {
    constructor(type: MessageType);

    /**
     * Application-specific data for this request.
     * It enables the sender and receiver to easily extend the media protocol
     * without having to use a new namespace with custom messages.
     */
    customData?: any;

    /**
     * Id of the media session that the request applies to.
     */
    mediaSessionId?: number;

    /**
     * Id of the request; used to correlate request/response.
     */
    requestId: number;
}

/**
 * Media event UPDATE queue request data.
 */
export interface QueueUpdateRequestData {
    /**
     * ID of the current media Item after the deletion
     * (if not provided; the currentItem value will be the same as before the deletion;
     *  if it does not exist because it has been deleted; the currentItem will point to
     * the next logical item in the list).
     */
    currentItemId?: number;

    /**
     * Seconds since the beginning of content to start playback of the current item.
     *  If provided; this value will take precedence over the startTime value provided
     * at the QueueItem level but only the first time the item is played.
     *  This is to cover the common case where the user jumps to the middle of an
     * item so the currentTime does not apply to the item permanently like the
     * QueueItem startTime does. It avoids having to reset the startTime dynamically
     *  (that may not be possible if the phone has gone to sleep).
     */
    currentTime?: number;

    /**
     * List of queue items to be updated. No reordering will happen; the items will
     * retain the existing order.
     */
    items?: QueueItem[];

    /**
     * Skip/Go back number of items with respect to the position of currentItem
     * (it can be negative). If it is out of boundaries; the currentItem will be the
     * next logical item in the queue wrapping around the boundaries.
     * The new currentItem position will follow the rules of the queue repeat behavior.
     */
    jump?: number;

    /**
     * Behavior of the queue when all items have been played.
     */
    repeatMode?: RepeatMode;

    /**
     * Shuffle the queue items when the update is processed.
     * After the queue items are shuffled; the item at the currentItem position will
     *  be loaded.
     */
    shuffle?: boolean;
}

/**
 * Media event queue REORDER request data.
 */
export class QueueReorderRequestData extends RequestData {
    constructor(itemIds: number[]);

    /**
     * ID of the current media Item after the deletion (if not provided;
     * the currentItem value will be the same as before the deletion;
     * if it does not exist because it has been deleted;
     * the currentItem will point to the next logical item in the list).
     */
    currentItemId?: number;

    /**
     * Seconds since the beginning of content to start playback of the current item.
     * If provided; this value will take precedence over the startTime value provided
     * at the QueueItem level but only the first time the item is played.
     * This is to cover the common case where the user jumps to the middle of an
     * item so the currentTime does not apply to the item permanently like
     * the QueueItem startTime does. It avoids having to reset the startTime dynamically
     * (that may not be possible if the phone has gone to sleep).
     */
    currentTime?: number;

    /**
     * ID of the item that will be located immediately after the reordered list.
     * If the ID is not found or it is not provided;
     * the reordered list will be appended at the end of the existing list.
     */
    insertBefore?: number;

    /**
     * IDs of the items to be reordered; in the new order.
     * Items not provided will keep their existing order.
     * The provided list will be inserted at the position determined by insertBefore.
     * For example:
     *  If insertBefore is not specified Existing queue: "A";"D";"G";"H";"B";"E" itemIds:
     * "D";"H";"B" New Order: "A";"G";"E";"D";"H";"B"
     *   If insertBefore is "A" Existing queue: "A";"D";"G";"H";"B" itemIds:
     *   "D";"H";"B" New Order: "D";"H";"B";"A";"G";"E"
     *   If insertBefore is "G" Existing queue: "A";"D";"G";"H";"B" itemIds:
     *   "D";"H";"B" New Order: "A";"D";"H";"B";"G";"E"
     */
    itemIds: number[];
}

/**
 * Media event queue REMOVE request data.
 */
export class QueueRemoveRequestData extends RequestData {
    constructor(itemIds: number[]);

    /**
     * ID of the current media Item after the deletion
     * (if not provided; the currentItem value will be the same as before the deletion;
     * if it does not exist because it has been deleted;
     * the currentItem will point to the next logical item in the list).
     */
    currentItemId?: number;

    /**
     * Seconds since the beginning of content to start playback of the current item.
     *  If provided; this value will take precedence over the startTime value provided
     * at the QueueItem level but only the first time the item is played.
     * This is to cover the common case where the user jumps to the middle of an
     * item so the currentTime does not apply to the item permanently like the
     *  QueueItem startTime does. It avoids having to reset the startTime dynamically
     * (that may not be possible if the phone has gone to sleep).
     */
    currentTime?: number;

    /**
     * IDs of queue items to be deleted.
     */
    itemIds?: number[];
}
/**
 * Media event queue LOAD request data.
 */
export class QueueLoadRequestData extends RequestData {
    constructor(items: QueueItem[]);

    /**
     * Seconds (since the beginning of content) to start playback of the first item to
     *  be played. If provided; this value will take precedence over the
     * startTime value provided at the QueueItem level but only the first
     * time the item is played. This is to cover the common case where the user
     * casts the item that was playing locally so the currentTime does not apply
     * to the item permanently like the QueueItem startTime does.
     * It avoids having to reset the startTime dynamically
     * (that may not be possible if the phone has gone to sleep).
     */
    currentTime?: number;

    /**
     * Behavior of the queue when all items have been played.
     */
    items: QueueItem[];

    /**
     * Id of the request; used to correlate request/response.
     */
    repeatMode?: RepeatMode;

    /**
     * The index of the item in the items array that must be the first currentItem
     * (the item that will be played first). Note this is the index of the array
     *  (starts at 0) and not the itemId (as it is not known until the queue is created).
     * If repeatMode is REPEAT_OFF playback will end when the last item in the array is
     * played (elements before the startIndex will not be played).
     * This may be useful for continuation scenarios where the user was already
     * using the sender app and in the middle decides to cast.
     * In this way the sender app does not need to map between the local and remote queue
     * positions or saves one extra QUEUE_UPDATE request.
     */
    startIndex?: number;
}

/**
 * Queue item information. Application developers may need to create a QueueItem to
 * insert a queue element using InsertQueueItems. In this case they should not
 * provide an itemId (as the actual itemId will be assigned when the item is inserted
 * in the queue). This prevents ID collisions with items added from a sender app.
 */
export class QueueItem {
    constructor(opt_itemId?: number);

    /**
     * Array of Track trackIds that are active. If the array is not provided;
     * the default tracks will be active.
     */
    activeTrackIds?: number[];

    /**
     * If the autoplay parameter is not specified or is true; the media player
     *  will begin playing the element in the queue when the item becomes the currentItem.
     */
    autoplay?: boolean;

    /**
     * The application can define any extra queue item information needed.
     */
    customData?: any;

    /**
     * Unique identifier of the item in the queue.
     * The attribute is optional because for LOAD or INSERT should not be provided
     * (as it will be assigned by the receiver when an item is first created/inserted).
     */
    itemId?: number;

    /**
     * Metadata (including contentId) of the playlist element.
     */
    media?: MediaInformation;

    /**
     * Playback duration of the item; if it is larger than the actual duration -
     * startTime it will be ignored (default behavior).
     * It can be negative; in such case the duration will be the actual asset
     * duration minus the duration provided.
     * It can be used for photo slideshows to control the duration the item should
     * be presented or for live events to control the duration that the program
     * should be played. It may be useful for autoplay scenarios to avoid displaying all
     *  the credits after an episode has ended.
     */
    playbackDuration?: number;

    /**
     * This parameter is a hint for the receiver to preload this media
     * item before it is played. It allows for a smooth transition between items
     * played from the queue. The time is expressed in seconds; relative to
     * the beginning of this item playback (usually the end of the previous item playback).
     *  Only positive values are valid. For example; if the value is 10 seconds; this item
     * will be preloaded 10 seconds before the previous item has finished.
     * The receiver will try to honor this value but will not guarantee it;
     * for example if the value is larger than the previous item duration the
     * receiver may just preload this item shortly after the previous item has started playing
     * (there will never be two items being preloaded in parallel).
     * Also; if an item is inserted in the queue just after the currentItem and the time to preload is higher than the
     * time left on the currentItem; the preload will just happen as soon as possible.
     */
    preloadTime?: number;

    /**
     * Seconds since beginning of content. If the content is live content;
     * and startTime is not specified; the stream will start at the live position.
     */
    startTime?: number;
}

/**
 * Media event queue INSERT request data.
 */
export class QueueInsertRequestData extends RequestData {
    constructor(items: QueueItem[]);

    /**
     * ID of the current media Item after the insertion (if not provided;
     * the currentItem value will be the same as before the insertion).
     */
    currentItemId?: number;

    /**
     * Index (relative to the items array; starting with 0) of the new current media Item.
     *  For inserted items we use the index (similar to startIndex in QUEUE_LOAD) and not
     * currentItemId; because the itemId is unknown until the items are inserted.
     * If not provided; the currentItem value will be the same as before the insertion
     * (unless currentItemId is provided). This param allows to make atomic the common use
     * case of insert and play an item.
     */
    currentItemIndex?: number;

    /**
     * Seconds since the beginning of content to start playback of the current item.
     * If provided; this value will take precedence over the startTime value provided
     * at the QueueItem level but only the first time the item is played.
     * This is to cover the common case where the user jumps to the middle of an
     * item so the currentTime does not apply to the item permanently like the
     * QueueItem startTime does. It avoids having to reset the startTime dynamically
     * (that may not be possible if the phone has gone to sleep).
     */
    currentTime?: number;

    /**
     * ID of the item that will be located immediately after the inserted list.
     *  If the ID is not found or it is not provided; the list will be appended at
     *  the end of the existing list.
     */
    insertBefore?: number;

    /**
     * List of queue items. The itemId field of the items should be empty.
     *  It is sorted (first element will be played first).
     */
    items: QueueItem[];
}

/**
 * Represents a data message containing the full list of queue ids.
 */
export interface QueueIds {
    /**
     * List of queue item ids.
     */
    itemIds?: number[];

    /**
     * The corresponding request id.
     */
    requestId?: number;

    type: MessageType;
}

/**
 * Queue data as part of the LOAD request.
 */
export class QueueData {
    constructor(
        id?: string,
        name?: string,
        description?: string,
        repeatMode?: RepeatMode,
        items?: QueueItem[],
        startIndex?: number,
        startTime?: number
    );

    /**
     * Description of the queue.
     */
    description?: string;

    /**
     * Optional Queue entity id; provide Google Assistant deep link.
     */
    entity?: string;

    /**
     * Id of the queue.
     */
    id?: string;

    /**
     * Array of queue items. It is sorted (first element will be played first).
     */
    items?: QueueItem[];

    /**
     * Name of the queue.
     */
    name?: string;

    /**
     * Queue type; e.g. album; playlist; radio station; tv series; etc.
     */
    queueType?: QueueType;

    /**
     * Continuous playback behavior of the queue.
     */
    repeatMode?: RepeatMode;

    /**
     * The index of the item in the queue that should be used to start playback first.
     */
    startIndex?: number;

    /**
     * Seconds (since the beginning of content) to start playback of the first item.
     */
    startTime?: number;
}

/**
 * Represents a queue change message; such as insert; remove; and update.
 */
export interface QueueChange {
    /**
     * The actual queue change type.
     */
    changeType?: QueueChangeType;

    /**
     * The id to insert the list of itemIds before.
     */
    insertBefore?: number;

    /**
     * List of changed itemIds.
     */
    itemIds?: number[];

    /**
     * The corresponding request id.
     */
    requestId?: number;

    /**
     * The queue change sequence ID. Used to coordinate state sync between various
     * senders and the receiver.
     */
    sequenceNumber?: number;

    type: MessageType;
}

/**
 * Media event PRELOAD request data.
 */
export class PreloadRequestData implements LoadRequestData {
    /**
     * Array of trackIds that are active. If the array is not provided;
     *  the default tracks will be active.
     */
    activeTrackIds: number[];
    /**
     * If the autoplay parameter is specified; the media player will begin playing
     * the content when it is loaded. Even if autoplay is not specified;the media player
     *  implementation may choose to begin playback immediately.
     */
    autoplay?: boolean;
    /**
     * Optional user credentials.
     */
    credentials?: string;
    /**
     * Optional credentials type. The type 'cloud' is a reserved type used by load
     * requests that were originated by voice assistant commands.
     */
    credentialsType?: string;
    /**
     * Seconds since beginning of content. If the content is live content;
     * and currentTime is not specified; the stream will start at the live position.
     */
    currentTime?: number;
    /**
     * If the autoplay parameter is specified; the media player will begin playing
     * the content when it is loaded. Even if autoplay is not specified; the media
     *  player implementation may choose to begin playback immediately.
     */
    media: MediaInformation;
    /**
     * The media playback rate.
     */
    playbackRate?: number;
    /**
     * Queue data.
     */
    queueData: QueueData;
    /**
     * Application-specific data for this request.
     * It enables the sender and receiver to easily extend the media protocol
     * without having to use a new namespace with custom messages.
     */
    customData?: any;
    /**
     * Id of the media session that the request applies to.
     */
    mediaSessionId?: number;
    /**
     * Id of the request; used to correlate request/response.
     */
    requestId: number;
    constructor(itemId: number);

    /**
     * The ID of the queue item.
     */
    itemId: number;
}

/**
 * Media event PRECACHE request data. (Some fields of the load request;
 * like autoplay and queueData; are ignored).
 */
export class PrecacheRequestData implements LoadRequestData {
    /**
     * Array of trackIds that are active. If the array is not provided;
     * the default tracks will be active.
     */
    activeTrackIds: number[];
    /**
     * If the autoplay parameter is specified; the media player will begin playing
     * the content when it is loaded. Even if autoplay is not specified;the media player
     * implementation may choose to begin playback immediately.
     */
    autoplay?: boolean;
    /**
     * Optional user credentials.
     */
    credentials?: string;
    /**
     * Optional credentials type. The type 'cloud' is a reserved type used by load
     * requests that were originated by voice assistant commands.
     */
    credentialsType?: string;
    /**
     * Seconds since beginning of content. If the content is live content; and
     * currentTime is not specified; the stream will start at the live position.
     */
    currentTime?: number;
    /**
     * If the autoplay parameter is specified; the media player will begin playing
     * the content when it is loaded. Even if autoplay is not specified;
     * the media player implementation may choose to begin playback immediately.
     */
    media: MediaInformation;
    /**
     * The media playback rate.
     */
    playbackRate?: number;
    /**
     * Queue data.
     */
    queueData: QueueData;
    /**
     * Application-specific data for this request.
     * It enables the sender and receiver to easily extend the media protocol
     * without having to use a new namespace with custom messages.
     */
    customData?: any;
    /**
     * Id of the media session that the request applies to.
     */
    mediaSessionId?: number;
    /**
     * Id of the request; used to correlate request/response.
     */
    requestId: number;
    constructor(data?: string);

    /**
     * Application precache data.
     */
    precacheData?: string;
}

/**
 * PlayString request data.
 */
export class PlayStringRequestData {
    constructor(stringId: PlayStringId, opt_arguments?: string[]);

    /**
     * An optional array of string values to be filled into the text.
     */
    arguments?: string[];

    /**
     * An identifier for the text to be played back.
     */
    stringId: PlayStringId;
}

/**
 * A photo media description.
 */
export interface PhotoMediaMetadata {
    /**
     * Name of the photographer.
     */
    artist?: string;

    /**
     * ISO 8601 date and time the photo was taken; e.g. 2014-02-10T15:47:00Z.
     */
    creationDateTime?: string;

    /**
     * Photo height; in pixels.
     */
    height?: number;

    /**
     * Images associated with the content. Examples would include a photo thumbnail.
     */
    images: Image[];

    /**
     * Latitude.
     */
    latitude?: number;

    /**
     * Location where the photo was taken. For example; "Seattle; Washington; USA".
     */
    location?: string;

    /**
     * Longitude.
     */
    longitude?: number;

    /**
     * Photo title.
     */
    title?: string;

    /**
     * Photo width; in pixels.
     */
    width?: number;
}

/**
 * A music track media description.
 */
export interface MusicTrackMediaMetadata {
    /**
     * Album artist name.
     */
    albumArtist?: string;

    /**
     * Album name.
     */
    albumName?: string;

    /**
     * Track artist name.
     */
    artist?: string;

    /**
     * @deprecated: use @see{@link artist} instead
     */
    artistName: string;

    /**
     * Track composer name.
     */
    composer?: string;

    /**
     * Disc number. A positive integer.
     */
    discNumber?: number;

    /**
     * Content images. Examples would include cover art or a thumbnail of the
     * currently playing media.
     */
    images: Image[];

    /**
     * ISO 8601 date when the track was released; e.g. 2014-02-10.
     */
    releaseDate?: string;

    /**
     * @deprecated: Use @see{@link releaseDate} instead
     */
    releaseYear?: string;

    /**
     * Track name.
     */
    songName?: string;

    /**
     * Track title.
     */
    title?: string;

    /**
     * Track number in album. A positive integer.
     */
    trackNumber?: number;
}

/**
 * A movie media description.
 */
export interface MovieMediaMetadata {
    /**
     * Content images. Examples would include cover art or a thumbnail of the
     * currently playing media.
     */
    images: Image[];

    /**
     * ISO 8601 date when the movie was released; e.g. 2014-02-10.
     */
    releaseDate?: string;

    /**
     * @deprecated: use @see{@link releaseDate} instead
     */
    releaseYear?: number;

    /**
     * Movie studio.
     */
    studio?: string;

    /**
     * Movie subtitle.
     */
    subtitle?: string;

    /**
     * Movie title.
     */
    title?: string;
}
/**
 * Represents the status of a media session.
 */
export interface MediaStatus {
    /**
     * List of IDs corresponding to the active tracks.
     */
    activeTrackIds: number[];

    /**
     * Status of break; if receiver is playing break.
     * This field will be defined only when receiver is playing break.
     */
    breakStatus: BreakStatus;

    /**
     * ID of this media item (the item that originated the status change).
     */
    currentItemId?: number;

    /**
     * The current playback position.
     */
    currentTime: number;

    /**
     * Application-specific media status.
     */
    customData?: any;

    /**
     * Extended media status information.
     */
    extendedStatus: ExtendedMediaStatus;

    /**
     * If the state is IDLE; the reason the player went to IDLE state.
     */
    idleReason: IdleReason;

    /**
     * List of media queue items.
     */
    items: QueueItem[];

    /**
     * Seekable range of a live or event stream. It uses relative media time in seconds.
     * It will be undefined for VOD streams.
     */
    liveSeekableRange: LiveSeekableRange;

    /**
     * ID of the media Item currently loading. If there is no item being loaded;
     * it will be undefined.
     */
    loadingItemId?: number;

    /**
     * The media information.
     */
    media: MediaInformation;

    /**
     * Unique id for the session.
     */
    mediaSessionId: number;

    /**
     * The playback rate.
     */
    playbackRate: number;

    /**
     * The playback state.
     */
    playerState: PlayerState;

    /**
     * ID of the next Item; only available if it has been preloaded.
     * Media items can be preloaded and cached temporarily in memory;
     * so when they are loaded later on; the process is faster
     * (as the media does not have to be fetched from the network).
     */
    preloadedItemId?: number;

    /**
     * Queue data.
     */
    queueData: QueueData;

    /**
     * The behavior of the queue when all items have been played.
     */
    repeatMode: RepeatMode;

    /**
     * The commands supported by this player.
     */
    supportedMediaCommands: number;

    type: MessageType;

    /**
     * The video information.
     */
    videoInfo: VideoInformation;

    /**
     * The current stream volume.
     */
    volume: Volume;
}
/**
 * Common media metadata used as part of MediaInformation
 */
export class MediaMetadata {
    constructor(type: MetadataType);

    /**
     * The type of metadata
     */
    metadataType: MetadataType;
}

/**
 * Represents the media information.
 */
export interface MediaInformation {
    /**
     * Partial list of break clips that includes current break clip that receiver
     * is playing or ones that receiver will play shortly after; instead of sending
     * whole list of clips. This is to avoid overflow of MediaStatus message.
     */
    breakClips?: BreakClip[];

    /**
     * List of breaks.
     */
    breaks?: Break[];

    /**
     * Typically the url of the media.
     */
    contentId: string;

    /**
     *  The content MIME type.
     */
    contentType: string;

    /**
     * Optional media url; to allow using contentId for real id. If contentUrl
     * is provided; it will be used as media url; otherwise the contentId will
     * be used as the media url.
     */
    contentUrl?: string;

    /**
     * Application-specific media information.
     */
    customData?: any;

    /**
     * The media duration.
     */
    duration?: number;

    /**
     * Optional Media entity; provide Google Assistant deep link.
     */
    entity?: string;

    /**
     * The format of the HLS media segment.
     */
    hlsSegmentFormat?: HlsSegmentFormat;

    /**
     * The media metadata.
     */
    metadata?:
    | MediaMetadata
    | GenericMediaMetadata
    | MovieMediaMetadata
    | MusicTrackMediaMetadata
    | PhotoMediaMetadata
    | TvShowMediaMetadata;

    /**
     * The stream type.
     */
    streamType: StreamType;

    /**
     * The style of text track.
     */
    textTrackStyle?: TextTrackStyle;

    /**
     * The media tracks.
     */
    tracks?: Track[];
}

/**
 * Media event LOAD request data.
 */
export interface LoadRequestData extends RequestData {
    /**
     * Array of trackIds that are active. If the array is not provided; the
     * default tracks will be active.
     */
    activeTrackIds: number[];

    /**
     * If the autoplay parameter is specified; the media player will begin
     * playing the content when it is loaded. Even if autoplay is not
     * specified;the media player implementation may choose to begin playback
     * immediately.
     */
    autoplay?: boolean;

    /**
     * Optional user credentials.
     */
    credentials?: string;

    /**
     * Optional credentials type. The type 'cloud' is a reserved type used by
     * load requests that were originated by voice assistant commands.
     */
    credentialsType?: string;

    /**
     * Seconds since beginning of content. If the content is live content;
     * and currentTime is not specified; the stream will start at the live position.
     */
    currentTime?: number;

    /**
     * If the autoplay parameter is specified; the media player will begin playing
     * the content when it is loaded. Even if autoplay is not specified; the media
     * player implementation may choose to begin playback immediately.
     */
    media: MediaInformation;

    /**
     * The media playback rate.
     */
    playbackRate?: number;

    /**
     * Queue data.
     */
    queueData: QueueData;
}

/**
 * LoadByEntity request data.
 */
export interface LoadByEntityRequestData {
    /**
     * Content entity information; typically represented by a stringified JSON object
     */
    entity: string;

    /**
     *  Shuffle the items to play.
     */
    shuffle?: boolean;

    /**
     * Optional request source. It contain the assistent query that initiate the request.
     */
    source?: string;
}

/**
 * Provides live seekable range with start and end time in seconds and two more
 * attributes.
 */
export class LiveSeekableRange {
    constructor(
        start?: number,
        end?: number,
        isMovingWindow?: boolean,
        isLiveDone?: boolean
    );

    /**
     * A boolean value indicates whether a live stream is ended. If it is done;
     * the end of live seekable range should stop updating.
     */
    isLiveDone?: boolean;

    /**
     * A boolean value indicates whether the live seekable range is a moving window.
     * If false; it will be either a expanding range or a fixed range meaning live
     * has ended.
     */
    isMovingWindow?: boolean;
}

/**
 * Represents a data message containing item information for each requested ids.
 */
export interface ItemsInfo {
    /**
     * List of changed itemIds.
     */
    items: QueueItem[];

    /**
     * The corresponding request id.
     */
    requestId?: number;

    type: MessageType;
}

/**
 * An image that describes a receiver application or media item.
 * This could be an application icon; cover art; or a thumbnail.
 */
export class Image {
    constructor(url: string);

    /**
     * The height of the image.
     */
    height?: number;

    /**
     * the URL to the image
     */
    url: string;

    /**
     * The width of the image
     */
    width?: number;
}
/** Media event GET_STATUS request data. */
export interface GetStatusRequestData extends RequestData {
    /**
     * The options of a GET_STATUS request.
     */
    options: GetStatusOptions;
}

/**
 * Get items info request data.
 */
export class GetItemsInfoRequestData extends RequestData {
    constructor(itemIds: number[]);

    /**
     * List of item ids to be requested.
     */
    itemIds: number[];
}
/**
 * A generic media description.
 */
export interface GenericMediaMetadata extends MediaMetadata {
    /**
     * Content images. Examples would include cover art or a thumbnail of the
     * currently playing media.
     */
    images: Image[];

    /**
     * ISO 8601 date and/or time when the content was released; e.g. 2014-02-10.
     */
    releaseDate?: string;

    /**
     * @deprecated - use @see{@link releaseDate} instead
     */
    releaseYear?: number;

    /**
     * Content subtitle.
     */
    subtitle?: string;

    /**
     * Content title.
     */
    title?: string;
}

/**
 * Focus state change message.
 */
export interface FocusStateRequestData {
    /**
     * The focus state of the app.
     */
    state: FocusState;
}

/** Fetch items request data. */
export class FetchItemsRequestData extends RequestData {
    constructor(itemId: number, nextCount: number, prevCount: number);

    /**
     * ID of the reference media item for fetching more items.
     */
    itemId: number;

    /**
     * Number of items after the reference item to be fetched.
     */
    nextCount: number;

    /**
     * Number of items before the reference item to be fetched.
     */
    prevCount: number;
}

/**
 * Extended media status information
 */
export class ExtendedMediaStatus {
    constructor(
        playerState: MediaInformation,
        opt_media?: MediaInformation
    );

    media: MediaInformation;

    playerState: ExtendedPlayerState;
}

/** Event data for @see{@link EventType.ERROR} event. */
export class ErrorEvent extends Event {
    constructor(detailedErrorCode?: DetailedErrorCode, error?: any);

    /**
     * An error code representing the cause of the error.
     */
    detailedErrorCode?: DetailedErrorCode;

    /**
     * The error object.
     * This could be an Error object (e.g.; if an Error was thrown in an event handler)
     * or an object with error information (e.g.; if the receiver received an invalid
     * command).
     */
    error?: any;
}

export class ErrorData {
    constructor(type: ErrorType);

    /**
     * Application-specific data for this request.
     * It enables the sender and receiver to easily extend the media protocol
     * without having to use a new namespace with custom messages.
     */
    customData?: any;

    /**
     * Id of the request; used to correlate request/response.
     */
    requestId?: number;
}

/**  Media event EDIT_TRACKS_INFO request data. */
export interface EditTracksInfoRequestData extends RequestData {
    /**
     * Array of the Track trackIds that should be active.
     * If it is not provided; the active tracks will not change.
     * If the array is empty; no track will be active.
     */
    activeTrackIds?: number[];

    /**
     * Flag to enable or disable text tracks.
     * If false it will disable all text tracks;
     * if true it will enable the first text track; or the previous active text tracks.
     * This flag is ignored if activeTrackIds or language is provided.
     */
    enableTextTracks?: boolean;

    /**
     * Indicates that the provided language was not explicit user request; but rather
     * inferred from used language in voice query.
     * It allows receiver apps to use user saved preference instead of spoken language.
     */
    isSuggestedLanguage?: boolean;

    /**
     * Language for the tracks that should be active. The language field will take
     * precedence over activeTrackIds if both are specified.
     */
    language?: string;

    textTrackStyle?: TextTrackStyle;
}

/**
 * Media event EDIT_AUDIO_TRACKS request data. If language is not provided;
 * the default audio track for the media will be enabled.
 */
export interface EditAudioTracksRequestData extends RequestData {
    /**
     * Indicates that the provided language was not explicit user request;
     * but rather inferred from used language in voice query.
     * It allows receiver apps to use user saved preference instead of spoken language.
     */
    isSuggestedLanguage?: boolean;

    language?: string;
}

/** DisplayStatus request data. */
export interface DisplayStatusRequestData {
    /**
     * Optional request source. It contain the assistent query that initiate the request.
     */
    source: string;
}

/** CustomCommand request data. */
export interface CustomCommandRequestData {
    /**
     * Custom Data; typically represented by a stringified JSON object.
     */
    data: string;

    /**
     * Optional request source. It contain the assistent query that initiate the request.
     */
    source: string;
}

export class BreakStatus {
    constructor(currentBreakTime: number, currentBreakClipTime: number);

    /**
     * Id of current break clip.
     */
    breakClipId: string;

    /**
     * Id of current break.
     */
    breakId: string;

    /**
     * Time in sec elapsed after current break clip starts.
     */
    currentBreakClipTime: number;

    /**
     * Time in sec elapsed after current break starts.
     */
    currentBreakTime: number;

    /**
     * The time in sec when this break clip becomes skippable.
     * 5 means that end user can skip this break clip after 5 seconds.
     * If this field is not defined; it means that current break clip is not skippable.
     */
    whenSkippable: number;
}

/**
 * Represents break clip (e.g. a clip of ad during ad break)
 */
export class BreakClip {
    constructor(id: string);

    /**
     * Url of page that sender will display; when end user clicks link on sender UI; while receiver is playing this clip.
     */
    clickThroughUrl?: string;
    /**
     * Typically the url of the break media (playing on the receiver).
     */
    contentId?: string;
    /**
     * The content MIME type.
     */
    contentType?: string;
    /**
     * Optional break media url; to allow using contentId for real id.
     * If contentUrl is provided; it will be used as media url;
     * otherwise the contentId will be used as the media url.
     */
    contentUrl?: string;
    /**
     * Application-specific break clip data.
     */
    customData?: any;
    /**
     * Duration of break clip in sec.
     */
    duration?: number;
    /**
     * The format of the HLS media segment.
     */
    hlsSegmentFormat?: HlsSegmentFormat;
    /**
     * Unique id of break clip.
     */
    id: string;
    /**
     * Url of content that sender will display while receiver is playing this clip.
     */
    posterUrl?: string;
    /**
     * Title of break clip. Sender might display this on its screen; if provided.
     */
    title?: string;
    /**
     * VAST ad request configuration. Used if contentId or contentUrl is not provided.
     */
    vastAdsRequest?: VastAdsRequest;
    /**
     * The time in sec when this break clip becomes skippable.
     * 5 means that end user can skip this break clip after 5 seconds.
     * If this field is not defined; it means that current break clip is not skippable.
     */
    whenSkippable?: number;
}

/** Represents break (e.g. ad break) included in main video. */
export class Break {
    constructor(id: string, breakClipIds: string[], position: number);
    /**
     * List of ids of break clip that this break includes.
     */
    breakClipIds: string[];
    /**
     * Duration of break in sec.
     */
    duration?: number;
    /**
     * Unique id of break.
     */
    id: string;
    /**
     * If true; indicates this is embedded break in main stream.
     */

    isEmbedded?: boolean;
    /**
     * Whether break is watched.
     * Sender can change color of progress bar marker corresponding to this break once
     *  this field changes from false to true;
     *  denoting that the end-user already watched this break.
     */
    isWatched: boolean;

    /**
     * Where the break is located inside main video. -1 represents the end of main video.
     */
    position: number;
}

redpajama_set_name: RedPajamaGithub


text:
package org.rythmengine.internal;

/**
 * Created by IntelliJ IDEA.
 * User: luog
 * Date: 29/01/12
 * Time: 11:24 AM
 * To change this template use File | Settings | File Templates.
 */
public interface IKeywordParserFactory extends IParserFactory {
    IKeyword keyword();
}


text:
<?php
	$curpage = (isset($_GET['page']) && !empty($_GET['page'])) ? $_GET['page'] : 'home' ;

	$pages = array();
	switch ($curpage) {
		case 'home':
			$pages['title'] = 'Prima pagina';
			$pages['file'] = 'pages/home.php';
			break;
		case 'register':
			$pages['title'] = 'Cont nou';
			$pages['file'] = 'pages/register.php';
			break;
		case 'highscore':
			$pages['title'] = 'Clasament';
			$pages['file'] = 'pages/highscore.php';
			break;
		case 'download':
			$pages['title'] = 'Descarcare client';
			$pages['file'] = 'pages/download.php';
			break;
		case 'guild':
			$pages['title'] = 'Informatii breasla';
			$pages['file'] = 'pages/guild.php';
			break;

		#### USER ####

		case 'login':
			$pages['title'] = 'Autentificare';
			$pages['file'] = 'pages/login.php';
			break;
		case 'logout':
			$pages['title'] = 'Delogare';
			$pages['file'] = 'pages/logout.php';
			break;
		case 'character':
			$pages['title'] = 'Informatii caracter';
			$pages['file'] = 'pages/character.php';
			break;
		case 'characters':
			$pages['title'] = 'Caracterele mele';
			$pages['file'] = 'pages/characters.php';
			break;
		case 'change_pass':
			$pages['title'] = 'Schimbare parola';
			$pages['file'] = 'pages/change_pass.php';
			break;
		case 'account':
			$pages['title'] = 'Informatii cont';
			$pages['file'] = 'pages/account.php';
			break;
		case 'buymd':
			$pages['title'] = 'Cumpara monede dragon';
			$pages['file'] = 'pages/buymd.php';
			break;
		case 'notifications':
			$pages['title'] = 'Notificari';
			$pages['file'] = 'pages/notifications.php';
			break;

		#### ADMIN ####

		case 'admin_home':
			$pages['title'] = 'Panou de administrare';
			$pages['file'] = 'pages/admin_home.php';
			break;
		case 'admin_settings':
			$pages['title'] = 'Setari website';
			$pages['file'] = 'pages/admin_settings.php';
			break;
		case 'admin_downloads':
			$pages['title'] = 'Administrare descarcari';
			$pages['file'] = 'pages/admin_downloads.php';
			break;
		case 'admin_news':
			$pages['title'] = 'Administrare stiri si evenimente';
			$pages['file'] = 'pages/admin_news.php';
			break;
		case 'admin_webadmins':
			$pages['title'] = 'Administratori site';
			$pages['file'] = 'pages/admin_webadmins.php';
			break;
		case 'admin_playersearch':
			$pages['title'] = 'Cautare jucator';
			$pages['file'] = 'pages/admin_playersearch.php';
			break;
		case 'admin_accountsearch':
			$pages['title'] = 'Cauta cont';
			$pages['file'] = 'pages/admin_accountsearch.php';
			break;
		case 'admin_charedit':
			$pages['title'] = 'Editare caracter';
			$pages['file'] = 'pages/admin_charedit.php';
			break;
		case 'admin_accedit':
			$pages['title'] = 'Editare cont';
			$pages['file'] = 'pages/admin_accedit.php';
			break;
		case 'admin_addcoins':
			$pages['title'] = 'Adaugare monede';
			$pages['file'] = 'pages/admin_addcoins.php';
			break;
		case 'admin_donations':
			$pages['title'] = 'Administrare donatii';
			$pages['file'] = 'pages/admin_donations.php';
			break;
		case 'admin_ishop_cat':
			$pages['title'] = 'Administrare categorii ishop';
			$pages['file'] = 'pages/admin_ishop_cat.php';
			break;
		case 'admin_ishop_items':
			$pages['title'] = 'Administrare iteme ishop';
			$pages['file'] = 'pages/admin_ishop_items.php';
			break;
		case 'admin_ishop_log':
			$pages['title'] = 'Log cumparaturi ishop';
			$pages['file'] = 'pages/admin_ishop_log.php';
			break;
		case 'admin_gmlog':
			$pages['title'] = 'Istoric comenzi GM';
			$pages['file'] = 'pages/admin_gmlog.php';
			break;

		#### DEFAULT ####

		default:
			$pages['title'] = 'Prima pagina';
			$pages['file'] = 'pages/home.php';
			break;
	}

?>


text:
package com.bsb.intellij.plugins.xmlbeans.compiler;

import com.bsb.intellij.plugins.xmlbeans.facet.XmlBeansFacet;
import com.bsb.intellij.plugins.xmlbeans.utils.facetcompiletask.AbstractFacetCompileTaskManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;

/**
 * @author gja
 * @version $Revision: 2308 $ $Date: 2013-08-19 15:47:35 +0200 (lun., 19 août 2013) $
 */
public class XmlBeansCleanCompileAndCopyTaskManager extends AbstractFacetCompileTaskManager<XmlBeansFacet, XmlBeansCleanCompileAndCopyTask> {

  public static XmlBeansCleanCompileAndCopyTaskManager getInstance(Project project) {
    return ServiceManager.getService(project, XmlBeansCleanCompileAndCopyTaskManager.class);
  }

  public XmlBeansCleanCompileAndCopyTaskManager(Project project) {
    super(project, ExecutionMoment.BEFORE);
  }
}


text:
package org.elasticsearch.client.sniff;

import com.carrotsearch.randomizedtesting.generators.RandomInts;
import com.carrotsearch.randomizedtesting.generators.RandomPicks;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientTestCase;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

public class HostsSnifferBuilderTests extends RestClientTestCase {

    public void testBuild() throws Exception {
        try {
            HostsSniffer.builder(null);
            fail("should have failed");
        } catch(NullPointerException e) {
            assertEquals(e.getMessage(), "restClient cannot be null");
        }

        int numNodes = RandomInts.randomIntBetween(getRandom(), 1, 5);
        HttpHost[] hosts = new HttpHost[numNodes];
        for (int i = 0; i < numNodes; i++) {
            hosts[i] = new HttpHost("localhost", 9200 + i);
        }

        try (RestClient client = RestClient.builder(hosts).build()) {
            try {
                HostsSniffer.builder(client).setScheme(null);
                fail("should have failed");
            } catch(NullPointerException e) {
                assertEquals(e.getMessage(), "scheme cannot be null");
            }

            try {
                HostsSniffer.builder(client).setSniffRequestTimeoutMillis(RandomInts.randomIntBetween(getRandom(), Integer.MIN_VALUE, 0));
                fail("should have failed");
            } catch(IllegalArgumentException e) {
                assertEquals(e.getMessage(), "sniffRequestTimeoutMillis must be greater than 0");
            }

            HostsSniffer.Builder builder = HostsSniffer.builder(client);
            if (getRandom().nextBoolean()) {
                builder.setScheme(RandomPicks.randomFrom(getRandom(), HostsSniffer.Scheme.values()));
            }
            if (getRandom().nextBoolean()) {
                builder.setSniffRequestTimeoutMillis(RandomInts.randomIntBetween(getRandom(), 1, Integer.MAX_VALUE));
            }
            assertNotNull(builder.build());
        }
    }
}


text:
(function($) {

	var selector = '.form-collection-container';

	var addButtonClickListener = function() {
		var $button = $(this),
			$collectionContainer = $button.closest(selector),
			template = $collectionContainer.children('span[data-template]').data('template'),
			placeholder = $collectionContainer.data('template-placeholder'),
			$content = $(template),
			$form = $content.find('form'),
			$addWrapper = $collectionContainer.find('.form-collection-container-add-wrapper');

		// add new form before add button
		$content.insertBefore($addWrapper)
			.hide()
			.fadeIn();

		// set key in case of valid insertion
		$form.on('yk:forms:success', function(event, data) {
            if ('valid' in data.data && data.data.valid) {
            	var key = $('<div>' + data.data.content + '</div>').find('*[data-entry-key]')
            		.attr('data-entry-key');
            	$form.attr('action', $form.attr('action').replace(new RegExp($collectionContainer.data('new-entry-key')), key))
            		.attr('data-entry-key', key)
            		.data('entry-key', key);
            }
        });

		initRemoveButtons($content);

		// following lines should be solved via triggering global init event or something like that
		$content.find(".sf-container").summaryform();
		$content.find("a").click($.fn.summaryform.ensureSave);
		$content.find('form:not([data-handle-by]), form[data-handle-by="yk-form"]').form();
	};

	var removeButtonClickListener = function()
	{
		var $button = $(this),
			$collectionContainer = $button.closest(selector);

		// confirm removal
		if (!window.confirm($collectionContainer.data('remove-question'))) {
			return false;
		}

		var $formContainer = $button.closest('.form-collection-container-form'),
			key = $formContainer.find('form[data-entry-key]').data('entry-key'),
			action = $collectionContainer.data('remove-action'),
			remove = function () {
				$formContainer.fadeOut(function() {
					$formContainer.remove()
				});
			};

		// check for new entry form
		if (key === $collectionContainer.data('new-entry-key')) {
			// simply remove it from DOM
			remove();
		} else {
			$.ajax({
				url: '?action=' + action,
				type: 'post',
				dataType: 'json',
				data: {key: key}
			})
			.done(function(data) {
				if (data.success) {
					// remove it from DOM after success removal on server side
					remove();
				}
			});
		}
	};

	var initAddButtons = function (collection) {
		collection.find('.form-collection-container-add-button')
			.on('click.formcollectionContainer', addButtonClickListener);
	};

	var initRemoveButtons = function (collection) {
		var event = 'click.formcollectionContainer',
			buttonSelector = '.form-collection-container-remove-button';
		collection.find(buttonSelector)
			.on(event, removeButtonClickListener);
		collection.find('form').on('yk:forms:success', function () {
			$(this).closest('.form-collection-container-form')
				.find(buttonSelector)
				.off(event)
				.on(event, removeButtonClickListener);
		})
	};

	$.fn.formcollectionContainer = function( ) {
		return this.each(function() {
			var collection = $(this);
			if (!collection.is(selector)) return;

			initAddButtons(collection);
			initRemoveButtons(collection);
		});
	};

	$(function() {
		$(selector).formcollectionContainer();
	});

})(jQuery);


text:
============
 aeromancer
============

OpenStack Source Explorer

* Free software: Apache license
* Documentation: http://docs.openstack.org/developer/aeromancer
* Source: http://git.openstack.org/cgit/openstack/aeromancer
* Bugs: http://bugs.launchpad.net/aeromancer

Features
--------

* TODO


text:
window.jsJobRun = function(data, options, callback) {
    var delay = data.delay || 1000;
    setTimeout(function() {
        return callback(null, data, null);
    }, delay);
};


text:
local function getinfo()
  print(debug.getinfo(1, 'n').name)
  print(debug.getinfo(1, 'n').namewhat)
  print(debug.getinfo(1, 'S').source)
  print(debug.getinfo(1, 'S').short_src)
  print(debug.getinfo(1, 'S').linedefined)
  print(debug.getinfo(1, 'S').lastlinedefined)
  print(debug.getinfo(1, 'S').what)
  print(debug.getinfo(1, 'l').currentline)
  -- print(debug.getinfo(1, 't').istailcall)
  print(debug.getinfo(1, 'u').nups)
  print(debug.getinfo(1, 'u').nparams)
  print(debug.getinfo(1, 'u').isvararg)
end

getinfo()


text:
<?php

namespace Coast\File;

use DateTime;

abstract class Path extends \Coast\Path
{
    public function exists()
    {
        return file_exists($this->_name);
    }

    public function isExist()
    {
        return $this->exists();
    }

    public function isDir()
    {
        return is_dir($this->_name);
    }

    public function isFile()
    {
        return is_file($this->_name);
    }

    public function isReadable()
    {
        return is_readable($this->_name);
    }

    public function isWritable()
    {
        return is_writable($this->_name);
    }

    public function permissions()
    {
        return substr(sprintf('%o', fileperms($this->_name)), -4);
    }

    public function move(\Coast\Dir $dir, $baseName = null)
    {
        $name = "{$dir}/" . (isset($baseName)
            ? $this->_parseBaseName($baseName)
            : $this->baseName());
        rename($this->_name, $name);
        $this->_name = $name;
        return $this;
    }

    public function rename($baseName, \Coast\Dir $dir = null)
    {
        $name = (isset($dir)
            ? $dir
            : $this->dirName()) . "/{$this->_parseBaseName($baseName)}";
        rename($this->_name, $name);
        $this->_name = $name;
        return $this;
    }

    abstract public function copy(\Coast\Dir $dir, $baseName = null);

    abstract public function remove();

    public function accessTime()
    {
        return (new DateTime())->setTimestamp(fileatime($this->_name));
    }

    public function changeTime()
    {
        return (new DateTime())->setTimestamp(filectime($this->_name));
    }

    public function modifyTime()
    {
        return (new DateTime())->setTimestamp(filemtime($this->_name));
    }

    protected function _parseBaseName($baseName)
    {
        if (is_array($baseName)) {
            $baseName = array_intersect_key($baseName, [
                'baseName' => null,
                'fileName' => null,
                'extName'  => null,
                'prefix'   => null,
                'suffix'   => null,
            ]);
            $path = new \Coast\Path($this->baseName());
            foreach ($baseName as $method => $value) {
                $path->$method($value);
            }
            $baseName = $path->baseName();
        }
        return $baseName;
    }
}