<commit_before>function APISamples (defaultResourceLevelTier) {
    this.sample_swagger = "{\"paths\":{\"/order\":{\"post\":{\"x-auth-type\":\"Application & Application User\"," +
    "\"x-throttling-tier\":\"" + defaultResourceLevelTier + "\",\"description\":\"Create a new Order\",\"parameters\"" +
    ":[{\"schema\":{\"$ref\":\"#/definitions/Order\"},\"description\":" +
    "\"Order object that needs to be added\",\"name\":\"body\",\"required\":true,\"in\":\"body\"}]," +
    "\"responses\":{\"201\":{\"headers\":{\"Location\":{\"description\":\"The URL of the newly created resource.\",\"type\":" +
    "\"string\"},\"Content-Type\":{\"description\":\"The content type of the body.\",\"type\":" +
    "\"string\"}},\"schema\":{\"$ref\":\"#/definitions/Order\"},\"description\":\"Created." +
    " Successful response with the newly created object as entity in the body. Location header" +
    " contains URL of newly created entity.\"},\"400\":{\"schema\":{\"$ref\":" +
    "\"#/definitions/Error\"},\"description\":\"Bad Request. Invalid request or validation error.\"}" +
    ",\"415\":{\"schema\":{\"$ref\":\"#/definitions/Error\"},\"description\":" +
    "\"Unsupported Media Type. The entity of the request was in a not supported format.\"}}}}," +
    "\"/menu\":{\"get\":{\"x-auth-type\":\"Application & Application User\",\"x-throttling-tier\":" +
    "\"" + defaultResourceLevelTier + "\",\"description\":\"Return a list of available menu items\",\"parameters\":" +
    "[],\"responses\":{\"200\":{\"headers\"" + ":{},\"schema\":{\"title\":\"Menu\"," + "\"properties\":{" +
    "\"list\":{\"items\":{\"$ref\":\"#/definitions/MenuItem\"},\"type\":\"array\"}},\"type\":" +
    "\"object\"},\"description\":\"OK. List of APIs is returned.\"},\"304\":{\"description\":" +
    "\"Not Modified. Empty body because the client has already the latest version of the requested " +
    "resource.\"},\"406\":{\"schema\":{\"$ref\":\"#/definitions/Error\"},\"description\":" +
    "\"Not Acceptable. The requested media type is not supported\"}}}},\"/order/{orderId}\"" +
    ":{\"put\":{\"x-auth-type\":\"Application & Application User\",\"x-throttling-tier\":" +
    "\"" + defaultResourceLevelTier + "\",\"description\":\"Update an existing Order\",\"parameters\":[{\"description\"" +
    ":\"Order Id\",\"name\":\"orderId\",\"format\":\"integer\",\"type\":\"number\",\"required\"" +
    ":true,\"in\":\"path\"},{\"schema\":{\"$ref\":\"#/definitions/Order\"},\"description\":\"" +
    "Order object that needs to be added\",\"name\":\"body\",\"required\":true,\"in\":\"body\"}]," +
    "\"responses\":{\"200\":{\"headers\":{\"Location\":{\"description\":\"The URL " +
    "of the newly created resource.\",\"type\":\"string\"},\"Content-Type\":{\"description\":\"The" +
    " content type of the body.\",\"type\":\"string\"}},\"schema\":{\"$ref\":" +
    "\"#/definitions/Order\"},\"description\":\"OK. Successful response with updated Order\"}," +
    "\"400\":{\"schema\":{\"$ref\":\"#/definitions/Error\"},\"description\":\"Bad Request. " +
    "Invalid request or validation error\"},\"404\":{\"schema\":{\"$ref\":\"#/definitions/Error\"}" +
    ",\"description\":\"Not Found. The resource to be updated does not exist.\"},\"412\":{\"schema\"" +
    ":{\"$ref\":\"#/definitions/Error\"},\"description\":\"Precondition Failed. The request has " +
    "not been performed because one of the preconditions is not met.\"}}},\"get\":{\"x-auth-type\"" +
    ":\"Application & Application User\",\"x-throttling-tier\":\"" + defaultResourceLevelTier + "\",\"description\":\"" +
    "Get details of an Order\",\"parameters\":[{\"description\":\"Order Id\",\"name\":\"orderId\"," +
    "\"format\":\"integer\",\"type\":\"number\",\"required\":true,\"in\":\"path\"}],\"responses\":" +
    "{\"200\":{\"schema\":{\"$ref\":\"#/definitions/Order\"},\"headers\":{}," +
    "\"description\":\"OK Requested Order will be returned\"},\"304\":{\"description\":" +
    "\"Not Modified. Empty body because the client has already the latest version of the " +
    "requested resource.\"},\"404\":{\"schema\":{\"$ref\":\"#/definitions/Error\"},\"description\"" +
    ":\"Not Found. Requested API does not exist.\"},\"406\":{\"schema\":{\"$ref\":" +
    "\"#/definitions/Error\"},\"description\":\"Not Acceptable. The requested media type is" +
    " not supported\"}}},\"delete\":{\"x-auth-type\":\"Application & Application User\"," +
    "\"x-throttling-tier\":\"" + defaultResourceLevelTier + "\",\"description\":\"Delete an existing Order\"," +
    "\"parameters\":[{\"description\":\"Order Id\",\"name\":\"orderId\",\"format\":\"integer\"," +
    "\"type\":\"number\",\"required\":true,\"in\":\"path\"}],\"responses\":{\"200\":{\"description\"" +
    ":\"OK. Resource successfully deleted.\"},\"404\":{\"schema\":{\"$ref\":\"#/definitions/Error\"}" +
    ",\"description\":\"Not Found. Resource to be deleted does not exist.\"},\"412\":{\"schema\"" +
    ":{\"$ref\":\"#/definitions/Error\"},\"description\":\"Precondition Failed. The request has " +
    "not been performed because one of the preconditions is not met.\"}}}}},\"schemes\":[\"https\"]" +
    ",\"produces\":[\"application/json\"],\"swagger\":\"2.0\",\"definitions\":{\"ErrorListItem\":" +
    "{\"title\":\"Description of individual errors that may have occored during a request.\"," +
    "\"properties\":{\"message\":{\"description\":\"Description about individual errors occored\"," +
    "\"type\":\"string\"},\"code\":{\"format\":\"int64\",\"type\":\"integer\"}},\"required\":" +
    "[\"code\",\"message\"]},\"MenuItem\":{\"title\":\"Pizza menu Item\",\"properties\":" +
    "{\"price\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"name\":{\"type\":" +
    "\"string\"},\"image\":{\"type\":\"string\"}},\"required\":[\"name\"]},\"Order\":{\"title\":" +
    "\"Pizza Order\",\"properties\":{\"customerName\":{\"type\":\"string\"},\"delivered\":{\"" +
    "type\":\"boolean\"},\"address\":{\"type\":\"string\"},\"pizzaType\":{\"type\":\"string\"}," +
    "\"creditCardNumber\":{\"type\":\"string\"},\"quantity\":{\"type\":\"number\"},\"orderId\":" +
    "{\"type\":\"integer\"}},\"required\":[\"orderId\"]},\"Error\":{\"title\":\"Error object" +
    " returned with 4XX HTTP status\",\"properties\":{\"message\":{\"description\":\"Error " +
    "message.\",\"type\":\"string\"},\"error\":{\"items\":{\"$ref\":\"#/definitions/ErrorListItem\"}" +
    ",\"description\":\"If there are more than one error list them out. Ex. list out validation" +
    " errors by each field.\",\"type\":\"array\"},\"description\":{\"description\":\"A detail " +
    "description about the error message.\",\"type\":\"string\"},\"code\":{\"format\":\"int64\"," +
    "\"type\":\"integer\"},\"moreInfo\":{\"description\":\"Preferably an url with more details" +
    " about the error.\",\"type\":\"string\"}},\"required\":[\"code\",\"message\"]}},\"consumes\"" +
    ":[\"application/json\"],\"info\":{\"title\":\"PizzaShackAPI\",\"description\":\"This document" +
    " describe a RESTFul API for Pizza Shack online pizza delivery store.\\n\",\"license\":{\"name\"" +
    ":\"Apache 2.0\",\"url\":\"http://www.apache.org/licenses/LICENSE-2.0.html\"},\"contact\":" +
    "{\"email\":\"architecture@PizzaShack.com\",\"name\":\"PizzaShack\",\"url\":" +
    "\"http://PizzaShack.lk\"},\"version\":\"1.0.0\"}}";
    }

APISamples.prototype.deploySample = function (defaultApiLevelTier, gatewayURL) {
    var addAPIUrl = "/site/blocks/item-design/ajax/add.jag";
    var addAPIData = {action: 'sampleDesign', name: 'PizzaShackAPI', provider: username,
        version: '1.0.0', description: 'This is a simple API for Pizza Shack online pizza delivery store.', tags: 'pizza',
        visibility: 'public', context: 'pizzashack',
        swagger: this.sample_swagger, apiThumb: '/site/themes/wso2/images/pizzaShackAPIImage.jpg'};

    jagg.message({
        content:"" ,
        type:"info",
        title:""
    });
    $('#messageModal').modal({backdrop: 'static', keyboard: false });
    $(".modal-header .close").hide();
    $(".modal-footer").html("");
    $(".modal-title").html("Please wait");
    $(".modal-body").addClass("loadingButton");
    $(".modal-body").css({"margin-left": 25});
    $(".modal-body").html("Sample API is Deploying");

    var _this = this;
    //add the sample api
    jagg.post(addAPIUrl, addAPIData,
        function (apiAddResult) {
            if (!apiAddResult.error) {
                var urlDesign = '/site/blocks/item-design/ajax/add.jag';
                var prodEndpoint = gatewayURL + "/am/sample/pizzashack/v1/api/";
                var sandboxEndpoint = gatewayURL + "/am/sample/pizzashack/v1/api/";
                var implementation = {
                    action: "implement",
                    name: "PizzaShackAPI",
                    version: "1.0.0",
                    provider: username,
                    implementation_methods: "endpoint",
                    endpoint_type: "http",
                    endpoint_config: "{" +
                    "\"production_endpoints\": {" +
                            "\"url\": \"" + prodEndpoint + "\"," +
                            "\"config\": null" +
                        "}," +
                        "\"sandbox_endpoints\": {" +
                            "\"url\": \"" + sandboxEndpoint + "\"," +
                            "\"config\": null" +
                        "}," +
                        "\"endpoint_type\": \"http\" " +
                    "}",
                    production_endpoints: prodEndpoint,
                    sandbox_endpoints: sandboxEndpoint,
                    endpointType: "nonsecured",
                    swagger: _this.sample_swagger
                };
                jagg.post(urlDesign, implementation,
                    function (result) {
                        jagg.post(urlDesign, {action: "manage", name: "PizzaShackAPI",
                            provider: username, version: "1.0.0", default_version_checked: " ",
                            tier: defaultApiLevelTier, tiersCollection: defaultApiLevelTier,
                            transport_http: "http", transport_https: "https",
                            bizOwner: "PizzaShack Business Owner",
                            bizOwnerMail: "marketing@PizzaShack.com",
                            techOwner: "PizzaShack Technical Owner",
                            techOwnerMail: "architecture@PizzaShack.com",
                            swagger: _this.sample_swagger},
                            function (result) {
                                if (isPublishPermitted) {
                                    var urlPublished = "/site/blocks/life-cycles/ajax/life-cycles.jag";
                                    var result2 = jagg.post(urlPublished, {action: "updateStatus",
                                        name: "PizzaShackAPI", version: "1.0.0", provider: username,
                                        status: "Publish", publishToGateway: true,
                                        requireResubscription: true},
                                        function (result) {
                                            if (!result.error) {
                                                window.location.assign(siteContext + "/site/pages/index.jag");
                                                $(".modal-body").removeClass("loadingButton");
                                                jagg.message({
                                                    content: "Sample PizzaShackAPI is Deployed Successfully",
                                                    type: "info",
                                                    title: "Success"
                                                });
                                                //Add document for the published sample
                                                addSampleAPIDoc();
                                            }
                                        }, 'json');
                                } else {
                                    window.location.assign(siteContext + "/site/pages/index.jag");
                                    $(".modal-body").removeClass("loadingButton");
                                    jagg.message({
                                        content: "Sample PizzaShackAPI is Deployed Successfully",
                                        type: "info",
                                        title: "Success"
                                    });
                                }
                            }, 'json');
                    }, 'json');
            } else {

                if (result.message == "timeout") {
                    jagg.showLogin();
                }else {
                    $(".modal-body").removeClass("loadingButton");
                    jagg.message({
                        content: "Error occurred while adding sample API",
                        type: "error",
                        title: "Error"
                    });
                }
            }
        }, 'json');
};

addSampleAPIDoc = function () {
    var addDocUrl = "/site/blocks/documentation/ajax/docs.jag";
    var addDocData = {action: 'addSampleDocumentation', provider: username,
        apiName: 'PizzaShackAPI',version: '1.0.0',
        docName: 'PizzaShack API Documentation',
        docType: 'how to', sourceType: 'file',
        summary: 'This is the API documentation for Pizza Shack API',
        docLocation: '/samples/PizzaShack/PizzaShackAPIDoc.pdf'
    };
    jagg.post(addDocUrl, addDocData,
        function (apiDocResult) {
            if (apiDocResult.error) {
                $(".modal-body").removeClass("loadingButton");
                jagg.message({
                    content: "Error occurred while adding sample API documentation",
                    type: "error",
                    title: "Error"
                });
            }
        }, 'json');
};

var deploySampleApi = function (defaultApiLevelTier, defaultResourceLevelTier, gatewayURL) {
    var deployer = new APISamples(defaultResourceLevelTier);
    deployer.deploySample(defaultApiLevelTier, gatewayURL);
};
<commit_msg>fix sample api redirect issue<commit_after>function APISamples (defaultResourceLevelTier) {
    this.sample_swagger = "{\"paths\":{\"/order\":{\"post\":{\"x-auth-type\":\"Application & Application User\"," +
    "\"x-throttling-tier\":\"" + defaultResourceLevelTier + "\",\"description\":\"Create a new Order\",\"parameters\"" +
    ":[{\"schema\":{\"$ref\":\"#/definitions/Order\"},\"description\":" +
    "\"Order object that needs to be added\",\"name\":\"body\",\"required\":true,\"in\":\"body\"}]," +
    "\"responses\":{\"201\":{\"headers\":{\"Location\":{\"description\":\"The URL of the newly created resource.\",\"type\":" +
    "\"string\"},\"Content-Type\":{\"description\":\"The content type of the body.\",\"type\":" +
    "\"string\"}},\"schema\":{\"$ref\":\"#/definitions/Order\"},\"description\":\"Created." +
    " Successful response with the newly created object as entity in the body. Location header" +
    " contains URL of newly created entity.\"},\"400\":{\"schema\":{\"$ref\":" +
    "\"#/definitions/Error\"},\"description\":\"Bad Request. Invalid request or validation error.\"}" +
    ",\"415\":{\"schema\":{\"$ref\":\"#/definitions/Error\"},\"description\":" +
    "\"Unsupported Media Type. The entity of the request was in a not supported format.\"}}}}," +
    "\"/menu\":{\"get\":{\"x-auth-type\":\"Application & Application User\",\"x-throttling-tier\":" +
    "\"" + defaultResourceLevelTier + "\",\"description\":\"Return a list of available menu items\",\"parameters\":" +
    "[],\"responses\":{\"200\":{\"headers\"" + ":{},\"schema\":{\"title\":\"Menu\"," + "\"properties\":{" +
    "\"list\":{\"items\":{\"$ref\":\"#/definitions/MenuItem\"},\"type\":\"array\"}},\"type\":" +
    "\"object\"},\"description\":\"OK. List of APIs is returned.\"},\"304\":{\"description\":" +
    "\"Not Modified. Empty body because the client has already the latest version of the requested " +
    "resource.\"},\"406\":{\"schema\":{\"$ref\":\"#/definitions/Error\"},\"description\":" +
    "\"Not Acceptable. The requested media type is not supported\"}}}},\"/order/{orderId}\"" +
    ":{\"put\":{\"x-auth-type\":\"Application & Application User\",\"x-throttling-tier\":" +
    "\"" + defaultResourceLevelTier + "\",\"description\":\"Update an existing Order\",\"parameters\":[{\"description\"" +
    ":\"Order Id\",\"name\":\"orderId\",\"format\":\"integer\",\"type\":\"number\",\"required\"" +
    ":true,\"in\":\"path\"},{\"schema\":{\"$ref\":\"#/definitions/Order\"},\"description\":\"" +
    "Order object that needs to be added\",\"name\":\"body\",\"required\":true,\"in\":\"body\"}]," +
    "\"responses\":{\"200\":{\"headers\":{\"Location\":{\"description\":\"The URL " +
    "of the newly created resource.\",\"type\":\"string\"},\"Content-Type\":{\"description\":\"The" +
    " content type of the body.\",\"type\":\"string\"}},\"schema\":{\"$ref\":" +
    "\"#/definitions/Order\"},\"description\":\"OK. Successful response with updated Order\"}," +
    "\"400\":{\"schema\":{\"$ref\":\"#/definitions/Error\"},\"description\":\"Bad Request. " +
    "Invalid request or validation error\"},\"404\":{\"schema\":{\"$ref\":\"#/definitions/Error\"}" +
    ",\"description\":\"Not Found. The resource to be updated does not exist.\"},\"412\":{\"schema\"" +
    ":{\"$ref\":\"#/definitions/Error\"},\"description\":\"Precondition Failed. The request has " +
    "not been performed because one of the preconditions is not met.\"}}},\"get\":{\"x-auth-type\"" +
    ":\"Application & Application User\",\"x-throttling-tier\":\"" + defaultResourceLevelTier + "\",\"description\":\"" +
    "Get details of an Order\",\"parameters\":[{\"description\":\"Order Id\",\"name\":\"orderId\"," +
    "\"format\":\"integer\",\"type\":\"number\",\"required\":true,\"in\":\"path\"}],\"responses\":" +
    "{\"200\":{\"schema\":{\"$ref\":\"#/definitions/Order\"},\"headers\":{}," +
    "\"description\":\"OK Requested Order will be returned\"},\"304\":{\"description\":" +
    "\"Not Modified. Empty body because the client has already the latest version of the " +
    "requested resource.\"},\"404\":{\"schema\":{\"$ref\":\"#/definitions/Error\"},\"description\"" +
    ":\"Not Found. Requested API does not exist.\"},\"406\":{\"schema\":{\"$ref\":" +
    "\"#/definitions/Error\"},\"description\":\"Not Acceptable. The requested media type is" +
    " not supported\"}}},\"delete\":{\"x-auth-type\":\"Application & Application User\"," +
    "\"x-throttling-tier\":\"" + defaultResourceLevelTier + "\",\"description\":\"Delete an existing Order\"," +
    "\"parameters\":[{\"description\":\"Order Id\",\"name\":\"orderId\",\"format\":\"integer\"," +
    "\"type\":\"number\",\"required\":true,\"in\":\"path\"}],\"responses\":{\"200\":{\"description\"" +
    ":\"OK. Resource successfully deleted.\"},\"404\":{\"schema\":{\"$ref\":\"#/definitions/Error\"}" +
    ",\"description\":\"Not Found. Resource to be deleted does not exist.\"},\"412\":{\"schema\"" +
    ":{\"$ref\":\"#/definitions/Error\"},\"description\":\"Precondition Failed. The request has " +
    "not been performed because one of the preconditions is not met.\"}}}}},\"schemes\":[\"https\"]" +
    ",\"produces\":[\"application/json\"],\"swagger\":\"2.0\",\"definitions\":{\"ErrorListItem\":" +
    "{\"title\":\"Description of individual errors that may have occored during a request.\"," +
    "\"properties\":{\"message\":{\"description\":\"Description about individual errors occored\"," +
    "\"type\":\"string\"},\"code\":{\"format\":\"int64\",\"type\":\"integer\"}},\"required\":" +
    "[\"code\",\"message\"]},\"MenuItem\":{\"title\":\"Pizza menu Item\",\"properties\":" +
    "{\"price\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"name\":{\"type\":" +
    "\"string\"},\"image\":{\"type\":\"string\"}},\"required\":[\"name\"]},\"Order\":{\"title\":" +
    "\"Pizza Order\",\"properties\":{\"customerName\":{\"type\":\"string\"},\"delivered\":{\"" +
    "type\":\"boolean\"},\"address\":{\"type\":\"string\"},\"pizzaType\":{\"type\":\"string\"}," +
    "\"creditCardNumber\":{\"type\":\"string\"},\"quantity\":{\"type\":\"number\"},\"orderId\":" +
    "{\"type\":\"integer\"}},\"required\":[\"orderId\"]},\"Error\":{\"title\":\"Error object" +
    " returned with 4XX HTTP status\",\"properties\":{\"message\":{\"description\":\"Error " +
    "message.\",\"type\":\"string\"},\"error\":{\"items\":{\"$ref\":\"#/definitions/ErrorListItem\"}" +
    ",\"description\":\"If there are more than one error list them out. Ex. list out validation" +
    " errors by each field.\",\"type\":\"array\"},\"description\":{\"description\":\"A detail " +
    "description about the error message.\",\"type\":\"string\"},\"code\":{\"format\":\"int64\"," +
    "\"type\":\"integer\"},\"moreInfo\":{\"description\":\"Preferably an url with more details" +
    " about the error.\",\"type\":\"string\"}},\"required\":[\"code\",\"message\"]}},\"consumes\"" +
    ":[\"application/json\"],\"info\":{\"title\":\"PizzaShackAPI\",\"description\":\"This document" +
    " describe a RESTFul API for Pizza Shack online pizza delivery store.\\n\",\"license\":{\"name\"" +
    ":\"Apache 2.0\",\"url\":\"http://www.apache.org/licenses/LICENSE-2.0.html\"},\"contact\":" +
    "{\"email\":\"architecture@PizzaShack.com\",\"name\":\"PizzaShack\",\"url\":" +
    "\"http://PizzaShack.lk\"},\"version\":\"1.0.0\"}}";
    }

APISamples.prototype.deploySample = function (defaultApiLevelTier, gatewayURL) {
    var addAPIUrl = "/site/blocks/item-design/ajax/add.jag";
    var addAPIData = {action: 'sampleDesign', name: 'PizzaShackAPI', provider: username,
        version: '1.0.0', description: 'This is a simple API for Pizza Shack online pizza delivery store.', tags: 'pizza',
        visibility: 'public', context: 'pizzashack',
        swagger: this.sample_swagger, apiThumb: '/site/themes/wso2/images/pizzaShackAPIImage.jpg'};

    jagg.message({
        content:"" ,
        type:"info",
        title:""
    });
    $('#messageModal').modal({backdrop: 'static', keyboard: false });
    $(".modal-header .close").hide();
    $(".modal-footer").html("");
    $(".modal-title").html("Please wait");
    $(".modal-body").addClass("loadingButton");
    $(".modal-body").css({"margin-left": 25});
    $(".modal-body").html("Sample API is Deploying");

    var _this = this;
    //add the sample api
    jagg.post(addAPIUrl, addAPIData,
        function (apiAddResult) {
            if (!apiAddResult.error) {
                var urlDesign = '/site/blocks/item-design/ajax/add.jag';
                var prodEndpoint = gatewayURL + "/am/sample/pizzashack/v1/api/";
                var sandboxEndpoint = gatewayURL + "/am/sample/pizzashack/v1/api/";
                var implementation = {
                    action: "implement",
                    name: "PizzaShackAPI",
                    version: "1.0.0",
                    provider: username,
                    implementation_methods: "endpoint",
                    endpoint_type: "http",
                    endpoint_config: "{" +
                    "\"production_endpoints\": {" +
                            "\"url\": \"" + prodEndpoint + "\"," +
                            "\"config\": null" +
                        "}," +
                        "\"sandbox_endpoints\": {" +
                            "\"url\": \"" + sandboxEndpoint + "\"," +
                            "\"config\": null" +
                        "}," +
                        "\"endpoint_type\": \"http\" " +
                    "}",
                    production_endpoints: prodEndpoint,
                    sandbox_endpoints: sandboxEndpoint,
                    endpointType: "nonsecured",
                    swagger: _this.sample_swagger
                };
                jagg.post(urlDesign, implementation,
                    function (result) {
                        jagg.post(urlDesign, {action: "manage", name: "PizzaShackAPI",
                            provider: username, version: "1.0.0", default_version_checked: " ",
                            tier: defaultApiLevelTier, tiersCollection: defaultApiLevelTier,
                            transport_http: "http", transport_https: "https",
                            bizOwner: "PizzaShack Business Owner",
                            bizOwnerMail: "marketing@PizzaShack.com",
                            techOwner: "PizzaShack Technical Owner",
                            techOwnerMail: "architecture@PizzaShack.com",
                            swagger: _this.sample_swagger},
                            function (result) {
                                if (isPublishPermitted) {
                                    var urlPublished = "/site/blocks/life-cycles/ajax/life-cycles.jag";
                                    var result2 = jagg.post(urlPublished, {action: "updateStatus",
                                        name: "PizzaShackAPI", version: "1.0.0", provider: username,
                                        status: "Publish", publishToGateway: true,
                                        requireResubscription: true},
                                        function (result) {
                                            if (!result.error) {
                                                $(".modal-body").removeClass("loadingButton");
                                                jagg.message({
                                                    content: "Sample PizzaShackAPI is Deployed Successfully",
                                                    type: "info",
                                                    title: "Success",
                                                    cbk:function(){window.location.assign(siteContext + "/site/pages/index.jag");}
                                                });
                                                //Add document for the published sample
                                                addSampleAPIDoc();
                                            }
                                        }, 'json');
                                } else {
                                    window.location.assign(siteContext + "/site/pages/index.jag");
                                    $(".modal-body").removeClass("loadingButton");
                                    jagg.message({
                                        content: "Sample PizzaShackAPI is Deployed Successfully",
                                        type: "info",
                                        title: "Success"
                                    });
                                }
                            }, 'json');
                    }, 'json');
            } else {

                if (result.message == "timeout") {
                    jagg.showLogin();
                }else {
                    $(".modal-body").removeClass("loadingButton");
                    jagg.message({
                        content: "Error occurred while adding sample API",
                        type: "error",
                        title: "Error"
                    });
                }
            }
        }, 'json');
};

addSampleAPIDoc = function () {
    var addDocUrl = "/site/blocks/documentation/ajax/docs.jag";
    var addDocData = {action: 'addSampleDocumentation', provider: username,
        apiName: 'PizzaShackAPI',version: '1.0.0',
        docName: 'PizzaShack API Documentation',
        docType: 'how to', sourceType: 'file',
        summary: 'This is the API documentation for Pizza Shack API',
        docLocation: '/samples/PizzaShack/PizzaShackAPIDoc.pdf'
    };
    jagg.post(addDocUrl, addDocData,
        function (apiDocResult) {
            if (apiDocResult.error) {
                $(".modal-body").removeClass("loadingButton");
                jagg.message({
                    content: "Error occurred while adding sample API documentation",
                    type: "error",
                    title: "Error"
                });
            }
        }, 'json');
};

var deploySampleApi = function (defaultApiLevelTier, defaultResourceLevelTier, gatewayURL) {
    var deployer = new APISamples(defaultResourceLevelTier);
    deployer.deploySample(defaultApiLevelTier, gatewayURL);
};
<|endoftext|>


<commit_before>// Copyright 2014 Splunk, Inc.
//
// Licensed 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.

(function() {
    var fs              = require("fs");
    var path            = require("path");
    var GithubAPI       = require("github");
    var splunkjs        = require("splunk-sdk");
    var Async           = splunkjs.Async;
    var ModularInputs   = splunkjs.ModularInputs;
    var Logger          = ModularInputs.Logger;
    var Event           = ModularInputs.Event;
    var Scheme          = ModularInputs.Scheme;
    var Argument        = ModularInputs.Argument;
    var utils           = ModularInputs.utils;

    // The version number should be updated every time a new version of the JavaScript SDK is released
    var SDK_UA_STRING = "splunk-sdk-javascript/1.4.0";

    // Create easy to read date format
    function getDisplayDate(date) {
        var monthStrings = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];

        date = new Date(date);

        var hours = date.getHours();
        if (hours < 10) {
            hours = "0" + hours.toString();
        }
        var mins = date.getMinutes();
        if (mins < 10) {
            mins = "0" + mins.toString();
        }

        return monthStrings[date.getMonth()] + " " + date.getDate() + ", " + date.getFullYear() +
            " - " + hours + ":" + mins + " " + (date.getUTCHours() < 12 ? "AM" : "PM");
    }

    exports.getScheme = function() {
        var scheme = new Scheme("Github Commits");

        scheme.description = "Streams events of commits in the specified Github repository (must be public, unless setting a token).";
        scheme.useExternalValidation = true;
        scheme.useSingleInstance = false; // Set to false so an input can have an optional interval parameter

        scheme.args = [
            new Argument({
                name: "owner",
                dataType: Argument.dataTypeString,
                description: "Github user or organization that created the repository.",
                requiredOnCreate: true,
                requiredOnEdit: false
            }),
            new Argument({
                name: "repository",
                dataType: Argument.dataTypeString,
                description: "Name of a public Github repository, owned by the specified owner.",
                requiredOnCreate: true,
                requiredOnEdit: false
            }),
            new Argument({
                name: "token",
                dataType: Argument.dataTypeString,
                description: "(Optional) A Github API access token. Required for private repositories (the token must have the 'repo' and 'public_repo' scopes enabled). Recommended to avoid Github's API limit, especially if setting an interval.",
                requiredOnCreate: false,
                requiredOnEdit: false
            })
        ];

        return scheme;
    };

    exports.validateInput = function(definition, done) {
        var owner = definition.parameters.owner;
        var repository = definition.parameters.repository;
        var token = definition.parameters.token;

        var Github = new GithubAPI({version: "3.0.0"});

        try {
            // Authenticate with the access token if it was provided
            if (token && token.length > 0) {
                Github.authenticate({
                    type: "oauth",
                    token: token
                });
            }

            Github.repos.getCommits({
                headers: {"User-Agent": SDK_UA_STRING},
                user: owner,
                repo: repository,
                per_page: 1, // The minimum per page value supported by the Github API
                page: 1
            }, function (err, res) {
                if (err) {
                    done(err);
                }
                else {
                    // If we get any kind of message, that's a bad sign
                    if (res.message) {
                        done(new Error(res.message));
                    }
                    // We got exactly what we expected
                    else if (res.length === 1 && res[0].hasOwnProperty("sha")) {
                        done();
                    }
                    else {
                        done(new Error("Expected only the latest commit, instead found " + res.length + " commits."));
                    }
                }
            });
        }
        catch (e) {
            done(e);
        }
    };

    exports.streamEvents = function(name, singleInput, eventWriter, done) {
        // Get the checkpoint directory out of the modular input's metadata
        var checkpointDir = this._inputDefinition.metadata["checkpoint_dir"];

        var owner = singleInput.owner;
        var repository = singleInput.repository;
        var token      = singleInput.token;

        var alreadyIndexed = 0;

        var Github = new GithubAPI({version: "3.0.0"});

        if (token && token.length > 0) {
            Github.authenticate({
                type: "oauth",
                token: token
            });
        }

        var page = 1;
        var working = true;

        Async.whilst(
            function() {
                return working;
            },
            function(callback) {
                try {
                    Github.repos.getCommits({
                        headers: {"User-Agent": SDK_UA_STRING},
                        user: owner,
                        repo: repository,
                        per_page: 100, // The maximum per page value supported by the Github API
                        page: page
                    }, function (err, res) {
                        if (err) {
                            callback(err);
                            return;
                        }
                        // When res.meta.link doesn't contain "next", we should stop the loop after streaming commits on this page
                        if (res.meta.link.indexOf("rel=\"next\"") < 0) {
                            working = false;
                        }
                        var errorFound = false;
                        for (var i = 0; i < res.length && !errorFound; i++) {
                            var json = {
                                sha: res[i].sha,
                                api_url: res[i].url,
                                url: "https://github.com/" + owner + "/" + repository + "/commit/" + res[i].sha
                            };

                            var checkpointFilePath  = path.join(checkpointDir, owner + " " + repository + ".txt");

                            // If the file exists and doesn't contain the sha, or if the file doesn't exist
                            if ((fs.existsSync(checkpointFilePath) && utils.readFile("", checkpointFilePath).indexOf(res[i].sha + "\n") < 0) || !fs.existsSync(checkpointFilePath)) {
                                var commit = res[i].commit;

                                // At this point, assumed checkpoint doesn't exist
                                json.message = commit.message.replace(/(\n|\r)+/g, " "); // Replace newlines and carriage returns with spaces
                                json.author = commit.author.name;
                                json.rawdate = commit.author.date;
                                json.displaydate = getDisplayDate(commit.author.date.replace("T|Z", " ").trim());

                                try {
                                    var event = new Event({
                                        stanza: repository,
                                        sourcetype: "github_commits",
                                        data: JSON.stringify(json), // Have Splunk index our event data as JSON
                                        time: Date.parse(json.rawdate) // Set the event timestamp to the time of the commit
                                    });
                                    eventWriter.writeEvent(event);

                                    fs.appendFileSync(checkpointFilePath, res[i].sha + "\n");
                                    Logger.info(name, "Indexed a Github commit with sha: " + res[i].sha);
                                }
                                catch (e) {
                                    errorFound = true;
                                    working = false; // Stop streaming we get an error
                                    Logger.error(name, e.message, eventWriter._err);
                                    done(e);

                                    // We had an error, die
                                    return;
                                }
                            }
                        }

                        if (alreadyIndexed > 0) {
                            Logger.info(name, "Skipped " + alreadyIndexed.toString() + " already indexed Github commits from " + owner + "/" + repository);
                        }

                        page++;
                        callback();
                    });
                }
                catch (e) {
                    callback(e);
                }
            },
            function(err) {
                // We're done streaming
                done(err);
            }
        );
    };

    ModularInputs.execute(exports, module);
})();<commit_msg>Editorial tweaks to comments.<commit_after>// Copyright 2014 Splunk, Inc.
//
// Licensed 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.

(function() {
    var fs              = require("fs");
    var path            = require("path");
    var GithubAPI       = require("github");
    var splunkjs        = require("splunk-sdk");
    var Async           = splunkjs.Async;
    var ModularInputs   = splunkjs.ModularInputs;
    var Logger          = ModularInputs.Logger;
    var Event           = ModularInputs.Event;
    var Scheme          = ModularInputs.Scheme;
    var Argument        = ModularInputs.Argument;
    var utils           = ModularInputs.utils;

    // The version number should be updated every time a new version of the JavaScript SDK is released.
    var SDK_UA_STRING = "splunk-sdk-javascript/1.4.0";

    // Create easy to read date format.
    function getDisplayDate(date) {
        var monthStrings = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];

        date = new Date(date);

        var hours = date.getHours();
        if (hours < 10) {
            hours = "0" + hours.toString();
        }
        var mins = date.getMinutes();
        if (mins < 10) {
            mins = "0" + mins.toString();
        }

        return monthStrings[date.getMonth()] + " " + date.getDate() + ", " + date.getFullYear() +
            " - " + hours + ":" + mins + " " + (date.getUTCHours() < 12 ? "AM" : "PM");
    }

    exports.getScheme = function() {
        var scheme = new Scheme("Github Commits");

        scheme.description = "Streams events of commits in the specified Github repository (must be public, unless setting a token).";
        scheme.useExternalValidation = true;
        scheme.useSingleInstance = false; // Set to false so an input can have an optional interval parameter.

        scheme.args = [
            new Argument({
                name: "owner",
                dataType: Argument.dataTypeString,
                description: "Github user or organization that created the repository.",
                requiredOnCreate: true,
                requiredOnEdit: false
            }),
            new Argument({
                name: "repository",
                dataType: Argument.dataTypeString,
                description: "Name of a public Github repository, owned by the specified owner.",
                requiredOnCreate: true,
                requiredOnEdit: false
            }),
            new Argument({
                name: "token",
                dataType: Argument.dataTypeString,
                description: "(Optional) A Github API access token. Required for private repositories (the token must have the 'repo' and 'public_repo' scopes enabled). Recommended to avoid Github's API limit, especially if setting an interval.",
                requiredOnCreate: false,
                requiredOnEdit: false
            })
        ];

        return scheme;
    };

    exports.validateInput = function(definition, done) {
        var owner = definition.parameters.owner;
        var repository = definition.parameters.repository;
        var token = definition.parameters.token;

        var Github = new GithubAPI({version: "3.0.0"});

        try {
            // Authenticate with the access token if it was provided.
            if (token && token.length > 0) {
                Github.authenticate({
                    type: "oauth",
                    token: token
                });
            }

            Github.repos.getCommits({
                headers: {"User-Agent": SDK_UA_STRING},
                user: owner,
                repo: repository,
                per_page: 1, // The minimum per page value supported by the Github API.
                page: 1
            }, function (err, res) {
                if (err) {
                    done(err);
                }
                else {
                    // If we get any kind of message, that's a bad sign.
                    if (res.message) {
                        done(new Error(res.message));
                    }
                    // We got exactly what we expected.
                    else if (res.length === 1 && res[0].hasOwnProperty("sha")) {
                        done();
                    }
                    else {
                        done(new Error("Expected only the latest commit, instead found " + res.length + " commits."));
                    }
                }
            });
        }
        catch (e) {
            done(e);
        }
    };

    exports.streamEvents = function(name, singleInput, eventWriter, done) {
        // Get the checkpoint directory out of the modular input's metadata.
        var checkpointDir = this._inputDefinition.metadata["checkpoint_dir"];

        var owner = singleInput.owner;
        var repository = singleInput.repository;
        var token      = singleInput.token;

        var alreadyIndexed = 0;

        var Github = new GithubAPI({version: "3.0.0"});

        if (token && token.length > 0) {
            Github.authenticate({
                type: "oauth",
                token: token
            });
        }

        var page = 1;
        var working = true;

        Async.whilst(
            function() {
                return working;
            },
            function(callback) {
                try {
                    Github.repos.getCommits({
                        headers: {"User-Agent": SDK_UA_STRING},
                        user: owner,
                        repo: repository,
                        per_page: 100, // The maximum per page value supported by the Github API.
                        page: page
                    }, function (err, res) {
                        if (err) {
                            callback(err);
                            return;
                        }
                        // When res.meta.link doesn't contain "next", we should stop the loop after streaming commits on this page.
                        if (res.meta.link.indexOf("rel=\"next\"") < 0) {
                            working = false;
                        }
                        var errorFound = false;
                        for (var i = 0; i < res.length && !errorFound; i++) {
                            var json = {
                                sha: res[i].sha,
                                api_url: res[i].url,
                                url: "https://github.com/" + owner + "/" + repository + "/commit/" + res[i].sha
                            };

                            var checkpointFilePath  = path.join(checkpointDir, owner + " " + repository + ".txt");

                            // If the file exists and doesn't contain the sha, or if the file doesn't exist.
                            if ((fs.existsSync(checkpointFilePath) && utils.readFile("", checkpointFilePath).indexOf(res[i].sha + "\n") < 0) || !fs.existsSync(checkpointFilePath)) {
                                var commit = res[i].commit;

                                // At this point, assumed checkpoint doesn't exist.
                                json.message = commit.message.replace(/(\n|\r)+/g, " "); // Replace newlines and carriage returns with spaces.
                                json.author = commit.author.name;
                                json.rawdate = commit.author.date;
                                json.displaydate = getDisplayDate(commit.author.date.replace("T|Z", " ").trim());

                                try {
                                    var event = new Event({
                                        stanza: repository,
                                        sourcetype: "github_commits",
                                        data: JSON.stringify(json), // Have Splunk index our event data as JSON.
                                        time: Date.parse(json.rawdate) // Set the event timestamp to the time of the commit.
                                    });
                                    eventWriter.writeEvent(event);

                                    fs.appendFileSync(checkpointFilePath, res[i].sha + "\n");
                                    Logger.info(name, "Indexed a Github commit with sha: " + res[i].sha);
                                }
                                catch (e) {
                                    errorFound = true;
                                    working = false; // Stop streaming we get an error.
                                    Logger.error(name, e.message, eventWriter._err);
                                    done(e);

                                    // We had an error, die.
                                    return;
                                }
                            }
                        }

                        if (alreadyIndexed > 0) {
                            Logger.info(name, "Skipped " + alreadyIndexed.toString() + " already indexed Github commits from " + owner + "/" + repository);
                        }

                        page++;
                        callback();
                    });
                }
                catch (e) {
                    callback(e);
                }
            },
            function(err) {
                // We're done streaming.
                done(err);
            }
        );
    };

    ModularInputs.execute(exports, module);
})();
<|endoftext|>


<commit_before>/* global window */
(function(window, M) {
  "use strict";

    // Feature detects checks
    var features = {
      canvas: (!M && (function() {
        // TODO: canvas feature detect
        return true;
      })) || M.canvas
    };

    // shim layer with setTimeout fallback
    window.requestAnimFrame = (function(){
      return  window.requestAnimationFrame       ||
              window.webkitRequestAnimationFrame ||
              window.mozRequestAnimationFrame    ||
              window.oRequestAnimationFrame      ||
              window.msRequestAnimationFrame     ||
              function( callback ){
                window.setTimeout(callback, 1000 / 60);
              };
    })();

   var CanvasHelper = {
    PIx2: Math.PI * 2,

    wedge: function(ctx, x, y, r, startAngle, endAngle, antiClockwise) {
      ctx.beginPath();
      ctx.moveTo(x,y);
      ctx.arc(x, y, r, startAngle, endAngle, !!antiClockwise);
      ctx.lineTo(x,y);
      ctx.closePath();

      return ctx;
    },

    circle: function(ctx, x, y, r) {
      ctx.beginPath();
      ctx.arc(x, y, r, 0, this.PIx2);
      ctx.closePath();
      return ctx;
    },

    radToDeg: function(rad) {
      return rad * (180.0 / Math.PI);
    }
  };

  var shallowExtend = function(dest, src) {
    for (var property in src) {
      dest[property] = src[property];
    }
    return dest;
  };

  var RoundGaugeView = function(options) {
    this.options = options || {};
    this.initialize();
  };

  RoundGaugeView.prototype = {
    el: null,

    faceCanvas: null,
    handCanvas: null,
    criticalCanvas: null,

    width: 0,
    height: 0,

    _noOfNicks: 0,
    _radiansPerNick: 0,
    _zeroNick: 0,

    _prefixedTransform: '',

    _initialDrawingComplete: false,

    initialize: function() {

      this.options = shallowExtend({
        id: null,
        css: null,
        classes: null,

        el: null,

        minLimit: 0,
        maxLimit: 100,

        minCritical: false,
        minCriticalStyle: 'rgba(255,0,0,.55)',
        maxCritical: false,
        maxCriticalStyle: 'rgba(255,0,0,.55)',

        value: 0,

        units: '',
        unitFont: '10pt Arial',
        valueReadOut: true,

        width: 400,
        height: 400,

        handTransition: false,

        scaleIncrement: 1,
        scaleStartAngle: Math.PI / 4,
        scaleSpanAngle: Math.PI * 1.5,
        scaleFont: '8pt Arial'
      }, this.options);

      this.el = (!this.options.el) ?
        window.document.createElement('div') :
        this.options.el;

      if (this.options.id) {
        this.el.id = this.options.id;
      }

      this.value = this.options.value;
    },

    frames:0,

    render: function() {
      if (!this._initialDrawingComplete) {
        this.initDrawing();
      }

      this.frames++;

      window.requestAnimFrame(this.moveHand.bind(this));

      return this;
    },

    initDrawing: function() {
      var options = this.options;

      this.faceCanvas = this._createCanvas('face');

      if (options.width) {
        this.el.style.width = (this.faceCanvas.width = options.width)+'px';
      }

      if (options.height) {
        this.el.style.height = (this.faceCanvas.height = options.height)+'px';
      }

      this.width = this.faceCanvas.width;
      this.height = this.faceCanvas.height;

      this._noOfNicks = Math.round(options.maxLimit - options.minLimit) /
        this.options.scaleIncrement;

      this._radiansPerNick = options.scaleSpanAngle / this._noOfNicks;

      this._zeroNick = (options.minLimit < 0) ?
        Math.abs(options.minLimit) / options.scaleIncrement : 0;

      this._prefixedTransform = M.prefixed('Transform');

      var ctx = this.faceCanvas.getContext('2d');
      this.drawFace(ctx);
      this.drawScale(ctx);

      if (!this.handCanvas) {
        this.handCanvas = this._createHandCanvas();
        this.drawHand(this.handCanvas.getContext('2d'));
      }

      if (!this.criticalCanvas) {
        this.criticalCanvas = this._createCanvas('criticals');
        this.drawCriticals(this.criticalCanvas.getContext('2d'));
      }

      this._initialDrawingComplete = true;
    },

    drawFace: function(ctx) {
      var options = this.options;

      ctx.save();
      ctx.lineWidth = 1;
      ctx.fillStyle = 'white';

      CanvasHelper.circle(ctx,
        this.width / 2, this.height / 2,
        Math.min(this.width, this.height) / 2 - 1
      );

      ctx.fill();
      ctx.stroke();

      // Inner face circle
      CanvasHelper.circle(ctx,
        this.width / 2, this.height / 2,
        Math.min(this.width, this.height) / 7 - 1
      );

      ctx.stroke();

      ctx.fillStyle = 'black';

      CanvasHelper.circle(ctx,
        this.width / 2, this.height / 2,
        Math.min(this.width, this.height) / 28 - 1
      );

      ctx.fill();
      ctx.stroke();

      // Units text
      if (options.units) {
        ctx.font = options.unitFont;
        var textWidth = ctx.measureText(options.units).width;
        ctx.fillText(options.units, this.width / 2 - textWidth / 2, this.height - 30);
      }

      ctx.restore();
    },

    drawCriticals: function(ctx) {
      var options = this.options;

      ctx.clearRect(0,0,this.width, this.height);

      if (options.maxCritical !== false) {
        ctx.save();
        ctx.fillStyle = options.maxCriticalStyle;
        ctx.lineWidth = 1;

        var maxAngle = this._valueToAngle(options.maxCritical);

        CanvasHelper.wedge(ctx,
          this.width / 2, this.height / 2,
          this.width / 2.3,
          maxAngle,  options.scaleStartAngle
        );

        ctx.fill();
        ctx.restore();
      }

      if (options.minCritical !== false) {
        ctx.save();
        ctx.fillStyle = options.minCriticalStyle;
        ctx.lineWidth = 1;

        var minAngle = this._valueToAngle(options.minCritical);

        CanvasHelper.wedge(ctx,
          this.width / 2, this.height / 2,
          this.width / 2.3,
          this._valueToAngle(options.minLimit), minAngle
        );

        ctx.fill();
        ctx.restore();
      }
    },

    drawScale: function(ctx) {
      var minDim = Math.min(this.width, this.height),
      options = this.options,
      scaleIndent = 10,
      noOfDecimals = (""+options.scaleIncrement).length - 2;

      if (noOfDecimals < 0) {
        noOfDecimals = 0;
      }

      ctx.save();

      // Transform canvas
      ctx.translate(this.width / 2, this.height / 2);
      ctx.rotate(options.scaleStartAngle - options.scaleSpanAngle);

      ctx.font = options.scaleFont;
      ctx.lineWidth = 1;

      var
      valueInterval = Math.max(this._noOfNicks / 10, 1),
      value = options.minLimit,
      i = 0,
      x1 = this.width / 2 - scaleIndent, x2;

      while (i <= this._noOfNicks) {
        x2 = x1 - 10;

        if (i % valueInterval === 0) {
          var val = value.toFixed(noOfDecimals),
          textWidth = ctx.measureText(val).width;
          ctx.fillText(val, x2 - textWidth - 10, 5)
          x2 -= 5;
        }

        ctx.beginPath();
        ctx.moveTo(x1, 0);
        ctx.lineTo(x2, 0);
        ctx.closePath();
        ctx.stroke();

        ctx.rotate(this._radiansPerNick);

        value += options.scaleIncrement;
        i += 1;
      }

      ctx.restore();
    },

    drawHand: function(ctx) {
      ctx.lineWidth = 3;
      ctx.beginPath();
      ctx.moveTo(0, 3);
      ctx.lineTo(this.width / 2.3, 3);
      ctx.closePath();
      ctx.stroke();
    },

    moveHand: function() {
      var options = this.options,
      canvas = this.handCanvas;

      if (this.value > options.maxLimit) {
        this.value = options.maxLimit;
      } else if (this.value < options.minLimit) {
        this.value = options.minLimit;
      }

      var handAngle = this._valueToAngle(this.value) * (180 / Math.PI);

      canvas.style[this._prefixedTransform] =
        'rotate(' + handAngle + 'deg)';
    },

    setValue: function(value) {
      if (this.value === value) {
        return;
      }

      this.value = value;
      this.render();

      return this;
    },

    increment: function(i) {
      this.value += i;
      this.render();

      return this;
    },

    setCriticals: function(min, max) {
      var ctx = this.criticalCanvas.getContext('2d'),
      me = this;

      if (typeof min === 'object') {
        max = min.max;
        min = min.min;
      }

      if (min) {
        this.options.minCritical = min;
      }

      if (max) {
        this.options.maxCritical = max;
      }

      window.requestAnimationFrame(function() {
        me.drawCriticals(ctx);
      });

      return this;
    },

    _createHandCanvas: function() {
      var canvas = document.createElement('canvas');

      if (this.el.id) {
        canvas.id = this.el.id+'-hand';
      }
      canvas.width = this.width / 2;
      canvas.height = 6;
      canvas.style.zIndex = 1;
      canvas.style[M.prefixed('TransformOrigin')] = '0px '+(canvas.height / 2)+'px';
      if (M.csstransitions && this.options.handTransition) {
        canvas.style[M.prefixed('Transition')] = this.options.handTransition;
      }
      canvas.style.position = 'absolute';
      canvas.style.top = (this.height / 2 - (canvas.height / 2)) + 'px';
      canvas.style.left = (this.width / 2) + 'px';

      this.el.appendChild(canvas);
      return canvas;
    },

    _createCanvas: function(id) {
      var canvas = document.createElement('canvas');

      if (this.el.id) {
        canvas.id = this.el.id+'-'+id;
      }
      canvas.width = this.width;
      canvas.height = this.height;
      canvas.style.position = 'absolute';
      canvas.style.top = '0px';
      canvas.style.left = '0px';

      this.el.appendChild(canvas);
      return canvas;
    },

    _valueToAngle: function(value) {
      var options = this.options,
      pos = (value >= 0) ?
        value / options.scaleIncrement + this._zeroNick :
        Math.abs(value - options.minLimit) / options.scaleIncrement;

      return pos * this._radiansPerNick +
        (options.scaleStartAngle - options.scaleSpanAngle);
    }
  };

  // Export
  window.RoundGauge = RoundGaugeView;
})(this, this.Modernizr /*(optional)*/);<commit_msg>Check if criticals changed to prevent unnecessary animation frame request<commit_after>/* global window */
(function(window, M) {
  "use strict";

    // Feature detects checks
    var features = {
      canvas: (!M && (function() {
        // TODO: canvas feature detect
        return true;
      })) || M.canvas
    };

    // shim layer with setTimeout fallback
    window.requestAnimFrame = (function(){
      return  window.requestAnimationFrame       ||
              window.webkitRequestAnimationFrame ||
              window.mozRequestAnimationFrame    ||
              window.oRequestAnimationFrame      ||
              window.msRequestAnimationFrame     ||
              function( callback ){
                window.setTimeout(callback, 1000 / 60);
              };
    })();

   var CanvasHelper = {
    PIx2: Math.PI * 2,

    wedge: function(ctx, x, y, r, startAngle, endAngle, antiClockwise) {
      ctx.beginPath();
      ctx.moveTo(x,y);
      ctx.arc(x, y, r, startAngle, endAngle, !!antiClockwise);
      ctx.lineTo(x,y);
      ctx.closePath();

      return ctx;
    },

    circle: function(ctx, x, y, r) {
      ctx.beginPath();
      ctx.arc(x, y, r, 0, this.PIx2);
      ctx.closePath();
      return ctx;
    },

    radToDeg: function(rad) {
      return rad * (180.0 / Math.PI);
    }
  };

  var shallowExtend = function(dest, src) {
    for (var property in src) {
      dest[property] = src[property];
    }
    return dest;
  };

  var RoundGaugeView = function(options) {
    this.options = options || {};
    this.initialize();
  };

  RoundGaugeView.prototype = {
    el: null,

    faceCanvas: null,
    handCanvas: null,
    criticalCanvas: null,

    width: 0,
    height: 0,

    _noOfNicks: 0,
    _radiansPerNick: 0,
    _zeroNick: 0,

    _prefixedTransform: '',

    _initialDrawingComplete: false,

    initialize: function() {

      this.options = shallowExtend({
        id: null,
        css: null,
        classes: null,

        el: null,

        minLimit: 0,
        maxLimit: 100,

        minCritical: false,
        minCriticalStyle: 'rgba(255,0,0,.55)',
        maxCritical: false,
        maxCriticalStyle: 'rgba(255,0,0,.55)',

        value: 0,

        units: '',
        unitFont: '10pt Arial',
        valueReadOut: true,

        width: 400,
        height: 400,

        handTransition: false,

        scaleIncrement: 1,
        scaleStartAngle: Math.PI / 4,
        scaleSpanAngle: Math.PI * 1.5,
        scaleFont: '8pt Arial'
      }, this.options);

      this.el = (!this.options.el) ?
        window.document.createElement('div') :
        this.options.el;

      if (this.options.id) {
        this.el.id = this.options.id;
      }

      this.value = this.options.value;
    },

    frames:0,

    render: function() {
      if (!this._initialDrawingComplete) {
        this.initDrawing();
      }

      this.frames++;

      window.requestAnimFrame(this.moveHand.bind(this));

      return this;
    },

    initDrawing: function() {
      var options = this.options;

      this.faceCanvas = this._createCanvas('face');

      if (options.width) {
        this.el.style.width = (this.faceCanvas.width = options.width)+'px';
      }

      if (options.height) {
        this.el.style.height = (this.faceCanvas.height = options.height)+'px';
      }

      this.width = this.faceCanvas.width;
      this.height = this.faceCanvas.height;

      this._noOfNicks = Math.round(options.maxLimit - options.minLimit) /
        this.options.scaleIncrement;

      this._radiansPerNick = options.scaleSpanAngle / this._noOfNicks;

      this._zeroNick = (options.minLimit < 0) ?
        Math.abs(options.minLimit) / options.scaleIncrement : 0;

      this._prefixedTransform = M.prefixed('Transform');

      var ctx = this.faceCanvas.getContext('2d');
      this.drawFace(ctx);
      this.drawScale(ctx);

      if (!this.handCanvas) {
        this.handCanvas = this._createHandCanvas();
        this.drawHand(this.handCanvas.getContext('2d'));
      }

      if (!this.criticalCanvas) {
        this.criticalCanvas = this._createCanvas('criticals');
        this.drawCriticals(this.criticalCanvas.getContext('2d'));
      }

      this._initialDrawingComplete = true;
    },

    drawFace: function(ctx) {
      var options = this.options;

      ctx.save();
      ctx.lineWidth = 1;
      ctx.fillStyle = 'white';

      CanvasHelper.circle(ctx,
        this.width / 2, this.height / 2,
        Math.min(this.width, this.height) / 2 - 1
      );

      ctx.fill();
      ctx.stroke();

      // Inner face circle
      CanvasHelper.circle(ctx,
        this.width / 2, this.height / 2,
        Math.min(this.width, this.height) / 7 - 1
      );

      ctx.stroke();

      ctx.fillStyle = 'black';

      CanvasHelper.circle(ctx,
        this.width / 2, this.height / 2,
        Math.min(this.width, this.height) / 28 - 1
      );

      ctx.fill();
      ctx.stroke();

      // Units text
      if (options.units) {
        ctx.font = options.unitFont;
        var textWidth = ctx.measureText(options.units).width;
        ctx.fillText(options.units, this.width / 2 - textWidth / 2, this.height - 30);
      }

      ctx.restore();
    },

    drawCriticals: function(ctx) {
      var options = this.options;

      ctx.clearRect(0,0,this.width, this.height);

      if (options.maxCritical !== false) {
        ctx.save();
        ctx.fillStyle = options.maxCriticalStyle;
        ctx.lineWidth = 1;

        var maxAngle = this._valueToAngle(options.maxCritical);

        CanvasHelper.wedge(ctx,
          this.width / 2, this.height / 2,
          this.width / 2.3,
          maxAngle,  options.scaleStartAngle
        );

        ctx.fill();
        ctx.restore();
      }

      if (options.minCritical !== false) {
        ctx.save();
        ctx.fillStyle = options.minCriticalStyle;
        ctx.lineWidth = 1;

        var minAngle = this._valueToAngle(options.minCritical);

        CanvasHelper.wedge(ctx,
          this.width / 2, this.height / 2,
          this.width / 2.3,
          this._valueToAngle(options.minLimit), minAngle
        );

        ctx.fill();
        ctx.restore();
      }
    },

    drawScale: function(ctx) {
      var minDim = Math.min(this.width, this.height),
      options = this.options,
      scaleIndent = 10,
      noOfDecimals = (""+options.scaleIncrement).length - 2;

      if (noOfDecimals < 0) {
        noOfDecimals = 0;
      }

      ctx.save();

      // Transform canvas
      ctx.translate(this.width / 2, this.height / 2);
      ctx.rotate(options.scaleStartAngle - options.scaleSpanAngle);

      ctx.font = options.scaleFont;
      ctx.lineWidth = 1;

      var
      valueInterval = Math.max(this._noOfNicks / 10, 1),
      value = options.minLimit,
      i = 0,
      x1 = this.width / 2 - scaleIndent, x2;

      while (i <= this._noOfNicks) {
        x2 = x1 - 10;

        if (i % valueInterval === 0) {
          var val = value.toFixed(noOfDecimals),
          textWidth = ctx.measureText(val).width;
          ctx.fillText(val, x2 - textWidth - 10, 5)
          x2 -= 5;
        }

        ctx.beginPath();
        ctx.moveTo(x1, 0);
        ctx.lineTo(x2, 0);
        ctx.closePath();
        ctx.stroke();

        ctx.rotate(this._radiansPerNick);

        value += options.scaleIncrement;
        i += 1;
      }

      ctx.restore();
    },

    drawHand: function(ctx) {
      ctx.lineWidth = 3;
      ctx.beginPath();
      ctx.moveTo(0, 3);
      ctx.lineTo(this.width / 2.3, 3);
      ctx.closePath();
      ctx.stroke();
    },

    moveHand: function() {
      var options = this.options,
      canvas = this.handCanvas;

      if (this.value > options.maxLimit) {
        this.value = options.maxLimit;
      } else if (this.value < options.minLimit) {
        this.value = options.minLimit;
      }

      var handAngle = this._valueToAngle(this.value) * (180 / Math.PI);

      canvas.style[this._prefixedTransform] =
        'rotate(' + handAngle + 'deg)';
    },

    setValue: function(value) {
      if (this.value === value) {
        return;
      }

      this.value = value;
      this.render();

      return this;
    },

    increment: function(i) {
      this.value += i;
      this.render();

      return this;
    },

    setCriticals: function(min, max) {
      var ctx = this.criticalCanvas.getContext('2d'),
      me = this,
      options = this.options;

      if (typeof min === 'object') {
        max = min.max;
        min = min.min;
      }

      var hasChanged = false;

      if (min && min != options.minCritical) {
        hasChanged = true;
        this.options.minCritical = min;
      }

      if (max && max != options.maxCritical) {
        hasChanged = true;
        this.options.maxCritical = max;
      }

      if (!hasChanged) { return; }

      window.requestAnimFrame(function() {
        me.drawCriticals(ctx);
      });

      return this;
    },

    _createHandCanvas: function() {
      var canvas = document.createElement('canvas');

      if (this.el.id) {
        canvas.id = this.el.id+'-hand';
      }
      canvas.width = this.width / 2;
      canvas.height = 6;
      canvas.style.zIndex = 1;
      canvas.style[M.prefixed('TransformOrigin')] = '0px '+(canvas.height / 2)+'px';
      if (M.csstransitions && this.options.handTransition) {
        canvas.style[M.prefixed('Transition')] = this.options.handTransition;
      }
      canvas.style.position = 'absolute';
      canvas.style.top = (this.height / 2 - (canvas.height / 2)) + 'px';
      canvas.style.left = (this.width / 2) + 'px';

      this.el.appendChild(canvas);
      return canvas;
    },

    _createCanvas: function(id) {
      var canvas = document.createElement('canvas');

      if (this.el.id) {
        canvas.id = this.el.id+'-'+id;
      }
      canvas.width = this.width;
      canvas.height = this.height;
      canvas.style.position = 'absolute';
      canvas.style.top = '0px';
      canvas.style.left = '0px';

      this.el.appendChild(canvas);
      return canvas;
    },

    _valueToAngle: function(value) {
      var options = this.options,
      pos = (value >= 0) ?
        value / options.scaleIncrement + this._zeroNick :
        Math.abs(value - options.minLimit) / options.scaleIncrement;

      return pos * this._radiansPerNick +
        (options.scaleStartAngle - options.scaleSpanAngle);
    }
  };

  // Export
  window.RoundGauge = RoundGaugeView;
})(this, this.Modernizr /*(optional)*/);<|endoftext|>


<commit_before>var Beaver = Class.create(Animal, {
    initialize : function(pos, scale) {
        Animal.call(this, 64, 64,
            "beaver",
            9,
            pos, 30, 190, scale);
        this.cowFriendly = 0;
    },

    cowFriendly : 0,

    smell: function(a) {
        if (a.type == "cow" && !this.cowFriendly) {
            if (a.groupSize() > this.groupSize()) {
                this.detachAnimal();

                //this.attachAnimal(a);  // why this is a bug??
                this.followedObject = a.groupie;

                this.cowFriendly = 1;
            }
            else {
                this.followedObject = a;
            }
        }
    },

    onColidedWith : function(a) {
        if (a.type == "cow" && !this.cowFriendly)
            a.onDie();
    }
});
<commit_msg>Beaver follow bug hack-fix.<commit_after>var Beaver = Class.create(Animal, {
    initialize : function(pos, scale) {
        Animal.call(this, 64, 64,
            "beaver",
            9,
            pos, 30, 190, scale);
        this.cowFriendly = 0;
    },

    cowFriendly : 0,

    smell: function(a) {
        if (a.type == "cow" && !this.cowFriendly) {
            if (a.groupSize() > this.groupSize()) {
                this.detachAnimal();

                //this.attachAnimal(a);  // why this is a bug??
                this.followedObject = a; //.groupie;

                this.cowFriendly = 1;
            }
            else {
                this.followedObject = a;
            }
        }
    },

    onColidedWith : function(a) {
        if (a.type == "cow" && !this.cowFriendly)
            a.onDie();
    }
});
<|endoftext|>


<commit_before>
// Javascript controlling the taxonomy browser.

var TaxonomyBrowser = function() {
  var self = this;

  self.init = function() {
    self.$browserDiv = $('#browse-container');
    self.loadTerms(null);
  };

  // Renders the browser, given a JSON list of subjects.
  self.renderTerms = function(terms) {
    var termList = '';
    for (var i = 0; i < terms.length; i++) {
      var fullPath = terms[i].subject;
      var levels = fullPath.split('/');
      var leaf = levels[levels.length - 1];
      var termHtml = $('#subject-term-template').html();
      termHtml = termHtml.replace('__TAXONOMY_TERM_ESCAPED__', encodeURIComponent(leaf));
      termHtml = termHtml.replace('__TAXONOMY_TERM_LEAF__', leaf);
      termHtml = termHtml.replace('__TAXONOMY_TERM_FULL_PATH__', fullPath);
      var childLinkStyle = 'browse-further browse-right';
      if (terms[i].childCount === 0) {
        childLinkStyle += ' inactive';
      }
      termHtml = termHtml.replace('__CHILD_LINK_STYLE__', childLinkStyle);
      termList += termHtml;
    }
    var html = $('#subject-list-template').html();
    html = html.replace('__TAXONOMY_LINKS__', termList);
    $('#browse-container').html(html);
    $('a.browse-further').click(function(e) {
      self.loadTerms($(this).data('term'));
    });
  };

  // Loads the child terms given a parent term.  If the parent evaluates to false,
  // the root taxonomy terms will be loaded.
  self.loadTerms = function(parent) {
    var url = 'taxonomy';
    if (parent) {
      url += parent;
    } else {
      url += '/';
    }
    $.ajax(url, {
      type: 'GET',
      success: function(data) {
        self.renderTerms(data);
      },
      error: function(xOptions, textStatus) {
        console.log(textStatus);
      }
    });
  };
};

$(document).ready(function () {
  var browser = new TaxonomyBrowser();
  browser.init();
});
<commit_msg>Only render the taxonomy browser when we need to.  Gets rid of a javascript error on all page loads.<commit_after>
// Javascript controlling the taxonomy browser.

var TaxonomyBrowser = function() {
  var self = this;

  self.init = function() {
    self.$browserDiv = $('#browse-container');
    if (self.$browserDiv.length) {
      self.loadTerms(null);
    }
  };

  // Renders the browser, given a JSON list of subjects.
  self.renderTerms = function(terms) {
    var termList = '';
    for (var i = 0; i < terms.length; i++) {
      var fullPath = terms[i].subject;
      var levels = fullPath.split('/');
      var leaf = levels[levels.length - 1];
      var termHtml = $('#subject-term-template').html();
      termHtml = termHtml.replace('__TAXONOMY_TERM_ESCAPED__', encodeURIComponent(leaf));
      termHtml = termHtml.replace('__TAXONOMY_TERM_LEAF__', leaf);
      termHtml = termHtml.replace('__TAXONOMY_TERM_FULL_PATH__', fullPath);
      var childLinkStyle = 'browse-further browse-right';
      if (terms[i].childCount === 0) {
        childLinkStyle += ' inactive';
      }
      termHtml = termHtml.replace('__CHILD_LINK_STYLE__', childLinkStyle);
      termList += termHtml;
    }
    var html = $('#subject-list-template').html();
    html = html.replace('__TAXONOMY_LINKS__', termList);
    $('#browse-container').html(html);
    $('a.browse-further').click(function(e) {
      self.loadTerms($(this).data('term'));
    });
  };

  // Loads the child terms given a parent term.  If the parent evaluates to false,
  // the root taxonomy terms will be loaded.
  self.loadTerms = function(parent) {
    var url = 'taxonomy';
    if (parent) {
      url += parent;
    } else {
      url += '/';
    }
    $.ajax(url, {
      type: 'GET',
      success: function(data) {
        self.renderTerms(data);
      },
      error: function(xOptions, textStatus) {
        console.log(textStatus);
      }
    });
  };
};

$(document).ready(function () {
  var browser = new TaxonomyBrowser();
  browser.init();
});
<|endoftext|>


<commit_before>const path = require('path')
const React = require('react')

const colors = require('material-ui/styles/colors')
const Checkbox = require('material-ui/Checkbox').default
const RaisedButton = require('material-ui/RaisedButton').default
const Heading = require('../components/heading')
const PathSelector = require('../components/path-selector')

const {dispatch} = require('../lib/dispatcher')
const config = require('../../config')

class PreferencesPage extends React.Component {
  constructor (props) {
    super(props)

    this.handleDownloadPathChange =
      this.handleDownloadPathChange.bind(this)

    this.handleOpenExternalPlayerChange =
      this.handleOpenExternalPlayerChange.bind(this)

    this.handleExternalPlayerPathChange =
      this.handleExternalPlayerPathChange.bind(this)

    this.handleStartupChange =
      this.handleStartupChange.bind(this)
  }

  downloadPathSelector () {
    return (
      <Preference>
        <PathSelector
          dialog={{
            title: 'Select download directory',
            properties: [ 'openDirectory' ]
          }}
          onChange={this.handleDownloadPathChange}
          title='Download location'
          value={this.props.state.unsaved.prefs.downloadPath} />
      </Preference>
    )
  }

  handleDownloadPathChange (filePath) {
    dispatch('updatePreferences', 'downloadPath', filePath)
  }

  openExternalPlayerCheckbox () {
    return (
      <Preference>
        <Checkbox
          className='control'
          checked={!this.props.state.unsaved.prefs.openExternalPlayer}
          label={'Play torrent media files using WebTorrent'}
          onCheck={this.handleOpenExternalPlayerChange} />
      </Preference>
    )
  }

  handleOpenExternalPlayerChange (e, isChecked) {
    dispatch('updatePreferences', 'openExternalPlayer', !isChecked)
  }

  highestPlaybackPriorityCheckbox () {
    return (
      <Preference>
        <Checkbox
          className='control'
          checked={this.props.state.unsaved.prefs.highestPlaybackPriority}
          label={'Highest Playback Priority'}
          onCheck={this.handleHighestPlaybackPriorityChange}
        />

Pauses all active torrents to allow playback to use all of the available bandwidth.

      </Preference>
    )
  }

  handleHighestPlaybackPriorityChange (e, isChecked) {
    dispatch('updatePreferences', 'highestPlaybackPriority', isChecked)
  }

  externalPlayerPathSelector () {
    const playerPath = this.props.state.unsaved.prefs.externalPlayerPath
    const playerName = this.props.state.getExternalPlayerName()

    const description = this.props.state.unsaved.prefs.openExternalPlayer
      ? `Torrent media files will always play in ${playerName}.`
      : `Torrent media files will play in ${playerName} if WebTorrent cannot play them.`

    return (
      <Preference>

{description}

        <PathSelector
          dialog={{
            title: 'Select media player app',
            properties: [ 'openFile' ]
          }}
          displayValue={playerName}
          onChange={this.handleExternalPlayerPathChange}
          title='External player'
          value={playerPath ? path.dirname(playerPath) : null} />
      </Preference>
    )
  }

  handleExternalPlayerPathChange (filePath) {
    dispatch('updatePreferences', 'externalPlayerPath', filePath)
  }

  autoAddTorrentsCheckbox () {
    return (
      <Preference>
        <Checkbox
          className='control'
          checked={this.props.state.unsaved.prefs.autoAddTorrents}
          label={'Enable'}
          onCheck={(e, value) => { this.handleAutoAddTorrentsChange(e, value) }}
        />
      </Preference>
    )
  }

  handleAutoAddTorrentsChange (e, isChecked) {
    const torrentsFolderPath = this.props.state.unsaved.prefs.torrentsFolderPath
    if (isChecked && !torrentsFolderPath) {
      alert('Select a torrents folder first.') // eslint-disable-line
      e.preventDefault()
      return
    }

    dispatch('updatePreferences', 'autoAddTorrents', isChecked)

    if (isChecked) {
      dispatch('startFolderWatcher', null)
      return
    }

    dispatch('stopFolderWatcher', null)
  }

  torrentsFolderPathSelector () {
    const torrentsFolderPath = this.props.state.unsaved.prefs.torrentsFolderPath

    const value = torrentsFolderPath || 'Path to be watched.'
    const description = 'Torrent files saved to this folder will be automatically added.'

    return (
      <Preference>

{description}

        <PathSelector
          dialog={{
            title: 'Select torrents folder path',
            properties: [ 'openDirectory' ]
          }}
          displayValue={value}
          onChange={this.handletorrentsFolderPathChange}
          title='Torrents folder'
          value={torrentsFolderPath ? path.dirname(torrentsFolderPath) : null} />
      </Preference>
    )
  }

  handletorrentsFolderPathChange (filePath) {
    dispatch('updatePreferences', 'torrentsFolderPath', filePath)
  }

  setDefaultAppButton () {
    const isFileHandler = this.props.state.unsaved.prefs.isFileHandler
    if (isFileHandler) {
      return (
        <Preference>

WebTorrent is your default torrent app. Hooray!

        </Preference>
      )
    }
    return (
      <Preference>

WebTorrent is not currently the default torrent app.

        <RaisedButton
          className='control'
          onClick={this.handleSetDefaultApp}
          label='Make WebTorrent the default' />
      </Preference>
    )
  }

  handleStartupChange (e, isChecked) {
    dispatch('updatePreferences', 'startup', isChecked)
  }

  setStartupSection () {
    if (config.IS_PORTABLE) {
      return
    }

    return (
      <PreferencesSection title='Startup'>
        <Preference>
          <Checkbox
            className='control'
            checked={this.props.state.unsaved.prefs.startup}
            label={'Open WebTorrent on startup.'}
            onCheck={this.handleStartupChange}
          />
        </Preference>
      </PreferencesSection>
    )
  }

  handleSetDefaultApp () {
    dispatch('updatePreferences', 'isFileHandler', true)
  }

  render () {
    const style = {
      color: colors.grey400,
      marginLeft: 25,
      marginRight: 25
    }
    return (

        <PreferencesSection title='Downloads'>
          {this.downloadPathSelector()}
        </PreferencesSection>
        <PreferencesSection title='Playback'>
          {this.openExternalPlayerCheckbox()}
          {this.externalPlayerPathSelector()}
          {this.highestPlaybackPriorityCheckbox()}
        </PreferencesSection>
        <PreferencesSection title='Default torrent app'>
          {this.setDefaultAppButton()}
        </PreferencesSection>
        <PreferencesSection title='Auto add torrents'>
          {this.autoAddTorrentsCheckbox()}
          {this.torrentsFolderPathSelector()}
        </PreferencesSection>
        {this.setStartupSection()}

    )
  }
}

class PreferencesSection extends React.Component {
  static get propTypes () {
    return {
      title: React.PropTypes.string
    }
  }

  render () {
    const style = {
      marginBottom: 25,
      marginTop: 25
    }
    return (

        <Heading level={2}>{this.props.title}</Heading>
        {this.props.children}

    )
  }
}

class Preference extends React.Component {
  render () {
    const style = { marginBottom: 10 }
    return (
{this.props.children}
)
  }
}

module.exports = PreferencesPage
<commit_msg>Preferences update<commit_after>const path = require('path')
const React = require('react')

const colors = require('material-ui/styles/colors')
const Checkbox = require('material-ui/Checkbox').default
const RaisedButton = require('material-ui/RaisedButton').default
const Heading = require('../components/heading')
const PathSelector = require('../components/path-selector')

const {dispatch} = require('../lib/dispatcher')
const config = require('../../config')

class PreferencesPage extends React.Component {
  constructor (props) {
    super(props)

    this.handleDownloadPathChange =
      this.handleDownloadPathChange.bind(this)

    this.handleOpenExternalPlayerChange =
      this.handleOpenExternalPlayerChange.bind(this)

    this.handleExternalPlayerPathChange =
      this.handleExternalPlayerPathChange.bind(this)

    this.handleStartupChange =
      this.handleStartupChange.bind(this)
  }

  downloadPathSelector () {
    return (
      <Preference>
        <PathSelector
          dialog={{
            title: 'Select download directory',
            properties: [ 'openDirectory' ]
          }}
          onChange={this.handleDownloadPathChange}
          title='Download location'
          value={this.props.state.unsaved.prefs.downloadPath} />
      </Preference>
    )
  }

  handleDownloadPathChange (filePath) {
    dispatch('updatePreferences', 'downloadPath', filePath)
  }

  openExternalPlayerCheckbox () {
    return (
      <Preference>
        <Checkbox
          className='control'
          checked={!this.props.state.unsaved.prefs.openExternalPlayer}
          label={'Play torrent media files using WebTorrent'}
          onCheck={this.handleOpenExternalPlayerChange} />
      </Preference>
    )
  }

  handleOpenExternalPlayerChange (e, isChecked) {
    dispatch('updatePreferences', 'openExternalPlayer', !isChecked)
  }

  highestPlaybackPriorityCheckbox () {
    return (
      <Preference>
        <Checkbox
          className='control'
          checked={this.props.state.unsaved.prefs.highestPlaybackPriority}
          label={'Highest Playback Priority'}
          onCheck={this.handleHighestPlaybackPriorityChange}
        />

Pauses all active torrents to allow playback to use all of the available bandwidth.

      </Preference>
    )
  }

  handleHighestPlaybackPriorityChange (e, isChecked) {
    dispatch('updatePreferences', 'highestPlaybackPriority', isChecked)
  }

  externalPlayerPathSelector () {
    const playerPath = this.props.state.unsaved.prefs.externalPlayerPath
    const playerName = this.props.state.getExternalPlayerName()

    const description = this.props.state.unsaved.prefs.openExternalPlayer
      ? `Torrent media files will always play in ${playerName}.`
      : `Torrent media files will play in ${playerName} if WebTorrent cannot play them.`

    return (
      <Preference>

{description}

        <PathSelector
          dialog={{
            title: 'Select media player app',
            properties: [ 'openFile' ]
          }}
          displayValue={playerName}
          onChange={this.handleExternalPlayerPathChange}
          title='External player'
          value={playerPath ? path.dirname(playerPath) : null} />
      </Preference>
    )
  }

  handleExternalPlayerPathChange (filePath) {
    dispatch('updatePreferences', 'externalPlayerPath', filePath)
  }

  autoAddTorrentsCheckbox () {
    return (
      <Preference>
        <Checkbox
          className='control'
          checked={this.props.state.unsaved.prefs.autoAddTorrents}
          label={'Watch for new .torrent files and add them immediately'}
          onCheck={(e, value) => { this.handleAutoAddTorrentsChange(e, value) }}
        />
      </Preference>
    )
  }

  handleAutoAddTorrentsChange (e, isChecked) {
    const torrentsFolderPath = this.props.state.unsaved.prefs.torrentsFolderPath
    if (isChecked && !torrentsFolderPath) {
      alert('Select a torrents folder first.') // eslint-disable-line
      e.preventDefault()
      return
    }

    dispatch('updatePreferences', 'autoAddTorrents', isChecked)

    if (isChecked) {
      dispatch('startFolderWatcher', null)
      return
    }

    dispatch('stopFolderWatcher', null)
  }

  torrentsFolderPathSelector () {
    const torrentsFolderPath = this.props.state.unsaved.prefs.torrentsFolderPath

    return (
      <Preference>
        <PathSelector
          dialog={{
            title: 'Select folder to watch for new torrents',
            properties: [ 'openDirectory' ]
          }}
          displayValue={torrentsFolderPath || ''}
          onChange={this.handletorrentsFolderPathChange}
          title='Folder to watch'
          value={torrentsFolderPath ? path.dirname(torrentsFolderPath) : null} />
      </Preference>
    )
  }

  handletorrentsFolderPathChange (filePath) {
    dispatch('updatePreferences', 'torrentsFolderPath', filePath)
  }

  setDefaultAppButton () {
    const isFileHandler = this.props.state.unsaved.prefs.isFileHandler
    if (isFileHandler) {
      return (
        <Preference>

WebTorrent is your default torrent app. Hooray!

        </Preference>
      )
    }
    return (
      <Preference>

WebTorrent is not currently the default torrent app.

        <RaisedButton
          className='control'
          onClick={this.handleSetDefaultApp}
          label='Make WebTorrent the default' />
      </Preference>
    )
  }

  handleStartupChange (e, isChecked) {
    dispatch('updatePreferences', 'startup', isChecked)
  }

  setStartupSection () {
    if (config.IS_PORTABLE) {
      return
    }

    return (
      <PreferencesSection title='Startup'>
        <Preference>
          <Checkbox
            className='control'
            checked={this.props.state.unsaved.prefs.startup}
            label={'Open WebTorrent on startup.'}
            onCheck={this.handleStartupChange}
          />
        </Preference>
      </PreferencesSection>
    )
  }

  handleSetDefaultApp () {
    dispatch('updatePreferences', 'isFileHandler', true)
  }

  render () {
    const style = {
      color: colors.grey400,
      marginLeft: 25,
      marginRight: 25
    }
    return (

        <PreferencesSection title='Folders'>
          {this.downloadPathSelector()}
          {this.autoAddTorrentsCheckbox()}
          {this.torrentsFolderPathSelector()}
        </PreferencesSection>
        <PreferencesSection title='Playback'>
          {this.openExternalPlayerCheckbox()}
          {this.externalPlayerPathSelector()}
          {this.highestPlaybackPriorityCheckbox()}
        </PreferencesSection>
        <PreferencesSection title='Default torrent app'>
          {this.setDefaultAppButton()}
        </PreferencesSection>
        {this.setStartupSection()}

    )
  }
}

class PreferencesSection extends React.Component {
  static get propTypes () {
    return {
      title: React.PropTypes.string
    }
  }

  render () {
    const style = {
      marginBottom: 25,
      marginTop: 25
    }
    return (

        <Heading level={2}>{this.props.title}</Heading>
        {this.props.children}

    )
  }
}

class Preference extends React.Component {
  render () {
    const style = { marginBottom: 10 }
    return (
{this.props.children}
)
  }
}

module.exports = PreferencesPage
<|endoftext|>