<commit_before>/*global jQuery */
(function($, Freemix) {

    $.fn.freemixPopupButton = function(title, contentFunction, config) {
        return this.each(function() {
            var $this = $(this);
            $this.qtip($.extend(true, {
                content: {
                    text: "

",
                    title: {
                        text: title,
                        button: ""
                    }
                },
                position: {
                    adjust: {
                        screen: true
                    }
                },
                show: 'click',
                hide: 'unfocus',
                style: {
                    name: 'themeroller'
                }
            },
            config));

            var api = $this.qtip("api");
            api.beforeShow = function(event) {
                api.updateContent("

");
                api.updateContent(contentFunction());
            };

        });
    };

    $.fn.freemixThumbnails = function(tags, items, clickHandler) {
        return this.each(function() {
            var list = $("

");
            $.each(tags,function(key, tag) {
                var item = items[tag];
                item.id = key;
                $("" +
                    item.label + "").click(function(e) {
                    clickHandler(item);
                    e.preventDefault();
                }).appendTo(list).wrap("

");
            });
            list.appendTo($(this));
        });
    };
    $.fn.facetContainer = function(properties) {
        return this.each(function() {
            var facetContainer = $.extend({},Freemix.exhibit.facetContainer);
            facetContainer._selector = $(this);
            facetContainer.id = facetContainer.findWidget().attr("id");

            var w = facetContainer.findWidget();
            w.sortable({
               connectWith: ['#build .facet-container'],
               distance: 10,
               handle: '.facet-header',
               items: '.facet'
            });
            w.data("model", facetContainer);
            w.addClass("ui-widget-content").addClass("facet-container");
            w.append("
Add a Facet
");

            w.find(".create-facet-button").freemixPopupButton("Create a facet", function() {
                    return facetContainer.getPopupContent();
                },{
                    style: {width: {min: 430}},
                    position: {target: $(".create-facet-button .ui-icon", facetContainer.findWidget())}
                });
        });
    };

    $.fn.viewContainer = function(properties) {
        return this.each(function() {
            var viewContainer = $.extend({}, Freemix.exhibit.viewContainer);
            viewContainer.id = $(this).attr("id");

            var model = $(this).data("model", viewContainer);
            model.append("

");
            model.append("

");
            model.addClass("view-container");

            var set = model.find(".view-set");
            set.sortable({
                    // axis: "x",
                    tolerance: "pointer",
                    distance: 10,
                    connectWith: ".view-container>ul",
                    cancel: "li.create-view, .bt-wrapper",
                    items: "li:not(.create-view)",
                    receive: function(event, ui) {
                        $(ui.item).data("model")._container = undefined;
                    }
                });
            set.append("

Add a View

");
            set.find(".create-view-button").freemixPopupButton("Create a View", function() {
                    return viewContainer.getPopupContent();
                },{style: {width: {min: 430}}});
        });
    };

    Freemix.getBuilder = function() {
        return $("#build");
    };

    Freemix.getPreview = function() {
        return $("#preview");
    };

    Freemix.syncMetadata = function(model) {
        var metadata = {};
        metadata.canvas = model.canvas;
        metadata.theme = model.theme;

        metadata.facets = {};
        $(".facet-container", Freemix.getBuilder()).each( function() {
            var data = $(this).data("model");
            metadata.facets[$(this).attr("id")] = data.getConfigList();
        });

        metadata.views = {};
        $(".view-container",Freemix.getBuilder()).each( function() {
            var data = $(this).data("model");
            metadata.views[$(this).attr("id")] = data.getConfigList();
        });

        return metadata;
    };

    $.fn.generateExhibitHTML = function(model) {
        return this.each(function() {
            var root = $(this);
            if (model.text) {
                $.each(model.text, function(key, value) {
                    var id = $(this).attr("id");
                    root.find("#" + key).text(value);
                });
            }
            root.find(".view-container").each(function() {
                var id = $(this).attr("id");
                var container = $("

");
                $.each(model.views[id], function() {
                    var view = Freemix.view.createView(this);
                    container.append(view.generateExhibitHTML());
                });

                root.find(".view-container#" + id).append(container);
            });

            $.each(model.facets, function(container, facets) {
                $.each(facets, function() {
                    var facet = Freemix.facet.createFacet(this);
                    root.find(".facet-container#" +container).append(facet.generateExhibitHTML());
                });
            });
        });
    };

    function updatePreview() {
        var metadata = Freemix.syncMetadata(Freemix.profile);
        Freemix.getPreview().empty();
        $("#canvas-template").clone().appendTo(Freemix.getPreview()).generateExhibitHTML(metadata).createExhibit();

    }

    function updateBuilder() {
        $(".view-container", Freemix.getBuilder()).each(function() {
            var container = $(this).data("model");
            container.getSelected().data("model").select();
        });
    }

    function build_db() {
        var profile = Freemix.profile;

        Freemix.property.initializeFreemix();
        // Setup Themeing
        var theme = Freemix.profile.theme;
        $("#theme").themeswitcher({
            loadTheme: Freemix.profile.theme,
            onSelect: function(theme) {
                Freemix.profile.theme = theme;
            }
        });

        var data = Freemix.data || [$("link[rel='exhibit/data']").attr("href")];

        var database = Freemix.exhibit.initializeDatabase(data, function() {
            $(".view-container", Freemix.getBuilder()).viewContainer();
            $.each(profile.views, function(container, views) {
                $.each(views, function() {
                    var view = Freemix.view.createView(this);
                    Freemix.view.getViewContainer(container).addView(view);
                });
            });

            $(".facet-container", Freemix.getBuilder()).facetContainer();
            $.each(profile.facets, function(container, facets) {
                $.each(facets, function() {
                    var facet = Freemix.facet.createFacet(this);
                    Freemix.facet.getFacetContainer(container).addFacet(facet);
                });
            });

            new Freemix.Identify(database);
            togglePreview();
            $("#contents").show();
        });

    }

    function togglePreview() {
        if ($("#preview_toggle").attr("checked")) {
            updatePreview();

            $("#preview_toggle").button("option", "label", "Show Builder");
            $("#build").hide();
            $("#preview").show();
        } else {
            updateBuilder();

            $("#preview_toggle").button("option", "label", "Show Preview");
            $("#preview").hide();
            $("#build").show();
        }

    }

    function setup_ui() {

        $("#preview_toggle").button();
        $("#preview_toggle").change(function() {
            togglePreview();
        });

        $('.ui-state-default').hover(
            function(){
                $(this).addClass('ui-state-hover');
            }, function(){
                $(this).removeClass('ui-state-hover');
            }
        );
    }

    function display() {

        setup_ui();

        var profile_url = $("link[rel='freemix/exhibit_profile']").attr("href");
        $.ajax({
            url: profile_url,
            type: "GET",
            dataType: "json",
            success: function(p) {
                Freemix.profile = p;
                var dp_url = $("link[rel='freemix/dataprofile']").attr("href");
                $.ajax({
                    url: dp_url,
                    type: "GET",
                    dataType: "json",
                    success: function(dp) {
                        Freemix.data_profile=dp;
                        build_db();
                    }
                });
            }

        });

    }

    $(document).ready(function() {display();});

})(window.Freemix.jQuery, window.Freemix);
<commit_msg>toggle theme dropdown on preview<commit_after>/*global jQuery */
(function($, Freemix) {

    $.fn.freemixPopupButton = function(title, contentFunction, config) {
        return this.each(function() {
            var $this = $(this);
            $this.qtip($.extend(true, {
                content: {
                    text: "

",
                    title: {
                        text: title,
                        button: ""
                    }
                },
                position: {
                    adjust: {
                        screen: true
                    }
                },
                show: 'click',
                hide: 'unfocus',
                style: {
                    name: 'themeroller'
                }
            },
            config));

            var api = $this.qtip("api");
            api.beforeShow = function(event) {
                api.updateContent("

");
                api.updateContent(contentFunction());
            };

        });
    };

    $.fn.freemixThumbnails = function(tags, items, clickHandler) {
        return this.each(function() {
            var list = $("

");
            $.each(tags,function(key, tag) {
                var item = items[tag];
                item.id = key;
                $("" +
                    item.label + "").click(function(e) {
                    clickHandler(item);
                    e.preventDefault();
                }).appendTo(list).wrap("

");
            });
            list.appendTo($(this));
        });
    };
    $.fn.facetContainer = function(properties) {
        return this.each(function() {
            var facetContainer = $.extend({},Freemix.exhibit.facetContainer);
            facetContainer._selector = $(this);
            facetContainer.id = facetContainer.findWidget().attr("id");

            var w = facetContainer.findWidget();
            w.sortable({
               connectWith: ['#build .facet-container'],
               distance: 10,
               handle: '.facet-header',
               items: '.facet'
            });
            w.data("model", facetContainer);
            w.addClass("ui-widget-content").addClass("facet-container");
            w.append("
Add a Facet
");

            w.find(".create-facet-button").freemixPopupButton("Create a facet", function() {
                    return facetContainer.getPopupContent();
                },{
                    style: {width: {min: 430}},
                    position: {target: $(".create-facet-button .ui-icon", facetContainer.findWidget())}
                });
        });
    };

    $.fn.viewContainer = function(properties) {
        return this.each(function() {
            var viewContainer = $.extend({}, Freemix.exhibit.viewContainer);
            viewContainer.id = $(this).attr("id");

            var model = $(this).data("model", viewContainer);
            model.append("

");
            model.append("

");
            model.addClass("view-container");

            var set = model.find(".view-set");
            set.sortable({
                    // axis: "x",
                    tolerance: "pointer",
                    distance: 10,
                    connectWith: ".view-container>ul",
                    cancel: "li.create-view, .bt-wrapper",
                    items: "li:not(.create-view)",
                    receive: function(event, ui) {
                        $(ui.item).data("model")._container = undefined;
                    }
                });
            set.append("

Add a View

");
            set.find(".create-view-button").freemixPopupButton("Create a View", function() {
                    return viewContainer.getPopupContent();
                },{style: {width: {min: 430}}});
        });
    };

    Freemix.getBuilder = function() {
        return $("#build");
    };

    Freemix.getPreview = function() {
        return $("#preview");
    };

    Freemix.syncMetadata = function(model) {
        var metadata = {};
        metadata.canvas = model.canvas;
        metadata.theme = model.theme;

        metadata.facets = {};
        $(".facet-container", Freemix.getBuilder()).each( function() {
            var data = $(this).data("model");
            metadata.facets[$(this).attr("id")] = data.getConfigList();
        });

        metadata.views = {};
        $(".view-container",Freemix.getBuilder()).each( function() {
            var data = $(this).data("model");
            metadata.views[$(this).attr("id")] = data.getConfigList();
        });

        return metadata;
    };

    $.fn.generateExhibitHTML = function(model) {
        return this.each(function() {
            var root = $(this);
            if (model.text) {
                $.each(model.text, function(key, value) {
                    var id = $(this).attr("id");
                    root.find("#" + key).text(value);
                });
            }
            root.find(".view-container").each(function() {
                var id = $(this).attr("id");
                var container = $("

");
                $.each(model.views[id], function() {
                    var view = Freemix.view.createView(this);
                    container.append(view.generateExhibitHTML());
                });

                root.find(".view-container#" + id).append(container);
            });

            $.each(model.facets, function(container, facets) {
                $.each(facets, function() {
                    var facet = Freemix.facet.createFacet(this);
                    root.find(".facet-container#" +container).append(facet.generateExhibitHTML());
                });
            });
        });
    };

    function updatePreview() {
        var metadata = Freemix.syncMetadata(Freemix.profile);
        Freemix.getPreview().empty();
        $("#canvas-template").clone().appendTo(Freemix.getPreview()).generateExhibitHTML(metadata).createExhibit();

    }

    function updateBuilder() {
        $(".view-container", Freemix.getBuilder()).each(function() {
            var container = $(this).data("model");
            container.getSelected().data("model").select();
        });
    }

    function build_db() {
        var profile = Freemix.profile;

        Freemix.property.initializeFreemix();
        // Setup Themeing
        var theme = Freemix.profile.theme;
        $("#theme").themeswitcher({
            loadTheme: Freemix.profile.theme,
            onSelect: function(theme) {
                Freemix.profile.theme = theme;
            }
        });

        var data = Freemix.data || [$("link[rel='exhibit/data']").attr("href")];

        var database = Freemix.exhibit.initializeDatabase(data, function() {
            $(".view-container", Freemix.getBuilder()).viewContainer();
            $.each(profile.views, function(container, views) {
                $.each(views, function() {
                    var view = Freemix.view.createView(this);
                    Freemix.view.getViewContainer(container).addView(view);
                });
            });

            $(".facet-container", Freemix.getBuilder()).facetContainer();
            $.each(profile.facets, function(container, facets) {
                $.each(facets, function() {
                    var facet = Freemix.facet.createFacet(this);
                    Freemix.facet.getFacetContainer(container).addFacet(facet);
                });
            });

            new Freemix.Identify(database);
            togglePreview();
            $("#contents").show();
        });

    }

    function togglePreview() {
        if ($("#preview_toggle").attr("checked")) {
            updatePreview();

            $("#preview_toggle").button("option", "label", "Show Builder");
            $("#build, #theme").hide();
            $("#preview").show();
        } else {
            updateBuilder();

            $("#preview_toggle").button("option", "label", "Show Preview");
            $("#preview").hide();
            $("#build,#theme").show();
        }

    }

    function setup_ui() {

        $("#preview_toggle").button();
        $("#preview_toggle").change(function() {
            togglePreview();
        });

        $('.ui-state-default').hover(
            function(){
                $(this).addClass('ui-state-hover');
            }, function(){
                $(this).removeClass('ui-state-hover');
            }
        );
    }

    function display() {

        setup_ui();

        var profile_url = $("link[rel='freemix/exhibit_profile']").attr("href");
        $.ajax({
            url: profile_url,
            type: "GET",
            dataType: "json",
            success: function(p) {
                Freemix.profile = p;
                var dp_url = $("link[rel='freemix/dataprofile']").attr("href");
                $.ajax({
                    url: dp_url,
                    type: "GET",
                    dataType: "json",
                    success: function(dp) {
                        Freemix.data_profile=dp;
                        build_db();
                    }
                });
            }

        });

    }

    $(document).ready(function() {display();});

})(window.Freemix.jQuery, window.Freemix);
<|endoftext|>


<commit_before>function htmlspecialchars_decode(string, quote_style) {
    // http://kevin.vanzonneveld.net
    // +   original by: Mirek Slugen
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // *     example 1: htmlspecialchars_decode("
this -> "
", 'ENT_NOQUOTES');
    // *     returns 1: '
this -> "
'

    string = string.toString();

    // Always encode
    string.replace('/&/g', '&');
    string.replace('/</g', '<');
    string.replace(/>/g, '>');

    // Encode depending on quote_style
    if (quote_style == 'ENT_QUOTES') {
        string.replace('/"/g', '"');
        string.replace('/'/g', '\'');
    } else if (quote_style != 'ENT_NOQUOTES') {
        // All other cases (ENT_COMPAT, default, but not ENT_NOQUOTES)
        string.replace('/"/g', '"');
    }

    return string;
}<commit_msg>Minor improvements to functions<commit_after>function htmlspecialchars_decode(string, quote_style) {
    // http://kevin.vanzonneveld.net
    // +   original by: Mirek Slugen
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // *     example 1: htmlspecialchars_decode("
this -> "
", 'ENT_NOQUOTES');
    // *     returns 1: '
this -> "
'

    string = string.toString();

    // Always encode
    string = string.replace('/&/g', '&');
    string = string.replace('/</g', '<');
    string = string.replace(/>/g, '>');

    // Encode depending on quote_style
    if (quote_style == 'ENT_QUOTES') {
        string = string.replace('/"/g', '"');
        string = string.replace('/'/g', '\'');
    } else if (quote_style != 'ENT_NOQUOTES') {
        // All other cases (ENT_COMPAT, default, but not ENT_NOQUOTES)
        string = string.replace('/"/g', '"');
    }

    return string;
}<|endoftext|>


<commit_before>const encoder = require('./encoder');
const signatures = require('./signatures');
const transform = require('./transform');
const sizes = require('./sizes');

class Writer {

    _setIntegerFrame(name, value) {
        const integer = parseInt(value, 10);

        this.frames.push({
            name,
            value: integer,
            size: sizes.getNumericFrameSize(integer.toString().length)
        });
    }

    _setStringFrame(name, value) {
        const stringValue = value.toString();

        this.frames.push({
            name,
            value: stringValue,
            size: sizes.getStringFrameSize(stringValue.length)
        });
    }

    _setPictureFrame(name, buffer) {
        const mimeType = signatures.getMimeType(new Uint8Array(buffer), 0, 12);

        if (!mimeType) {
            throw new Error('Unknown picture MIME type');
        }
        this.frames.push({
            name,
            value: buffer,
            mimeType,
            size: sizes.getPictureFrameSize(buffer.byteLength, mimeType.length)
        });
    }

    _setLyricsFrame(name, lyrics) {
        const stringValue = lyrics.toString();

        this.frames.push({
            name,
            value: stringValue,
            size: sizes.getLyricsFrameSize(stringValue.length)
        });
    }

    constructor(buffer) {
        if (!buffer || typeof buffer !== 'object' || !('byteLength' in buffer)) {
            throw new Error('First argument should be an instance of ArrayBuffer or Buffer');
        }

        this.arrayBuffer = buffer;
        this.padding = 4096;
        this.frames = [];
        this.url = '';
    }

    setFrame(frameName, frameValue) {
        switch (frameName) {
            case 'TPE1': // song artists
            case 'TCOM': { // song composers
                if (!Array.isArray(frameValue)) {
                    throw new Error(`${frameName} frame value should be an array of strings`);
                }
                const artists = frameValue
                    .map((artist) => artist.toString())
                    .join('/');

                this._setStringFrame(frameName, artists);
                break;
            }
            case 'TCON': { // song genre
                if (!Array.isArray(frameValue)) {
                    throw new Error(`${frameName} frame value should be an array of strings`);
                }
                const genres = frameValue
                    .map((frame) => frame.toString())
                    .join(';');

                this._setStringFrame(frameName, genres);
                break;
            }
            case 'TIT2': // song title
            case 'TALB': // album title
            case 'TPE2': // album artist // spec doesn't say anything about separator, so it is a string, not array
            case 'TRCK': // song number in album: 5 or 5/10
            case 'TPOS': // album disc number: 1 or 1/3
            case 'TPUB': { // label name
                this._setStringFrame(frameName, frameValue);
                break;
            }
            case 'TLEN': // song duration
            case 'TYER': { // album release year
                this._setIntegerFrame(frameName, frameValue);
                break;
            }
            case 'USLT': { // unsychronised lyrics
                this._setLyricsFrame(frameName, frameValue);
                break;
            }
            case 'APIC': { // song cover
                if (typeof frameValue !== 'object' || !('byteLength' in frameValue)) {
                    throw new Error('APIC frame value should be an instance of ArrayBuffer or Buffer');
                }
                this._setPictureFrame(frameName, frameValue);
                break;
            }
            default: {
                throw new Error(`Unsupported frame ${frameName}`);
            }
        }
        return this;
    }

    removeTag() {
        const headerLength = 10;
        const bufferLength = this.arrayBuffer.byteLength;

        if (bufferLength < headerLength) {
            return;
        }
        const firstTenBytes = new Uint8Array(this.arrayBuffer, 0, headerLength);
        const version = firstTenBytes[3];
        const tagSize = transform.uint7ArrayToUint28([
                firstTenBytes[6], firstTenBytes[7],
                firstTenBytes[8], firstTenBytes[9]
            ]) + headerLength;

        if (!signatures.isId3v2(firstTenBytes) || version < 2 || version > 4) {
            return;
        }

        this.arrayBuffer = this.arrayBuffer.slice(tagSize);
    }

    addTag() {
        this.removeTag();

        const BOM = [0xff, 0xfe];
        const headerSize = 10;
        const totalFrameSize = sizes.getTotalFrameSize(this.frames);
        const totalTagSize = headerSize + totalFrameSize + this.padding;
        const buffer = new ArrayBuffer(this.arrayBuffer.byteLength + totalTagSize);
        const bufferWriter = new Uint8Array(buffer);

        let offset = 0;
        let writeBytes = [];

        writeBytes = [0x49, 0x44, 0x33, 3]; // ID3 tag and version
        bufferWriter.set(writeBytes, offset);
        offset += writeBytes.length;

        offset++; // version revision
        offset++; // flags

        writeBytes = transform.uint28ToUint7Array(totalTagSize - headerSize); // tag size (without header)
        bufferWriter.set(writeBytes, offset);
        offset += writeBytes.length;

        this.frames.forEach((frame) => {
            writeBytes = encoder.encodeUtf8Ascii(frame.name); // frame name
            bufferWriter.set(writeBytes, offset);
            offset += writeBytes.length;

            writeBytes = transform.uint32ToUint8Array(frame.size - headerSize); // frame size (without header)
            bufferWriter.set(writeBytes, offset);
            offset += writeBytes.length;

            offset += 2; // flags

            switch (frame.name) {
                case 'TPE1':
                case 'TCOM':
                case 'TCON':
                case 'TIT2':
                case 'TALB':
                case 'TPE2':
                case 'TRCK':
                case 'TPOS':
                case 'TPUB': {
                    writeBytes = [1].concat(BOM); // encoding, BOM
                    bufferWriter.set(writeBytes, offset);
                    offset += writeBytes.length;

                    writeBytes = encoder.encodeUtf16le(frame.value); // frame value
                    bufferWriter.set(writeBytes, offset);
                    offset += writeBytes.length;
                    break;
                }
                case 'USLT': {
                    const langEng = [101, 110, 103];

                    writeBytes = [1].concat(langEng, BOM); // encoding, language, BOM for content descriptor
                    bufferWriter.set(writeBytes, offset);
                    offset += writeBytes.length;

                    offset += 2; // content descriptor

                    writeBytes = BOM; // BOM for frame value
                    bufferWriter.set(writeBytes, offset);
                    offset += writeBytes.length;

                    writeBytes = encoder.encodeUtf16le(frame.value); // frame value
                    bufferWriter.set(writeBytes, offset);
                    offset += writeBytes.length;
                    break;
                }
                case 'TLEN':
                case 'TYER': {
                    offset++; // encoding

                    writeBytes = encoder.encodeUtf8Ascii(frame.value); // frame value
                    bufferWriter.set(writeBytes, offset);
                    offset += writeBytes.length;
                    break;
                }
                case 'APIC': {
                    offset++; // encoding

                    writeBytes = encoder.encodeUtf8Ascii(frame.mimeType); // MIME type
                    bufferWriter.set(writeBytes, offset);
                    offset += writeBytes.length;

                    writeBytes = [0, 3, 0]; // delemiter, pic type, delemiter
                    bufferWriter.set(writeBytes, offset);
                    offset += writeBytes.length;

                    bufferWriter.set(new Uint8Array(frame.value), offset); // picture content
                    offset += frame.value.byteLength;
                    break;
                }
            }
        });

        offset += this.padding; // free space for rewriting
        bufferWriter.set(new Uint8Array(this.arrayBuffer), offset);
        this.arrayBuffer = buffer;
        return buffer;
    }

    getBlob() {
        return new Blob([this.arrayBuffer], {type: 'audio/mpeg'});
    }

    getURL() {
        if (!this.url) {
            this.url = URL.createObjectURL(this.getBlob());
        }
        return this.url;
    }

    revokeURL() {
        URL.revokeObjectURL(this.url);
    }

}

module.exports = Writer;
<commit_msg>arr.join transforms values to strings itself<commit_after>const encoder = require('./encoder');
const signatures = require('./signatures');
const transform = require('./transform');
const sizes = require('./sizes');

class Writer {

    _setIntegerFrame(name, value) {
        const integer = parseInt(value, 10);

        this.frames.push({
            name,
            value: integer,
            size: sizes.getNumericFrameSize(integer.toString().length)
        });
    }

    _setStringFrame(name, value) {
        const stringValue = value.toString();

        this.frames.push({
            name,
            value: stringValue,
            size: sizes.getStringFrameSize(stringValue.length)
        });
    }

    _setPictureFrame(name, buffer) {
        const mimeType = signatures.getMimeType(new Uint8Array(buffer), 0, 12);

        if (!mimeType) {
            throw new Error('Unknown picture MIME type');
        }
        this.frames.push({
            name,
            value: buffer,
            mimeType,
            size: sizes.getPictureFrameSize(buffer.byteLength, mimeType.length)
        });
    }

    _setLyricsFrame(name, lyrics) {
        const stringValue = lyrics.toString();

        this.frames.push({
            name,
            value: stringValue,
            size: sizes.getLyricsFrameSize(stringValue.length)
        });
    }

    constructor(buffer) {
        if (!buffer || typeof buffer !== 'object' || !('byteLength' in buffer)) {
            throw new Error('First argument should be an instance of ArrayBuffer or Buffer');
        }

        this.arrayBuffer = buffer;
        this.padding = 4096;
        this.frames = [];
        this.url = '';
    }

    setFrame(frameName, frameValue) {
        switch (frameName) {
            case 'TPE1': // song artists
            case 'TCOM': { // song composers
                if (!Array.isArray(frameValue)) {
                    throw new Error(`${frameName} frame value should be an array of strings`);
                }
                const artists = frameValue.join('/');

                this._setStringFrame(frameName, artists);
                break;
            }
            case 'TCON': { // song genre
                if (!Array.isArray(frameValue)) {
                    throw new Error(`${frameName} frame value should be an array of strings`);
                }
                const genres = frameValue.join(';');

                this._setStringFrame(frameName, genres);
                break;
            }
            case 'TIT2': // song title
            case 'TALB': // album title
            case 'TPE2': // album artist // spec doesn't say anything about separator, so it is a string, not array
            case 'TRCK': // song number in album: 5 or 5/10
            case 'TPOS': // album disc number: 1 or 1/3
            case 'TPUB': { // label name
                this._setStringFrame(frameName, frameValue);
                break;
            }
            case 'TLEN': // song duration
            case 'TYER': { // album release year
                this._setIntegerFrame(frameName, frameValue);
                break;
            }
            case 'USLT': { // unsychronised lyrics
                this._setLyricsFrame(frameName, frameValue);
                break;
            }
            case 'APIC': { // song cover
                if (typeof frameValue !== 'object' || !('byteLength' in frameValue)) {
                    throw new Error('APIC frame value should be an instance of ArrayBuffer or Buffer');
                }
                this._setPictureFrame(frameName, frameValue);
                break;
            }
            default: {
                throw new Error(`Unsupported frame ${frameName}`);
            }
        }
        return this;
    }

    removeTag() {
        const headerLength = 10;
        const bufferLength = this.arrayBuffer.byteLength;

        if (bufferLength < headerLength) {
            return;
        }
        const firstTenBytes = new Uint8Array(this.arrayBuffer, 0, headerLength);
        const version = firstTenBytes[3];
        const tagSize = transform.uint7ArrayToUint28([
                firstTenBytes[6], firstTenBytes[7],
                firstTenBytes[8], firstTenBytes[9]
            ]) + headerLength;

        if (!signatures.isId3v2(firstTenBytes) || version < 2 || version > 4) {
            return;
        }

        this.arrayBuffer = this.arrayBuffer.slice(tagSize);
    }

    addTag() {
        this.removeTag();

        const BOM = [0xff, 0xfe];
        const headerSize = 10;
        const totalFrameSize = sizes.getTotalFrameSize(this.frames);
        const totalTagSize = headerSize + totalFrameSize + this.padding;
        const buffer = new ArrayBuffer(this.arrayBuffer.byteLength + totalTagSize);
        const bufferWriter = new Uint8Array(buffer);

        let offset = 0;
        let writeBytes = [];

        writeBytes = [0x49, 0x44, 0x33, 3]; // ID3 tag and version
        bufferWriter.set(writeBytes, offset);
        offset += writeBytes.length;

        offset++; // version revision
        offset++; // flags

        writeBytes = transform.uint28ToUint7Array(totalTagSize - headerSize); // tag size (without header)
        bufferWriter.set(writeBytes, offset);
        offset += writeBytes.length;

        this.frames.forEach((frame) => {
            writeBytes = encoder.encodeUtf8Ascii(frame.name); // frame name
            bufferWriter.set(writeBytes, offset);
            offset += writeBytes.length;

            writeBytes = transform.uint32ToUint8Array(frame.size - headerSize); // frame size (without header)
            bufferWriter.set(writeBytes, offset);
            offset += writeBytes.length;

            offset += 2; // flags

            switch (frame.name) {
                case 'TPE1':
                case 'TCOM':
                case 'TCON':
                case 'TIT2':
                case 'TALB':
                case 'TPE2':
                case 'TRCK':
                case 'TPOS':
                case 'TPUB': {
                    writeBytes = [1].concat(BOM); // encoding, BOM
                    bufferWriter.set(writeBytes, offset);
                    offset += writeBytes.length;

                    writeBytes = encoder.encodeUtf16le(frame.value); // frame value
                    bufferWriter.set(writeBytes, offset);
                    offset += writeBytes.length;
                    break;
                }
                case 'USLT': {
                    const langEng = [101, 110, 103];

                    writeBytes = [1].concat(langEng, BOM); // encoding, language, BOM for content descriptor
                    bufferWriter.set(writeBytes, offset);
                    offset += writeBytes.length;

                    offset += 2; // content descriptor

                    writeBytes = BOM; // BOM for frame value
                    bufferWriter.set(writeBytes, offset);
                    offset += writeBytes.length;

                    writeBytes = encoder.encodeUtf16le(frame.value); // frame value
                    bufferWriter.set(writeBytes, offset);
                    offset += writeBytes.length;
                    break;
                }
                case 'TLEN':
                case 'TYER': {
                    offset++; // encoding

                    writeBytes = encoder.encodeUtf8Ascii(frame.value); // frame value
                    bufferWriter.set(writeBytes, offset);
                    offset += writeBytes.length;
                    break;
                }
                case 'APIC': {
                    offset++; // encoding

                    writeBytes = encoder.encodeUtf8Ascii(frame.mimeType); // MIME type
                    bufferWriter.set(writeBytes, offset);
                    offset += writeBytes.length;

                    writeBytes = [0, 3, 0]; // delemiter, pic type, delemiter
                    bufferWriter.set(writeBytes, offset);
                    offset += writeBytes.length;

                    bufferWriter.set(new Uint8Array(frame.value), offset); // picture content
                    offset += frame.value.byteLength;
                    break;
                }
            }
        });

        offset += this.padding; // free space for rewriting
        bufferWriter.set(new Uint8Array(this.arrayBuffer), offset);
        this.arrayBuffer = buffer;
        return buffer;
    }

    getBlob() {
        return new Blob([this.arrayBuffer], {type: 'audio/mpeg'});
    }

    getURL() {
        if (!this.url) {
            this.url = URL.createObjectURL(this.getBlob());
        }
        return this.url;
    }

    revokeURL() {
        URL.revokeObjectURL(this.url);
    }

}

module.exports = Writer;
<|endoftext|>


<commit_before>var _ = require('lodash');
var wrapKRLType = require('../wrapKRLType');

var returnFalse = function(e, loc){
  return e('return', e('false', loc), loc);
};

module.exports = function(ast, comp, e){
  //FYI the graph allready vetted the domain and type

  var fn_body = [];

  if((_.size(ast.attributes) + _.size(ast.setting)) > 0){
    fn_body.push(e('var', e('id', 'matches'), e('arr', [])));
    fn_body.push(e('var', e('id', 'm')));
  }
  _.each(ast.attributes, function(a){
    var readAttr = e('||', e('get',
      e('id', 'ctx.event.attrs', a.key.loc),
      e('str', a.key.value, a.key.loc),
      a.key.loc
    ), e('str', '', a.key.loc), a.key.loc);

    var regex_exec = e('.',
        comp(a.value),
        e('id', 'exec', a.value.loc), a.value.loc);

    var m = e('id', 'm', a.loc);

    fn_body.push(e(';', e('=', m,
            e('call', regex_exec, [readAttr]),
            a.loc), a.loc));

    fn_body.push(e('if', e('!', m, a.loc), returnFalse(e, a.loc), a.loc));

    fn_body.push(e('if',
          e('>', e('.', m, e('id', 'length', a.loc), a.loc), e('num', 1, a.loc), a.loc),
          e(';',
          e('call', e('id', 'matches.push', a.loc), [
            e('get', m, e('num', 1, a.loc), a.loc)
          ], a.loc), a.loc), a.loc));
  });

  //TODO ast.where

  _.each(ast.setting, function(s){
    fn_body.push(e(';',
      e('call', e('id', 'ctx.scope.set', s.loc), [
        e('str', s.value, s.loc),
        wrapKRLType(e, 'String', [
          e('get', e('id', 'matches', s.loc), e('num', 0, s.loc), s.loc)
        ])
      ], s.loc), s.loc));
  });

  fn_body.push(e('return', e(true)));

  return e('fn', ['ctx'], fn_body);
};
<commit_msg>starting ctx.krl.RegExp<commit_after>var _ = require('lodash');
var wrapKRLType = require('../wrapKRLType');

module.exports = function(ast, comp, e){
  //FYI the graph allready vetted the domain and type

  var fn_body = [];

  if(!_.isEmpty(ast.attributes)){
    fn_body.push(e('var', 'matches',
            e('call', e('id', 'ctx.event.attrs.getMatches'), [
              e('array', _.map(ast.attributes, function(a){
                return comp(a.value);
              }))
            ])));
    fn_body.push(e('if', e('!', e('id', 'matches')), e('return', e('false'))));
  }

  //TODO ast.where

  _.each(ast.setting, function(s){
    fn_body.push(e(';',
      e('call', e('id', 'ctx.scope.set', s.loc), [
        e('str', s.value, s.loc),
        wrapKRLType(e, 'String', [
          e('get', e('id', 'matches', s.loc), e('num', 0, s.loc), s.loc)
        ])
      ], s.loc), s.loc));
  });

  fn_body.push(e('return', e(true)));

  return e('fn', ['ctx'], fn_body);
};
<|endoftext|>


<commit_before>import React from 'react';
import SimpleCalendar from "../../docs/src/app/components/containers/components/SimpleCalendar";

// jsdom for eventharness**
import jsdom from 'jsdom';
global.document = jsdom.jsdom('');
global.window = document.defaultView;
document.body.addEventListener('o.initCalendar', e => new Calendar(e.detail))
// *************************

function Calendar(props) {
  return (
     <SimpleCalendar locale={props.params.locale}/>
   );
}

export default Calendar;
<commit_msg>fix: test push<commit_after>import React from 'react';
import SimpleCalendar from "../../docs/src/app/components/containers/components/SimpleCalendar";

// jsdom for eventharness**
import jsdom from 'jsdom';
global.document = jsdom.jsdom('');
global.window = document.defaultView;
document.body.addEventListener('o.initCalendar', e => new Calendar(e.detail))
// *************************

function Calendar(props) {
  return (
     <SimpleCalendar locale={props.params.locale}/>
   );
}

export default Calendar;
<|endoftext|>


<commit_before>/**
 * @fileOverview Funnel Chart
 */
import PropTypes from 'prop-types';
import generateCategoricalChart from './generateCategoricalChart';
import Funnel from '../component/Funnel';

export default generateCategoricalChart({
  chartName: 'FunnelChart',
  GraphicalChild: Funnel,
  eventType: 'item',
  axisComponents:[],
  defaultProps: {
    layout: 'centric',
  },
  propTypes: {
    layout: PropTypes.oneOf(['centric']),
  }
});
<commit_msg>fix: code style<commit_after>/**
 * @fileOverview Funnel Chart
 */
import PropTypes from 'prop-types';
import generateCategoricalChart from './generateCategoricalChart';
import Funnel from '../component/Funnel';

export default generateCategoricalChart({
  chartName: 'FunnelChart',
  GraphicalChild: Funnel,
  eventType: 'item',
  axisComponents: [],
  defaultProps: {
    layout: 'centric',
  },
  propTypes: {
    layout: PropTypes.oneOf(['centric']),
  }
});
<|endoftext|>


<commit_before>
var path = require('path');
var fs = require('fs');

var assert = require('assert');
var rewire = require('rewire');

var stripJsonComments = require('strip-json-comments');
var HTMLHint = require('htmlhint').HTMLHint;

// add base rules
function getConfig() {
  var configPath = path.join(__dirname, '..', '..', '.htmlhintrc');
  if (fs.existsSync(configPath)) {
    var config = fs.readFileSync(configPath, 'utf-8');
    var ruleset = JSON.parse(stripJsonComments(config));
    return ruleset;
  }
}
var ruleset = getConfig();

// add custom rules
require('../src/htmlhint_custom');

describe('--attr-value-single-quotes', function() {
  describe('input is valid', function() {
    it('should have no errors', function (done) {
      var input = "";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 0);
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --attr-value-single-quotes', function (done) {
      var input = '';
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--attr-value-single-quotes");
      done();
    });
  });
});

describe('--no-tag-self-close', function() {
  describe('input is valid', function() {
    it('should have no errors', function (done) {
      var input = "
";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 0);
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --no-tag-self-close', function (done) {
      var input = "
";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--no-tag-self-close");
      done();
    });
  });
});

describe('--vue-component-conventions', function() {
  describe('input is valid', function() {
    it('should have no errors', function (done) {
      var input = "<template>\n\n  html\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 0);
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n  html\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n\nhtml\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "\n<template>\n\n  html\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n\n  html\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n\n  html\n\n</template>\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n\n  html\n\n</template>\n\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n\n  html\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n\n  html\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
});
<commit_msg>adding a few more tests for more coverage<commit_after>
var path = require('path');
var fs = require('fs');

var assert = require('assert');
var rewire = require('rewire');

var stripJsonComments = require('strip-json-comments');
var HTMLHint = require('htmlhint').HTMLHint;

// add base rules
function getConfig() {
  var configPath = path.join(__dirname, '..', '..', '.htmlhintrc');
  if (fs.existsSync(configPath)) {
    var config = fs.readFileSync(configPath, 'utf-8');
    var ruleset = JSON.parse(stripJsonComments(config));
    return ruleset;
  }
}
var ruleset = getConfig();

// add custom rules
require('../src/htmlhint_custom');

describe('--attr-value-single-quotes', function() {
  describe('input is valid', function() {
    it('should have no errors', function (done) {
      var input = "";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 0);
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --attr-value-single-quotes', function (done) {
      var input = '';
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--attr-value-single-quotes");
      done();
    });
  });
});

describe('--no-tag-self-close', function() {
  describe('input is valid', function() {
    it('should have no errors', function (done) {
      var input = "
";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 0);
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --no-tag-self-close', function (done) {
      var input = "
";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--no-tag-self-close");
      done();
    });
  });
});

describe('--vue-component-conventions', function() {
  describe('input is valid', function() {
    it('should have no errors', function (done) {
      var input = "<template>\n\n  html\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 0);
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n  html\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n\nhtml\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "\n<template>\n\n  html\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n\n  html\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n\n  html\n\n</template>\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n\n  html\n\n</template>\n\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n\n  html\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n\n  html\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n\n  html\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n\n  html\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is valid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n\n  html\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 0);
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n\n  html\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n\n  html\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n\n  html\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
  describe('input is invalid', function() {
    it('should have one error with rule id: --vue-component-conventions', function (done) {
      var input = "<template>\n\n\n  html\n\n</template>\n\n\n\n\n\n";
      var output = HTMLHint.verify(input, ruleset);
      assert(output.length === 1 && output[0].rule.id === "--vue-component-conventions");
      done();
    });
  });
});
<|endoftext|>


<commit_before>/*
 * jQuery Search as you Type plugin
 *
 * Website: http://drawne.com
 */

(function($) {
	$.fn.sayt	=	function(options) {

	// Keeps track of the width of the input box in case user resizes browser
	var resizeTimer;
	$(window).resize(function() {
	  clearTimeout(resizeTimer);
	  resizeTimer = setTimeout(function() {
	    var getInputWidth = $(this).outerWidth()-2;
	  }, 200);
	});

		// Default options
		var defaults = {
			inputId: '%-sayt',
			classPrefix: 'sayt-',
			noResultsText: 'No results.',
			inputWidth: getInputWidth,
			minChars: 2,
			showSectionHeadings: false,
			showDescription: true,
			showImages: true,
			includeCSS: true,
			seeAllLink: false
		};

		var options = $.extend(defaults, options);

		//Include default stylesheet
		if(options.includeCSS) {
			$('head').append('<link rel="stylesheet" href="sayt.css" type="text/css" />');
		}

		options.inputId = options.inputId.replace('%', $(this).attr('id'));

		var prevQuery = '';
		var data;

		$(this).attr('autocomplete', 'off');
		$(this).after('

');
		var input = $(this);
		var boxObj = $('#'+options.inputId);

		//Actual function with keyup
		var timeout = null;
		var currentRequest = null;
		var requestCount = 0;
		input.keyup(function(event) {

			//only trigger on keystokes
			if (event.which != 13 && event.which != 9 && event.which != 37 && event.which != 38 && event.which != 39 && event.which != 40){

				var query = input.val();
				if(query == "" || query.length < options.minChars) {
					//do nothing if min value isn't met
					boxObj.fadeOut(200);
				}else{

					prevQuery = query;

					//Loading animation, great for adding a whirlywiggy
					input.addClass(options.classPrefix+'thinking');

					currentRequest = $.ajax({
						url: options.src+"?query="+query+"&callback=?",
						crossDomain: true,
						contentType: "application/json",
						dataType: "jsonp",
						data: {
							jsonp: "callback"
						},
						requestCount: ++requestCount,
					    success: function(data) {
							 if (requestCount !== this.requestCount) return;

							 	var output = "";

								var resultsExist = false;
								$.each(data, function(i, section) {
									if (section['data'].length > 0)
									{
										resultsExist = true;
									}
								});

								if(!resultsExist) {

								}else{

								 	$.each(data, function(i, section) {

								 		var num = section['section']['num'];

								 		if (num != 0){
								 		var limit = section['section']['limit'];
								 		var i = 0;

								 		if (options.showSectionHeadings && section['section']['title'] != undefined) {
								 			output += '
';
								 			output += section['section']['title'];
								 			output += '
';
								 		}

								 		$.each(section['data'], function (ii, item) {

								 				if (i < limit) {
									 				var haslink = (item['url'] != undefined || item['onclick'] != undefined ) ? true : false;

									 				var link = (haslink == true ) ? "<a " : "";
									 				if (haslink == true ){
										 				link = ""

									 				}else{
										 				link = '
'
									 				}

										 			var linkclose = (haslink == true ) ? "" : "
";

										 			output += '
' + link;
										 			output += '

'
										 			output += (item['image'] != undefined && options.showImages) ? '	' : '';
										 			output += '';
										 			output += '
';
										 			output += (item['title'] != undefined) ? '' + item['title'] + '
\n' : '';
										 			output += (item['description'] != undefined) ? '' + item['description'] + '' : '';
										 			output += '
';
										 			output += '	';
										 			output += '

';
										 			output += linkclose;
										 			output += '
';

									 			}

									 			i++;
								 		})

								 		}

								 	})

								 	//See all link, basically just submits to the form #sticks&stones
								 	if(options.seeAllLink) {

												output += '
';
												output += '

';
												output += '';
												output += '
';
												output += 'See All Results...
\n';
												output += '
'+"\n";
												output += '	';
												output += '

';
												output += '
'+"\n";

								 	}

								 	boxObj.html(output);

								 	boxObj.css('width', options.inputWidth);
								 	boxObj.css('position', 'absolute');
									boxObj.css('top', input.offset().top+input.outerHeight());
									boxObj.css('left', input.offset().left);

									//remove thinking class
									input.removeClass(options.classPrefix+'thinking');

								 	boxObj.fadeIn(200);

									// use keyboard for selecting results
									var current_index = -1,
										$number_list = $('.'+options.classPrefix+'box'),
										$options = $number_list.find('.'+options.classPrefix+'result'),
										items_total = $options.length;

									$options.hover(function() {
										$options.removeClass('selected');
										$(this).addClass('hover selected');
										current_index = $options.index(this);
									}, function() {
										$(this).removeClass('hover selected');
										current_index = -1;
									});

									input.bind('keyup', function(e) {
										if (e.which == 40) {
											if (current_index + 1 < items_total) {
												current_index++;
												change_selection();
											}
											input.val(input.val());
											e.preventDefault();
										} else if (e.which == 38) {
											if (current_index > 0) {
												current_index--;
												change_selection();
											}
											input.val(input.val());
											e.preventDefault();
										} else if (e.which == 13) {
											if(!$options.eq(current_index).hasClass('hover') && current_index > -1){
											window.location = $options.eq(current_index).find('a').attr("href");
											e.preventDefault();
											};
										}
									});

									function change_selection()
									{
										$options.removeClass('selected');
										$options.removeClass('hover');
										$options.eq(current_index).addClass('selected');
									}

							 	}

								return;
					    },
					    error: function(xhr, textStatus, errorThrown) {
						},

						beforeSend : function()
							{
								if(currentRequest != null)
								{
									currentRequest.abort()
									//cannont use in a JSONP request
								}
							}
					});

				}
			};
		});

		//show last results if input focused again
		input.focus(function(){
			if (input.val() == prevQuery && input.val() != '') {
				boxObj.fadeIn(200);
			}
		});

		//hide search when input if unselected
		input.blur(function() {
			boxObj.fadeOut(0);
		});

	}
})(jQuery);<commit_msg>bugfix<commit_after>/*
 * jQuery Search as you Type plugin
 *
 * Website: http://drawne.com
 */

(function($) {
	$.fn.sayt	=	function(options) {

	var getInputWidth = $(this).outerWidth()-2;
	// Keeps track of the width of the input box in case user resizes browser
	var resizeTimer;
	$(window).resize(function() {
	  clearTimeout(resizeTimer);
	  resizeTimer = setTimeout(function() {
	    var getInputWidth = $(this).outerWidth()-2;
	  }, 200);
	});

		// Default options
		var defaults = {
			inputId: '%-sayt',
			classPrefix: 'sayt-',
			noResultsText: 'No results.',
			inputWidth: getInputWidth,
			minChars: 2,
			showSectionHeadings: false,
			showDescription: true,
			showImages: true,
			includeCSS: true,
			seeAllLink: false
		};

		var options = $.extend(defaults, options);

		//Include default stylesheet
		if(options.includeCSS) {
			$('head').append('<link rel="stylesheet" href="sayt.css" type="text/css" />');
		}

		options.inputId = options.inputId.replace('%', $(this).attr('id'));

		var prevQuery = '';
		var data;

		$(this).attr('autocomplete', 'off');
		$(this).after('

');
		var input = $(this);
		var boxObj = $('#'+options.inputId);

		//Actual function with keyup
		var timeout = null;
		var currentRequest = null;
		var requestCount = 0;
		input.keyup(function(event) {

			//only trigger on keystokes
			if (event.which != 13 && event.which != 9 && event.which != 37 && event.which != 38 && event.which != 39 && event.which != 40){

				var query = input.val();
				if(query == "" || query.length < options.minChars) {
					//do nothing if min value isn't met
					boxObj.fadeOut(200);
				}else{

					prevQuery = query;

					//Loading animation, great for adding a whirlywiggy
					input.addClass(options.classPrefix+'thinking');

					currentRequest = $.ajax({
						url: options.src+"?query="+query+"&callback=?",
						crossDomain: true,
						contentType: "application/json",
						dataType: "jsonp",
						data: {
							jsonp: "callback"
						},
						requestCount: ++requestCount,
					    success: function(data) {
							 if (requestCount !== this.requestCount) return;

							 	var output = "";

								var resultsExist = false;
								$.each(data, function(i, section) {
									if (section['data'].length > 0)
									{
										resultsExist = true;
									}
								});

								if(!resultsExist) {

								}else{

								 	$.each(data, function(i, section) {

								 		var num = section['section']['num'];

								 		if (num != 0){
								 		var limit = section['section']['limit'];
								 		var i = 0;

								 		if (options.showSectionHeadings && section['section']['title'] != undefined) {
								 			output += '
';
								 			output += section['section']['title'];
								 			output += '
';
								 		}

								 		$.each(section['data'], function (ii, item) {

								 				if (i < limit) {
									 				var haslink = (item['url'] != undefined || item['onclick'] != undefined ) ? true : false;

									 				var link = (haslink == true ) ? "<a " : "";
									 				if (haslink == true ){
										 				link = ""

									 				}else{
										 				link = '
'
									 				}

										 			var linkclose = (haslink == true ) ? "" : "
";

										 			output += '
' + link;
										 			output += '

'
										 			output += (item['image'] != undefined && options.showImages) ? '	' : '';
										 			output += '';
										 			output += '
';
										 			output += (item['title'] != undefined) ? '' + item['title'] + '
\n' : '';
										 			output += (item['description'] != undefined) ? '' + item['description'] + '' : '';
										 			output += '
';
										 			output += '	';
										 			output += '

';
										 			output += linkclose;
										 			output += '
';

									 			}

									 			i++;
								 		})

								 		}

								 	})

								 	//See all link, basically just submits to the form #sticks&stones
								 	if(options.seeAllLink) {

												output += '
';
												output += '

';
												output += '';
												output += '
';
												output += 'See All Results...
\n';
												output += '
'+"\n";
												output += '	';
												output += '

';
												output += '
'+"\n";

								 	}

								 	boxObj.html(output);

								 	boxObj.css('width', options.inputWidth);
								 	boxObj.css('position', 'absolute');
									boxObj.css('top', input.offset().top+input.outerHeight());
									boxObj.css('left', input.offset().left);

									//remove thinking class
									input.removeClass(options.classPrefix+'thinking');

								 	boxObj.fadeIn(200);

									// use keyboard for selecting results
									var current_index = -1,
										$number_list = $('.'+options.classPrefix+'box'),
										$options = $number_list.find('.'+options.classPrefix+'result'),
										items_total = $options.length;

									$options.hover(function() {
										$options.removeClass('selected');
										$(this).addClass('hover selected');
										current_index = $options.index(this);
									}, function() {
										$(this).removeClass('hover selected');
										current_index = -1;
									});

									input.bind('keyup', function(e) {
										if (e.which == 40) {
											if (current_index + 1 < items_total) {
												current_index++;
												change_selection();
											}
											input.val(input.val());
											e.preventDefault();
										} else if (e.which == 38) {
											if (current_index > 0) {
												current_index--;
												change_selection();
											}
											input.val(input.val());
											e.preventDefault();
										} else if (e.which == 13) {
											if(!$options.eq(current_index).hasClass('hover') && current_index > -1){
											window.location = $options.eq(current_index).find('a').attr("href");
											e.preventDefault();
											};
										}
									});

									function change_selection()
									{
										$options.removeClass('selected');
										$options.removeClass('hover');
										$options.eq(current_index).addClass('selected');
									}

							 	}

								return;
					    },
					    error: function(xhr, textStatus, errorThrown) {
						},

						beforeSend : function()
							{
								if(currentRequest != null)
								{
									currentRequest.abort()
									//cannont use in a JSONP request
								}
							}
					});

				}
			};
		});

		//show last results if input focused again
		input.focus(function(){
			if (input.val() == prevQuery && input.val() != '') {
				boxObj.fadeIn(200);
			}
		});

		//hide search when input if unselected
		input.blur(function() {
			boxObj.fadeOut(0);
		});

	}
})(jQuery);<|endoftext|>


<commit_before>$(document).ready(function(){
	$('a[href^="#"]').on('click',function (e) {
	    e.preventDefault();

	    var target = this.hash,
	    $target = $(target);

	    $('html, body').stop().animate({
	        'scrollTop': $target.offset().top
	    }, 900, 'swing', function () {
	        window.location.hash = target;
	    });
	});
});
<commit_msg>re-factored code<commit_after>$(document).ready(function(){
	$('a[href^="#"]').on('click',function () {

	    var target = this.hash,
	    $target = $(target);

	    $('html, body').stop().animate({
	        'scrollTop': $target.offset().top
	    }, 900, 'swing', function () {
	        window.location.hash = target;
	    });

	    return false;
	});
});
<|endoftext|>


<commit_before>/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import * as zrUtil from 'zrender/src/core/util';
import * as graphic from '../../util/graphic';
import ChartView from '../../view/Chart';

/**
 * @param {module:echarts/model/Series} seriesModel
 * @param {boolean} hasAnimation
 * @inner
 */
function updateDataSelected(uid, seriesModel, hasAnimation, api) {
    var data = seriesModel.getData();
    var dataIndex = this.dataIndex;
    var name = data.getName(dataIndex);
    var selectedOffset = seriesModel.get('selectedOffset');

    api.dispatchAction({
        type: 'pieToggleSelect',
        from: uid,
        name: name,
        seriesId: seriesModel.id
    });

    data.each(function (idx) {
        toggleItemSelected(
            data.getItemGraphicEl(idx),
            data.getItemLayout(idx),
            seriesModel.isSelected(data.getName(idx)),
            selectedOffset,
            hasAnimation
        );
    });
}

/**
 * @param {module:zrender/graphic/Sector} el
 * @param {Object} layout
 * @param {boolean} isSelected
 * @param {number} selectedOffset
 * @param {boolean} hasAnimation
 * @inner
 */
function toggleItemSelected(el, layout, isSelected, selectedOffset, hasAnimation) {
    var midAngle = (layout.startAngle + layout.endAngle) / 2;

    var dx = Math.cos(midAngle);
    var dy = Math.sin(midAngle);

    var offset = isSelected ? selectedOffset : 0;
    var position = [dx * offset, dy * offset];

    hasAnimation
        // animateTo will stop revious animation like update transition
        ? el.animate()
        .when(200, {
            position: position
        })
        .start('bounceOut') :
        el.attr('position', position);
}

/**
 * Piece of pie including Sector, Label, LabelLine
 * @constructor
 * @extends {module:zrender/graphic/Group}
 */
function PiePiece(data, idx) {

    graphic.Group.call(this);

    var sector = new graphic.Sector({
        z2: 2
    });
    var polyline = new graphic.Polyline();
    var text = new graphic.Text();
    this.add(sector);
    this.add(polyline);
    this.add(text);

    this.updateData(data, idx, true);

    // Hover to change label and labelLine
    function onEmphasis() {
        polyline.ignore = polyline.hoverIgnore;
        text.ignore = text.hoverIgnore;
    }
    function onNormal() {
        polyline.ignore = polyline.normalIgnore;
        text.ignore = text.normalIgnore;
    }
    this.on('emphasis', onEmphasis)
        .on('normal', onNormal)
        .on('mouseover', onEmphasis)
        .on('mouseout', onNormal);
}

var piePieceProto = PiePiece.prototype;

piePieceProto.updateData = function (data, idx, firstCreate) {

    var sector = this.childAt(0);

    var seriesModel = data.hostModel;
    var itemModel = data.getItemModel(idx);
    var layout = data.getItemLayout(idx);
    var sectorShape = zrUtil.extend({}, layout);
    sectorShape.label = null;

    if (firstCreate) {
        sector.setShape(sectorShape);

        var animationType = seriesModel.getShallow('animationType');
        if (animationType === 'scale') {
            sector.shape.r = layout.r0;
            graphic.initProps(sector, {
                shape: {
                    r: layout.r
                }
            }, seriesModel, idx);
        }
        // Expansion
        else {
            sector.shape.endAngle = layout.startAngle;
            graphic.updateProps(sector, {
                shape: {
                    endAngle: layout.endAngle
                }
            }, seriesModel, idx);
        }

    }
    else {
        graphic.updateProps(sector, {
            shape: sectorShape
        }, seriesModel, idx);
    }

    // Update common style
    var visualColor = data.getItemVisual(idx, 'color');

    sector.useStyle(
        zrUtil.defaults(
            {
                lineJoin: 'bevel',
                fill: visualColor
            },
            itemModel.getModel('itemStyle').getItemStyle()
        )
    );
    sector.hoverStyle = itemModel.getModel('emphasis.itemStyle').getItemStyle();

    var cursorStyle = itemModel.getShallow('cursor');
    cursorStyle && sector.attr('cursor', cursorStyle);

    // Toggle selected
    toggleItemSelected(
        this,
        data.getItemLayout(idx),
        seriesModel.isSelected(null, idx),
        seriesModel.get('selectedOffset'),
        seriesModel.get('animation')
    );

    function onEmphasis() {
        // Sector may has animation of updating data. Force to move to the last frame
        // Or it may stopped on the wrong shape
        sector.stopAnimation(true);
        sector.animateTo({
            shape: {
                r: layout.r + seriesModel.get('hoverOffset')
            }
        }, 300, 'elasticOut');
    }
    function onNormal() {
        sector.stopAnimation(true);
        sector.animateTo({
            shape: {
                r: layout.r
            }
        }, 300, 'elasticOut');
    }
    sector.off('mouseover').off('mouseout').off('emphasis').off('normal');
    if (itemModel.get('hoverAnimation') && seriesModel.isAnimationEnabled()) {
        sector
            .on('mouseover', onEmphasis)
            .on('mouseout', onNormal)
            .on('emphasis', onEmphasis)
            .on('normal', onNormal);
    }

    this._updateLabel(data, idx);

    graphic.setHoverStyle(this);
};

piePieceProto._getFilterIgnore = function(data, idx) {
    var seriesModel = data.hostModel;
    var itemModel = data.getItemModel(idx);
    var valueDim = data.mapDimension('value');
    var sum = data.getSum(valueDim);
    var filterValue = seriesModel.getModel('filterValue');
    var filterIgnore = false;
    if (sum * filterValue.option > itemModel.option.value) {
        filterIgnore = true;
    }
    return filterIgnore;
}

piePieceProto._updateLabel = function(data, idx) {

    var labelLine = this.childAt(1);
    var labelText = this.childAt(2);

    var seriesModel = data.hostModel;
    var itemModel = data.getItemModel(idx);
    var layout = data.getItemLayout(idx);
    var labelLayout = layout.label;
    var visualColor = data.getItemVisual(idx, 'color');
    var filterIgnore = this._getFilterIgnore(data, idx);

    graphic.updateProps(labelLine, {
        shape: {
            points: labelLayout.linePoints || [
                [labelLayout.x, labelLayout.y], [labelLayout.x, labelLayout.y], [labelLayout.x, labelLayout.y]
            ]
        }
    }, seriesModel, idx);

    graphic.updateProps(labelText, {
        style: {
            x: labelLayout.x,
            y: labelLayout.y
        }
    }, seriesModel, idx);
    labelText.attr({
        rotation: labelLayout.rotation,
        origin: [labelLayout.x, labelLayout.y],
        z2: 10
    });

    var labelModel = itemModel.getModel('label');
    var labelHoverModel = itemModel.getModel('emphasis.label');
    var labelLineModel = itemModel.getModel('labelLine');
    var labelLineHoverModel = itemModel.getModel('emphasis.labelLine');
    var visualColor = data.getItemVisual(idx, 'color');

    graphic.setLabelStyle(
        labelText.style, labelText.hoverStyle = {}, labelModel, labelHoverModel,
        {
            labelFetcher: data.hostModel,
            labelDataIndex: idx,
            defaultText: data.getName(idx),
            autoColor: visualColor,
            useInsideStyle: !!labelLayout.inside
        },
        {
            textAlign: labelLayout.textAlign,
            textVerticalAlign: labelLayout.verticalAlign,
            opacity: data.getItemVisual(idx, 'opacity')
        }
    );

    labelText.ignore = labelText.normalIgnore = !labelModel.get('show') || filterIgnore;
    labelText.hoverIgnore = !labelHoverModel.get('show') || filterIgnore;

    labelLine.ignore = labelLine.normalIgnore = !labelLineModel.get('show') || filterIgnore;
    labelLine.hoverIgnore = !labelLineHoverModel.get('show') || filterIgnore;

    // Default use item visual color
    labelLine.setStyle({
        stroke: visualColor,
        opacity: data.getItemVisual(idx, 'opacity')
    });
    labelLine.setStyle(labelLineModel.getModel('lineStyle').getLineStyle());

    labelLine.hoverStyle = labelLineHoverModel.getModel('lineStyle').getLineStyle();

    var smooth = labelLineModel.get('smooth');
    if (smooth && smooth === true) {
        smooth = 0.4;
    }
    labelLine.setShape({
        smooth: smooth
    });
};

zrUtil.inherits(PiePiece, graphic.Group);

// Pie view
var PieView = ChartView.extend({

    type: 'pie',

    init: function () {
        var sectorGroup = new graphic.Group();
        this._sectorGroup = sectorGroup;
    },

    render: function (seriesModel, ecModel, api, payload) {
        if (payload && (payload.from === this.uid)) {
            return;
        }

        var data = seriesModel.getData();
        var oldData = this._data;
        var group = this.group;

        var hasAnimation = ecModel.get('animation');
        var isFirstRender = !oldData;
        var animationType = seriesModel.get('animationType');

        var onSectorClick = zrUtil.curry(
            updateDataSelected, this.uid, seriesModel, hasAnimation, api
        );

        var selectedMode = seriesModel.get('selectedMode');

        data.diff(oldData)
            .add(function (idx) {
                var piePiece = new PiePiece(data, idx);
                // Default expansion animation
                if (isFirstRender && animationType !== 'scale') {
                    piePiece.eachChild(function (child) {
                        child.stopAnimation(true);
                    });
                }

                selectedMode && piePiece.on('click', onSectorClick);

                data.setItemGraphicEl(idx, piePiece);

                group.add(piePiece);
            })
            .update(function (newIdx, oldIdx) {
                var piePiece = oldData.getItemGraphicEl(oldIdx);

                piePiece.updateData(data, newIdx);

                piePiece.off('click');
                selectedMode && piePiece.on('click', onSectorClick);
                group.add(piePiece);
                data.setItemGraphicEl(newIdx, piePiece);
            })
            .remove(function (idx) {
                var piePiece = oldData.getItemGraphicEl(idx);
                group.remove(piePiece);
            })
            .execute();

        if (
            hasAnimation && isFirstRender && data.count() > 0
            // Default expansion animation
            && animationType !== 'scale'
        ) {
            var shape = data.getItemLayout(0);
            var r = Math.max(api.getWidth(), api.getHeight()) / 2;

            var removeClipPath = zrUtil.bind(group.removeClipPath, group);
            group.setClipPath(this._createClipPath(
                shape.cx, shape.cy, r, shape.startAngle, shape.clockwise, removeClipPath, seriesModel
            ));
        }

        this._data = data;
    },

    dispose: function () {},

    _createClipPath: function (
        cx, cy, r, startAngle, clockwise, cb, seriesModel
    ) {
        var clipPath = new graphic.Sector({
            shape: {
                cx: cx,
                cy: cy,
                r0: 0,
                r: r,
                startAngle: startAngle,
                endAngle: startAngle,
                clockwise: clockwise
            }
        });

        graphic.initProps(clipPath, {
            shape: {
                endAngle: startAngle + (clockwise ? 1 : -1) * Math.PI * 2
            }
        }, seriesModel, cb);

        return clipPath;
    },

    /**
     * @implement
     */
    containPoint: function (point, seriesModel) {
        var data = seriesModel.getData();
        var itemLayout = data.getItemLayout(0);
        if (itemLayout) {
            var dx = point[0] - itemLayout.cx;
            var dy = point[1] - itemLayout.cy;
            var radius = Math.sqrt(dx * dx + dy * dy);
            return radius <= itemLayout.r && radius >= itemLayout.r0;
        }
    }

});

export default PieView;
<commit_msg>delete Space<commit_after>/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import * as zrUtil from 'zrender/src/core/util';
import * as graphic from '../../util/graphic';
import ChartView from '../../view/Chart';

/**
 * @param {module:echarts/model/Series} seriesModel
 * @param {boolean} hasAnimation
 * @inner
 */
function updateDataSelected(uid, seriesModel, hasAnimation, api) {
    var data = seriesModel.getData();
    var dataIndex = this.dataIndex;
    var name = data.getName(dataIndex);
    var selectedOffset = seriesModel.get('selectedOffset');

    api.dispatchAction({
        type: 'pieToggleSelect',
        from: uid,
        name: name,
        seriesId: seriesModel.id
    });

    data.each(function (idx) {
        toggleItemSelected(
            data.getItemGraphicEl(idx),
            data.getItemLayout(idx),
            seriesModel.isSelected(data.getName(idx)),
            selectedOffset,
            hasAnimation
        );
    });
}

/**
 * @param {module:zrender/graphic/Sector} el
 * @param {Object} layout
 * @param {boolean} isSelected
 * @param {number} selectedOffset
 * @param {boolean} hasAnimation
 * @inner
 */
function toggleItemSelected(el, layout, isSelected, selectedOffset, hasAnimation) {
    var midAngle = (layout.startAngle + layout.endAngle) / 2;

    var dx = Math.cos(midAngle);
    var dy = Math.sin(midAngle);

    var offset = isSelected ? selectedOffset : 0;
    var position = [dx * offset, dy * offset];

    hasAnimation
        // animateTo will stop revious animation like update transition
        ? el.animate()
            .when(200, {
                position: position
            })
            .start('bounceOut')
        : el.attr('position', position);
}

/**
 * Piece of pie including Sector, Label, LabelLine
 * @constructor
 * @extends {module:zrender/graphic/Group}
 */
function PiePiece(data, idx) {

    graphic.Group.call(this);

    var sector = new graphic.Sector({
        z2: 2
    });
    var polyline = new graphic.Polyline();
    var text = new graphic.Text();
    this.add(sector);
    this.add(polyline);
    this.add(text);

    this.updateData(data, idx, true);

    // Hover to change label and labelLine
    function onEmphasis() {
        polyline.ignore = polyline.hoverIgnore;
        text.ignore = text.hoverIgnore;
    }
    function onNormal() {
        polyline.ignore = polyline.normalIgnore;
        text.ignore = text.normalIgnore;
    }
    this.on('emphasis', onEmphasis)
        .on('normal', onNormal)
        .on('mouseover', onEmphasis)
        .on('mouseout', onNormal);
}

var piePieceProto = PiePiece.prototype;

piePieceProto.updateData = function (data, idx, firstCreate) {

    var sector = this.childAt(0);

    var seriesModel = data.hostModel;
    var itemModel = data.getItemModel(idx);
    var layout = data.getItemLayout(idx);
    var sectorShape = zrUtil.extend({}, layout);
    sectorShape.label = null;

    if (firstCreate) {
        sector.setShape(sectorShape);

        var animationType = seriesModel.getShallow('animationType');
        if (animationType === 'scale') {
            sector.shape.r = layout.r0;
            graphic.initProps(sector, {
                shape: {
                    r: layout.r
                }
            }, seriesModel, idx);
        }
        // Expansion
        else {
            sector.shape.endAngle = layout.startAngle;
            graphic.updateProps(sector, {
                shape: {
                    endAngle: layout.endAngle
                }
            }, seriesModel, idx);
        }

    }
    else {
        graphic.updateProps(sector, {
            shape: sectorShape
        }, seriesModel, idx);
    }

    // Update common style
    var visualColor = data.getItemVisual(idx, 'color');

    sector.useStyle(
        zrUtil.defaults(
            {
                lineJoin: 'bevel',
                fill: visualColor
            },
            itemModel.getModel('itemStyle').getItemStyle()
        )
    );
    sector.hoverStyle = itemModel.getModel('emphasis.itemStyle').getItemStyle();

    var cursorStyle = itemModel.getShallow('cursor');
    cursorStyle && sector.attr('cursor', cursorStyle);

    // Toggle selected
    toggleItemSelected(
        this,
        data.getItemLayout(idx),
        seriesModel.isSelected(null, idx),
        seriesModel.get('selectedOffset'),
        seriesModel.get('animation')
    );

    function onEmphasis() {
        // Sector may has animation of updating data. Force to move to the last frame
        // Or it may stopped on the wrong shape
        sector.stopAnimation(true);
        sector.animateTo({
            shape: {
                r: layout.r + seriesModel.get('hoverOffset')
            }
        }, 300, 'elasticOut');
    }
    function onNormal() {
        sector.stopAnimation(true);
        sector.animateTo({
            shape: {
                r: layout.r
            }
        }, 300, 'elasticOut');
    }
    sector.off('mouseover').off('mouseout').off('emphasis').off('normal');
    if (itemModel.get('hoverAnimation') && seriesModel.isAnimationEnabled()) {
        sector
            .on('mouseover', onEmphasis)
            .on('mouseout', onNormal)
            .on('emphasis', onEmphasis)
            .on('normal', onNormal);
    }

    this._updateLabel(data, idx);

    graphic.setHoverStyle(this);
};

piePieceProto._getFilterIgnore = function(data, idx) {
    var seriesModel = data.hostModel;
    var itemModel = data.getItemModel(idx);
    var valueDim = data.mapDimension('value');
    var sum = data.getSum(valueDim);
    var filterValue = seriesModel.getModel('filterValue');
    var filterIgnore = false;
    if (sum * filterValue.option > itemModel.option.value) {
        filterIgnore = true;
    }
    return filterIgnore;
}

piePieceProto._updateLabel = function(data, idx) {

    var labelLine = this.childAt(1);
    var labelText = this.childAt(2);

    var seriesModel = data.hostModel;
    var itemModel = data.getItemModel(idx);
    var layout = data.getItemLayout(idx);
    var labelLayout = layout.label;
    var visualColor = data.getItemVisual(idx, 'color');
    var filterIgnore = this._getFilterIgnore(data, idx);

    graphic.updateProps(labelLine, {
        shape: {
            points: labelLayout.linePoints || [
                [labelLayout.x, labelLayout.y], [labelLayout.x, labelLayout.y], [labelLayout.x, labelLayout.y]
            ]
        }
    }, seriesModel, idx);

    graphic.updateProps(labelText, {
        style: {
            x: labelLayout.x,
            y: labelLayout.y
        }
    }, seriesModel, idx);
    labelText.attr({
        rotation: labelLayout.rotation,
        origin: [labelLayout.x, labelLayout.y],
        z2: 10
    });

    var labelModel = itemModel.getModel('label');
    var labelHoverModel = itemModel.getModel('emphasis.label');
    var labelLineModel = itemModel.getModel('labelLine');
    var labelLineHoverModel = itemModel.getModel('emphasis.labelLine');
    var visualColor = data.getItemVisual(idx, 'color');

    graphic.setLabelStyle(
        labelText.style, labelText.hoverStyle = {}, labelModel, labelHoverModel,
        {
            labelFetcher: data.hostModel,
            labelDataIndex: idx,
            defaultText: data.getName(idx),
            autoColor: visualColor,
            useInsideStyle: !!labelLayout.inside
        },
        {
            textAlign: labelLayout.textAlign,
            textVerticalAlign: labelLayout.verticalAlign,
            opacity: data.getItemVisual(idx, 'opacity')
        }
    );

    labelText.ignore = labelText.normalIgnore = !labelModel.get('show') || filterIgnore;
    labelText.hoverIgnore = !labelHoverModel.get('show') || filterIgnore;

    labelLine.ignore = labelLine.normalIgnore = !labelLineModel.get('show') || filterIgnore;
    labelLine.hoverIgnore = !labelLineHoverModel.get('show') || filterIgnore;

    // Default use item visual color
    labelLine.setStyle({
        stroke: visualColor,
        opacity: data.getItemVisual(idx, 'opacity')
    });
    labelLine.setStyle(labelLineModel.getModel('lineStyle').getLineStyle());

    labelLine.hoverStyle = labelLineHoverModel.getModel('lineStyle').getLineStyle();

    var smooth = labelLineModel.get('smooth');
    if (smooth && smooth === true) {
        smooth = 0.4;
    }
    labelLine.setShape({
        smooth: smooth
    });
};

zrUtil.inherits(PiePiece, graphic.Group);

// Pie view
var PieView = ChartView.extend({

    type: 'pie',

    init: function () {
        var sectorGroup = new graphic.Group();
        this._sectorGroup = sectorGroup;
    },

    render: function (seriesModel, ecModel, api, payload) {
        if (payload && (payload.from === this.uid)) {
            return;
        }

        var data = seriesModel.getData();
        var oldData = this._data;
        var group = this.group;

        var hasAnimation = ecModel.get('animation');
        var isFirstRender = !oldData;
        var animationType = seriesModel.get('animationType');

        var onSectorClick = zrUtil.curry(
            updateDataSelected, this.uid, seriesModel, hasAnimation, api
        );

        var selectedMode = seriesModel.get('selectedMode');

        data.diff(oldData)
            .add(function (idx) {
                var piePiece = new PiePiece(data, idx);
                // Default expansion animation
                if (isFirstRender && animationType !== 'scale') {
                    piePiece.eachChild(function (child) {
                        child.stopAnimation(true);
                    });
                }

                selectedMode && piePiece.on('click', onSectorClick);

                data.setItemGraphicEl(idx, piePiece);

                group.add(piePiece);
            })
            .update(function (newIdx, oldIdx) {
                var piePiece = oldData.getItemGraphicEl(oldIdx);

                piePiece.updateData(data, newIdx);

                piePiece.off('click');
                selectedMode && piePiece.on('click', onSectorClick);
                group.add(piePiece);
                data.setItemGraphicEl(newIdx, piePiece);
            })
            .remove(function (idx) {
                var piePiece = oldData.getItemGraphicEl(idx);
                group.remove(piePiece);
            })
            .execute();

        if (
            hasAnimation && isFirstRender && data.count() > 0
            // Default expansion animation
            && animationType !== 'scale'
        ) {
            var shape = data.getItemLayout(0);
            var r = Math.max(api.getWidth(), api.getHeight()) / 2;

            var removeClipPath = zrUtil.bind(group.removeClipPath, group);
            group.setClipPath(this._createClipPath(
                shape.cx, shape.cy, r, shape.startAngle, shape.clockwise, removeClipPath, seriesModel
            ));
        }

        this._data = data;
    },

    dispose: function () {},

    _createClipPath: function (
        cx, cy, r, startAngle, clockwise, cb, seriesModel
    ) {
        var clipPath = new graphic.Sector({
            shape: {
                cx: cx,
                cy: cy,
                r0: 0,
                r: r,
                startAngle: startAngle,
                endAngle: startAngle,
                clockwise: clockwise
            }
        });

        graphic.initProps(clipPath, {
            shape: {
                endAngle: startAngle + (clockwise ? 1 : -1) * Math.PI * 2
            }
        }, seriesModel, cb);

        return clipPath;
    },

    /**
     * @implement
     */
    containPoint: function (point, seriesModel) {
        var data = seriesModel.getData();
        var itemLayout = data.getItemLayout(0);
        if (itemLayout) {
            var dx = point[0] - itemLayout.cx;
            var dy = point[1] - itemLayout.cy;
            var radius = Math.sqrt(dx * dx + dy * dy);
            return radius <= itemLayout.r && radius >= itemLayout.r0;
        }
    }

});

export default PieView;
<|endoftext|>