403Webshell
Server IP : 14.225.204.176  /  Your IP : 216.73.216.6
Web Server : nginx/1.24.0
System : Linux nodejs-ybgk 6.8.0-40-generic #40-Ubuntu SMP PREEMPT_DYNAMIC Fri Jul 5 10:34:03 UTC 2024 x86_64
User : root ( 0)
PHP Version : 8.1.34
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /var/www/html/php/zinisoft.net-react/node_modules/video-worker/src/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/html/php/zinisoft.net-react/node_modules/video-worker/src/video-worker.esm.js
import global from 'global';

// Deferred
// thanks http://stackoverflow.com/questions/18096715/implement-deferred-object-without-using-jquery
function Deferred() {
    this.doneCallbacks = [];
    this.failCallbacks = [];
}

Deferred.prototype = {
    execute( list, args ) {
        let i = list.length;
        args = Array.prototype.slice.call( args );

        while ( i ) {
            i -= 1;
            list[ i ].apply( null, args );
        }
    },
    resolve( ...args ) {
        this.execute( this.doneCallbacks, args );
    },
    reject( ...args ) {
        this.execute( this.failCallbacks, args );
    },
    done( callback ) {
        this.doneCallbacks.push( callback );
    },
    fail( callback ) {
        this.failCallbacks.push( callback );
    },
};

let ID = 0;
let YoutubeAPIadded = 0;
let VimeoAPIadded = 0;
let loadingYoutubePlayer = 0;
let loadingVimeoPlayer = 0;
const loadingYoutubeDefer = new Deferred();
const loadingVimeoDefer = new Deferred();

export default class VideoWorker {
    constructor( url, options ) {
        const self = this;

        self.url = url;

        self.options_default = {
            autoplay: false,
            loop: false,
            mute: false,
            volume: 100,
            showControls: true,
            accessibilityHidden: false,

            // start / end video time in seconds
            startTime: 0,
            endTime: 0,
        };

        self.options = self.extend( {}, self.options_default, options );

        // Fix wrong option name.
        // Thanks to https://github.com/nk-o/video-worker/issues/13.
        if ( 'undefined' !== typeof self.options.showContols ) {
            self.options.showControls = self.options.showContols;
            delete self.options.showContols;
        }

        // check URL
        self.videoID = self.parseURL( url );

        // init
        if ( self.videoID ) {
            self.ID = ID;
            ID += 1;
            self.loadAPI();
            self.init();
        }
    }

    // Extend like jQuery.extend
    // eslint-disable-next-line class-methods-use-this
    extend( ...args ) {
        const out = args[ 0 ] || {};

        Object.keys( args ).forEach( ( i ) => {
            if ( ! args[ i ] ) {
                return;
            }
            Object.keys( args[ i ] ).forEach( ( key ) => {
                out[ key ] = args[ i ][ key ];
            } );
        } );

        return out;
    }

    parseURL( url ) {
        // parse youtube ID
        function getYoutubeID( ytUrl ) {
            // eslint-disable-next-line no-useless-escape
            const regExp = /.*(?:youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=)([^#\&\?]*).*/;
            const match = ytUrl.match( regExp );
            return match && 11 === match[ 1 ].length ? match[ 1 ] : false;
        }

        // parse vimeo ID
        function getVimeoID( vmUrl ) {
            // eslint-disable-next-line no-useless-escape
            const regExp = /https?:\/\/(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|video\/|)(\d+)(?:$|\/|\?)/;
            const match = vmUrl.match( regExp );
            return match && match[ 3 ] ? match[ 3 ] : false;
        }

        // parse local string
        function getLocalVideos( locUrl ) {
            // eslint-disable-next-line no-useless-escape
            const videoFormats = locUrl.split( /,(?=mp4\:|webm\:|ogv\:|ogg\:)/ );
            const result = {};
            let ready = 0;
            videoFormats.forEach( ( val ) => {
                // eslint-disable-next-line no-useless-escape
                const match = val.match( /^(mp4|webm|ogv|ogg)\:(.*)/ );
                if ( match && match[ 1 ] && match[ 2 ] ) {
                    // eslint-disable-next-line prefer-destructuring
                    result[ 'ogv' === match[ 1 ] ? 'ogg' : match[ 1 ] ] = match[ 2 ];
                    ready = 1;
                }
            } );
            return ready ? result : false;
        }

        const Youtube = getYoutubeID( url );
        const Vimeo = getVimeoID( url );
        const Local = getLocalVideos( url );

        if ( Youtube ) {
            this.type = 'youtube';
            return Youtube;
        }

        if ( Vimeo ) {
            this.type = 'vimeo';
            return Vimeo;
        }

        if ( Local ) {
            this.type = 'local';
            return Local;
        }

        return false;
    }

    isValid() {
        return !! this.videoID;
    }

    // events
    on( name, callback ) {
        this.userEventsList = this.userEventsList || [];

        // add new callback in events list
        ( this.userEventsList[ name ] || ( this.userEventsList[ name ] = [] ) ).push( callback );
    }

    off( name, callback ) {
        if ( ! this.userEventsList || ! this.userEventsList[ name ] ) {
            return;
        }

        if ( ! callback ) {
            delete this.userEventsList[ name ];
        } else {
            this.userEventsList[ name ].forEach( ( val, key ) => {
                if ( val === callback ) {
                    this.userEventsList[ name ][ key ] = false;
                }
            } );
        }
    }

    fire( name, ...args ) {
        if ( this.userEventsList && 'undefined' !== typeof this.userEventsList[ name ] ) {
            this.userEventsList[ name ].forEach( ( val ) => {
                // call with all arguments
                if ( val ) {
                    val.apply( this, args );
                }
            } );
        }
    }

    play( start ) {
        const self = this;
        if ( ! self.player ) {
            return;
        }

        if ( 'youtube' === self.type && self.player.playVideo ) {
            if ( 'undefined' !== typeof start ) {
                self.player.seekTo( start || 0 );
            }
            if ( global.YT.PlayerState.PLAYING !== self.player.getPlayerState() ) {
                self.player.playVideo();
            }
        }

        if ( 'vimeo' === self.type ) {
            if ( 'undefined' !== typeof start ) {
                self.player.setCurrentTime( start );
            }
            self.player.getPaused().then( ( paused ) => {
                if ( paused ) {
                    self.player.play();
                }
            } );
        }

        if ( 'local' === self.type ) {
            if ( 'undefined' !== typeof start ) {
                self.player.currentTime = start;
            }
            if ( self.player.paused ) {
                self.player.play();
            }
        }
    }

    pause() {
        const self = this;
        if ( ! self.player ) {
            return;
        }

        if ( 'youtube' === self.type && self.player.pauseVideo ) {
            if ( global.YT.PlayerState.PLAYING === self.player.getPlayerState() ) {
                self.player.pauseVideo();
            }
        }

        if ( 'vimeo' === self.type ) {
            self.player.getPaused().then( ( paused ) => {
                if ( ! paused ) {
                    self.player.pause();
                }
            } );
        }

        if ( 'local' === self.type ) {
            if ( ! self.player.paused ) {
                self.player.pause();
            }
        }
    }

    mute() {
        const self = this;
        if ( ! self.player ) {
            return;
        }

        if ( 'youtube' === self.type && self.player.mute ) {
            self.player.mute();
        }

        if ( 'vimeo' === self.type && self.player.setVolume ) {
            self.player.setVolume( 0 );
        }

        if ( 'local' === self.type ) {
            self.$video.muted = true;
        }
    }

    unmute() {
        const self = this;
        if ( ! self.player ) {
            return;
        }

        if ( 'youtube' === self.type && self.player.mute ) {
            self.player.unMute();
        }

        if ( 'vimeo' === self.type && self.player.setVolume ) {
            self.player.setVolume( self.options.volume );
        }

        if ( 'local' === self.type ) {
            self.$video.muted = false;
        }
    }

    setVolume( volume = false ) {
        const self = this;
        if ( ! self.player || ! volume ) {
            return;
        }

        if ( 'youtube' === self.type && self.player.setVolume ) {
            self.player.setVolume( volume );
        }

        if ( 'vimeo' === self.type && self.player.setVolume ) {
            self.player.setVolume( volume );
        }

        if ( 'local' === self.type ) {
            self.$video.volume = volume / 100;
        }
    }

    getVolume( callback ) {
        const self = this;
        if ( ! self.player ) {
            callback( false );
            return;
        }

        if ( 'youtube' === self.type && self.player.getVolume ) {
            callback( self.player.getVolume() );
        }

        if ( 'vimeo' === self.type && self.player.getVolume ) {
            self.player.getVolume().then( ( volume ) => {
                callback( volume );
            } );
        }

        if ( 'local' === self.type ) {
            callback( self.$video.volume * 100 );
        }
    }

    getMuted( callback ) {
        const self = this;
        if ( ! self.player ) {
            callback( null );
            return;
        }

        if ( 'youtube' === self.type && self.player.isMuted ) {
            callback( self.player.isMuted() );
        }

        if ( 'vimeo' === self.type && self.player.getVolume ) {
            self.player.getVolume().then( ( volume ) => {
                callback( !! volume );
            } );
        }

        if ( 'local' === self.type ) {
            callback( self.$video.muted );
        }
    }

    getImageURL( callback ) {
        const self = this;

        if ( self.videoImage ) {
            callback( self.videoImage );
            return;
        }

        if ( 'youtube' === self.type ) {
            const availableSizes = [
                'maxresdefault',
                'sddefault',
                'hqdefault',
                '0',
            ];
            let step = 0;

            const tempImg = new Image();
            tempImg.onload = function() {
                // if no thumbnail, youtube add their own image with width = 120px
                if ( 120 !== ( this.naturalWidth || this.width ) || step === availableSizes.length - 1 ) {
                    // ok
                    self.videoImage = `https://img.youtube.com/vi/${ self.videoID }/${ availableSizes[ step ] }.jpg`;
                    callback( self.videoImage );
                } else {
                    // try another size
                    step += 1;
                    this.src = `https://img.youtube.com/vi/${ self.videoID }/${ availableSizes[ step ] }.jpg`;
                }
            };
            tempImg.src = `https://img.youtube.com/vi/${ self.videoID }/${ availableSizes[ step ] }.jpg`;
        }

        if ( 'vimeo' === self.type ) {
            let request = new XMLHttpRequest();
            request.open( 'GET', `https://vimeo.com/api/v2/video/${ self.videoID }.json`, true );
            request.onreadystatechange = function() {
                if ( 4 === this.readyState ) {
                    if ( 200 <= this.status && 400 > this.status ) {
                        // Success!
                        const response = JSON.parse( this.responseText );
                        self.videoImage = response[ 0 ].thumbnail_large;
                        callback( self.videoImage );
                    } else {
                        // Error :(
                    }
                }
            };
            request.send();
            request = null;
        }
    }

    // fallback to the old version.
    getIframe( callback ) {
        this.getVideo( callback );
    }

    getVideo( callback ) {
        const self = this;

        // return generated video block
        if ( self.$video ) {
            callback( self.$video );
            return;
        }

        // generate new video block
        self.onAPIready( () => {
            let hiddenDiv;
            if ( ! self.$video ) {
                hiddenDiv = document.createElement( 'div' );
                hiddenDiv.style.display = 'none';
            }

            // Youtube
            if ( 'youtube' === self.type ) {
                self.playerOptions = {
                    // GDPR Compliance.
                    host: 'https://www.youtube-nocookie.com',
                    videoId: self.videoID,
                    playerVars: {
                        autohide: 1,
                        rel: 0,
                        autoplay: 0,
                        // autoplay enable on mobile devices
                        playsinline: 1,
                    },
                };

                // hide controls
                if ( ! self.options.showControls ) {
                    self.playerOptions.playerVars.iv_load_policy = 3;
                    self.playerOptions.playerVars.modestbranding = 1;
                    self.playerOptions.playerVars.controls = 0;
                    self.playerOptions.playerVars.showinfo = 0;
                    self.playerOptions.playerVars.disablekb = 1;
                }

                // events
                let ytStarted;
                let ytProgressInterval;
                self.playerOptions.events = {
                    onReady( e ) {
                        // mute
                        if ( self.options.mute ) {
                            e.target.mute();
                        } else if ( self.options.volume ) {
                            e.target.setVolume( self.options.volume );
                        }

                        // autoplay
                        if ( self.options.autoplay ) {
                            self.play( self.options.startTime );
                        }
                        self.fire( 'ready', e );

                        // For seamless loops, set the endTime to 0.1 seconds less than the video's duration
                        // https://github.com/nk-o/video-worker/issues/2
                        if ( self.options.loop && ! self.options.endTime ) {
                            const secondsOffset = 0.1;
                            self.options.endTime = self.player.getDuration() - secondsOffset;
                        }

                        // volumechange
                        setInterval( () => {
                            self.getVolume( ( volume ) => {
                                if ( self.options.volume !== volume ) {
                                    self.options.volume = volume;
                                    self.fire( 'volumechange', e );
                                }
                            } );
                        }, 150 );
                    },
                    onStateChange( e ) {
                        // loop
                        if ( self.options.loop && e.data === global.YT.PlayerState.ENDED ) {
                            self.play( self.options.startTime );
                        }
                        if ( ! ytStarted && e.data === global.YT.PlayerState.PLAYING ) {
                            ytStarted = 1;
                            self.fire( 'started', e );
                        }
                        if ( e.data === global.YT.PlayerState.PLAYING ) {
                            self.fire( 'play', e );
                        }
                        if ( e.data === global.YT.PlayerState.PAUSED ) {
                            self.fire( 'pause', e );
                        }
                        if ( e.data === global.YT.PlayerState.ENDED ) {
                            self.fire( 'ended', e );
                        }

                        // progress check
                        if ( e.data === global.YT.PlayerState.PLAYING ) {
                            ytProgressInterval = setInterval( () => {
                                self.fire( 'timeupdate', e );

                                // check for end of video and play again or stop
                                if ( self.options.endTime && self.player.getCurrentTime() >= self.options.endTime ) {
                                    if ( self.options.loop ) {
                                        self.play( self.options.startTime );
                                    } else {
                                        self.pause();
                                    }
                                }
                            }, 150 );
                        } else {
                            clearInterval( ytProgressInterval );
                        }
                    },
                    onError( e ) {
                        self.fire( 'error', e );
                    },
                };

                const firstInit = ! self.$video;
                if ( firstInit ) {
                    const div = document.createElement( 'div' );
                    div.setAttribute( 'id', self.playerID );
                    hiddenDiv.appendChild( div );
                    document.body.appendChild( hiddenDiv );
                }
                self.player = self.player || new global.YT.Player( self.playerID, self.playerOptions );
                if ( firstInit ) {
                    self.$video = document.getElementById( self.playerID );

                    // add accessibility attributes
                    if ( self.options.accessibilityHidden ) {
                        self.$video.setAttribute( 'tabindex', '-1' );
                        self.$video.setAttribute( 'aria-hidden', 'true' );
                    }

                    // get video width and height
                    self.videoWidth = parseInt( self.$video.getAttribute( 'width' ), 10 ) || 1280;
                    self.videoHeight = parseInt( self.$video.getAttribute( 'height' ), 10 ) || 720;
                }
            }

            // Vimeo
            if ( 'vimeo' === self.type ) {
                self.playerOptions = {
                    // GDPR Compliance.
                    dnt: 1,
                    id: self.videoID,
                    autopause: 0,
                    transparent: 0,
                    autoplay: self.options.autoplay ? 1 : 0,
                    loop: self.options.loop ? 1 : 0,
                    muted: self.options.mute ? 1 : 0,
                };

                if ( self.options.volume ) {
                    self.playerOptions.volume = self.options.volume;
                }

                // hide controls
                if ( ! self.options.showControls ) {
                    self.playerOptions.badge = 0;
                    self.playerOptions.byline = 0;
                    self.playerOptions.portrait = 0;
                    self.playerOptions.title = 0;
                    self.playerOptions.background = 1;
                }

                if ( ! self.$video ) {
                    let playerOptionsString = '';
                    Object.keys( self.playerOptions ).forEach( ( key ) => {
                        if ( '' !== playerOptionsString ) {
                            playerOptionsString += '&';
                        }
                        playerOptionsString += `${ key }=${ encodeURIComponent( self.playerOptions[ key ] ) }`;
                    } );

                    // we need to create iframe manually because when we create it using API
                    // js events won't triggers after iframe moved to another place
                    self.$video = document.createElement( 'iframe' );
                    self.$video.setAttribute( 'id', self.playerID );
                    self.$video.setAttribute( 'src', `https://player.vimeo.com/video/${ self.videoID }?${ playerOptionsString }` );
                    self.$video.setAttribute( 'frameborder', '0' );
                    self.$video.setAttribute( 'mozallowfullscreen', '' );
                    self.$video.setAttribute( 'allowfullscreen', '' );
                    self.$video.setAttribute( 'title', 'Vimeo video player' );

                    // add accessibility attributes
                    if ( self.options.accessibilityHidden ) {
                        self.$video.setAttribute( 'tabindex', '-1' );
                        self.$video.setAttribute( 'aria-hidden', 'true' );
                    }

                    hiddenDiv.appendChild( self.$video );
                    document.body.appendChild( hiddenDiv );
                }
                self.player = self.player || new global.Vimeo.Player( self.$video, self.playerOptions );

                // set current time for autoplay
                if ( self.options.startTime && self.options.autoplay ) {
                    self.player.setCurrentTime( self.options.startTime );
                }

                // get video width and height
                self.player.getVideoWidth().then( ( width ) => {
                    self.videoWidth = width || 1280;
                } );
                self.player.getVideoHeight().then( ( height ) => {
                    self.videoHeight = height || 720;
                } );

                // events
                let vmStarted;
                self.player.on( 'timeupdate', ( e ) => {
                    if ( ! vmStarted ) {
                        self.fire( 'started', e );
                        vmStarted = 1;
                    }

                    self.fire( 'timeupdate', e );

                    // check for end of video and play again or stop
                    if ( self.options.endTime ) {
                        if ( self.options.endTime && e.seconds >= self.options.endTime ) {
                            if ( self.options.loop ) {
                                self.play( self.options.startTime );
                            } else {
                                self.pause();
                            }
                        }
                    }
                } );
                self.player.on( 'play', ( e ) => {
                    self.fire( 'play', e );

                    // check for the start time and start with it
                    if ( self.options.startTime && 0 === e.seconds ) {
                        self.play( self.options.startTime );
                    }
                } );
                self.player.on( 'pause', ( e ) => {
                    self.fire( 'pause', e );
                } );
                self.player.on( 'ended', ( e ) => {
                    self.fire( 'ended', e );
                } );
                self.player.on( 'loaded', ( e ) => {
                    self.fire( 'ready', e );
                } );
                self.player.on( 'volumechange', ( e ) => {
                    self.fire( 'volumechange', e );
                } );
                self.player.on( 'error', ( e ) => {
                    self.fire( 'error', e );
                } );
            }

            // Local
            function addSourceToLocal( element, src, type ) {
                const source = document.createElement( 'source' );
                source.src = src;
                source.type = type;
                element.appendChild( source );
            }
            if ( 'local' === self.type ) {
                if ( ! self.$video ) {
                    self.$video = document.createElement( 'video' );

                    // show controls
                    if ( self.options.showControls ) {
                        self.$video.controls = true;
                    }

                    // mute
                    if ( self.options.mute ) {
                        self.$video.muted = true;
                    } else if ( self.$video.volume ) {
                        self.$video.volume = self.options.volume / 100;
                    }

                    // loop
                    if ( self.options.loop ) {
                        self.$video.loop = true;
                    }

                    // autoplay enable on mobile devices
                    self.$video.setAttribute( 'playsinline', '' );
                    self.$video.setAttribute( 'webkit-playsinline', '' );

                    // add accessibility attributes
                    if ( self.options.accessibilityHidden ) {
                        self.$video.setAttribute( 'tabindex', '-1' );
                        self.$video.setAttribute( 'aria-hidden', 'true' );
                    }

                    self.$video.setAttribute( 'id', self.playerID );
                    hiddenDiv.appendChild( self.$video );
                    document.body.appendChild( hiddenDiv );

                    Object.keys( self.videoID ).forEach( ( key ) => {
                        addSourceToLocal( self.$video, self.videoID[ key ], `video/${ key }` );
                    } );
                }

                self.player = self.player || self.$video;

                let locStarted;
                self.player.addEventListener( 'playing', ( e ) => {
                    if ( ! locStarted ) {
                        self.fire( 'started', e );
                    }
                    locStarted = 1;
                } );
                self.player.addEventListener( 'timeupdate', function( e ) {
                    self.fire( 'timeupdate', e );

                    // check for end of video and play again or stop
                    if ( self.options.endTime ) {
                        if ( self.options.endTime && this.currentTime >= self.options.endTime ) {
                            if ( self.options.loop ) {
                                self.play( self.options.startTime );
                            } else {
                                self.pause();
                            }
                        }
                    }
                } );
                self.player.addEventListener( 'play', ( e ) => {
                    self.fire( 'play', e );
                } );
                self.player.addEventListener( 'pause', ( e ) => {
                    self.fire( 'pause', e );
                } );
                self.player.addEventListener( 'ended', ( e ) => {
                    self.fire( 'ended', e );
                } );
                self.player.addEventListener( 'loadedmetadata', function() {
                    // get video width and height
                    self.videoWidth = this.videoWidth || 1280;
                    self.videoHeight = this.videoHeight || 720;

                    self.fire( 'ready' );

                    // autoplay
                    if ( self.options.autoplay ) {
                        self.play( self.options.startTime );
                    }
                } );
                self.player.addEventListener( 'volumechange', ( e ) => {
                    self.getVolume( ( volume ) => {
                        self.options.volume = volume;
                    } );
                    self.fire( 'volumechange', e );
                } );
                self.player.addEventListener( 'error', ( e ) => {
                    self.fire( 'error', e );
                } );
            }
            callback( self.$video );
        } );
    }

    init() {
        const self = this;

        self.playerID = `VideoWorker-${ self.ID }`;
    }

    loadAPI() {
        const self = this;

        if ( YoutubeAPIadded && VimeoAPIadded ) {
            return;
        }

        let src = '';

        // load Youtube API
        if ( 'youtube' === self.type && ! YoutubeAPIadded ) {
            YoutubeAPIadded = 1;
            src = 'https://www.youtube.com/iframe_api';
        }

        // load Vimeo API
        if ( 'vimeo' === self.type && ! VimeoAPIadded ) {
            VimeoAPIadded = 1;

            // Useful when Vimeo API added using RequireJS https://github.com/nk-o/video-worker/pull/7
            if ( 'undefined' !== typeof global.Vimeo ) {
                return;
            }

            src = 'https://player.vimeo.com/api/player.js';
        }

        if ( ! src ) {
            return;
        }

        // add script in head section
        let tag = document.createElement( 'script' );
        let head = document.getElementsByTagName( 'head' )[ 0 ];
        tag.src = src;

        head.appendChild( tag );

        head = null;
        tag = null;
    }

    onAPIready( callback ) {
        const self = this;

        // Youtube
        if ( 'youtube' === self.type ) {
            // Listen for global YT player callback
            if ( ( 'undefined' === typeof global.YT || 0 === global.YT.loaded ) && ! loadingYoutubePlayer ) {
                // Prevents Ready event from being called twice
                loadingYoutubePlayer = 1;

                // Creates deferred so, other players know when to wait.
                window.onYouTubeIframeAPIReady = function() {
                    window.onYouTubeIframeAPIReady = null;
                    loadingYoutubeDefer.resolve( 'done' );
                    callback();
                };
            } else if ( 'object' === typeof global.YT && 1 === global.YT.loaded ) {
                callback();
            } else {
                loadingYoutubeDefer.done( () => {
                    callback();
                } );
            }
        }

        // Vimeo
        if ( 'vimeo' === self.type ) {
            if ( 'undefined' === typeof global.Vimeo && ! loadingVimeoPlayer ) {
                loadingVimeoPlayer = 1;
                const vimeoInterval = setInterval( () => {
                    if ( 'undefined' !== typeof global.Vimeo ) {
                        clearInterval( vimeoInterval );
                        loadingVimeoDefer.resolve( 'done' );
                        callback();
                    }
                }, 20 );
            } else if ( 'undefined' !== typeof global.Vimeo ) {
                callback();
            } else {
                loadingVimeoDefer.done( () => {
                    callback();
                } );
            }
        }

        // Local
        if ( 'local' === self.type ) {
            callback();
        }
    }
}

Youez - 2016 - github.com/yon3zu
LinuXploit