Basic webplayer

Now able to play a single file, in a format supported by your browser.

* Playlists not yet supported.
* Volume is a simple on/off switch.
* Repeat / Random not yet supported.
Bu işleme şunda yer alıyor:
Lucas Verney 2016-08-07 00:58:36 +02:00
ebeveyn 4cef2c2014
işleme 4d4ce6c14e
22 değiştirilmiş dosya ile 373 ekleme ve 84 silme

Dosyayı Görüntüle

@ -5,7 +5,7 @@ import { CALL_API } from "../middleware/api";
import { artist, track, album } from "../models/api";
export const DEFAULT_LIMIT = 30; /** Default max number of elements to retrieve. */
export const DEFAULT_LIMIT = 32; /** Default max number of elements to retrieve. */
export default function (action, requestType, successType, failureType) {
const itemName = action.rstrip("s");

Dosyayı Görüntüle

@ -11,3 +11,4 @@ export var { loadSongs } = APIAction("songs", API_REQUEST, API_SUCCESS, API_FAIL
export * from "./paginate";
export * from "./store";
export * from "./webplayer";

92
app/actions/webplayer.js Normal dosya
Dosyayı Görüntüle

@ -0,0 +1,92 @@
export const PLAY_PAUSE = "PLAY_PAUSE";
/**
* true to play, false to pause.
*/
export function togglePlaying(playPause) {
return (dispatch, getState) => {
let isPlaying = false;
if (typeof playPause !== "undefined") {
isPlaying = playPause;
} else {
isPlaying = !(getState().webplayer.isPlaying);
}
dispatch({
type: PLAY_PAUSE,
payload: {
isPlaying: isPlaying
}
});
};
}
export const PUSH_PLAYLIST = "PUSH_PLAYLIST";
export function playTrack(trackID) {
return (dispatch, getState) => {
const track = getState().api.entities.getIn(["track", trackID]);
const album = getState().api.entities.getIn(["album", track.get("album")]);
const artist = getState().api.entities.getIn(["artist", track.get("artist")]);
dispatch({
type: PUSH_PLAYLIST,
payload: {
playlist: [trackID],
tracks: [
[trackID, track]
],
albums: [
[album.get("id"), album]
],
artists: [
[artist.get("id"), artist]
]
}
});
dispatch(togglePlaying(true));
};
}
export const CHANGE_TRACK = "CHANGE_TRACK";
export function playPrevious() {
// TODO: Playlist overflow
return (dispatch, getState) => {
let { index } = getState().webplayer;
dispatch({
type: CHANGE_TRACK,
payload: {
index: index - 1
}
});
};
}
export function playNext() {
// TODO: Playlist overflow
return (dispatch, getState) => {
let { index } = getState().webplayer;
dispatch({
type: CHANGE_TRACK,
payload: {
index: index + 1
}
});
};
}
export const TOGGLE_RANDOM = "TOGGLE_RANDOM";
export function toggleRandom() {
return {
type: TOGGLE_RANDOM
};
}
export const TOGGLE_REPEAT = "TOGGLE_REPEAT";
export function toggleRepeat() {
return {
type: TOGGLE_REPEAT
};
}
export const TOGGLE_MUTE = "TOGGLE_MUTE";
export function toggleMute() {
return {
type: TOGGLE_MUTE
};
}

Dosyayı Görüntüle

@ -1,6 +1,6 @@
import React, { Component, PropTypes } from "react";
import CSSModules from "react-css-modules";
import { defineMessages, FormattedMessage } from "react-intl";
import { defineMessages, FormattedMessage, injectIntl, intlShape } from "react-intl";
import FontAwesome from "react-fontawesome";
import Immutable from "immutable";
@ -12,13 +12,14 @@ import css from "../styles/Album.scss";
const albumMessages = defineMessages(messagesMap(Array.concat([], commonMessages)));
class AlbumTrackRowCSS extends Component {
class AlbumTrackRowCSSIntl extends Component {
render () {
const { formatMessage } = this.props.intl;
const length = formatLength(this.props.track.get("time"));
return (
<tr>
<td>
<button styleName="play">
<button styleName="play" title={formatMessage(albumMessages["app.common.play"])} onClick={() => this.props.playAction(this.props.track.get("id"))}>
<span className="sr-only">
<FormattedMessage {...albumMessages["app.common.play"]} />
</span>
@ -33,18 +34,21 @@ class AlbumTrackRowCSS extends Component {
}
}
AlbumTrackRowCSS.propTypes = {
track: PropTypes.instanceOf(Immutable.Map).isRequired
AlbumTrackRowCSSIntl.propTypes = {
playAction: PropTypes.func.isRequired,
track: PropTypes.instanceOf(Immutable.Map).isRequired,
intl: intlShape.isRequired
};
export let AlbumTrackRow = CSSModules(AlbumTrackRowCSS, css);
export let AlbumTrackRow = injectIntl(CSSModules(AlbumTrackRowCSSIntl, css));
class AlbumTracksTableCSS extends Component {
render () {
let rows = [];
const playAction = this.props.playAction;
this.props.tracks.forEach(function (item) {
rows.push(<AlbumTrackRow track={item} key={item.get("id")} />);
rows.push(<AlbumTrackRow playAction={playAction} track={item} key={item.get("id")} />);
});
return (
<table className="table table-hover" styleName="songs">
@ -57,6 +61,7 @@ class AlbumTracksTableCSS extends Component {
}
AlbumTracksTableCSS.propTypes = {
playAction: PropTypes.func.isRequired,
tracks: PropTypes.instanceOf(Immutable.List).isRequired
};
@ -75,7 +80,7 @@ class AlbumRowCSS extends Component {
<div className="col-xs-9 col-sm-10 table-responsive">
{
this.props.songs.size > 0 ?
<AlbumTracksTable tracks={this.props.songs} /> :
<AlbumTracksTable playAction={this.props.playAction} tracks={this.props.songs} /> :
null
}
</div>
@ -85,6 +90,7 @@ class AlbumRowCSS extends Component {
}
AlbumRowCSS.propTypes = {
playAction: PropTypes.func.isRequired,
album: PropTypes.instanceOf(Immutable.Map).isRequired,
songs: PropTypes.instanceOf(Immutable.List).isRequired
};

Dosyayı Görüntüle

@ -26,7 +26,7 @@ class ArtistCSS extends Component {
</div>
);
if (this.props.isFetching && !this.props.artist) {
if (this.props.isFetching && !this.props.artist.size > 0) {
// Loading
return loading;
}
@ -37,7 +37,7 @@ class ArtistCSS extends Component {
}
let albumsRows = [];
const { albums, songs } = this.props;
const { albums, songs, playAction } = this.props;
const artistAlbums = this.props.artist.get("albums");
if (albums && songs && artistAlbums && artistAlbums.size > 0) {
this.props.artist.get("albums").forEach(function (album) {
@ -45,7 +45,7 @@ class ArtistCSS extends Component {
const albumSongs = album.get("tracks").map(
id => songs.get(id)
);
albumsRows.push(<AlbumRow album={album} songs={albumSongs} key={album.get("id")} />);
albumsRows.push(<AlbumRow playAction={playAction} album={album} songs={albumSongs} key={album.get("id")} />);
});
}
else {
@ -76,6 +76,7 @@ class ArtistCSS extends Component {
}
ArtistCSS.propTypes = {
playAction: PropTypes.func.isRequired,
isFetching: PropTypes.bool.isRequired,
error: PropTypes.string,
artist: PropTypes.instanceOf(Immutable.Map),

Dosyayı Görüntüle

@ -1,7 +1,7 @@
import React, { Component, PropTypes } from "react";
import { Link} from "react-router";
import CSSModules from "react-css-modules";
import { defineMessages, FormattedMessage } from "react-intl";
import { defineMessages, injectIntl, intlShape, FormattedMessage } from "react-intl";
import FontAwesome from "react-fontawesome";
import Immutable from "immutable";
import Fuse from "fuse.js";
@ -18,15 +18,16 @@ import css from "../styles/Songs.scss";
const songsMessages = defineMessages(messagesMap(Array.concat([], commonMessages, messages)));
class SongsTableRowCSS extends Component {
class SongsTableRowCSSIntl extends Component {
render () {
const { formatMessage } = this.props.intl;
const length = formatLength(this.props.song.get("time"));
const linkToArtist = "/artist/" + this.props.song.getIn(["artist", "id"]);
const linkToAlbum = "/album/" + this.props.song.getIn(["album", "id"]);
return (
<tr>
<td>
<button styleName="play">
<button styleName="play" title={formatMessage(songsMessages["app.common.play"])} onClick={() => this.props.playAction(this.props.song.get("id"))}>
<span className="sr-only">
<FormattedMessage {...songsMessages["app.common.play"]} />
</span>
@ -43,11 +44,13 @@ class SongsTableRowCSS extends Component {
}
}
SongsTableRowCSS.propTypes = {
song: PropTypes.instanceOf(Immutable.Map).isRequired
SongsTableRowCSSIntl.propTypes = {
playAction: PropTypes.func.isRequired,
song: PropTypes.instanceOf(Immutable.Map).isRequired,
intl: intlShape.isRequired
};
export let SongsTableRow = CSSModules(SongsTableRowCSS, css);
export let SongsTableRow = injectIntl(CSSModules(SongsTableRowCSSIntl, css));
class SongsTableCSS extends Component {
@ -67,8 +70,9 @@ class SongsTableCSS extends Component {
}
let rows = [];
const { playAction } = this.props;
displayedSongs.forEach(function (song) {
rows.push(<SongsTableRow song={song} key={song.get("id")} />);
rows.push(<SongsTableRow playAction={playAction} song={song} key={song.get("id")} />);
});
let loading = null;
if (rows.length == 0 && this.props.isFetching) {
@ -112,6 +116,7 @@ class SongsTableCSS extends Component {
}
SongsTableCSS.propTypes = {
playAction: PropTypes.func.isRequired,
songs: PropTypes.instanceOf(Immutable.List).isRequired,
filterText: PropTypes.string
};
@ -145,7 +150,7 @@ export default class FilterablePaginatedSongsTable extends Component {
<div>
{ error }
<FilterBar filterText={this.state.filterText} onUserInput={this.handleUserInput} />
<SongsTable isFetching={this.props.isFetching} songs={this.props.songs} filterText={this.state.filterText} />
<SongsTable playAction={this.props.playAction} isFetching={this.props.isFetching} songs={this.props.songs} filterText={this.state.filterText} />
<Pagination {...this.props.pagination} />
</div>
);
@ -153,6 +158,7 @@ export default class FilterablePaginatedSongsTable extends Component {
}
FilterablePaginatedSongsTable.propTypes = {
playAction: PropTypes.func.isRequired,
isFetching: PropTypes.bool.isRequired,
error: PropTypes.string,
songs: PropTypes.instanceOf(Immutable.List).isRequired,

Dosyayı Görüntüle

@ -23,15 +23,24 @@ class WebPlayerCSSIntl extends Component {
artOpacityHandler (ev) {
if (ev.type == "mouseover") {
this.refs.art.style.opacity = "1";
this.refs.artText.style.display = "none";
} else {
this.refs.art.style.opacity = "0.75";
this.refs.artText.style.display = "block";
}
}
render () {
const { formatMessage } = this.props.intl;
const song = this.props.currentTrack;
if (!song) {
return (<div></div>);
}
const playPause = this.props.isPlaying ? "pause" : "play";
const volumeMute = this.props.isMute ? "volume-off" : "volume-up";
const randomBtnStyles = ["randomBtn"];
const repeatBtnStyles = ["repeatBtn"];
if (this.props.isRandom) {
@ -46,36 +55,38 @@ class WebPlayerCSSIntl extends Component {
<div className="col-xs-12">
<div className="row" styleName="artRow" onMouseOver={this.artOpacityHandler} onMouseOut={this.artOpacityHandler}>
<div className="col-xs-12">
<img src={this.props.song.get("art")} width="200" height="200" alt={formatMessage(webplayerMessages["app.common.art"])} ref="art" styleName="art" />
<h2>{this.props.song.get("title")}</h2>
<h3>
<span className="text-capitalize">
<FormattedMessage {...webplayerMessages["app.webplayer.by"]} />
</span> {this.props.song.get("artist")}
</h3>
<img src={song.get("art")} width="200" height="200" alt={formatMessage(webplayerMessages["app.common.art"])} ref="art" styleName="art" />
<div ref="artText">
<h2>{song.get("title")}</h2>
<h3>
<span className="text-capitalize">
<FormattedMessage {...webplayerMessages["app.webplayer.by"]} />
</span> { this.props.currentArtist.get("name") }
</h3>
</div>
</div>
</div>
<div className="row text-center" styleName="controls">
<div className="col-xs-12">
<button styleName="prevBtn" aria-label={formatMessage(webplayerMessages["app.webplayer.previous"])} title={formatMessage(webplayerMessages["app.webplayer.previous"])}>
<button styleName="prevBtn" aria-label={formatMessage(webplayerMessages["app.webplayer.previous"])} title={formatMessage(webplayerMessages["app.webplayer.previous"])} onClick={this.props.onPrev}>
<FontAwesome name="step-backward" />
</button>
<button className="play" styleName="playPauseBtn" aria-label={formatMessage(webplayerMessages["app.common." + playPause])} title={formatMessage(webplayerMessages["app.common." + playPause])}>
<button className="play" styleName="playPauseBtn" aria-label={formatMessage(webplayerMessages["app.common." + playPause])} title={formatMessage(webplayerMessages["app.common." + playPause])} onClick={this.props.onPlayPause}>
<FontAwesome name={playPause} />
</button>
<button styleName="nextBtn" aria-label={formatMessage(webplayerMessages["app.webplayer.next"])} title={formatMessage(webplayerMessages["app.webplayer.next"])}>
<button styleName="nextBtn" aria-label={formatMessage(webplayerMessages["app.webplayer.next"])} title={formatMessage(webplayerMessages["app.webplayer.next"])} onClick={this.props.onSkip}>
<FontAwesome name="step-forward" />
</button>
</div>
<div className="col-xs-12">
<button styleName="volumeBtn" aria-label={formatMessage(webplayerMessages["app.webplayer.volume"])} title={formatMessage(webplayerMessages["app.webplayer.volume"])}>
<FontAwesome name="volume-up" />
<button styleName="volumeBtn" aria-label={formatMessage(webplayerMessages["app.webplayer.volume"])} title={formatMessage(webplayerMessages["app.webplayer.volume"])} onClick={this.props.onMute}>
<FontAwesome name={volumeMute} />
</button>
<button styleName={repeatBtnStyles.join(" ")} aria-label={formatMessage(webplayerMessages["app.webplayer.repeat"])} title={formatMessage(webplayerMessages["app.webplayer.repeat"])} aria-pressed={this.props.isRepeat}>
<button styleName={repeatBtnStyles.join(" ")} aria-label={formatMessage(webplayerMessages["app.webplayer.repeat"])} title={formatMessage(webplayerMessages["app.webplayer.repeat"])} aria-pressed={this.props.isRepeat} onClick={this.props.onRepeat}>
<FontAwesome name="repeat" />
</button>
<button styleName={randomBtnStyles.join(" ")} aria-label={formatMessage(webplayerMessages["app.webplayer.random"])} title={formatMessage(webplayerMessages["app.webplayer.random"])} aria-pressed={this.props.isRandom}>
<button styleName={randomBtnStyles.join(" ")} aria-label={formatMessage(webplayerMessages["app.webplayer.random"])} title={formatMessage(webplayerMessages["app.webplayer.random"])} aria-pressed={this.props.isRandom} onClick={this.props.onRandom}>
<FontAwesome name="random" />
</button>
<button styleName="playlistBtn" aria-label={formatMessage(webplayerMessages["app.webplayer.playlist"])} title={formatMessage(webplayerMessages["app.webplayer.playlist"])}>
@ -90,10 +101,18 @@ class WebPlayerCSSIntl extends Component {
}
WebPlayerCSSIntl.propTypes = {
song: PropTypes.instanceOf(Immutable.Map).isRequired,
isPlaying: PropTypes.bool.isRequired,
isRandom: PropTypes.bool.isRequired,
isRepeat: PropTypes.bool.isRequired,
isMute: PropTypes.bool.isRequired,
currentTrack: PropTypes.instanceOf(Immutable.Map),
currentArtist: PropTypes.instanceOf(Immutable.Map),
onPlayPause: PropTypes.func.isRequired,
onPrev: PropTypes.func.isRequired,
onSkip: PropTypes.func.isRequired,
onRandom: PropTypes.func.isRequired,
onRepeat: PropTypes.func.isRequired,
onMute: PropTypes.func.isRequired,
intl: intlShape.isRequired
};

17
app/models/webplayer.js Normal dosya
Dosyayı Görüntüle

@ -0,0 +1,17 @@
import Immutable from "immutable";
export const entitiesRecord = new Immutable.Record({
artists: new Immutable.Map(),
albums: new Immutable.Map(),
tracks: new Immutable.Map()
});
export const stateRecord = new Immutable.Record({
isPlaying: false,
isRandom: false,
isRepeat: false,
isMute: false,
currentIndex: 0,
playlist: new Immutable.List(),
entities: new entitiesRecord()
});

Dosyayı Görüntüle

@ -3,6 +3,7 @@ import { combineReducers } from "redux";
import auth from "./auth";
import paginate from "./paginate";
import webplayer from "./webplayer";
import * as ActionTypes from "../actions";
@ -16,7 +17,8 @@ const api = paginate([
const rootReducer = combineReducers({
routing,
auth,
api
api,
webplayer
});
export default rootReducer;

51
app/reducers/webplayer.js Normal dosya
Dosyayı Görüntüle

@ -0,0 +1,51 @@
import Immutable from "immutable";
import {
PUSH_PLAYLIST,
CHANGE_TRACK,
PLAY_PAUSE,
TOGGLE_RANDOM,
TOGGLE_REPEAT,
TOGGLE_MUTE } from "../actions";
import { createReducer } from "../utils";
import { stateRecord } from "../models/webplayer";
/**
* Initial state
*/
var initialState = new stateRecord();
/**
* Reducers
*/
export default createReducer(initialState, {
[PLAY_PAUSE]: (state, payload) => {
return state.set("isPlaying", payload.isPlaying);
},
[CHANGE_TRACK]: (state, payload) => {
return state.set("currentIndex", payload.index);
},
[PUSH_PLAYLIST]: (state, payload) => {
return (
state
.set("playlist", new Immutable.List(payload.playlist))
.setIn(["entities", "artists"], new Immutable.Map(payload.artists))
.setIn(["entities", "albums"], new Immutable.Map(payload.albums))
.setIn(["entities", "tracks"], new Immutable.Map(payload.tracks))
.set("currentIndex", 0)
.set("isPlaying", true)
);
},
[TOGGLE_RANDOM]: (state) => {
return state.set("isRandom", !state.get("isRandom"));
},
[TOGGLE_REPEAT]: (state) => {
return state.set("isRepeat", !state.get("isRepeat"));
},
[TOGGLE_MUTE]: (state) => {
return state.set("isMute", !state.get("isMute"));
},
});

Dosyayı Görüntüle

@ -25,11 +25,14 @@ $controlsMarginTop: 10px;
.btn {
background: transparent;
border: none;
opacity: 0.8;
opacity: 0.4;
}
.btn:hover {
.btn:hover,
.btn:active,
.btn:focus {
opacity: 1;
outline: none;
}
.prevBtn,

Dosyayı Görüntüle

@ -27,14 +27,14 @@ class ArtistPageIntl extends Component {
const {formatMessage} = this.props.intl;
const error = handleErrorI18nObject(this.props.error, formatMessage, artistMessages);
return (
<Artist isFetching={this.props.isFetching} error={error} artist={this.props.artist} albums={this.props.albums} songs={this.props.songs} />
<Artist playAction={this.props.actions.playTrack} isFetching={this.props.isFetching} error={error} artist={this.props.artist} albums={this.props.albums} songs={this.props.songs} />
);
}
}
const mapStateToProps = (state, ownProps) => {
const artists = state.api.entities.get("artist");
let artist = undefined;
let artist = new Immutable.Map();
let albums = new Immutable.Map();
let songs = new Immutable.Map();
if (artists) {

Dosyayı Görüntüle

@ -35,7 +35,7 @@ class SongsPageIntl extends Component {
const {formatMessage} = this.props.intl;
const error = handleErrorI18nObject(this.props.error, formatMessage, songsMessages);
return (
<Songs isFetching={this.props.isFetching} error={error} songs={this.props.songsList} pagination={pagination} />
<Songs playAction={this.props.actions.playTrack} isFetching={this.props.isFetching} error={error} songs={this.props.songsList} pagination={pagination} />
);
}
}

Dosyayı Görüntüle

@ -1,23 +1,112 @@
import React, { Component } from "react";
import { bindActionCreators } from "redux";
import { connect } from "react-redux";
import { Howl } from "howler";
import Immutable from "immutable";
import * as actionCreators from "../actions";
import WebPlayerComponent from "../components/elements/WebPlayer";
class WebPlayer extends Component {
constructor (props) {
super(props);
this.play = this.play.bind(this);
this.howl = null;
}
componentDidMount () {
this.play(this.props.isPlaying);
}
componentWillUpdate (nextProps) {
// Toggle play / pause
if (nextProps.isPlaying != this.props.isPlaying) {
// This check ensure we do not start multiple times the same music.
this.play(nextProps);
}
// Toggle mute / unmute
if (this.howl) {
this.howl.mute(nextProps.isMute);
}
}
getCurrentTrackPath (props) {
return [
"tracks",
props.playlist.get(props.currentIndex)
];
}
play (props) {
if (props.isPlaying) {
if (!this.howl) {
const url = props.entities.getIn(
Array.concat([], this.getCurrentTrackPath(props), ["url"])
);
if (!url) {
// TODO: Error handling
return;
}
this.howl = new Howl({
src: [url],
html5: true,
loop: false,
mute: props.isMute,
autoplay: false,
});
}
this.howl.play();
}
else {
if (this.howl) {
this.howl.pause();
}
}
}
export default class WebPlayer extends Component {
render () {
const currentTrack = this.props.entities.getIn(this.getCurrentTrackPath(this.props));
let currentArtist = new Immutable.Map();
if (currentTrack) {
currentArtist = this.props.entities.getIn(["artists", currentTrack.get("artist")]);
}
const webplayerProps = {
song: new Immutable.Map({
art: "http://albumartcollection.com/wp-content/uploads/2011/07/summer-album-art.jpg",
title: "Tel-ho",
artist: "Lapso Laps",
}),
isPlaying: false,
isRandom: false,
isRepeat: true
isPlaying: this.props.isPlaying,
isRandom: this.props.isRandom,
isRepeat: this.props.isRepeat,
isMute: this.props.isMute,
currentTrack: currentTrack,
currentArtist: currentArtist,
onPlayPause: (() => this.props.actions.togglePlaying()),
onPrev: this.props.actions.playPrevious,
onSkip: this.props.actions.playNext,
onRandom: this.props.actions.toggleRandom,
onRepeat: this.props.actions.toggleRepeat,
onMute: this.props.actions.toggleMute
};
return (
<WebPlayerComponent {...webplayerProps} />
);
}
}
const mapStateToProps = (state) => ({
isPlaying: state.webplayer.isPlaying,
isRandom: state.webplayer.isRandom,
isRepeat: state.webplayer.isRepeat,
isMute: state.webplayer.isMute,
currentIndex: state.webplayer.currentIndex,
playlist: state.webplayer.playlist,
entities: state.webplayer.entities
});
const mapDispatchToProps = (dispatch) => ({
actions: bindActionCreators(actionCreators, dispatch)
});
export default connect(mapStateToProps, mapDispatchToProps)(WebPlayer);

Dosyayı Görüntüle

@ -26,6 +26,7 @@
"eslint": "^3.2.2",
"font-awesome": "^4.6.3",
"fuse.js": "^2.4.1",
"howler": "^2.0.0",
"html5shiv": "^3.7.3",
"humps": "^1.1.0",
"imagesloaded": "^4.1.0",

Dosya farkları bir veya daha fazla satır çok uzun olduğundan bastırıldı

Dosya farkları bir veya daha fazla satır çok uzun olduğundan bastırıldı

Dosyayı Görüntüle

@ -1,2 +1,2 @@
!function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var n={};return t.m=e,t.c=n,t.p="./",t(0)}({0:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(626);Object.keys(r).forEach(function(e){"default"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return r[e]}})})},626:function(e,t){!function(t,n){function r(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x<style>"+t+"</style>",r.insertBefore(n.lastChild,r.firstChild)}function a(){var e=b.elements;return"string"==typeof e?e.split(" "):e}function o(e,t){var n=b.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof e&&(e=e.join(" ")),b.elements=n+" "+e,s(t)}function c(e){var t=E[e[v]];return t||(t={},y++,e[v]=y,E[y]=t),t}function i(e,t,r){if(t||(t=n),f)return t.createElement(e);r||(r=c(t));var a;return a=r.cache[e]?r.cache[e].cloneNode():g.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!a.canHaveChildren||p.test(e)||a.tagUrn?a:r.frag.appendChild(a)}function l(e,t){if(e||(e=n),f)return e.createDocumentFragment();t=t||c(e);for(var r=t.frag.cloneNode(),o=0,i=a(),l=i.length;o<l;o++)r.createElement(i[o]);return r}function u(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return b.shivMethods?i(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+a().join().replace(/[\w\-:]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(b,t.frag)}function s(e){e||(e=n);var t=c(e);return!b.shivCSS||d||t.hasCSS||(t.hasCSS=!!r(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),f||u(e,t),e}var d,f,m="3.7.3-pre",h=t.html5||{},p=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,g=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",y=0,E={};!function(){try{var e=n.createElement("a");e.innerHTML="<xyz></xyz>",d="hidden"in e,f=1==e.childNodes.length||function(){n.createElement("a");var e=n.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(t){d=!0,f=!0}}();var b={elements:h.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:h.shivCSS!==!1,supportsUnknownElements:f,shivMethods:h.shivMethods!==!1,type:"default",shivDocument:s,createElement:i,createDocumentFragment:l,addElements:o};t.html5=b,s(n),"object"==typeof e&&e.exports&&(e.exports=b)}("undefined"!=typeof window?window:this,document)}});
!function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var n={};return t.m=e,t.c=n,t.p="./",t(0)}({0:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(630);Object.keys(r).forEach(function(e){"default"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return r[e]}})})},630:function(e,t){!function(t,n){function r(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x<style>"+t+"</style>",r.insertBefore(n.lastChild,r.firstChild)}function a(){var e=b.elements;return"string"==typeof e?e.split(" "):e}function o(e,t){var n=b.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof e&&(e=e.join(" ")),b.elements=n+" "+e,s(t)}function c(e){var t=E[e[v]];return t||(t={},y++,e[v]=y,E[y]=t),t}function i(e,t,r){if(t||(t=n),f)return t.createElement(e);r||(r=c(t));var a;return a=r.cache[e]?r.cache[e].cloneNode():g.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!a.canHaveChildren||p.test(e)||a.tagUrn?a:r.frag.appendChild(a)}function l(e,t){if(e||(e=n),f)return e.createDocumentFragment();t=t||c(e);for(var r=t.frag.cloneNode(),o=0,i=a(),l=i.length;o<l;o++)r.createElement(i[o]);return r}function u(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return b.shivMethods?i(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+a().join().replace(/[\w\-:]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(b,t.frag)}function s(e){e||(e=n);var t=c(e);return!b.shivCSS||d||t.hasCSS||(t.hasCSS=!!r(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),f||u(e,t),e}var d,f,m="3.7.3-pre",h=t.html5||{},p=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,g=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",y=0,E={};!function(){try{var e=n.createElement("a");e.innerHTML="<xyz></xyz>",d="hidden"in e,f=1==e.childNodes.length||function(){n.createElement("a");var e=n.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(t){d=!0,f=!0}}();var b={elements:h.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:h.shivCSS!==!1,supportsUnknownElements:f,shivMethods:h.shivMethods!==!1,type:"default",shivDocument:s,createElement:i,createDocumentFragment:l,addElements:o};t.html5=b,s(n),"object"==typeof e&&e.exports&&(e.exports=b)}("undefined"!=typeof window?window:this,document)}});
//# sourceMappingURL=fix.ie9.js.map

Dosya farkları bir veya daha fazla satır çok uzun olduğundan bastırıldı

Dosya farkları bir veya daha fazla satır çok uzun olduğundan bastırıldı

Dosya farkları bir veya daha fazla satır çok uzun olduğundan bastırıldı

Dosya farkları bir veya daha fazla satır çok uzun olduğundan bastırıldı