<commit_before>/* Copyright (c) 2012-2014 The TagSpaces Authors. All rights reserved.
 * Use of this source code is governed by a AGPL3 license that
 * can be found in the LICENSE file. */
define(function (require, exports, module) {
    "use strict";

    exports.defaultSettings = {
        "appName":                  "@@APPNAME",
        "appVersion":               "@@VERSION",
        "appBuild":                 "@@BUILD",
        "appBuildID":               "@@BID",
        "settingsVersion":           2,
        "newTextFileContent":       "",
        "newHTMLFileContent":       "<title>Created with TagSpaces</title><meta http-equiv='Content-Type' content='text/html; charset=utf-8'>",
        "newMDFileContent":         '',
        "showUnixHiddenEntries":    false,
        "checkForUpdates":          true,
        "firstRun":                 true,
        "lastOpenedDirectory":      "",
        "tagspacesList":            [@@DEFAULTLOCATIONS],
        "extensionsPath":           "ext",
        "showWarningRecursiveScan": true,
        "prefixTagContainer":       "",
        "tagDelimiter":             " ",
        "calculateTags":            false,
        "loadLocationMeta":         false,
        "warnIncludeSubdirs":       true,
        "isWindowMaximized":        false,
        "showMainMenu":             true,
        "lastOpenedLocation":       "",
        "webDavPath"  :             "oc/remote.php/webdav",
        "ootbPerspectives":         [@@DEFAULTPERSPECTIVES],
        "ootbViewers":              [ "viewerBrowser", "viewerMD", "viewerImage", "viewerPDF", "editorText", "viewerText", "editorODF", "viewerURL" ],
        "ootbEditors":              [ "editorHTML", "editorText", "editorODF" ],
        "perspectives":             [@@ACTIVATEDPERSPECTIVES],
        "interfaceLanguage": "en_US",
        "supportedLanguages": [
            { "iso": "en-US",   "title": "English" },
            { "iso": "de_DE",   "title": "Deutsch (German)" },
            { "iso": "it",	    "title": "Italiano (Italian)" },
            { "iso": "zh_CN",	"title": "中国的 (Chinese)" },
            { "iso": "bg",  	"title": "Български (Bulgarian)" },
            { "iso": "ja",  	"title": "日本の (Japanese)" },
            { "iso": "pt_BR",   "title": "Português (Brazil)" },
            { "iso": "pt_PT",   "title": "Português (Portugal)" },
            { "iso": "fr",	    "title": "Français (French)" },
            { "iso": "sk_SK",   "title": "Slovenský (Slovak)" },
            { "iso": "es",	    "title": "Español (Spanish)" },
            { "iso": "uk",	    "title": "Український (Ukrainian)" },
            { "iso": "ru",	    "title": "Русский (Russian)" }
        ],
        "keyBindings": {
            "closeViewer":              "mod+w",
            "saveDocument":             "mod+s",
            "reloadDocument":           "mod+r",
            "editDocument":             "mod+e",
            "deleteDocument":           "del",
            "showTagLibrary":           "s t",
            "showFolderNavigator":      "s f",
            "toggleShowHiddenEntries":  "mod+h",
            "addRemoveTags":            "mod+t",
            "propertiesDocument":       "alt+enter",
            "nextDocument":             ['right', 'down'],
            "prevDocument":             ['left', 'up'],
            "showHelp":                 "f1",
            "reloadApplication":        "r a",
            "toggleFullScreen":         "f11",
            "openDevTools":             "f12"
        },
        "supportedFileTypes": [
            { "type": "jpg",	"viewer": "viewerImage",     "editor": "false" },
            { "type": "jpeg", 	"viewer": "viewerImage",     "editor": "false" },
            { "type": "gif", 	"viewer": "viewerImage",     "editor": "false" },
            { "type": "png", 	"viewer": "viewerImage",     "editor": "false" },
            { "type": "webp", 	"viewer": "viewerImage",     "editor": "false" },
            { "type": "bmp", 	"viewer": "viewerImage",     "editor": "false" },
            { "type": "svg", 	"viewer": "viewerImage",   "editor": "editorText" },
            { "type": "pdf", 	"viewer": "@@PDFVIEWER",	 "editor": "false" },
            { "type": "html", 	"viewer": "viewerBrowser",   "editor": "editorHTML" },
            { "type": "htm", 	"viewer": "viewerBrowser",   "editor": "editorHTML" },
            { "type": "xhtml", 	"viewer": "viewerBrowser",   "editor": "editorText" },
            { "type": "mht", 	"viewer": "@@MHTVIEWER",     "editor": "false" },
            { "type": "mhtml", 	"viewer": "@@MHTVIEWER",     "editor": "false" },
            { "type": "odt",    "viewer": "editorODF",       "editor": "false" },
            { "type": "ods",    "viewer": "editorODF",       "editor": "false" },
            { "type": "odp",    "viewer": "editorODF",       "editor": "false" },
            { "type": "odg",    "viewer": "editorODF",       "editor": "false" },
            { "type": "txt", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "xml", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "js", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "json",   "viewer": "editorText",      "editor": "editorText" },
            { "type": "css", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "h", 		"viewer": "editorText",      "editor": "editorText" },
            { "type": "c", 		"viewer": "editorText",      "editor": "editorText" },
            { "type": "clj", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "coffee", "viewer": "editorText",      "editor": "editorText" },
            { "type": "cpp", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "cs", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "groovy", "viewer": "editorText",      "editor": "editorText" },
            { "type": "haxe", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "java", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "jsm", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "less", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "lua", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "ml", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "mli", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "pl", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "php", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "py", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "rb", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "sh", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "sql", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "mkd", 	"viewer": "viewerMD",        "editor": "editorText" },
            { "type": "mdwn", 	"viewer": "viewerMD",        "editor": "editorText" },
            { "type": "markdown","viewer": "viewerMD",       "editor": "editorText" },
            { "type": "mdown", 	"viewer": "viewerMD",        "editor": "editorText" },
            { "type": "md", 	"viewer": "viewerMD",        "editor": "editorText" },
            { "type": "avi", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "ogg", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "ogv", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "oga", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "ogx", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "spx", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "opus", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "mp3", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "mp4", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "m4p", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "wav", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "wave", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "webm", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "m4v", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "m4a", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "mov", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "desktop","viewer": "viewerURL",       "editor": "false" },
            { "type": "website","viewer": "viewerURL",       "editor": "false" },
            { "type": "url", 	"viewer": "viewerURL",       "editor": "false" }
        ],
        "tagGroups": [
            {
                "title":"Common Tags",
                "isFolder": "true",
                "key":"OTB",
                "expand": "true",
                "children":[
                    {
                        "title":"book",
                        "type":"plain"
                    },
                    {
                        "title":"paper",
                        "type":"plain"
                    }
                ]
            },
            {
                "title":"Getting Things Done",
                "isFolder": "true",
                "key":"GTD",
                "expand": "true",
                "children":[
                    {
                        "title":"done",
                        "type":"plain"
                    },
                    {
                        "title":"next",
                        "type":"plain"
                    },
                    {
                        "title":"maybe",
                        "type":"plain"
                    },
                    {
                        "title":"waiting",
                        "type":"plain"
                    }
                ]
            },
            {
                "title": "Smart Tags",
                "key": "SMR",
                "expanded": true,
                "children": [
                    {
                        "type":          "smart",
                        "title":         "now",
                        "functionality": "now",
                        "desciption":    "Adds the current date and time as tag",
                        "color":         "#4986e7",
                        "textcolor":     "#ffffff"
                    },
                    {
                        "type":          "smart",
                        "title":         "today",
                        "functionality": "today",
                        "desciption":    "Adds the current date as tag",
                        "color":         "#4986e7",
                        "textcolor":     "#ffffff"
                    },
                    {
                        "type":          "smart",
                        "title":         "tomorrow",
                        "functionality": "tomorrow",
                        "desciption":    "Adds tomorrow's date as tag",
                        "color":         "#4986e7",
                        "textcolor":     "#ffffff"
                    },
                    {
                        "type":          "smart",
                        "title":         "yesterday",
                        "functionality": "yesterday",
                        "desciption":    "Adds the date of yesterday as tag",
                        "color":         "#4986e7",
                        "textcolor":     "#ffffff"
                    },
                    {
                        "type":          "smart",
                        "title":         "month",
                        "functionality": "currentMonth",
                        "desciption":    "Adds the current year and month as tag",
                        "color":         "#4986e7",
                        "textcolor":     "#ffffff"
                    },
                    {
                        "type":          "smart",
                        "title":         "year",
                        "functionality": "currentYear",
                        "desciption":    "Adds the current year as tag",
                        "color":         "#4986e7",
                        "textcolor":     "#ffffff"
                    }
                ]
            },
            {
                "title": "Priorities",
                "key": "PRI",
                "expanded": true,
                "children": [
                    {
                        "type": "plain",
                        "title": "high",
                        "color": "#ff7537",
                        "textcolor": "#ffffff",
                        "keyBinding": "t h"
                    },
                    {
                        "type": "plain",
                        "title": "medium",
                        "color": "#ffad46",
                        "textcolor": "#ffffff",
                        "keyBinding": "t m"
                    },
                    {
                        "type": "plain",
                        "title": "low",
                        "color": "#7bd148",
                        "textcolor": "#ffffff",
                        "keyBinding": "t l"
                    }
                ]
            },
            {
                "title": "Ratings",
                "key": "REV",
                "expanded": true,
                "children": [
                    {
                        "type": "plain",
                        "title": "1star",
                        "color": "#FFCC24",
                        "textcolor": "#ffffff",
                        "keyBinding": "t 1"
                    },
                    {
                        "type": "plain",
                        "title": "2star",
                        "color": "#FFCC24",
                        "textcolor": "#ffffff",
                        "keyBinding": "t 2"
                    },
                    {
                        "type": "plain",
                        "title": "3star",
                        "color": "#FFCC24",
                        "textcolor": "#ffffff",
                        "keyBinding": "t 3"
                    },
                    {
                        "type": "plain",
                        "title": "4star",
                        "color": "#FFCC24",
                        "textcolor": "#ffffff",
                        "keyBinding": "t 4"
                    },
                    {
                        "type": "plain",
                        "title": "5star",
                        "color": "#FFCC24",
                        "textcolor": "#ffffff",
                        "keyBinding": "t 5"
                    }
                ]
            }
        ]
    };
});<commit_msg>updating the build number<commit_after>/* Copyright (c) 2012-2014 The TagSpaces Authors. All rights reserved.
 * Use of this source code is governed by a AGPL3 license that
 * can be found in the LICENSE file. */
define(function (require, exports, module) {
    "use strict";

    exports.defaultSettings = {
        "appName":                  "@@APPNAME",
        "appVersion":               "@@VERSION",
        "appBuild":                 "@@BUILD",
        "appBuildID":               "@@BID",
        "settingsVersion":           2,
        "newTextFileContent":       "",
        "newHTMLFileContent":       "<title>Created with TagSpaces</title><meta http-equiv='Content-Type' content='text/html; charset=utf-8'>",
        "newMDFileContent":         '',
        "showUnixHiddenEntries":    false,
        "checkForUpdates":          true,
        "firstRun":                 true,
        "lastOpenedDirectory":      "",
        "tagspacesList":            [@@DEFAULTLOCATIONS],
        "extensionsPath":           "ext",
        "showWarningRecursiveScan": true,
        "prefixTagContainer":       "",
        "tagDelimiter":             " ",
        "calculateTags":            false,
        "loadLocationMeta":         false,
        "warnIncludeSubdirs":       true,
        "isWindowMaximized":        false,
        "showMainMenu":             true,
        "lastOpenedLocation":       "",
        "webDavPath"  :             "oc/remote.php/webdav",
        "ootbPerspectives":         [@@DEFAULTPERSPECTIVES],
        "ootbViewers":              [ "viewerBrowser", "viewerMD", "viewerImage", "viewerPDF", "editorText", "viewerText", "editorODF", "viewerURL" ],
        "ootbEditors":              [ "editorHTML", "editorText", "editorODF" ],
        "perspectives":             [@@ACTIVATEDPERSPECTIVES],
        "interfaceLanguage": "en_US",
        "supportedLanguages": [
            { "iso": "en_US",   "title": "English" },
            { "iso": "de_DE",   "title": "Deutsch (German)" },
            { "iso": "it",	    "title": "Italiano (Italian)" },
            { "iso": "zh_CN",	"title": "中国的 (Chinese)" },
            { "iso": "bg",  	"title": "Български (Bulgarian)" },
            { "iso": "ja",  	"title": "日本の (Japanese)" },
            { "iso": "pt_BR",   "title": "Português (Brazil)" },
            { "iso": "pt_PT",   "title": "Português (Portugal)" },
            { "iso": "fr",	    "title": "Français (French)" },
            { "iso": "sk_SK",   "title": "Slovenský (Slovak)" },
            { "iso": "es",	    "title": "Español (Spanish)" },
            { "iso": "uk",	    "title": "Український (Ukrainian)" },
            { "iso": "ru",	    "title": "Русский (Russian)" }
        ],
        "keyBindings": {
            "closeViewer":              "mod+w",
            "saveDocument":             "mod+s",
            "reloadDocument":           "mod+r",
            "editDocument":             "mod+e",
            "deleteDocument":           "del",
            "showTagLibrary":           "s t",
            "showFolderNavigator":      "s f",
            "toggleShowHiddenEntries":  "mod+h",
            "addRemoveTags":            "mod+t",
            "propertiesDocument":       "alt+enter",
            "nextDocument":             ['right', 'down'],
            "prevDocument":             ['left', 'up'],
            "showHelp":                 "f1",
            "reloadApplication":        "r a",
            "toggleFullScreen":         "f11",
            "openDevTools":             "f12"
        },
        "supportedFileTypes": [
            { "type": "jpg",	"viewer": "viewerImage",     "editor": "false" },
            { "type": "jpeg", 	"viewer": "viewerImage",     "editor": "false" },
            { "type": "gif", 	"viewer": "viewerImage",     "editor": "false" },
            { "type": "png", 	"viewer": "viewerImage",     "editor": "false" },
            { "type": "webp", 	"viewer": "viewerImage",     "editor": "false" },
            { "type": "bmp", 	"viewer": "viewerImage",     "editor": "false" },
            { "type": "svg", 	"viewer": "viewerImage",   "editor": "editorText" },
            { "type": "pdf", 	"viewer": "@@PDFVIEWER",	 "editor": "false" },
            { "type": "html", 	"viewer": "viewerBrowser",   "editor": "editorHTML" },
            { "type": "htm", 	"viewer": "viewerBrowser",   "editor": "editorHTML" },
            { "type": "xhtml", 	"viewer": "viewerBrowser",   "editor": "editorText" },
            { "type": "mht", 	"viewer": "@@MHTVIEWER",     "editor": "false" },
            { "type": "mhtml", 	"viewer": "@@MHTVIEWER",     "editor": "false" },
            { "type": "odt",    "viewer": "editorODF",       "editor": "false" },
            { "type": "ods",    "viewer": "editorODF",       "editor": "false" },
            { "type": "odp",    "viewer": "editorODF",       "editor": "false" },
            { "type": "odg",    "viewer": "editorODF",       "editor": "false" },
            { "type": "txt", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "xml", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "js", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "json",   "viewer": "editorText",      "editor": "editorText" },
            { "type": "css", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "h", 		"viewer": "editorText",      "editor": "editorText" },
            { "type": "c", 		"viewer": "editorText",      "editor": "editorText" },
            { "type": "clj", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "coffee", "viewer": "editorText",      "editor": "editorText" },
            { "type": "cpp", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "cs", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "groovy", "viewer": "editorText",      "editor": "editorText" },
            { "type": "haxe", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "java", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "jsm", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "less", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "lua", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "ml", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "mli", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "pl", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "php", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "py", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "rb", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "sh", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "sql", 	"viewer": "editorText",      "editor": "editorText" },
            { "type": "mkd", 	"viewer": "viewerMD",        "editor": "editorText" },
            { "type": "mdwn", 	"viewer": "viewerMD",        "editor": "editorText" },
            { "type": "markdown","viewer": "viewerMD",       "editor": "editorText" },
            { "type": "mdown", 	"viewer": "viewerMD",        "editor": "editorText" },
            { "type": "md", 	"viewer": "viewerMD",        "editor": "editorText" },
            { "type": "avi", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "ogg", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "ogv", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "oga", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "ogx", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "spx", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "opus", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "mp3", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "mp4", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "m4p", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "wav", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "wave", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "webm", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "m4v", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "m4a", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "mov", 	"viewer": "viewerBrowser",   "editor": "false" },
            { "type": "desktop","viewer": "viewerURL",       "editor": "false" },
            { "type": "website","viewer": "viewerURL",       "editor": "false" },
            { "type": "url", 	"viewer": "viewerURL",       "editor": "false" }
        ],
        "tagGroups": [
            {
                "title":"Common Tags",
                "isFolder": "true",
                "key":"OTB",
                "expand": "true",
                "children":[
                    {
                        "title":"book",
                        "type":"plain"
                    },
                    {
                        "title":"paper",
                        "type":"plain"
                    }
                ]
            },
            {
                "title":"Getting Things Done",
                "isFolder": "true",
                "key":"GTD",
                "expand": "true",
                "children":[
                    {
                        "title":"done",
                        "type":"plain"
                    },
                    {
                        "title":"next",
                        "type":"plain"
                    },
                    {
                        "title":"maybe",
                        "type":"plain"
                    },
                    {
                        "title":"waiting",
                        "type":"plain"
                    }
                ]
            },
            {
                "title": "Smart Tags",
                "key": "SMR",
                "expanded": true,
                "children": [
                    {
                        "type":          "smart",
                        "title":         "now",
                        "functionality": "now",
                        "desciption":    "Adds the current date and time as tag",
                        "color":         "#4986e7",
                        "textcolor":     "#ffffff"
                    },
                    {
                        "type":          "smart",
                        "title":         "today",
                        "functionality": "today",
                        "desciption":    "Adds the current date as tag",
                        "color":         "#4986e7",
                        "textcolor":     "#ffffff"
                    },
                    {
                        "type":          "smart",
                        "title":         "tomorrow",
                        "functionality": "tomorrow",
                        "desciption":    "Adds tomorrow's date as tag",
                        "color":         "#4986e7",
                        "textcolor":     "#ffffff"
                    },
                    {
                        "type":          "smart",
                        "title":         "yesterday",
                        "functionality": "yesterday",
                        "desciption":    "Adds the date of yesterday as tag",
                        "color":         "#4986e7",
                        "textcolor":     "#ffffff"
                    },
                    {
                        "type":          "smart",
                        "title":         "month",
                        "functionality": "currentMonth",
                        "desciption":    "Adds the current year and month as tag",
                        "color":         "#4986e7",
                        "textcolor":     "#ffffff"
                    },
                    {
                        "type":          "smart",
                        "title":         "year",
                        "functionality": "currentYear",
                        "desciption":    "Adds the current year as tag",
                        "color":         "#4986e7",
                        "textcolor":     "#ffffff"
                    }
                ]
            },
            {
                "title": "Priorities",
                "key": "PRI",
                "expanded": true,
                "children": [
                    {
                        "type": "plain",
                        "title": "high",
                        "color": "#ff7537",
                        "textcolor": "#ffffff",
                        "keyBinding": "t h"
                    },
                    {
                        "type": "plain",
                        "title": "medium",
                        "color": "#ffad46",
                        "textcolor": "#ffffff",
                        "keyBinding": "t m"
                    },
                    {
                        "type": "plain",
                        "title": "low",
                        "color": "#7bd148",
                        "textcolor": "#ffffff",
                        "keyBinding": "t l"
                    }
                ]
            },
            {
                "title": "Ratings",
                "key": "REV",
                "expanded": true,
                "children": [
                    {
                        "type": "plain",
                        "title": "1star",
                        "color": "#FFCC24",
                        "textcolor": "#ffffff",
                        "keyBinding": "t 1"
                    },
                    {
                        "type": "plain",
                        "title": "2star",
                        "color": "#FFCC24",
                        "textcolor": "#ffffff",
                        "keyBinding": "t 2"
                    },
                    {
                        "type": "plain",
                        "title": "3star",
                        "color": "#FFCC24",
                        "textcolor": "#ffffff",
                        "keyBinding": "t 3"
                    },
                    {
                        "type": "plain",
                        "title": "4star",
                        "color": "#FFCC24",
                        "textcolor": "#ffffff",
                        "keyBinding": "t 4"
                    },
                    {
                        "type": "plain",
                        "title": "5star",
                        "color": "#FFCC24",
                        "textcolor": "#ffffff",
                        "keyBinding": "t 5"
                    }
                ]
            }
        ]
    };
});<|endoftext|>


<commit_before>import macro from 'vtk.js/Sources/macro';
import vtkInteractorStyle from 'vtk.js/Sources/Rendering/Core/InteractorStyle';

// ----------------------------------------------------------------------------
// Event Types
// ----------------------------------------------------------------------------

const START_INTERACTION_EVENT = { type: 'StartInteractionEvent' };
const INTERACTION_EVENT = { type: 'InteractionEvent' };
const END_INTERACTION_EVENT = { type: 'EndInteractionEvent' };

// ----------------------------------------------------------------------------
// vtkInteractorStyleRemoteMouse methods
// ----------------------------------------------------------------------------

function vtkInteractorStyleRemoteMouse(publicAPI, model) {
  // Set our className
  model.classHierarchy.push('vtkInteractorStyleRemoteMouse');

  function createRemoteEvent(callData) {
    // Fields:
    //  - action: [down, up]
    //  - x, y (Normalized)
    // Flags:
    //  - buttonLeft, buttonMiddle, buttonRight
    //  - shiftKey, ctrlKey, altKey, metaKey
    const { buttonLeft, buttonMiddle, buttonRight } = model;
    const shiftKey = callData.shiftKey ? 1 : 0;
    const ctrlKey = callData.controlKey ? 1 : 0;
    const altKey = callData.altKey ? 1 : 0;
    const metaKey = callData.metaKey ? 1 : 0; // Might be platform specific
    const action = buttonLeft || buttonMiddle || buttonRight ? 'down' : 'up';

    // Fixme x / y
    const [width, height] = model.interactor.getView().getSizeByReference();
    let { x, y } = callData.position;
    x /= width;
    y /= height;

    return {
      action,
      x,
      y,
      buttonLeft,
      buttonMiddle,
      buttonRight,
      shiftKey,
      altKey,
      ctrlKey,
      metaKey,
      ...model.remoteEventAddOn,
    };
  }

  //-------------------------------------------------------------------------
  // Mouse
  //-------------------------------------------------------------------------
  publicAPI.handleLeftButtonPress = (callData) => {
    model.previousPosition = callData.position;
    model.buttonLeft = 1;
    publicAPI.onButtonDown(1, callData);
  };

  //-------------------------------------------------------------------------
  publicAPI.handleMiddleButtonPress = (callData) => {
    model.previousPosition = callData.position;
    model.buttonMiddle = 1;
    publicAPI.onButtonDown(2, callData);
  };

  //-------------------------------------------------------------------------
  publicAPI.handleRightButtonPress = (callData) => {
    model.previousPosition = callData.position;
    model.buttonRight = 1;
    publicAPI.onButtonDown(3, callData);
  };

  //-------------------------------------------------------------------------
  publicAPI.handleLeftButtonRelease = (callData) => {
    model.buttonLeft = 0;
    publicAPI.onButtonUp(1, callData);
  };

  //-------------------------------------------------------------------------
  publicAPI.handleMiddleButtonRelease = (callData) => {
    model.buttonMiddle = 0;
    publicAPI.onButtonUp(2, callData);
  };

  //-------------------------------------------------------------------------
  publicAPI.handleRightButtonRelease = (callData) => {
    model.buttonRight = 0;
    publicAPI.onButtonUp(3, callData);
  };

  //-------------------------------------------------------------------------
  publicAPI.onButtonDown = (button, callData) => {
    model.interactor.requestAnimation(publicAPI.onButtonDown);
    publicAPI.invokeStartInteractionEvent(START_INTERACTION_EVENT);
    publicAPI.invokeRemoteMouseEvent(createRemoteEvent(callData));
  };

  //-------------------------------------------------------------------------
  publicAPI.onButtonUp = (button, callData) => {
    publicAPI.invokeRemoteMouseEvent(createRemoteEvent(callData));
    publicAPI.invokeEndInteractionEvent(END_INTERACTION_EVENT);
    model.interactor.cancelAnimation(publicAPI.onButtonDown);
  };

  //-------------------------------------------------------------------------
  publicAPI.handleStartMouseWheel = (callData) => {
    const { spinY } = callData;
    model.interactor.requestAnimation(publicAPI.handleStartMouseWheel);
    publicAPI.invokeStartInteractionEvent(START_INTERACTION_EVENT);
    publicAPI.invokeRemoteWheelEvent({
      type: 'StartMouseWheel',
      spinY,
      ...model.remoteEventAddOn,
    });
  };

  //-------------------------------------------------------------------------
  publicAPI.handleMouseWheel = (callData) => {
    const { spinY } = callData;
    publicAPI.invokeRemoteWheelEvent({
      type: 'MouseWheel',
      spinY,
      ...model.remoteEventAddOn,
    });
    publicAPI.invokeInteractionEvent(INTERACTION_EVENT);
  };

  //-------------------------------------------------------------------------
  publicAPI.handleEndMouseWheel = () => {
    publicAPI.invokeRemoteWheelEvent({
      type: 'EndMouseWheel',
      ...model.remoteEventAddOn,
    });
    model.interactor.cancelAnimation(publicAPI.handleStartMouseWheel);
    publicAPI.invokeEndInteractionEvent(END_INTERACTION_EVENT);
  };

  //-------------------------------------------------------------------------
  publicAPI.handleMouseMove = (callData) => {
    const ts = Date.now();
    const needToSend = model.throttleDelay < ts - model.lastThrottleTime;
    if (
      needToSend &&
      (model.sendMouseMove ||
        model.buttonLeft ||
        model.buttonMiddle ||
        model.buttonRight)
    ) {
      model.lastThrottleTime = ts;
      publicAPI.invokeRemoteMouseEvent(createRemoteEvent(callData));
    }
    publicAPI.invokeInteractionEvent(INTERACTION_EVENT);
  };

  // Override default handler
  publicAPI.handleKeyPress = () => {};

  //-------------------------------------------------------------------------
  // Gesture
  //-------------------------------------------------------------------------

  publicAPI.handleStartPinch = (callData) => {
    publicAPI.startDolly();
    const { scale } = callData;
    model.interactor.requestAnimation(publicAPI.handleStartPinch);
    publicAPI.invokeStartInteractionEvent(START_INTERACTION_EVENT);
    publicAPI.invokeRemoteGestureEvent({
      type: 'StartPinch',
      scale,
      ...model.remoteEventAddOn,
    });
  };

  //----------------------------------------------------------------------------

  publicAPI.handlePinch = (callData) => {
    const { scale } = callData;
    publicAPI.invokeRemoteGestureEvent({
      type: 'Pinch',
      scale,
      ...model.remoteEventAddOn,
    });
  };

  //--------------------------------------------------------------------------

  publicAPI.handleEndPinch = () => {
    publicAPI.endDolly();
    publicAPI.invokeRemoteGestureEvent({
      type: 'EndPinch',
      ...model.remoteEventAddOn,
    });
    model.interactor.cancelAnimation(publicAPI.handleStartPinch);
    publicAPI.invokeEndInteractionEvent(END_INTERACTION_EVENT);
  };

  //----------------------------------------------------------------------------

  publicAPI.handleStartRotate = (callData) => {
    publicAPI.startRotate();
    const { rotation } = callData;
    model.interactor.requestAnimation(publicAPI.handleStartRotate);
    publicAPI.invokeStartInteractionEvent(START_INTERACTION_EVENT);
    publicAPI.invokeRemoteGestureEvent({
      type: 'StartRotate',
      rotation,
      ...model.remoteEventAddOn,
    });
  };

  //----------------------------------------------------------------------------

  publicAPI.handleRotate = (callData) => {
    const { rotation } = callData;
    publicAPI.invokeRemoteGestureEvent({
      type: 'Rotate',
      rotation,
      ...model.remoteEventAddOn,
    });
  };

  //--------------------------------------------------------------------------

  publicAPI.handleEndRotate = () => {
    publicAPI.endRotate();
    publicAPI.invokeRemoteGestureEvent({
      type: 'EndRotate',
      ...model.remoteEventAddOn,
    });
    model.interactor.cancelAnimation(publicAPI.handleStartRotate);
    publicAPI.invokeEndInteractionEvent(END_INTERACTION_EVENT);
  };

  //----------------------------------------------------------------------------

  publicAPI.handleStartPan = (callData) => {
    publicAPI.startPan();
    const { translation } = callData;
    model.interactor.requestAnimation(publicAPI.handleStartPan);
    publicAPI.invokeStartInteractionEvent(START_INTERACTION_EVENT);
    publicAPI.invokeRemoteGestureEvent({
      type: 'StartPan',
      translation,
      ...model.remoteEventAddOn,
    });
  };

  //----------------------------------------------------------------------------

  publicAPI.handlePan = (callData) => {
    const { translation } = callData;
    publicAPI.invokeRemoteGestureEvent({
      type: 'Pan',
      translation,
      ...model.remoteEventAddOn,
    });
  };

  //--------------------------------------------------------------------------

  publicAPI.handleEndPan = () => {
    publicAPI.endPan();
    publicAPI.invokeRemoteGestureEvent({
      type: 'EndPan',
      ...model.remoteEventAddOn,
    });
    model.interactor.cancelAnimation(publicAPI.handleStartPan);
    publicAPI.invokeEndInteractionEvent(END_INTERACTION_EVENT);
  };
}

// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {
  buttonLeft: 0,
  buttonMiddle: 0,
  buttonRight: 0,
  sendMouseMove: false,
  throttleDelay: 33.3, // 33.3 millisecond <=> 30 events/second
  lastThrottleTime: 0,
  // remoteEventAddOn: null,
};

// ----------------------------------------------------------------------------

export function extend(publicAPI, model, initialValues = {}) {
  Object.assign(model, DEFAULT_VALUES, initialValues);

  // Inheritance
  vtkInteractorStyle.extend(publicAPI, model, initialValues);
  macro.setGet(publicAPI, model, [
    'sendMouseMove',
    'remoteEventAddOn',
    'throttleDelay',
  ]);
  macro.event(publicAPI, model, 'RemoteMouseEvent');
  macro.event(publicAPI, model, 'RemoteWheelEvent');
  macro.event(publicAPI, model, 'RemoteGestureEvent');

  // Object specific methods
  vtkInteractorStyleRemoteMouse(publicAPI, model);
}

// ----------------------------------------------------------------------------

export const newInstance = macro.newInstance(
  extend,
  'vtkInteractorStyleRemoteMouse'
);

// ----------------------------------------------------------------------------

export default { newInstance, extend };
<commit_msg>fix(InteractorStyleRemoteMouse): add key modifier on MouseWheel events<commit_after>import macro from 'vtk.js/Sources/macro';
import vtkInteractorStyle from 'vtk.js/Sources/Rendering/Core/InteractorStyle';

// ----------------------------------------------------------------------------
// Event Types
// ----------------------------------------------------------------------------

const START_INTERACTION_EVENT = { type: 'StartInteractionEvent' };
const INTERACTION_EVENT = { type: 'InteractionEvent' };
const END_INTERACTION_EVENT = { type: 'EndInteractionEvent' };

// ----------------------------------------------------------------------------
// vtkInteractorStyleRemoteMouse methods
// ----------------------------------------------------------------------------

function vtkInteractorStyleRemoteMouse(publicAPI, model) {
  // Set our className
  model.classHierarchy.push('vtkInteractorStyleRemoteMouse');

  function createRemoteEvent(callData) {
    // Fields:
    //  - action: [down, up]
    //  - x, y (Normalized)
    // Flags:
    //  - buttonLeft, buttonMiddle, buttonRight
    //  - shiftKey, ctrlKey, altKey, metaKey
    const { buttonLeft, buttonMiddle, buttonRight } = model;
    const shiftKey = callData.shiftKey ? 1 : 0;
    const ctrlKey = callData.controlKey ? 1 : 0;
    const altKey = callData.altKey ? 1 : 0;
    const metaKey = callData.metaKey ? 1 : 0; // Might be platform specific
    const action = buttonLeft || buttonMiddle || buttonRight ? 'down' : 'up';

    // Fixme x / y
    const [width, height] = model.interactor.getView().getSizeByReference();
    let { x, y } = callData.position;
    x /= width;
    y /= height;

    return {
      action,
      x,
      y,
      buttonLeft,
      buttonMiddle,
      buttonRight,
      shiftKey,
      altKey,
      ctrlKey,
      metaKey,
      ...model.remoteEventAddOn,
    };
  }

  //-------------------------------------------------------------------------
  // Mouse
  //-------------------------------------------------------------------------
  publicAPI.handleLeftButtonPress = (callData) => {
    model.previousPosition = callData.position;
    model.buttonLeft = 1;
    publicAPI.onButtonDown(1, callData);
  };

  //-------------------------------------------------------------------------
  publicAPI.handleMiddleButtonPress = (callData) => {
    model.previousPosition = callData.position;
    model.buttonMiddle = 1;
    publicAPI.onButtonDown(2, callData);
  };

  //-------------------------------------------------------------------------
  publicAPI.handleRightButtonPress = (callData) => {
    model.previousPosition = callData.position;
    model.buttonRight = 1;
    publicAPI.onButtonDown(3, callData);
  };

  //-------------------------------------------------------------------------
  publicAPI.handleLeftButtonRelease = (callData) => {
    model.buttonLeft = 0;
    publicAPI.onButtonUp(1, callData);
  };

  //-------------------------------------------------------------------------
  publicAPI.handleMiddleButtonRelease = (callData) => {
    model.buttonMiddle = 0;
    publicAPI.onButtonUp(2, callData);
  };

  //-------------------------------------------------------------------------
  publicAPI.handleRightButtonRelease = (callData) => {
    model.buttonRight = 0;
    publicAPI.onButtonUp(3, callData);
  };

  //-------------------------------------------------------------------------
  publicAPI.onButtonDown = (button, callData) => {
    model.interactor.requestAnimation(publicAPI.onButtonDown);
    publicAPI.invokeStartInteractionEvent(START_INTERACTION_EVENT);
    publicAPI.invokeRemoteMouseEvent(createRemoteEvent(callData));
  };

  //-------------------------------------------------------------------------
  publicAPI.onButtonUp = (button, callData) => {
    publicAPI.invokeRemoteMouseEvent(createRemoteEvent(callData));
    publicAPI.invokeEndInteractionEvent(END_INTERACTION_EVENT);
    model.interactor.cancelAnimation(publicAPI.onButtonDown);
  };

  //-------------------------------------------------------------------------
  publicAPI.handleStartMouseWheel = (callData) => {
    const { spinY, altKey, controlKey, shiftKey } = callData;
    model.interactor.requestAnimation(publicAPI.handleStartMouseWheel);
    publicAPI.invokeStartInteractionEvent(START_INTERACTION_EVENT);
    publicAPI.invokeRemoteWheelEvent({
      type: 'StartMouseWheel',
      spinY,
      altKey,
      controlKey,
      shiftKey,
      ...model.remoteEventAddOn,
    });
  };

  //-------------------------------------------------------------------------
  publicAPI.handleMouseWheel = (callData) => {
    const { spinY, altKey, controlKey, shiftKey } = callData;
    publicAPI.invokeRemoteWheelEvent({
      type: 'MouseWheel',
      spinY,
      altKey,
      controlKey,
      shiftKey,
      ...model.remoteEventAddOn,
    });
    publicAPI.invokeInteractionEvent(INTERACTION_EVENT);
  };

  //-------------------------------------------------------------------------
  publicAPI.handleEndMouseWheel = () => {
    publicAPI.invokeRemoteWheelEvent({
      type: 'EndMouseWheel',
      ...model.remoteEventAddOn,
    });
    model.interactor.cancelAnimation(publicAPI.handleStartMouseWheel);
    publicAPI.invokeEndInteractionEvent(END_INTERACTION_EVENT);
  };

  //-------------------------------------------------------------------------
  publicAPI.handleMouseMove = (callData) => {
    const ts = Date.now();
    const needToSend = model.throttleDelay < ts - model.lastThrottleTime;
    if (
      needToSend &&
      (model.sendMouseMove ||
        model.buttonLeft ||
        model.buttonMiddle ||
        model.buttonRight)
    ) {
      model.lastThrottleTime = ts;
      publicAPI.invokeRemoteMouseEvent(createRemoteEvent(callData));
    }
    publicAPI.invokeInteractionEvent(INTERACTION_EVENT);
  };

  // Override default handler
  publicAPI.handleKeyPress = () => {};

  //-------------------------------------------------------------------------
  // Gesture
  //-------------------------------------------------------------------------

  publicAPI.handleStartPinch = (callData) => {
    publicAPI.startDolly();
    const { scale } = callData;
    model.interactor.requestAnimation(publicAPI.handleStartPinch);
    publicAPI.invokeStartInteractionEvent(START_INTERACTION_EVENT);
    publicAPI.invokeRemoteGestureEvent({
      type: 'StartPinch',
      scale,
      ...model.remoteEventAddOn,
    });
  };

  //----------------------------------------------------------------------------

  publicAPI.handlePinch = (callData) => {
    const { scale } = callData;
    publicAPI.invokeRemoteGestureEvent({
      type: 'Pinch',
      scale,
      ...model.remoteEventAddOn,
    });
  };

  //--------------------------------------------------------------------------

  publicAPI.handleEndPinch = () => {
    publicAPI.endDolly();
    publicAPI.invokeRemoteGestureEvent({
      type: 'EndPinch',
      ...model.remoteEventAddOn,
    });
    model.interactor.cancelAnimation(publicAPI.handleStartPinch);
    publicAPI.invokeEndInteractionEvent(END_INTERACTION_EVENT);
  };

  //----------------------------------------------------------------------------

  publicAPI.handleStartRotate = (callData) => {
    publicAPI.startRotate();
    const { rotation } = callData;
    model.interactor.requestAnimation(publicAPI.handleStartRotate);
    publicAPI.invokeStartInteractionEvent(START_INTERACTION_EVENT);
    publicAPI.invokeRemoteGestureEvent({
      type: 'StartRotate',
      rotation,
      ...model.remoteEventAddOn,
    });
  };

  //----------------------------------------------------------------------------

  publicAPI.handleRotate = (callData) => {
    const { rotation } = callData;
    publicAPI.invokeRemoteGestureEvent({
      type: 'Rotate',
      rotation,
      ...model.remoteEventAddOn,
    });
  };

  //--------------------------------------------------------------------------

  publicAPI.handleEndRotate = () => {
    publicAPI.endRotate();
    publicAPI.invokeRemoteGestureEvent({
      type: 'EndRotate',
      ...model.remoteEventAddOn,
    });
    model.interactor.cancelAnimation(publicAPI.handleStartRotate);
    publicAPI.invokeEndInteractionEvent(END_INTERACTION_EVENT);
  };

  //----------------------------------------------------------------------------

  publicAPI.handleStartPan = (callData) => {
    publicAPI.startPan();
    const { translation } = callData;
    model.interactor.requestAnimation(publicAPI.handleStartPan);
    publicAPI.invokeStartInteractionEvent(START_INTERACTION_EVENT);
    publicAPI.invokeRemoteGestureEvent({
      type: 'StartPan',
      translation,
      ...model.remoteEventAddOn,
    });
  };

  //----------------------------------------------------------------------------

  publicAPI.handlePan = (callData) => {
    const { translation } = callData;
    publicAPI.invokeRemoteGestureEvent({
      type: 'Pan',
      translation,
      ...model.remoteEventAddOn,
    });
  };

  //--------------------------------------------------------------------------

  publicAPI.handleEndPan = () => {
    publicAPI.endPan();
    publicAPI.invokeRemoteGestureEvent({
      type: 'EndPan',
      ...model.remoteEventAddOn,
    });
    model.interactor.cancelAnimation(publicAPI.handleStartPan);
    publicAPI.invokeEndInteractionEvent(END_INTERACTION_EVENT);
  };
}

// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {
  buttonLeft: 0,
  buttonMiddle: 0,
  buttonRight: 0,
  sendMouseMove: false,
  throttleDelay: 33.3, // 33.3 millisecond <=> 30 events/second
  lastThrottleTime: 0,
  // remoteEventAddOn: null,
};

// ----------------------------------------------------------------------------

export function extend(publicAPI, model, initialValues = {}) {
  Object.assign(model, DEFAULT_VALUES, initialValues);

  // Inheritance
  vtkInteractorStyle.extend(publicAPI, model, initialValues);
  macro.setGet(publicAPI, model, [
    'sendMouseMove',
    'remoteEventAddOn',
    'throttleDelay',
  ]);
  macro.event(publicAPI, model, 'RemoteMouseEvent');
  macro.event(publicAPI, model, 'RemoteWheelEvent');
  macro.event(publicAPI, model, 'RemoteGestureEvent');

  // Object specific methods
  vtkInteractorStyleRemoteMouse(publicAPI, model);
}

// ----------------------------------------------------------------------------

export const newInstance = macro.newInstance(
  extend,
  'vtkInteractorStyleRemoteMouse'
);

// ----------------------------------------------------------------------------

export default { newInstance, extend };
<|endoftext|>


<commit_before>
(function(){
    // Simple bar chart
    // ----------------

    var BarChart = Datawrapper.Visualizations.BarChart = function() {

    };

    _.extend(BarChart.prototype, Datawrapper.Visualizations.RaphaelChart.prototype, {

        render: function(el) {
            el = $(el);

            this.setRoot(el);

            var me = this, row = 0,
            sortBars = me.get('sort-values'),
            reverse = me.get('reverse-order'),
            useNegativeColor = me.get('negative-color', false);

            if (!_.isUndefined(me.get('selected-row'))) {
                row = me.get('selected-row', 0);
                row = row > me.chart.numRows() ? 0 : row;
            }

            var filterUI = me.getFilterUI(row);
            if (filterUI) $('#header').append(filterUI);

            var c = me.initCanvas({
                h: Math.max(me.getSize()[1] - me.theme.padding.top - me.theme.padding.bottom - me.theme.vpadding, 18 * 1.35 * me.chart.dataSeries().length)
            });

            var
            chart_width = c.w - c.lpad - c.rpad,
            series_gap = 0.05, // pull from theme
            row_gap = 0.01,
            labelsInsideBars = me.get('labels-inside-bars', false);

            if (me.chart.numRows() > 1) me.chart.filterRow(row);

            me.init();
            me.initDimensions(0);

            $('.tooltip').hide();

            c.lastBarY = 0;

            _.each(me.chart.dataSeries(sortBars, reverse), function(series, s) {
                _.each(series.data, function(val, r) {
                    var d = me.barDimensions(series, s, r),
                        lpos = me.labelPosition(series, s, r),
                        fill = me.getSeriesColor(series, r, useNegativeColor),
                        stroke = d3.cie.lch(d3.rgb(fill)).darker(0.6).toString();

                    if (labelsInsideBars) d.x -= 10;

                    // draw bar
                    me.registerSeriesElement(c.paper.rect(d.x, d.y, d.width, d.height).attr({
                        'stroke': stroke,
                        'fill': fill
                    }).data('strokeCol', stroke), series);

                    if (lpos.show_val) {
                        me.registerSeriesLabel(me.label(lpos.val_x, lpos.top, me.chart.formatValue(series.data[r], true),{
                            w: 40,
                            align: lpos.val_align,
                            cl: 'value' + lpos.lblClass
                        }), series);
                    }

                    if (lpos.show_lbl) {
                        me.registerSeriesLabel(me.label(lpos.lbl_x , lpos.top, series.name,{
                            w: 160,
                            align: lpos.lbl_align,
                            cl: 'series' + lpos.lblClass
                        }), series);
                    }

                    c.lastBarY = Math.max(c.lastBarY, d.y + d.height);
                });
            });

            if (me.__domain[0] < 0) {
                var x = c.lpad + c.zero ;
                if (labelsInsideBars) x -= 10;
                // add y-axis
                me.path([['M', x, c.tpad], ['L', x, c.lastBarY ]], 'axis')
                    .attr(me.theme.yAxis);
            }

            // enable mouse events
            el.mousemove(_.bind(me.onMouseMove, me));

        },

        update: function(row) {
            var me = this;
            // re-filter dataset
            me.chart.filterRow(row);

            // update scales
            me.initDimensions(0);

            // update bar heights and labels
            _.each(me.chart.dataSeries(), function(series, s) {
                _.each(me.__seriesElements[series.name], function(rect) {
                    var dim = me.barDimensions(series, s, 0);
                    console.log(series.name, rect, dim);
                    rect.animate(dim, 1000, 'expoInOut');
                });

                _.each(me.__seriesLabels[series.name], function(lbl) {
                    var pos = me.labelPosition(series, s, 0), lpos;
                    if (lbl.hasClass('value')) {
                        // update value
                        $('span', lbl).html(me.chart.formatValue(series.data[0]));
                        lpos = { halign: pos.val_align, left: pos.val_x, top: pos.top };

                    } else if (lbl.hasClass('series')) {
                        // update series label position
                        lpos = { halign: pos.lbl_align, left: pos.lbl_x, top: pos.top };
                    }
                    if (lpos) {
                        lbl.data('attrs', $.extend(lbl.data('attrs'), { halign: lpos.halign }));
                        lbl.animate(lbl.data('lblcss')(lbl, lpos.left, lpos.top), {
                            easing: 'easeInOutExpo',
                            duration: 1000
                        });
                    }
                });
            });
        },

        initDimensions: function(r) {
            //
            var me = this, c = me.__canvas,
                dMin = 0, dMax = 0, w = c.w - c.lpad - c.rpad - 30;
            _.each(me.chart.dataSeries(), function(series) {
                dMin = Math.min(dMin, series._min());
                dMax = Math.max(dMax, series._max());
            });
            me.__domain = [dMin, dMax];
            me.__scales = {
                y: d3.scale.linear().domain([dMin, dMax])
            };
            /* how maxw works:
             *
             * maxw[0] .. max series name label width      \
             * maxw[1] .. max formatted value label width   } positive
             * largestVal[0] .. max absolute value               /
             * maxw[2] .. max series name label width      \
             * maxw[3] .. max formatted value label width   } negative
             * largestVal[1] .. max absolute value               /
             */
            var maxw = [0, 0, 0, 0], ratio, largestVal = [0, 0];
            _.each(me.chart.dataSeries(), function(series, s) {
                var neg = series.data[r] < 0;
                largestVal[neg ? 1 : 0] = Math.max(largestVal[neg ? 1 : 0], Math.abs(series.data[r]));
                console.log(series.name, r, series.data[r]);
            });
            console.log(largestVal);
            _.each(me.chart.dataSeries(), function(series, s) {
                var val = series.data[r],
                    neg = val < 0,
                    t = neg ? 2 : 0,
                    bw;
                bw = Math.abs(val) / (largestVal[0] + largestVal[1]) * w;
                maxw[t] = Math.max(maxw[t], me.labelWidth(series.name, 'series') + 20);
                maxw[t+1] = Math.max(maxw[t+1], me.labelWidth(me.chart.formatValue(series.data[r], true), 'value') + 20 + bw);
            });

            c.left = 0;
            c.right = 0;
            c.zero = largestVal[1] / (largestVal[0] + largestVal[1]) * w;

            if (!me.get('labels-inside-bars', false) && w > 300) {

                var maxNegBar = c.zero;
                //console.log('c.left', );
                c.left = Math.max(maxw[0], maxw[3]) - c.zero;
                c.right = Math.max(maxw[1], maxw[2]) - (w - c.zero); // Math.max((maxw[2] + maxw[1]) - (w - c.zero), 0);

                w -= c.left + c.right;

                c.zero = c.left + largestVal[1] / (largestVal[0] + largestVal[1]) * w;
            } else {
                c.zero += 15;
            }

            console.log('zero', c.zero, c.left, largestVal, w);

            c.maxSeriesLabelWidth = [maxw[0], maxw[2]];
            c.maxValueLabelWidth = [maxw[1], maxw[3]];

            me.__scales.y.rangeRound([c.lpad, w]);
        },

        barDimensions: function(series, s, r) {
            var me = this, w, h, x, y, i, cw, n = me.chart.dataSeries().length,
                sc = me.__scales, c = me.__canvas, bw, pad = 0.35, vspace = 0.1,
                val = series.data[r];
            //
            cw = c.h - c.bpad - c.tpad;
            //
            bw = Math.max(18, Math.min(50, cw / (n + (n-1) * pad)));
            w = sc.y(val) - sc.y(0);
            h = bw;
            if (w > 0) {
                x = c.lpad + c.zero;
            } else {
                x = c.lpad + c.zero + w;
                w *= -1;
            }
            y = Math.round(c.tpad + s * (bw + bw * pad));
            return { width: w, height: h, x: x, y: y };
        },

        labelPosition: function(series, s, r) {
            var me = this,
                d = me.barDimensions(series, s, r),
                c = me.__canvas,
                val = series.data[r],
                lbl_x = val >= 0 ?
                    c.zero - 10
                    : c.zero + 10,
                lbl_align = val >= 0 ? 'right' : 'left',
                val_x = val >= 0 ?
                    d.x + d.width + 10
                    : d.x - 10,
                val_align = val >= 0 ? 'left' : 'right',
                show_lbl = true,
                show_val = true,
                lblClass = me.chart.hasHighlight() && me.chart.isHighlighted(series) ? ' highlighted' : '';

            if (me.get('labels-inside-bars', false)) {
                lbl_x = val >= 0 ? d.x + 10 : d.x + d.width - 10;
                val_x = val >= 0 ? d.x + d.width - 10 : d.x + 10;
                lbl_align = val >= 0 ? 'left' : 'right';
                val_align = val >= 0 ? 'right' : 'left';

                // check if the label is bigger than the bar
                var slblw = me.labelWidth(series.name, 'series')+10,
                    vlblw = me.labelWidth(me.chart.formatValue(val, true), 'value')+20;
                if (slblw + vlblw > d.width) {
                    show_val = false;
                    if (slblw > d.width) show_lbl = false;
                }
                if (me.invertLabel(fill)) lblClass += ' inverted';
            }

            return { lblClass: lblClass, val_align: val_align, show_lbl: show_lbl,
                show_val: show_val, lbl_align: lbl_align, lbl_x: lbl_x, val_x: val_x,
                top: d.y + d.height * 0.5 };
        },

        getDataRowByPoint: function(x, y) {
            return 0;
        },

        showTooltip: function() {

        },

        hideTooltip: function() {

        },

        hoverSeries: function(series) {
            var me = this;
            _.each(me.chart.dataSeries(), function(s) {
                _.each(me.__seriesLabels[s.name], function(lbl) {
                    if (series !== undefined && s.name == series.name) {
                        lbl.addClass('hover');
                    } else {
                        lbl.removeClass('hover');
                    }
                    _.each(me.__seriesElements[s.name], function(el) {
                        var fill = me.getSeriesColor(s, 0, me.get('negative-color', false)), stroke;
                        if (series !== undefined && s.name == series.name) fill = d3.cie.lch(d3.rgb(fill)).darker(0.6).toString();
                        stroke = d3.cie.lch(d3.rgb(fill)).darker(0.6).toString();
                        if (el.attrs.fill != fill || el.attrs.stroke != stroke)
                            el.animate({ fill: fill, stroke: stroke }, 50);
                    });
                });
            });
        },

        unhoverSeries: function() {
            this.hoverSeries();
        }
    });

}).call(this);<commit_msg>removed logging output<commit_after>
(function(){
    // Simple bar chart
    // ----------------

    var BarChart = Datawrapper.Visualizations.BarChart = function() {

    };

    _.extend(BarChart.prototype, Datawrapper.Visualizations.RaphaelChart.prototype, {

        render: function(el) {
            el = $(el);

            this.setRoot(el);

            var me = this, row = 0,
            sortBars = me.get('sort-values'),
            reverse = me.get('reverse-order'),
            useNegativeColor = me.get('negative-color', false);

            if (!_.isUndefined(me.get('selected-row'))) {
                row = me.get('selected-row', 0);
                row = row > me.chart.numRows() ? 0 : row;
            }

            var filterUI = me.getFilterUI(row);
            if (filterUI) $('#header').append(filterUI);

            var c = me.initCanvas({
                h: Math.max(me.getSize()[1] - me.theme.padding.top - me.theme.padding.bottom - me.theme.vpadding, 18 * 1.35 * me.chart.dataSeries().length)
            });

            var
            chart_width = c.w - c.lpad - c.rpad,
            series_gap = 0.05, // pull from theme
            row_gap = 0.01,
            labelsInsideBars = me.get('labels-inside-bars', false);

            if (me.chart.numRows() > 1) me.chart.filterRow(row);

            me.init();
            me.initDimensions(0);

            $('.tooltip').hide();

            c.lastBarY = 0;

            _.each(me.chart.dataSeries(sortBars, reverse), function(series, s) {
                _.each(series.data, function(val, r) {
                    var d = me.barDimensions(series, s, r),
                        lpos = me.labelPosition(series, s, r),
                        fill = me.getSeriesColor(series, r, useNegativeColor),
                        stroke = d3.cie.lch(d3.rgb(fill)).darker(0.6).toString();

                    if (labelsInsideBars) d.x -= 10;

                    // draw bar
                    me.registerSeriesElement(c.paper.rect(d.x, d.y, d.width, d.height).attr({
                        'stroke': stroke,
                        'fill': fill
                    }).data('strokeCol', stroke), series);

                    if (lpos.show_val) {
                        me.registerSeriesLabel(me.label(lpos.val_x, lpos.top, me.chart.formatValue(series.data[r], true),{
                            w: 40,
                            align: lpos.val_align,
                            cl: 'value' + lpos.lblClass
                        }), series);
                    }

                    if (lpos.show_lbl) {
                        me.registerSeriesLabel(me.label(lpos.lbl_x , lpos.top, series.name,{
                            w: 160,
                            align: lpos.lbl_align,
                            cl: 'series' + lpos.lblClass
                        }), series);
                    }

                    c.lastBarY = Math.max(c.lastBarY, d.y + d.height);
                });
            });

            if (me.__domain[0] < 0) {
                var x = c.lpad + c.zero ;
                if (labelsInsideBars) x -= 10;
                // add y-axis
                me.path([['M', x, c.tpad], ['L', x, c.lastBarY ]], 'axis')
                    .attr(me.theme.yAxis);
            }

            // enable mouse events
            el.mousemove(_.bind(me.onMouseMove, me));

        },

        update: function(row) {
            var me = this;
            // re-filter dataset
            me.chart.filterRow(row);

            // update scales
            me.initDimensions(0);

            // update bar heights and labels
            _.each(me.chart.dataSeries(), function(series, s) {
                _.each(me.__seriesElements[series.name], function(rect) {
                    var dim = me.barDimensions(series, s, 0);
                    rect.animate(dim, 1000, 'expoInOut');
                });

                _.each(me.__seriesLabels[series.name], function(lbl) {
                    var pos = me.labelPosition(series, s, 0), lpos;
                    if (lbl.hasClass('value')) {
                        // update value
                        $('span', lbl).html(me.chart.formatValue(series.data[0]));
                        lpos = { halign: pos.val_align, left: pos.val_x, top: pos.top };

                    } else if (lbl.hasClass('series')) {
                        // update series label position
                        lpos = { halign: pos.lbl_align, left: pos.lbl_x, top: pos.top };
                    }
                    if (lpos) {
                        lbl.data('attrs', $.extend(lbl.data('attrs'), { halign: lpos.halign }));
                        lbl.animate(lbl.data('lblcss')(lbl, lpos.left, lpos.top), {
                            easing: 'easeInOutExpo',
                            duration: 1000
                        });
                    }
                });
            });
        },

        initDimensions: function(r) {
            //
            var me = this, c = me.__canvas,
                dMin = 0, dMax = 0, w = c.w - c.lpad - c.rpad - 30;
            _.each(me.chart.dataSeries(), function(series) {
                dMin = Math.min(dMin, series._min());
                dMax = Math.max(dMax, series._max());
            });
            me.__domain = [dMin, dMax];
            me.__scales = {
                y: d3.scale.linear().domain([dMin, dMax])
            };
            /* how maxw works:
             *
             * maxw[0] .. max series name label width      \
             * maxw[1] .. max formatted value label width   } positive
             * largestVal[0] .. max absolute value               /
             * maxw[2] .. max series name label width      \
             * maxw[3] .. max formatted value label width   } negative
             * largestVal[1] .. max absolute value               /
             */
            var maxw = [0, 0, 0, 0], ratio, largestVal = [0, 0];
            _.each(me.chart.dataSeries(), function(series, s) {
                var neg = series.data[r] < 0;
                largestVal[neg ? 1 : 0] = Math.max(largestVal[neg ? 1 : 0], Math.abs(series.data[r]));
            });
            _.each(me.chart.dataSeries(), function(series, s) {
                var val = series.data[r],
                    neg = val < 0,
                    t = neg ? 2 : 0,
                    bw;
                bw = Math.abs(val) / (largestVal[0] + largestVal[1]) * w;
                maxw[t] = Math.max(maxw[t], me.labelWidth(series.name, 'series') + 20);
                maxw[t+1] = Math.max(maxw[t+1], me.labelWidth(me.chart.formatValue(series.data[r], true), 'value') + 20 + bw);
            });

            c.left = 0;
            c.right = 0;
            c.zero = largestVal[1] / (largestVal[0] + largestVal[1]) * w;

            if (!me.get('labels-inside-bars', false) && w > 300) {

                var maxNegBar = c.zero;
                //console.log('c.left', );
                c.left = Math.max(maxw[0], maxw[3]) - c.zero;
                c.right = Math.max(maxw[1], maxw[2]) - (w - c.zero); // Math.max((maxw[2] + maxw[1]) - (w - c.zero), 0);

                w -= c.left + c.right;

                c.zero = c.left + largestVal[1] / (largestVal[0] + largestVal[1]) * w;
            } else {
                c.zero += 15;
            }

            c.maxSeriesLabelWidth = [maxw[0], maxw[2]];
            c.maxValueLabelWidth = [maxw[1], maxw[3]];

            me.__scales.y.rangeRound([c.lpad, w]);
        },

        barDimensions: function(series, s, r) {
            var me = this, w, h, x, y, i, cw, n = me.chart.dataSeries().length,
                sc = me.__scales, c = me.__canvas, bw, pad = 0.35, vspace = 0.1,
                val = series.data[r];
            //
            cw = c.h - c.bpad - c.tpad;
            //
            bw = Math.max(18, Math.min(50, cw / (n + (n-1) * pad)));
            w = sc.y(val) - sc.y(0);
            h = bw;
            if (w > 0) {
                x = c.lpad + c.zero;
            } else {
                x = c.lpad + c.zero + w;
                w *= -1;
            }
            y = Math.round(c.tpad + s * (bw + bw * pad));
            return { width: w, height: h, x: x, y: y };
        },

        labelPosition: function(series, s, r) {
            var me = this,
                d = me.barDimensions(series, s, r),
                c = me.__canvas,
                val = series.data[r],
                lbl_x = val >= 0 ?
                    c.zero - 10
                    : c.zero + 10,
                lbl_align = val >= 0 ? 'right' : 'left',
                val_x = val >= 0 ?
                    d.x + d.width + 10
                    : d.x - 10,
                val_align = val >= 0 ? 'left' : 'right',
                show_lbl = true,
                show_val = true,
                lblClass = me.chart.hasHighlight() && me.chart.isHighlighted(series) ? ' highlighted' : '';

            if (me.get('labels-inside-bars', false)) {
                lbl_x = val >= 0 ? d.x + 10 : d.x + d.width - 10;
                val_x = val >= 0 ? d.x + d.width - 10 : d.x + 10;
                lbl_align = val >= 0 ? 'left' : 'right';
                val_align = val >= 0 ? 'right' : 'left';

                // check if the label is bigger than the bar
                var slblw = me.labelWidth(series.name, 'series')+10,
                    vlblw = me.labelWidth(me.chart.formatValue(val, true), 'value')+20;
                if (slblw + vlblw > d.width) {
                    show_val = false;
                    if (slblw > d.width) show_lbl = false;
                }
                if (me.invertLabel(fill)) lblClass += ' inverted';
            }

            return { lblClass: lblClass, val_align: val_align, show_lbl: show_lbl,
                show_val: show_val, lbl_align: lbl_align, lbl_x: lbl_x, val_x: val_x,
                top: d.y + d.height * 0.5 };
        },

        getDataRowByPoint: function(x, y) {
            return 0;
        },

        showTooltip: function() {

        },

        hideTooltip: function() {

        },

        hoverSeries: function(series) {
            var me = this;
            _.each(me.chart.dataSeries(), function(s) {
                _.each(me.__seriesLabels[s.name], function(lbl) {
                    if (series !== undefined && s.name == series.name) {
                        lbl.addClass('hover');
                    } else {
                        lbl.removeClass('hover');
                    }
                    _.each(me.__seriesElements[s.name], function(el) {
                        var fill = me.getSeriesColor(s, 0, me.get('negative-color', false)), stroke;
                        if (series !== undefined && s.name == series.name) fill = d3.cie.lch(d3.rgb(fill)).darker(0.6).toString();
                        stroke = d3.cie.lch(d3.rgb(fill)).darker(0.6).toString();
                        if (el.attrs.fill != fill || el.attrs.stroke != stroke)
                            el.animate({ fill: fill, stroke: stroke }, 50);
                    });
                });
            });
        },

        unhoverSeries: function() {
            this.hoverSeries();
        }
    });

}).call(this);<|endoftext|>


<commit_before>/*
* ExtMapTypeControl Class
*  Copyright (c) 2007, Google
*  Author: Pamela Fox, others
*
* 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.
*
* This class lets you add a control to the map which mimics GMapTypeControl
*  and allows for the addition of a traffic button/traffic key.
*/

/*
 * Constructor for ExtMapTypeControl, which uses an option hash
 * to decide what elements to put in the control.
 * @param {opt_opts} Named optional arguments:
 *   opt_opts.showTraffic {Boolean} Controls whether traffic button is shown
 *   opt_opts.showTrafficKey {Boolean} Controls whether traffic key is shown
 */
function ExtMapTypeControl(opt_opts) {
  this.options = opt_opts || {};
}

ExtMapTypeControl.prototype = new GControl();

/**
 * Is called by GMap2's addOverlay method. Creates the button
 *  and appends to the map div.
 * @param {GMap2} map The map that has had this ExtMapTypeControl added to it.
 * @return {DOM Object} Div that holds the control
 */
ExtMapTypeControl.prototype.initialize = function(map) {
  var container = document.createElement("div");
  var me = this;

  var satDiv = me.createButton_("Satellite");
  var mapDiv = me.createButton_("Map");
  var hybDiv = me.createButton_("Hybrid");

  me.assignButtonEvent_(satDiv, map, G_SATELLITE_MAP, [mapDiv, hybDiv]);
  me.assignButtonEvent_(hybDiv, map, G_HYBRID_MAP, [satDiv, mapDiv]);
  me.assignButtonEvent_(mapDiv, map, G_NORMAL_MAP, [satDiv, hybDiv]);
  GEvent.addListener(map, "maptypechanged", function() {
    if (map.getCurrentMapType() == G_NORMAL_MAP) {
      GEvent.trigger(mapDiv, "click");
    } else if (map.getCurrentMapType() == G_SATELLITE_MAP) {
      GEvent.trigger(satDiv, "click");
    } else if (map.getCurrentMapType() == G_HYBRID_MAP) {
      GEvent.trigger(hybDiv, "click");
    }
  });

 if (me.options.showTraffic) {
   var trafficDiv = me.createButton_("Traffic");
   trafficDiv.style.marginRight = "8px";
   trafficDiv.firstChild.style.cssFloat = "left";
   trafficDiv.firstChild.style.styleFloat = "left";
   // Sending true makes overlay hidden by default
   me.trafficInfo = new GTrafficOverlay(true);
   // We have to do this so that we can sense if traffic is in view
   GEvent.addListener(me.trafficInfo, "changed", function(hasTrafficInView) {
     if (hasTrafficInView) {
       trafficDiv.style.visibility = 'visible';
     } else {
       trafficDiv.style.visibility = 'hidden';
     }
   });
   map.addOverlay(me.trafficInfo);

   GEvent.addDomListener(trafficDiv, "click", function() {
     if (me.trafficInfo.isHidden()) {
      me.trafficInfo.show();
     } else {
       me.trafficInfo.hide();
     }
      me.toggleButton_(trafficDiv, !me.trafficInfo.isHidden());
    });

    me.toggleButton_(trafficDiv, false);
    container.appendChild(trafficDiv);
  }

  container.appendChild(satDiv);
  container.appendChild(mapDiv);
  container.appendChild(hybDiv);

  map.getContainer().appendChild(container);

  return container;
}

/*
 * Creates simple buttons with text nodes.
 * @param {String} text Text to display in button
 * @return {DOM Object} The div for the button.
 */
ExtMapTypeControl.prototype.createButton_ = function(text) {
  var buttonDiv = document.createElement("div");
  buttonDiv.mapType = text;
  this.setButtonStyle_(buttonDiv, text);
  buttonDiv.style.cssFloat = "left";
  buttonDiv.style.styleFloat = "left";
  var textDiv = document.createElement("div");
  textDiv.appendChild(document.createTextNode(""));
  textDiv.style.width = "6em";
  buttonDiv.appendChild(textDiv);
  return buttonDiv;
}

/*
 * Assigns events to MapType buttons to change maptype
 *  and toggle button styles correctly for all buttons
 *  when button is clicked.
 *  @param {DOM Object} div Button's div to assign click to
 *  @param {GMap2} Map object to change maptype of.
 *  @param {Object} mapType GMapType to change map to when clicked
 *  @param {Array} otherDivs Array of other button divs to toggle off
 */
ExtMapTypeControl.prototype.assignButtonEvent_ = function(div, map, mapType, otherDivs) {
  var me = this;

  GEvent.addDomListener(div, "click", function() {
    for (var i = 0; i < otherDivs.length; i++) {
      me.toggleButton_(otherDivs[i], false);
    }
    me.toggleButton_(div, true);
    map.setMapType(mapType);
  });
}

/*
 * Changes style of button to appear on/off depending on boolean passed in.
 * @param {DOM Object} div  Button div to change style of
 * @param {Boolean} boolCheck Used to decide to use on style or off style
 */
ExtMapTypeControl.prototype.toggleButton_ = function(div, boolCheck) {
  var add = boolCheck ? "_down" : "";
  div.style.background = "url('bluebutton_" + div.mapType + add + ".png')";
}

/*
 * Required by GMaps API for controls.
 * @return {GControlPosition} Default location for control
 */
ExtMapTypeControl.prototype.getDefaultPosition = function() {
  return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(7, 7));
}

/*
 * Sets the proper CSS for the given button element.
 * @param {DOM Object} button Button div to set style for
 */
ExtMapTypeControl.prototype.setButtonStyle_ = function(button, label) {
  button.style.color = "#000000";
  button.style.backgroundColor = "white";
  button.style.background = "url('bluebutton_" + label + ".png')";
  button.style.width = "85px";
  button.style.height = "30px";
  button.style.font = "small Arial";
  button.style.border = "1px solid black";
  button.style.padding = "0px";
  button.style.margin= "0px";
  button.style.textAlign = "center";
  button.style.fontSize = "12px";
  button.style.cursor = "pointer";
}

<commit_msg>Traffic<commit_after>/*
* ExtMapTypeControl Class
*  Copyright (c) 2007, Google
*  Author: Pamela Fox, others
*
* 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.
*
* This class lets you add a control to the map which mimics GMapTypeControl
*  and allows for the addition of a traffic button/traffic key.
*/

/*
 * Constructor for ExtMapTypeControl, which uses an option hash
 * to decide what elements to put in the control.
 * @param {opt_opts} Named optional arguments:
 *   opt_opts.showTraffic {Boolean} Controls whether traffic button is shown
 *   opt_opts.showTrafficKey {Boolean} Controls whether traffic key is shown
 */
function ExtMapTypeControl(opt_opts) {
  this.options = opt_opts || {};
}

ExtMapTypeControl.prototype = new GControl();

/**
 * Is called by GMap2's addOverlay method. Creates the button
 *  and appends to the map div.
 * @param {GMap2} map The map that has had this ExtMapTypeControl added to it.
 * @return {DOM Object} Div that holds the control
 */
ExtMapTypeControl.prototype.initialize = function(map) {
  var container = document.createElement("div");
  var me = this;

  var satDiv = me.createButton_("Satellite");
  var mapDiv = me.createButton_("Map");
  var hybDiv = me.createButton_("Hybrid");

  me.assignButtonEvent_(satDiv, map, G_SATELLITE_MAP, [mapDiv, hybDiv]);
  me.assignButtonEvent_(hybDiv, map, G_HYBRID_MAP, [satDiv, mapDiv]);
  me.assignButtonEvent_(mapDiv, map, G_NORMAL_MAP, [satDiv, hybDiv]);
  GEvent.addListener(map, "maptypechanged", function() {
    if (map.getCurrentMapType() == G_NORMAL_MAP) {
      GEvent.trigger(mapDiv, "click");
    } else if (map.getCurrentMapType() == G_SATELLITE_MAP) {
      GEvent.trigger(satDiv, "click");
    } else if (map.getCurrentMapType() == G_HYBRID_MAP) {
      GEvent.trigger(hybDiv, "click");
    }
  });

 if (me.options.showTraffic) {
   var trafficDiv = me.createButton_("Traffic");
   trafficDiv.style.marginRight = "8px";
   trafficDiv.firstChild.style.cssFloat = "left";
   trafficDiv.firstChild.style.styleFloat = "left";
   // Sending true makes overlay hidden by default
   me.trafficInfo = new GTrafficOverlay(true);
   // We have to do this so that we can sense if traffic is in view
   GEvent.addListener(me.trafficInfo, "changed", function(hasTrafficInView) {
     GLog.write(hasTrafficInView);
     if (hasTrafficInView) {
       trafficDiv.style.visibility = 'visible';
     } else {
       trafficDiv.style.visibility = 'hidden';
     }
   });
   map.addOverlay(me.trafficInfo);

   GEvent.addDomListener(trafficDiv, "click", function() {
     if (me.trafficInfo.isHidden()) {
      me.trafficInfo.show();
     } else {
       me.trafficInfo.hide();
     }
      me.toggleButton_(trafficDiv, !me.trafficInfo.isHidden());
    });

    me.toggleButton_(trafficDiv, false);
    container.appendChild(trafficDiv);
  }

  container.appendChild(satDiv);
  container.appendChild(mapDiv);
  container.appendChild(hybDiv);

  map.getContainer().appendChild(container);

  return container;
}

/*
 * Creates simple buttons with text nodes.
 * @param {String} text Text to display in button
 * @return {DOM Object} The div for the button.
 */
ExtMapTypeControl.prototype.createButton_ = function(text) {
  var buttonDiv = document.createElement("div");
  buttonDiv.mapType = text;
  this.setButtonStyle_(buttonDiv, text);
  buttonDiv.style.cssFloat = "left";
  buttonDiv.style.styleFloat = "left";
  var textDiv = document.createElement("div");
  textDiv.appendChild(document.createTextNode(""));
  textDiv.style.width = "6em";
  buttonDiv.appendChild(textDiv);
  return buttonDiv;
}

/*
 * Assigns events to MapType buttons to change maptype
 *  and toggle button styles correctly for all buttons
 *  when button is clicked.
 *  @param {DOM Object} div Button's div to assign click to
 *  @param {GMap2} Map object to change maptype of.
 *  @param {Object} mapType GMapType to change map to when clicked
 *  @param {Array} otherDivs Array of other button divs to toggle off
 */
ExtMapTypeControl.prototype.assignButtonEvent_ = function(div, map, mapType, otherDivs) {
  var me = this;

  GEvent.addDomListener(div, "click", function() {
    for (var i = 0; i < otherDivs.length; i++) {
      me.toggleButton_(otherDivs[i], false);
    }
    me.toggleButton_(div, true);
    map.setMapType(mapType);
  });
}

/*
 * Changes style of button to appear on/off depending on boolean passed in.
 * @param {DOM Object} div  Button div to change style of
 * @param {Boolean} boolCheck Used to decide to use on style or off style
 */
ExtMapTypeControl.prototype.toggleButton_ = function(div, boolCheck) {
  var add = boolCheck ? "_down" : "";
  div.style.background = "url('bluebutton_" + div.mapType + add + ".png')";
}

/*
 * Required by GMaps API for controls.
 * @return {GControlPosition} Default location for control
 */
ExtMapTypeControl.prototype.getDefaultPosition = function() {
  return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(7, 7));
}

/*
 * Sets the proper CSS for the given button element.
 * @param {DOM Object} button Button div to set style for
 */
ExtMapTypeControl.prototype.setButtonStyle_ = function(button, label) {
  button.style.color = "#000000";
  button.style.backgroundColor = "white";
  button.style.background = "url('bluebutton_" + label + ".png')";
  button.style.width = "85px";
  button.style.height = "30px";
  button.style.font = "small Arial";
  button.style.border = "1px solid black";
  button.style.padding = "0px";
  button.style.margin= "0px";
  button.style.textAlign = "center";
  button.style.fontSize = "12px";
  button.style.cursor = "pointer";
}

<|endoftext|>


<commit_before>angular.module('mwUI.UiComponents')
//TODO rename
/**
 * @ngdoc directive
 * @name mwUI.UiComponents.directive:mwTabs
 *
 * @description Shows a tab view. Requires that you transclude mw-tabs-pane. They define the title, icon, etc of the tab
 * When setting removeInactiveContent so true it will remove the tab content of inactive tabs from the dom. This is
 * recommended for tab content that has a complex logic
 *
 * @param {justified} boolean defines the arrangement of the tabs. When set to true they fill available with. Default false
 * @param {activePaneNumber} number defines the tab that should be selected. Starts with 1
 * @param {activePaneId} string alternative to activePaneNumber defines the active tab by its id. Requires that you set an id on mw-tabs-pane
 * @param {tabChanged} function the callback that shall be executed when the tab is changed. Will pass the activePaneNumber, newPane scope, previous pane scope as params
 * @param {removeInactiveContent} boolean defines wether inactive pane content should be removed from dom or just be set to hidden. Default false
 *
 * @example ```html
 * <!-- change callback example -->
 * <div mw-tabs
 *      active-pane-number="myCtrl.activePane"
 *      tab-changed="myCtrl.tabChanged"
 *      remove-inactive-content="true">
 *   <div mw-tabs-pane="{{'mytitle'| i18n}}">
 *     Tab Content 1
 *   </div>
 *   <div mw-tabs-pane="{{'mytitle_2'| i18n}}">
 *     Tab Content 2
 *   </div>
 * </div>
 * ```
 */
  .directive('mwTabs', function ($rootScope) {
    return {
      transclude: true,
      scope: {
        justified: '=?',
        activePaneNumber: '=?',
        activePaneId: '@?',
        tabChanged: '=?',
        removeInactiveContent: '=?'
      },
      templateUrl: 'uikit/mw-ui-components/directives/templates/mw_tab_bar.html',
      controller: function ($scope) {
        // The panes are populated by the mw-tabs-pane directive that is calling `registerPane`of this controller
        // It is defined as a scope attribute so it is available in this html template
        var activePaneIndex;

        $scope.panes = [];

        var setInitialSelection = function () {
          activePaneIndex = null;

          // In case that no active pane is defined by setting activePaneNumber or Id the first pane will be selected
          if (angular.isUndefined($scope.activePaneNumber) && angular.isUndefined($scope.activePaneId) && $scope.panes.length>0) {
            $scope.select($scope.panes[0]);

          // When a pane number is defined the pane with the index of activePaneNumber + 1 will be selected
          // So when the second tab shall be selected set activePaneNumber to 2
          } else if (angular.isDefined($scope.activePaneNumber)) {
            $scope.selectTabByNumber($scope.activePaneNumber);

          // When a pane id is defined the pane where the pane id equals the activePaneId will be selected
          // Make sure to set an id on the mw-tab-pane
          } else if (angular.isDefined($scope.activePaneId)) {
            $scope.selectTabById($scope.activePaneId);
          }
        };

        var throttledSetInitialSelection = _.debounce(setInitialSelection, 100);

        $scope.getActivePane = function () {
          var activePane;
          $scope.panes.every(function (pane) {
            if (pane.isSelected()) {
              activePane = pane;
              return false;
            }
            return true;
          });
          return activePane;
        };

        $scope.select = function (newPane) {
          var newPaneIndex = _.indexOf($scope.panes, newPane);

          if (newPane && newPaneIndex !== -1 && newPaneIndex !== activePaneIndex) {
            var previousSelectedPane = $scope.getActivePane();
            if (previousSelectedPane) {
              previousSelectedPane.deselect();
            }

            newPane.select();
            activePaneIndex = newPaneIndex;

            if ($scope.tabChanged && typeof $scope.tabChanged === 'function') {
              $scope.tabChanged(activePaneIndex + 1, newPane, previousSelectedPane);
              $rootScope.$emit('$mwTabChange');
            }
          }
        };

        $scope.selectTabByNumber = function (number) {
          if (number > 0 && number <= $scope.panes.length) {
            $scope.select($scope.panes[number - 1]);
          }
        };

        $scope.selectTabById = function (id) {
          $scope.panes.every(function (pane) {
            if (pane.getId() === id) {
              $scope.select(pane);
              return false;
            }
            return true;
          });
        };

        $scope.getActivePaneIndex = function () {
          if (activePaneIndex) {
            return activePaneIndex;
          } else {
            return 0;
          }
        };

        $scope.canShowPaneContent = function () {
          var activePane = $scope.panes[activePaneIndex];
          return (activePane && activePane.isInitialised);
        };

        // add a change listener on the pane
        $scope.$watch('activePaneNumber', function (_new, _old) {
          if (_new && _new !== _old) {
            $scope.selectTabByNumber(_new);
          }
        });

        $scope.$watch('activePaneId', function (_newId) {
          if (_newId) {
            $scope.selectTabById(_newId);
          }
        });

        this.registerPane = function (pane) {
          $scope.panes.push(pane);
          throttledSetInitialSelection();
        };

        this.unRegisterPane = function (pane) {
          if (pane) {
            var indexOfExistingPane = _.indexOf($scope.panes, pane);
            if (indexOfExistingPane !== -1) {
              $scope.panes.splice(indexOfExistingPane, 1);
            }
            throttledSetInitialSelection();
          }
        };

        this.canRemoveInactiveContent = function(){
          return $scope.removeInactiveContent;
        };
      }
    };
  });<commit_msg>Indent code<commit_after>angular.module('mwUI.UiComponents')
//TODO rename
/**
 * @ngdoc directive
 * @name mwUI.UiComponents.directive:mwTabs
 *
 * @description Shows a tab view. Requires that you transclude mw-tabs-pane. They define the title, icon, etc of the tab
 * When setting removeInactiveContent so true it will remove the tab content of inactive tabs from the dom. This is
 * recommended for tab content that has a complex logic
 *
 * @param {justified} boolean defines the arrangement of the tabs. When set to true they fill available with. Default false
 * @param {activePaneNumber} number defines the tab that should be selected. Starts with 1
 * @param {activePaneId} string alternative to activePaneNumber defines the active tab by its id. Requires that you set an id on mw-tabs-pane
 * @param {tabChanged} function the callback that shall be executed when the tab is changed. Will pass the activePaneNumber, newPane scope, previous pane scope as params
 * @param {removeInactiveContent} boolean defines wether inactive pane content should be removed from dom or just be set to hidden. Default false
 *
 * @example ```html
 * <!-- change callback example -->
 * <div mw-tabs
 *      active-pane-number="myCtrl.activePane"
 *      tab-changed="myCtrl.tabChanged"
 *      remove-inactive-content="true">
 *   <div mw-tabs-pane="{{'mytitle'| i18n}}">
 *     Tab Content 1
 *   </div>
 *   <div mw-tabs-pane="{{'mytitle_2'| i18n}}">
 *     Tab Content 2
 *   </div>
 * </div>
 * ```
 */
  .directive('mwTabs', function ($rootScope) {
    return {
      transclude: true,
      scope: {
        justified: '=?',
        activePaneNumber: '=?',
        activePaneId: '@?',
        tabChanged: '=?',
        removeInactiveContent: '=?'
      },
      templateUrl: 'uikit/mw-ui-components/directives/templates/mw_tab_bar.html',
      controller: function ($scope) {
        // The panes are populated by the mw-tabs-pane directive that is calling `registerPane`of this controller
        // It is defined as a scope attribute so it is available in this html template
        var activePaneIndex;

        $scope.panes = [];

        var setInitialSelection = function () {
          activePaneIndex = null;

          // In case that no active pane is defined by setting activePaneNumber or Id the first pane will be selected
          if (angular.isUndefined($scope.activePaneNumber) && angular.isUndefined($scope.activePaneId) && $scope.panes.length > 0) {
            $scope.select($scope.panes[0]);

          // When a pane number is defined the pane with the index of activePaneNumber + 1 will be selected
          // So when the second tab shall be selected set activePaneNumber to 2
          } else if (angular.isDefined($scope.activePaneNumber)) {
            $scope.selectTabByNumber($scope.activePaneNumber);

          // When a pane id is defined the pane where the pane id equals the activePaneId will be selected
          // Make sure to set an id on the mw-tab-pane
          } else if (angular.isDefined($scope.activePaneId)) {
            $scope.selectTabById($scope.activePaneId);
          }
        };

        var throttledSetInitialSelection = _.debounce(setInitialSelection, 100);

        $scope.getActivePane = function () {
          var activePane;
          $scope.panes.every(function (pane) {
            if (pane.isSelected()) {
              activePane = pane;
              return false;
            }
            return true;
          });
          return activePane;
        };

        $scope.select = function (newPane) {
          var newPaneIndex = _.indexOf($scope.panes, newPane);

          if (newPane && newPaneIndex !== -1 && newPaneIndex !== activePaneIndex) {
            var previousSelectedPane = $scope.getActivePane();
            if (previousSelectedPane) {
              previousSelectedPane.deselect();
            }

            newPane.select();
            activePaneIndex = newPaneIndex;

            if ($scope.tabChanged && typeof $scope.tabChanged === 'function') {
              $scope.tabChanged(activePaneIndex + 1, newPane, previousSelectedPane);
              $rootScope.$emit('$mwTabChange');
            }
          }
        };

        $scope.selectTabByNumber = function (number) {
          if (number > 0 && number <= $scope.panes.length) {
            $scope.select($scope.panes[number - 1]);
          }
        };

        $scope.selectTabById = function (id) {
          $scope.panes.every(function (pane) {
            if (pane.getId() === id) {
              $scope.select(pane);
              return false;
            }
            return true;
          });
        };

        $scope.getActivePaneIndex = function () {
          if (activePaneIndex) {
            return activePaneIndex;
          } else {
            return 0;
          }
        };

        $scope.canShowPaneContent = function () {
          var activePane = $scope.panes[activePaneIndex];
          return (activePane && activePane.isInitialised);
        };

        // add a change listener on the pane
        $scope.$watch('activePaneNumber', function (_new, _old) {
          if (_new && _new !== _old) {
            $scope.selectTabByNumber(_new);
          }
        });

        $scope.$watch('activePaneId', function (_newId) {
          if (_newId) {
            $scope.selectTabById(_newId);
          }
        });

        this.registerPane = function (pane) {
          $scope.panes.push(pane);
          throttledSetInitialSelection();
        };

        this.unRegisterPane = function (pane) {
          if (pane) {
            var indexOfExistingPane = _.indexOf($scope.panes, pane);
            if (indexOfExistingPane !== -1) {
              $scope.panes.splice(indexOfExistingPane, 1);
            }
            throttledSetInitialSelection();
          }
        };

        this.canRemoveInactiveContent = function(){
          return $scope.removeInactiveContent;
        };
      }
    };
  });<|endoftext|>