[
  {
    "path": ".eslintrc.json",
    "content": "{\n  \"env\": {\n    \"es6\": true,\n    \"node\": true\n  },\n  \"extends\": \"eslint:recommended\",\n  \"parserOptions\": {\n    \"ecmaVersion\": 2015\n  },\n  \"rules\": {\n    \"brace-style\": \"error\",\n    \"no-irregular-whitespace\":\"error\",\n    \"no-octal-escape\": \"error\",\n    \"no-octal\": \"error\",\n    \"no-proto\":\"error\",\n    \"strict\":[\"error\", \"global\"],\n    \"no-undef\":\"error\",\n    \"no-use-before-define\": \"off\",\n    \"indent\": [\"error\", 2],\n    \"semi\": [2, \"always\"],\n    \"quotes\": [2, \"single\"]\n  }\n}\n"
  },
  {
    "path": ".gitignore",
    "content": ".dccache\nnode_modules\np.js\np1.js\np2.js\nnpm-debug.log\nlog.txt\nweather.query\n"
  },
  {
    "path": ".npmignore",
    "content": "node_modules\np.js\np1.js\np2.js\nnpm-debug.log\ndocs\nexamples"
  },
  {
    "path": "LICENSE.md",
    "content": "## MIT License\n\nCopyright (c) 2015 Yaron Naveh and blessed-contrib contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "## blessed-contrib\n\nBuild dashboards (or any other application) using ascii/ansi art and javascript.\n\nFriendly to terminals, ssh and developers. Extends [blessed](https://github.com/chjj/blessed) with custom  [drawille](https://github.com/madbence/node-drawille) and other widgets.\n\nYou should also [check WOPR](https://github.com/yaronn/wopr): a markup for creating terminal reports, presentations and infographics.\n\n\n**Contributors:**\n\nYaron Naveh ([@YaronNaveh](http://twitter.com/YaronNaveh))\nChris ([@xcezzz](https://twitter.com/xcezzz))\nMiguel Valadas ([@mvaladas](https://github.com/mvaladas))\nLiran Tal ([@lirantal](https://github.com/lirantal))\n\n**Demo ([full size](https://raw.githubusercontent.com/yaronn/blessed-contrib/master/docs/images/term3.gif)):**\n\n<img src=\"./docs/images/truload.png\" alt=\"term\" width=\"800\">\n\n<img src=\"./docs/images/term3.gif\" alt=\"term\" width=\"800\">\n\n([source code](./examples/dashboard.js))\n\n**Running the demo**\n\n    git clone https://github.com/yaronn/blessed-contrib.git\n    cd blessed-contrib\n    npm install\n    node ./examples/dashboard.js\n\nWorks on Linux, OS X and Windows. For Windows follow the [pre requisites](http://webservices20.blogspot.co.il/2015/04/running-terminal-dashboards-on-windows.html).\n\n## Installation (to build custom projects)\n\n    npm install blessed blessed-contrib\n\n## Usage\n\nYou can use any of the default widgets of [blessed](https://github.com/chjj/blessed) (texts, lists and etc) or the widgets added in blessed-contrib (described below). A [layout](#layouts) is optional but useful for dashboards. The widgets in blessed-contrib follow the same usage pattern:\n\n`````javascript\n   var blessed = require('blessed')\n     , contrib = require('blessed-contrib')\n     , screen = blessed.screen()\n     , line = contrib.line(\n         { style:\n           { line: \"yellow\"\n           , text: \"green\"\n           , baseline: \"black\"}\n         , xLabelPadding: 3\n         , xPadding: 5\n         , label: 'Title'})\n     , data = {\n         x: ['t1', 't2', 't3', 't4'],\n         y: [5, 1, 7, 5]\n      }\n   screen.append(line) //must append before setting data\n   line.setData([data])\n\n   screen.key(['escape', 'q', 'C-c'], function(ch, key) {\n     return process.exit(0);\n   });\n\n   screen.render()\n`````\n\nSee below for a complete list of widgets.\n\n\n## Widgets\n\n[Line Chart](#line-chart)\n\n[Bar Chart](#bar-chart)\n\n[Stacked Bar Chart](#stacked-bar-chart)\n\n[Map](#map)\n\n[Gauge](#gauge)\n\n[Stacked Gauge](#stacked-gauge)\n\n[Donut](#donut)\n\n[LCD Display](#lcd-display)\n\n[Rolling Log](#rolling-log)\n\n[Picture](#picture)\n\n[Sparkline](#sparkline)\n\n[Table](#table)\n\n[Tree](#tree)\n\n[Markdown](#markdown)\n\n### Line Chart\n\n<img src=\"./docs/images/line.gif\" alt=\"line\" width=\"400\">\n\n`````javascript\n   var line = contrib.line(\n         { style:\n           { line: \"yellow\"\n           , text: \"green\"\n           , baseline: \"black\"}\n         , xLabelPadding: 3\n         , xPadding: 5\n         , showLegend: true\n         , wholeNumbersOnly: false //true=do not show fraction in y axis\n         , label: 'Title'})\n   var series1 = {\n         title: 'apples',\n         x: ['t1', 't2', 't3', 't4'],\n         y: [5, 1, 7, 5]\n      }\n   var series2 = {\n         title: 'oranges',\n         x: ['t1', 't2', 't3', 't4'],\n         y: [2, 1, 4, 8]\n      }\n   screen.append(line) //must append before setting data\n   line.setData([series1, series2])\n`````\n**Examples:** [simple line chart](./examples/line-fraction.js), [multiple lines](./examples/multi-line-chart.js), [256 colors](./examples/line-random-colors.js)\n\n### Bar Chart\n\n<img src=\"./docs/images/bar.gif\" alt=\"bar\" width=\"250\">\n\n`````javascript\n    var bar = contrib.bar(\n       { label: 'Server Utilization (%)'\n       , barWidth: 4\n       , barSpacing: 6\n       , xOffset: 0\n       , maxHeight: 9})\n    screen.append(bar) //must append before setting data\n    bar.setData(\n       { titles: ['bar1', 'bar2']\n       , data: [5, 10]})\n`````\n\n### Stacked Bar Chart\n\n<img src=\"./docs/images/stacked-bar.png\" alt=\"stacked-bar\" width=\"250\">\n\n`````javascript\n    bar = contrib.stackedBar(\n       { label: 'Server Utilization (%)'\n       , barWidth: 4\n       , barSpacing: 6\n       , xOffset: 0\n       //, maxValue: 15\n       , height: \"40%\"\n       , width: \"50%\"\n       , barBgColor: [ 'red', 'blue', 'green' ]})\n    screen.append(bar)\n    bar.setData(\n       { barCategory: ['Q1', 'Q2', 'Q3', 'Q4']\n       , stackedCategory: ['US', 'EU', 'AP']\n       , data:\n          [ [ 7, 7, 5]\n          , [8, 2, 0]\n          , [0, 0, 0]\n          , [2, 3, 2] ]\n       })\n`````\n\n### Map\n\n<img src=\"./docs/images/map.gif\" alt=\"map\" width=\"500\">\n\n`````javascript\n   var map = contrib.map({label: 'World Map'})\n   map.addMarker({\"lon\" : \"-79.0000\", \"lat\" : \"37.5000\", color: \"red\", char: \"X\" })\n`````\n\n\n### Gauge\n\n<img src=\"./docs/images/gauge.gif\" alt=\"gauge\" width=\"170\">\n\n`````javascript\n   var gauge = contrib.gauge({label: 'Progress', stroke: 'green', fill: 'white'})\n   gauge.setPercent(25)\n`````\n\n### Stacked Gauge\n\n<img src=\"./docs/images/stackgauge.gif\" alt=\"stackedgauge\">\n\nEither specify each stacked portion with a `percent` and `stroke`...\n\n`````javascript\n   var gauge = contrib.gauge({label: 'Stacked '})\n   gauge.setStack([{percent: 30, stroke: 'green'}, {percent: 30, stroke: 'magenta'}, {percent: 40, stroke: 'cyan'}])\n`````\n\nOr, you can just supply an array of numbers and random colors will be chosen.\n\n`````javascript\n   var gauge = contrib.gauge({label: 'Stacked Progress'})\n   gauge.setStack([30,30,40])\n`````\n\n### Donut\n\n<img src=\"./docs/images/donut.gif\" alt=\"donut\">\n\n\n`````javascript\n   var donut = contrib.donut({\n\tlabel: 'Test',\n\tradius: 8,\n\tarcWidth: 3,\n\tremainColor: 'black',\n\tyPadding: 2,\n\tdata: [\n\t  {percent: 80, label: 'web1', color: 'green'}\n\t]\n  });\n`````\n\nData passed in uses `percent` and `label` to draw the donut graph. Color is optional and defaults to green.\n\n`````javascript\n   donut.setData([\n   \t{percent: 87, label: 'rcp','color': 'green'},\n\t{percent: 43, label: 'rcp','color': 'cyan'},\n   ]);\n`````\n\nUpdating the donut is as easy as passing in an array to `setData` using the same array format as in the constructor. Pass in as many objects to the array of data as you want, they will automatically resize and try to fit. However, please note that you will still be restricted to actual screen space.\n\nYou can also hardcode a specific numeric into the donut's core display instead of the percentage by passing an `percentAltNumber` property to the data, such as:\n\n`````javascript\n   var donut = contrib.donut({\n\tlabel: 'Test',\n\tradius: 8,\n\tarcWidth: 3,\n\tremainColor: 'black',\n\tyPadding: 2,\n\tdata: [\n\t  {percentAltNumber: 50, percent: 80, label: 'web1', color: 'green'}\n\t]\n  });\n`````\n\nSee an example of this in one of the donuts settings on `./examples/donut.js`.\n\n### LCD Display\n\n<img src=\"./docs/images/lcd.gif\" alt=\"lcd\">\n\n`````javascript\n   var lcd = contrib.lcd(\n     { segmentWidth: 0.06 // how wide are the segments in % so 50% = 0.5\n     , segmentInterval: 0.11 // spacing between the segments in % so 50% = 0.550% = 0.5\n     , strokeWidth: 0.11 // spacing between the segments in % so 50% = 0.5\n     , elements: 4 // how many elements in the display. or how many characters can be displayed.\n     , display: 321 // what should be displayed before first call to setDisplay\n     , elementSpacing: 4 // spacing between each element\n     , elementPadding: 2 // how far away from the edges to put the elements\n     , color: 'white' // color for the segments\n     , label: 'Storage Remaining'})\n`````\n\n`````javascript\n\n\tlcd.setDisplay(23 + 'G'); // will display \"23G\"\n\tlcd.setOptions({}) // adjust options at runtime\n\n`````\n\nPlease see the **examples/lcd.js** for an example. The example provides keybindings to adjust the `segmentWidth` and `segmentInterval` and `strokeWidth` in real-time so that you can see how they manipulate the look and feel.\n\n\n### Rolling Log\n\n<img src=\"./docs/images/log.gif\" alt=\"log\" width=\"180\">\n\n`````javascript\n   var log = contrib.log(\n      { fg: \"green\"\n      , selectedFg: \"green\"\n      , label: 'Server Log'})\n   log.log(\"new log line\")\n`````\n\n\n### Picture\n\n(Also check the new blessed [image implementation](https://github.com/chjj/blessed#image-from-box) which has several benefits over this one.)\n\n<img src=\"./docs/images/picture.png\" alt=\"log\" width=\"180\">\n\n`````javascript\n    var pic = contrib.picture(\n       { file: './flower.png'\n       , cols: 25\n       , onReady: ready})\n    function ready() {screen.render()}\n`````\n\nnote: only png images are supported\n\n\n### Sparkline\n\n<img src=\"./docs/images/spark.gif\" alt=\"spark\" width=\"180\">\n\n`````javascript\n   var spark = contrib.sparkline(\n     { label: 'Throughput (bits/sec)'\n     , tags: true\n     , style: { fg: 'blue' }})\n\n   sparkline.setData(\n   [ 'Sparkline1', 'Sparkline2'],\n   [ [10, 20, 30, 20]\n   , [40, 10, 40, 50]])\n`````\n\n### Table\n\n<img src=\"./docs/images/table.gif\" alt=\"table\" width=\"250\">\n\n`````javascript\n   var table = contrib.table(\n     { keys: true\n     , fg: 'white'\n     , selectedFg: 'white'\n     , selectedBg: 'blue'\n     , interactive: true\n     , label: 'Active Processes'\n     , width: '30%'\n     , height: '30%'\n     , border: {type: \"line\", fg: \"cyan\"}\n     , columnSpacing: 10 //in chars\n     , columnWidth: [16, 12, 12] /*in chars*/ })\n\n   //allow control the table with the keyboard\n   table.focus()\n\n   table.setData(\n   { headers: ['col1', 'col2', 'col3']\n   , data:\n      [ [1, 2, 3]\n      , [4, 5, 6] ]})\n`````\n\n### Tree\n\n<img src=\"./docs/images/tree.gif\" alt=\"table\" width=\"250\">\n\n`````javascript\n   var tree = contrib.tree({fg: 'green'})\n\n   //allow control the table with the keyboard\n   tree.focus()\n\n   tree.on('select',function(node){\n     if (node.myCustomProperty){\n       console.log(node.myCustomProperty);\n     }\n     console.log(node.name);\n   }\n\n   // you can specify a name property at root level to display root\n   tree.setData(\n   { extended: true\n   , children:\n     {\n       'Fruit':\n       { children:\n         { 'Banana': {}\n         , 'Apple': {}\n         , 'Cherry': {}\n         , 'Exotics': {\n             children:\n             { 'Mango': {}\n             , 'Papaya': {}\n             , 'Kiwi': { name: 'Kiwi (not the bird!)', myCustomProperty: \"hairy fruit\" }\n             }}\n         , 'Pear': {}}}\n     , 'Vegetables':\n       { children:\n         { 'Peas': {}\n         , 'Lettuce': {}\n         , 'Pepper': {}}}}})\n`````\n\n#### Options\n\n * keys : Key to expand nodes. Default : ['enter','default']\n * extended : Should nodes be extended/generated by default? Be careful with this setting when using a callback function. Default : false\n * template :\n   * extend : Suffix \"icon\" for closed node. Default : '[+]'\n   * retract : Suffix \"icon\" for opened node. Default : '[-]'\n   * lines : Show lines in tree. Default : true\n\n#### Nodes\n\nEvery node is a hash and it can have custom properties that can be used in \"select\" event callback. However, there are several special keys :\n\n* name\n  * *Type* : `string`\n  * *Desc* : Node name\n  * If the node isn't the root and you don't specify the name, will be set to hash key\n  * *Example* : <code>{ name: 'Fruit'}</code>\n* children\n  * *Type* : `hash` or `function(node){ return children }`\n  * *Desc* : Node children.\n  * The function must return a hash that could have been used as children property\n  * If you use a function, the result will be stored in `node.childrenContent` and `children`\n  * *Example* :\n    * Hash : <code>{'Fruit':{ name: 'Fruit', children:{ 'Banana': {}, 'Cherry': {}}}}</code>\n    * Function : see `examples/explorer.js`\n* childrenContent\n  * *Type* : `hash`\n  * *Desc* : Children content for internal usage *DO NOT MODIFY*\n  * If `node.children` is a hash, `node.children===node.childrenContent`\n  * If `node.children` is a function, it's used to store the `node.children()` result\n  * You can read this property, but you should never write it.\n  * Usually this will be used to check `if(node.childrenContent)` in your `node.children` function to generate children only once\n* extended\n  * *Type* : `boolean`\n  * *Desc* : Determine if this node is extended\n  * No effect when the node have no child\n  * Default value for each node will be `treeInstance.options.extended` if the node `extended` option is not set\n  * *Example* : <code>{'Fruit':{ name: 'Fruit', extended: true, children:{ 'Banana': {}, 'Cherry': {}}}}</code>\n\n### Markdown\n\n<img src=\"./docs/images/markdown.png\" alt=\"table\">\n\n`````javascript\n   var markdown = contrib.markdown()\n   markdown.setMarkdown('# Hello \\n blessed-contrib renders markdown using `marked-terminal`')\n`````\n\n### Colors\nYou can use 256 colors ([source](./examples/line-random-colors.js)):\n\n`````javascript\n  function randomColor() {\n    return [Math.random() * 255,Math.random()*255, Math.random()*255]\n  }\n\n  line = contrib.line(\n  {\n    ...\n    , style: { line: randomColor(), text: randomColor(), baseline: randomColor() }\n  })\n`````\n   \n### Layouts\n\n[Grid](#grid)\n\n[Carousel](#carousel)\n\n### Grid\n\nA grid layout can auto position your elements in a grid layout.\nWhen using a grid, you should not create the widgets, rather specify to the grid which widget to create and with which params.\nEach widget can span multiple rows and columns.\n\n`````javascript\n   var screen = blessed.screen()\n\n   var grid = new contrib.grid({rows: 12, cols: 12, screen: screen})\n\n   //grid.set(row, col, rowSpan, colSpan, obj, opts)\n   var map = grid.set(0, 0, 4, 4, contrib.map, {label: 'World Map'})\n   var box = grid.set(4, 4, 4, 4, blessed.box, {content: 'My Box'})\n\n   screen.render()\n`````\n\n### Carousel\nA carousel layout switches between different views based on time or keyboard activity.\nOne use case is an office dashboard with rotating views:\n\n`````javascript\n    var blessed = require('blessed')\n      , contrib = require('./')\n      , screen = blessed.screen()\n\n    function page1(screen) {\n       var map = contrib.map()\n       screen.append(map)\n    }\n\n    function page2(screen) {\n      var line = contrib.line(\n       { width: 80\n       , height: 30\n       , left: 15\n       , top: 12\n       , xPadding: 5\n       , label: 'Title'\n       })\n\n      var data = [ { title: 'us-east',\n                 x: ['t1', 't2', 't3', 't4'],\n                 y: [0, 0.0695652173913043, 0.11304347826087, 2],\n                 style: {\n                  line: 'red'\n                 }\n               }\n            ]\n\n      screen.append(line)\n      line.setData(data)\n    }\n\n    screen.key(['escape', 'q', 'C-c'], function(ch, key) {\n      return process.exit(0);\n    });\n\n    var carousel = new contrib.carousel( [page1, page2]\n                                       , { screen: screen\n                                         , interval: 3000 //how often to switch views (set 0 to never swicth automatically)\n                                         , controlKeys: true  //should right and left keyboard arrows control view rotation\n                                         })\n    carousel.start()\n\n`````\n\n## Samples\n\n\n### Terminal Dashboard\n\n<img src=\"./docs/images/term3.gif\" alt=\"term\" width=\"800\">\n\n**Running the sample**\n\n    git clone https://github.com/yaronn/blessed-contrib.git\n    cd blessed-contrib\n    npm install\n    node ./examples/dashboard.js\n\n**Installation (for a custom dashboard)**\n\n    npm install blessed\n    npm install blessed-contrib\n\n\n**A simple dashboard**\n\n`````javascript\n   var blessed = require('blessed')\n     , contrib = require('blessed-contrib')\n     , screen = blessed.screen()\n     , grid = new contrib.grid({rows: 1, cols: 2, screen: screen})\n\n   var line = grid.set(0, 0, 1, 1, contrib.line,\n     { style:\n       { line: \"yellow\"\n       , text: \"green\"\n       , baseline: \"black\"}\n     , xLabelPadding: 3\n     , xPadding: 5\n     , label: 'Stocks'})\n\n   var map = grid.set(0, 1, 1, 1, contrib.map, {label: 'Servers Location'})\n\n   var lineData = {\n      x: ['t1', 't2', 't3', 't4'],\n      y: [5, 1, 7, 5]\n   }\n\n   line.setData([lineData])\n\n   screen.key(['escape', 'q', 'C-c'], function(ch, key) {\n     return process.exit(0);\n   });\n\n   screen.render()\n`````\n\n**Rich dashboard**\n\nSee [source code](./examples/dashboard.js)\n\n## Troubleshooting\nIf you see questions marks or some (or all) missign characters try running with these env vars to fix encoding / terminal: \n`````\n    $> LANG=en_US.utf8 TERM=xterm-256color node your-code.js \n`````\n\n## License\nThis library is under the [MIT License](http://opensource.org/licenses/MIT)\n\n## More Information\nCreated by Yaron Naveh ([twitter](http://twitter.com/YaronNaveh), [blog](http://webservices20.blogspot.com/))\n"
  },
  {
    "path": "examples/bar.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../')\n  , screen = blessed.screen()\n  , bar = contrib.bar(\n       { label: 'Server Utilization (%)'\n       , barWidth: 4\n       , barSpacing: 6\n       , xOffset: 0\n       , maxHeight: 9\n       , height: \"40%\"})\n\nscreen.append(bar)\n\nbar.setData(\n       { titles: ['bar1', 'bar2']\n       , data: [5, 10]})\n\nscreen.render()"
  },
  {
    "path": "examples/carousel.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../')\n  , screen = blessed.screen()\n\nfunction page1(screen) {  \n   var grid = new contrib.grid({rows: 4, cols: 4, screen: screen})\n\n   var line = grid.set(1, 0, 2, 2, contrib.line, \n     { style: \n       { line: \"yellow\"\n       , text: \"green\"\n       , baseline: \"black\"}\n     , xLabelPadding: 3\n     , xPadding: 5\n     , label: 'Stocks'})\n\n   var map = grid.set(1, 2, 2, 2, contrib.map, {label: 'Servers Location'})\n\n   var box = blessed.box({content: 'click right-left arrows or wait 3 seconds for the next layout in the carousel', top: '80%', left: '10%'})\n   screen.append(box)\n\n   var lineData = {\n      x: ['t1', 't2', 't3', 't4'],\n      y: [5, 1, 7, 5]\n   }\n\n   line.setData([lineData]) \n}\n\nfunction page2(screen) {  \n  var line = contrib.line(\n   { width: 80\n   , height: 30\n   , left: 15\n   , top: 12  \n   , xPadding: 5\n   , label: 'Title'\n   })\n\n  var data = [ { title: 'us-east',\n             x: ['t1', 't2', 't3', 't4'],\n             y: [0, 0.0695652173913043, 0.11304347826087, 2],\n             style: {\n              line: 'red'\n             }\n           }\n        ]\n\n  screen.append(line)\n  line.setData(data)\n\n  var box = blessed.box({content: 'click right-left arrows or wait 3 seconds for the next layout in the carousel', top: '80%', left: '10%'})\n  screen.append(box)\n\n}\n\nscreen.key(['escape', 'q', 'C-c'], function(ch, key) {\n  return process.exit(0);\n});\n\nvar carousel = new contrib.carousel( [page1, page2]\n                                   , { screen: screen\n                                     , interval: 3000\n                                     , controlKeys: true })\ncarousel.start()\n"
  },
  {
    "path": "examples/dashboard-random-colors.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../index')\n\nvar screen = blessed.screen()\n\n//create layout and widgets\n\n  // Create a random color\n  function randomColor() {\n    return [Math.random() * 255,Math.random()*255, Math.random()*255]\n}\n\nvar grid = new contrib.grid({rows: 12, cols: 12, screen: screen})\n\n/**\n * Donut Options\n  self.options.radius = options.radius || 14; // how wide is it? over 5 is best\n  self.options.arcWidth = options.arcWidth || 4; //width of the donut\n  self.options.yPadding = options.yPadding || 2; //padding from the top\n */\nvar donut = grid.set(8, 8, 4, 2, contrib.donut, \n  {\n  label: 'Percent Donut',\n  radius: 16,\n  arcWidth: 4,\n  yPadding: 2,\n  data: [{label: 'Storage', percent: 87}]\n})\n\n// var latencyLine = grid.set(8, 8, 4, 2, contrib.line, \n//   { style: \n//     { line: \"yellow\"\n//     , text: \"green\"\n//     , baseline: \"black\"}\n//   , xLabelPadding: 3\n//   , xPadding: 5\n//   , label: 'Network Latency (sec)'})\n\nvar gauge = grid.set(8, 10, 2, 2, contrib.gauge, {label: 'Storage', percent: [80,20]})\nvar gauge_two = grid.set(2, 9, 2, 3, contrib.gauge, {label: 'Deployment Progress', percent: 80})\n\nvar sparkline = grid.set(10, 10, 2, 2, contrib.sparkline, \n  { label: 'Throughput (bits/sec)'\n  , tags: true\n  , style: { fg: 'blue', titleFg: 'white' }})\n\nvar bar = grid.set(4, 6, 4, 3, contrib.bar, \n  { label: 'Server Utilization (%)'\n  , barWidth: 4\n  , barSpacing: 6\n  , xOffset: 2\n  , maxHeight: 9})\n\nvar table =  grid.set(4, 9, 4, 3, contrib.table, \n  { keys: true\n  , fg: 'green'\n  , label: 'Active Processes'\n  , columnSpacing: 1\n  , columnWidth: [24, 10, 10]})\n\n/*\n *\n * LCD Options\n//these options need to be modified epending on the resulting positioning/size\n  options.segmentWidth = options.segmentWidth || 0.06; // how wide are the segments in % so 50% = 0.5\n  options.segmentInterval = options.segmentInterval || 0.11; // spacing between the segments in % so 50% = 0.5\n  options.strokeWidth = options.strokeWidth || 0.11; // spacing between the segments in % so 50% = 0.5\n//default display settings\n  options.elements = options.elements || 3; // how many elements in the display. or how many characters can be displayed.\n  options.display = options.display || 321; // what should be displayed before anything is set\n  options.elementSpacing = options.spacing || 4; // spacing between each element\n  options.elementPadding = options.padding || 2; // how far away from the edges to put the elements\n//coloring\n  options.color = options.color || \"white\";\n*/\nvar lcdLineOne = grid.set(0,9,2,3, contrib.lcd,\n  {\n    label: \"LCD Test\",\n    segmentWidth: 0.06,\n    segmentInterval: 0.11,\n    strokeWidth: 0.1,\n    elements: 5,\n    display: 3210,\n    elementSpacing: 4,\n    elementPadding: 2\n  }\n);\n\nvar errorsLine = grid.set(0, 6, 4, 3, contrib.line, \n  { style: \n    { line: randomColor()\n    , text: randomColor()\n    , baseline: randomColor()}\n  , label: 'Errors Rate'\n  , maxY: 60\n  , showLegend: true })\n\nvar transactionsLine = grid.set(0, 0, 6, 6, contrib.line, \n          { showNthLabel: 5\n          , maxY: 100\n          , label: 'Total Transactions'\n          , showLegend: true\n          , legend: {width: 10}})\n\nvar map = grid.set(6, 0, 6, 6, contrib.map, {label: 'Servers Location'})\n\nvar log = grid.set(8, 6, 4, 2, contrib.log, \n  { fg: randomColor()\n  , selectedFg: randomColor()\n  , label: 'Server Log'})\n\n\n//dummy data\nvar servers = ['US1', 'US2', 'EU1', 'AU1', 'AS1', 'JP1']\nvar commands = ['grep', 'node', 'java', 'timer', '~/ls -l', 'netns', 'watchdog', 'gulp', 'tar -xvf', 'awk', 'npm install']\n\n\n//set dummy data on gauge\nvar gauge_percent = 0\nsetInterval(function() {\n  gauge.setData([gauge_percent, 100-gauge_percent]);\n  gauge_percent++;\n  if (gauge_percent>=100) gauge_percent = 0  \n}, 200)\n\nvar gauge_percent_two = 0\nsetInterval(function() {\n  gauge_two.setData(gauge_percent_two);\n  gauge_percent_two++;\n  if (gauge_percent_two>=100) gauge_percent_two = 0  \n}, 200);\n\n\n//set dummy data on bar chart\nfunction fillBar() {\n  var arr = []\n  for (var i=0; i<servers.length; i++) {\n    arr.push(Math.round(Math.random()*10))\n  }\n  bar.setData({titles: servers, data: arr})\n}\nfillBar()\nsetInterval(fillBar, 2000)\n\n\n//set dummy data for table\nfunction generateTable() {\n   var data = []\n\n   for (var i=0; i<30; i++) {\n     var row = []          \n     row.push(commands[Math.round(Math.random()*(commands.length-1))])\n     row.push(Math.round(Math.random()*5))\n     row.push(Math.round(Math.random()*100))\n\n     data.push(row)\n   }\n\n   table.setData({headers: ['Process', 'Cpu (%)', 'Memory'], data: data})\n}\n\ngenerateTable()\ntable.focus()\nsetInterval(generateTable, 3000)\n\n\n//set log dummy data\nsetInterval(function() {\n   var rnd = Math.round(Math.random()*2)\n   if (rnd==0) log.log('starting process ' + commands[Math.round(Math.random()*(commands.length-1))])   \n   else if (rnd==1) log.log('terminating server ' + servers[Math.round(Math.random()*(servers.length-1))])\n   else if (rnd==2) log.log('avg. wait time ' + Math.random().toFixed(2))\n   screen.render()\n}, 500)\n\n\n//set spark dummy data\nvar spark1 = [1,2,5,2,1,5,1,2,5,2,1,5,4,4,5,4,1,5,1,2,5,2,1,5,1,2,5,2,1,5,1,2,5,2,1,5]\nvar spark2 = [4,4,5,4,1,5,1,2,5,2,1,5,4,4,5,4,1,5,1,2,5,2,1,5,1,2,5,2,1,5,1,2,5,2,1,5]\n\nrefreshSpark()\nsetInterval(refreshSpark, 1000)\n\nfunction refreshSpark() {\n  spark1.shift()\n  spark1.push(Math.random()*5+1)       \n  spark2.shift()\n  spark2.push(Math.random()*5+1)       \n  sparkline.setData(['Server1', 'Server2'], [spark1, spark2])  \n}\n\n\n\n//set map dummy markers\nvar marker = true\nsetInterval(function() {\n   if (marker) {\n    map.addMarker({\"lon\" : \"-79.0000\", \"lat\" : \"37.5000\", color: randomColor(), char: 'X' })\n    map.addMarker({\"lon\" : \"-122.6819\", \"lat\" : \"45.5200\" })\n    map.addMarker({\"lon\" : \"-6.2597\", \"lat\" : \"53.3478\" })\n    map.addMarker({\"lon\" : \"103.8000\", \"lat\" : \"1.3000\" })\n   }\n   else {\n    map.clearMarkers()\n   }\n   marker =! marker\n   screen.render()\n}, 1000)\n\n//set line charts dummy data\n\nvar transactionsData = {\n   title: 'USA',\n   style: {line:'red'},\n   x: ['00:00', '00:05', '00:10', '00:15', '00:20', '00:30', '00:40', '00:50', '01:00', '01:10', '01:20', '01:30', '01:40', '01:50', '02:00', '02:10', '02:20', '02:30', '02:40', '02:50', '03:00', '03:10', '03:20', '03:30', '03:40', '03:50', '04:00', '04:10', '04:20', '04:30'],\n   y: [0, 20, 40, 45, 45, 50, 55, 70, 65, 58, 50, 55, 60, 65, 70, 80, 70, 50, 40, 50, 60, 70, 82, 88, 89, 89, 89, 80, 72, 70]\n}\n\nvar transactionsData1 = {\n   title: 'Europe',\n   style: {line:'yellow'},\n   x: ['00:00', '00:05', '00:10', '00:15', '00:20', '00:30', '00:40', '00:50', '01:00', '01:10', '01:20', '01:30', '01:40', '01:50', '02:00', '02:10', '02:20', '02:30', '02:40', '02:50', '03:00', '03:10', '03:20', '03:30', '03:40', '03:50', '04:00', '04:10', '04:20', '04:30'],\n   y: [0, 5, 5, 10, 10, 15, 20, 30, 25, 30, 30, 20, 20, 30, 30, 20, 15, 15, 19, 25, 30, 25, 25, 20, 25, 30, 35, 35, 30, 30]\n}\n\nvar errorsData = {\n   title: 'server 1',\n   x: ['00:00', '00:05', '00:10', '00:15', '00:20', '00:25'],\n   y: [30, 50, 70, 40, 50, 20]\n}\n\nvar latencyData = {\n   x: ['t1', 't2', 't3', 't4'],\n   y: [5, 1, 7, 5]\n}\n\nsetLineData([transactionsData, transactionsData1], transactionsLine)\nsetLineData([errorsData], errorsLine)\n// setLineData([latencyData], latencyLine)\n\nsetInterval(function() {\n   setLineData([transactionsData, transactionsData1], transactionsLine)\n   screen.render()\n}, 500)\n\nsetInterval(function() {   \n    setLineData([errorsData], errorsLine)\n}, 1500)\n\nsetInterval(function(){\n  var colors = [randomColor(),randomColor(),randomColor(),randomColor(),randomColor()];\n  var text = ['A','B','C','D','E','F','G','H','I','J','K','L'];\n\n  var value = Math.round(Math.random() * 100);\n  lcdLineOne.setDisplay(value + text[value%12]);\n  lcdLineOne.setOptions({\n    color: colors[value%5],\n    elementPadding: 4\n  });\n  screen.render()\n}, 1500);\n\nvar pct = 0.00;\n\nfunction updateDonut(){\n  if (pct > 0.99) pct = 0.00;\n  var color = \"green\";\n  if (pct >= 0.25) color = \"cyan\";\n  if (pct >= 0.5) color = \"yellow\";\n  if (pct >= 0.75) color = \"red\";  \n  donut.setData([\n    {percent: parseFloat((pct+0.00) % 1).toFixed(2), label: 'storage', 'color': color}\n  ]);\n  pct += 0.01;\n}\n\nsetInterval(function() {   \n   updateDonut();\n   screen.render()\n}, 500)\n\nfunction setLineData(mockData, line) {\n  for (var i=0; i<mockData.length; i++) {\n    var last = mockData[i].y[mockData[i].y.length-1]\n    mockData[i].y.shift()\n    var num = Math.max(last + Math.round(Math.random()*10) - 5, 10)    \n    mockData[i].y.push(num)  \n  }\n  \n  line.setData(mockData)\n}\n\n\nscreen.key(['escape', 'q', 'C-c'], function(ch, key) {\n  return process.exit(0);\n});\n\nscreen.render()\n"
  },
  {
    "path": "examples/dashboard.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../index')\n\nvar screen = blessed.screen()\n\n//create layout and widgets\n\nvar grid = new contrib.grid({rows: 12, cols: 12, screen: screen})\n\n/**\n * Donut Options\n  self.options.radius = options.radius || 14; // how wide is it? over 5 is best\n  self.options.arcWidth = options.arcWidth || 4; //width of the donut\n  self.options.yPadding = options.yPadding || 2; //padding from the top\n */\nvar donut = grid.set(8, 8, 4, 2, contrib.donut, \n  {\n  label: 'Percent Donut',\n  radius: 16,\n  arcWidth: 4,\n  yPadding: 2,\n  data: [{label: 'Storage', percent: 87}]\n})\n\n// var latencyLine = grid.set(8, 8, 4, 2, contrib.line, \n//   { style: \n//     { line: \"yellow\"\n//     , text: \"green\"\n//     , baseline: \"black\"}\n//   , xLabelPadding: 3\n//   , xPadding: 5\n//   , label: 'Network Latency (sec)'})\n\nvar gauge = grid.set(8, 10, 2, 2, contrib.gauge, {label: 'Storage', percent: [80,20]})\nvar gauge_two = grid.set(2, 9, 2, 3, contrib.gauge, {label: 'Deployment Progress', percent: 80})\n\nvar sparkline = grid.set(10, 10, 2, 2, contrib.sparkline, \n  { label: 'Throughput (bits/sec)'\n  , tags: true\n  , style: { fg: 'blue', titleFg: 'white' }})\n\nvar bar = grid.set(4, 6, 4, 3, contrib.bar, \n  { label: 'Server Utilization (%)'\n  , barWidth: 4\n  , barSpacing: 6\n  , xOffset: 2\n  , maxHeight: 9})\n\nvar table =  grid.set(4, 9, 4, 3, contrib.table, \n  { keys: true\n  , fg: 'green'\n  , label: 'Active Processes'\n  , columnSpacing: 1\n  , columnWidth: [24, 10, 10]})\n\n/*\n *\n * LCD Options\n//these options need to be modified epending on the resulting positioning/size\n  options.segmentWidth = options.segmentWidth || 0.06; // how wide are the segments in % so 50% = 0.5\n  options.segmentInterval = options.segmentInterval || 0.11; // spacing between the segments in % so 50% = 0.5\n  options.strokeWidth = options.strokeWidth || 0.11; // spacing between the segments in % so 50% = 0.5\n//default display settings\n  options.elements = options.elements || 3; // how many elements in the display. or how many characters can be displayed.\n  options.display = options.display || 321; // what should be displayed before anything is set\n  options.elementSpacing = options.spacing || 4; // spacing between each element\n  options.elementPadding = options.padding || 2; // how far away from the edges to put the elements\n//coloring\n  options.color = options.color || \"white\";\n*/\nvar lcdLineOne = grid.set(0,9,2,3, contrib.lcd,\n  {\n    label: \"LCD Test\",\n    segmentWidth: 0.06,\n    segmentInterval: 0.11,\n    strokeWidth: 0.1,\n    elements: 5,\n    display: 3210,\n    elementSpacing: 4,\n    elementPadding: 2\n  }\n);\n\nvar errorsLine = grid.set(0, 6, 4, 3, contrib.line, \n  { style: \n    { line: \"red\"\n    , text: \"white\"\n    , baseline: \"black\"}\n  , label: 'Errors Rate'\n  , maxY: 60\n  , showLegend: true })\n\nvar transactionsLine = grid.set(0, 0, 6, 6, contrib.line, \n          { showNthLabel: 5\n          , maxY: 100\n          , label: 'Total Transactions'\n          , showLegend: true\n          , legend: {width: 10}})\n\nvar map = grid.set(6, 0, 6, 6, contrib.map, {label: 'Servers Location'})\n\nvar log = grid.set(8, 6, 4, 2, contrib.log, \n  { fg: \"green\"\n  , selectedFg: \"green\"\n  , label: 'Server Log'})\n\n\n//dummy data\nvar servers = ['US1', 'US2', 'EU1', 'AU1', 'AS1', 'JP1']\nvar commands = ['grep', 'node', 'java', 'timer', '~/ls -l', 'netns', 'watchdog', 'gulp', 'tar -xvf', 'awk', 'npm install']\n\n\n//set dummy data on gauge\nvar gauge_percent = 0\nsetInterval(function() {\n  gauge.setData([gauge_percent, 100-gauge_percent]);\n  gauge_percent++;\n  if (gauge_percent>=100) gauge_percent = 0  \n}, 200)\n\nvar gauge_percent_two = 0\nsetInterval(function() {\n  gauge_two.setData(gauge_percent_two);\n  gauge_percent_two++;\n  if (gauge_percent_two>=100) gauge_percent_two = 0  \n}, 200);\n\n\n//set dummy data on bar chart\nfunction fillBar() {\n  var arr = []\n  for (var i=0; i<servers.length; i++) {\n    arr.push(Math.round(Math.random()*10))\n  }\n  bar.setData({titles: servers, data: arr})\n}\nfillBar()\nsetInterval(fillBar, 2000)\n\n\n//set dummy data for table\nfunction generateTable() {\n   var data = []\n\n   for (var i=0; i<30; i++) {\n     var row = []          \n     row.push(commands[Math.round(Math.random()*(commands.length-1))])\n     row.push(Math.round(Math.random()*5))\n     row.push(Math.round(Math.random()*100))\n\n     data.push(row)\n   }\n\n   table.setData({headers: ['Process', 'Cpu (%)', 'Memory'], data: data})\n}\n\ngenerateTable()\ntable.focus()\nsetInterval(generateTable, 3000)\n\n\n//set log dummy data\nsetInterval(function() {\n   var rnd = Math.round(Math.random()*2)\n   if (rnd==0) log.log('starting process ' + commands[Math.round(Math.random()*(commands.length-1))])   \n   else if (rnd==1) log.log('terminating server ' + servers[Math.round(Math.random()*(servers.length-1))])\n   else if (rnd==2) log.log('avg. wait time ' + Math.random().toFixed(2))\n   screen.render()\n}, 500)\n\n\n//set spark dummy data\nvar spark1 = [1,2,5,2,1,5,1,2,5,2,1,5,4,4,5,4,1,5,1,2,5,2,1,5,1,2,5,2,1,5,1,2,5,2,1,5]\nvar spark2 = [4,4,5,4,1,5,1,2,5,2,1,5,4,4,5,4,1,5,1,2,5,2,1,5,1,2,5,2,1,5,1,2,5,2,1,5]\n\nrefreshSpark()\nsetInterval(refreshSpark, 1000)\n\nfunction refreshSpark() {\n  spark1.shift()\n  spark1.push(Math.random()*5+1)       \n  spark2.shift()\n  spark2.push(Math.random()*5+1)       \n  sparkline.setData(['Server1', 'Server2'], [spark1, spark2])  \n}\n\n\n\n//set map dummy markers\nvar marker = true\nsetInterval(function() {\n   if (marker) {\n    map.addMarker({\"lon\" : \"-79.0000\", \"lat\" : \"37.5000\", color: 'yellow', char: 'X' })\n    map.addMarker({\"lon\" : \"-122.6819\", \"lat\" : \"45.5200\" })\n    map.addMarker({\"lon\" : \"-6.2597\", \"lat\" : \"53.3478\" })\n    map.addMarker({\"lon\" : \"103.8000\", \"lat\" : \"1.3000\" })\n   }\n   else {\n    map.clearMarkers()\n   }\n   marker =! marker\n   screen.render()\n}, 1000)\n\n//set line charts dummy data\n\nvar transactionsData = {\n   title: 'USA',\n   style: {line: 'red'},\n   x: ['00:00', '00:05', '00:10', '00:15', '00:20', '00:30', '00:40', '00:50', '01:00', '01:10', '01:20', '01:30', '01:40', '01:50', '02:00', '02:10', '02:20', '02:30', '02:40', '02:50', '03:00', '03:10', '03:20', '03:30', '03:40', '03:50', '04:00', '04:10', '04:20', '04:30'],\n   y: [0, 20, 40, 45, 45, 50, 55, 70, 65, 58, 50, 55, 60, 65, 70, 80, 70, 50, 40, 50, 60, 70, 82, 88, 89, 89, 89, 80, 72, 70]\n}\n\nvar transactionsData1 = {\n   title: 'Europe',\n   style: {line: 'yellow'},\n   x: ['00:00', '00:05', '00:10', '00:15', '00:20', '00:30', '00:40', '00:50', '01:00', '01:10', '01:20', '01:30', '01:40', '01:50', '02:00', '02:10', '02:20', '02:30', '02:40', '02:50', '03:00', '03:10', '03:20', '03:30', '03:40', '03:50', '04:00', '04:10', '04:20', '04:30'],\n   y: [0, 5, 5, 10, 10, 15, 20, 30, 25, 30, 30, 20, 20, 30, 30, 20, 15, 15, 19, 25, 30, 25, 25, 20, 25, 30, 35, 35, 30, 30]\n}\n\nvar errorsData = {\n   title: 'server 1',\n   x: ['00:00', '00:05', '00:10', '00:15', '00:20', '00:25'],\n   y: [30, 50, 70, 40, 50, 20]\n}\n\nvar latencyData = {\n   x: ['t1', 't2', 't3', 't4'],\n   y: [5, 1, 7, 5]\n}\n\nsetLineData([transactionsData, transactionsData1], transactionsLine)\nsetLineData([errorsData], errorsLine)\n// setLineData([latencyData], latencyLine)\n\nsetInterval(function() {\n   setLineData([transactionsData, transactionsData1], transactionsLine)\n   screen.render()\n}, 500)\n\nsetInterval(function() {   \n    setLineData([errorsData], errorsLine)\n}, 1500)\n\nsetInterval(function(){\n  var colors = ['green','magenta','cyan','red','blue'];\n  var text = ['A','B','C','D','E','F','G','H','I','J','K','L'];\n\n  var value = Math.round(Math.random() * 100);\n  lcdLineOne.setDisplay(value + text[value%12]);\n  lcdLineOne.setOptions({\n    color: colors[value%5],\n    elementPadding: 4\n  });\n  screen.render()\n}, 1500);\n\nvar pct = 0.00;\n\nfunction updateDonut(){\n  if (pct > 0.99) pct = 0.00;\n  var color = \"green\";\n  if (pct >= 0.25) color = \"cyan\";\n  if (pct >= 0.5) color = \"yellow\";\n  if (pct >= 0.75) color = \"red\";  \n  donut.setData([\n    {percent: parseFloat((pct+0.00) % 1).toFixed(2), label: 'storage', 'color': color}\n  ]);\n  pct += 0.01;\n}\n\nsetInterval(function() {   \n   updateDonut();\n   screen.render()\n}, 500)\n\nfunction setLineData(mockData, line) {\n  for (var i=0; i<mockData.length; i++) {\n    var last = mockData[i].y[mockData[i].y.length-1]\n    mockData[i].y.shift()\n    var num = Math.max(last + Math.round(Math.random()*10) - 5, 10)    \n    mockData[i].y.push(num)  \n  }\n  \n  line.setData(mockData)\n}\n\n\nscreen.key(['escape', 'q', 'C-c'], function(ch, key) {\n  return process.exit(0);\n});\n\n// fixes https://github.com/yaronn/blessed-contrib/issues/10\nscreen.on('resize', function() {\n  donut.emit('attach');\n  gauge.emit('attach');\n  gauge_two.emit('attach');\n  sparkline.emit('attach');\n  bar.emit('attach');\n  table.emit('attach');\n  lcdLineOne.emit('attach');\n  errorsLine.emit('attach');\n  transactionsLine.emit('attach');\n  map.emit('attach');\n  log.emit('attach');\n});\n\nscreen.render()\n"
  },
  {
    "path": "examples/donut.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../index')\n  , screen = blessed.screen();\n\n/**\n * Donut Options\n  self.options.stroke = options.stroke || \"magenta\"\n  self.options.radius = options.radius || 14;\n  self.options.arcWidth = options.arcWidth || 4;\n  self.options.spacing = options.spacing || 2;\n  self.options.yPadding = options.yPadding || 2;\n */\n\nvar donut = contrib.donut({\n  \tlabel: 'Test',\n  \tradius: 8,\n  \tarcWidth: 3,\n  \tyPadding: 2,\n    data: [\n      {percent: 80, label: 'web1', color: 'green'}\n    ]\n  });\n    \nscreen.append(donut)\n\nsetInterval(updateDonuts, 5);\n\nvar pct = 0.00;\n\nfunction updateDonuts(){\n\tif (pct > 0.99) pct = 0.00;\n\tdonut.update([\n\t\t{percent: parseFloat((pct+0.00) % 1).toFixed(2), label: 'rcp','color':[100,200,170]},\n\t\t{percent: parseFloat((pct+0.25) % 1).toFixed(2), label: 'rcp','color':[128,128,128]},\n\t\t{percent: parseFloat((pct+0.50) % 1).toFixed(2), label: 'rcp','color':[255,0,0]},\n\t\t{percentAltNumber: 42, percent: parseFloat((pct+0.75) % 1).toFixed(2), label: 'web1', 'color': [255,128,0]}\n\t]);\n\tscreen.render();\n\tpct += 0.01;\n}\n\nscreen.key(['escape', 'q', 'C-c'], function(ch, key) {\n\treturn process.exit(0);\n});\n"
  },
  {
    "path": "examples/explorer.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../index')\n  , fs = require('fs')\n  , path = require('path')\n\nvar screen = blessed.screen()\n\n//create layout and widgets\nvar grid = new contrib.grid({rows: 1, cols: 2, screen: screen})\n\nvar tree =  grid.set(0, 0, 1, 1, contrib.tree, \n  { style: { text: \"red\" }\n  , template: { lines: true }\n  , label: 'Filesystem Tree'})\n\nvar table =  grid.set(0, 1, 1, 1, contrib.table, \n  { keys: true\n  , fg: 'green'\n  , label: 'Informations'\n  , columnWidth: [24, 10, 10]})\n\n//file explorer\nvar explorer = { name: '/'\n  , extended: true\n  // Custom function used to recursively determine the node path\n  , getPath: function(self){\n      // If we don't have any parent, we are at tree root, so return the base case\n      if(! self.parent)\n        return '';\n      // Get the parent node path and add this node name\n      return self.parent.getPath(self.parent)+'/'+self.name;\n    }\n  // Child generation function\n  , children: function(self){\n      var result = {};\n      var selfPath = self.getPath(self);\n      try {\n        // List files in this directory\n        var children = fs.readdirSync(selfPath+'/');\n\n        // childrenContent is a property filled with self.children() result\n        // on tree generation (tree.setData() call)\n        if (!self.childrenContent) {\n          for(var child in children){\n            child = children[child];\n            var completePath = selfPath+'/'+child;\n            if( fs.lstatSync(completePath).isDirectory() ){\n              // If it's a directory we generate the child with the children generation function\n              result[child] = { name: child, getPath: self.getPath, extended: false, children: self.children };\n            }else{\n              // Otherwise children is not set (you can also set it to \"{}\" or \"null\" if you want)\n              result[child] = { name: child, getPath: self.getPath, extended: false };\n            }\n          }\n        }else{\n          result = self.childrenContent;\n        }\n      } catch (e){}\n      return result;\n    }\n}\n\n//set tree\ntree.setData(explorer);\n\n// Handling select event. Every custom property that was added to node is \n// available like the \"node.getPath\" defined above\ntree.on('select',function(node){\n  var path = node.getPath(node);\n  var data = [];\n\n  // The filesystem root return an empty string as a base case\n  if ( path == '')\n    path = '/';\n  \n  // Add data to right array\n  data.push([path]);\n  data.push(['']);\n  try {\n    // Add results\n    data = data.concat(JSON.stringify(fs.lstatSync(path),null,2).split(\"\\n\").map(function(e){return [e]}));\n    table.setData({headers: ['Info'], data: data});\n  }catch(e){\n    table.setData({headers: ['Info'], data: [[e.toString()]]});\n  }\n  \n  screen.render();\n});\n\n//set default table\ntable.setData({headers: ['Info'], data: [[]]})\n\nscreen.key(['escape', 'q', 'C-c'], function(ch, key) {\n  return process.exit(0);\n});\n\nscreen.key(['tab'], function(ch, key) {\n  if(screen.focused == tree.rows)\n    table.focus();\n  else\n    tree.focus();\n});\n\ntree.focus()\nscreen.render()\n"
  },
  {
    "path": "examples/gauge-list.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../')\n  , screen = blessed.screen()\n  , grid = new contrib.grid({rows: 2, cols: 2, hideBorder: true, screen: screen})\n  , gaugeList = grid.set(0, 0, 1, 2, contrib.gaugeList,\n      {\n        gaugeSpacing: 0,\n        gaugeHeight: 1,\n        gauges:\n          [ {showLabel: false, stack: [{percent: 30, stroke: 'green'}, {percent: 30, stroke: 'magenta'}, {percent: 40, stroke: 'cyan'}] }\n          , {showLabel: false, stack: [{percent: 40, stroke: 'yellow'}, {percent: 20, stroke: 'magenta'}, {percent: 40, stroke: 'green'}] }\n          , {showLabel: false, stack: [{percent: 50, stroke: 'red'}, {percent: 10, stroke: 'magenta'}, {percent: 40, stroke: 'cyan'}] } ]\n      }\n    )\n\nscreen.render()\n\n\n\nscreen.key(['escape', 'q', 'C-c'], function(ch, key) {\n  return process.exit(0);\n});\n\n"
  },
  {
    "path": "examples/gauge-stack.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../')\n  , screen = blessed.screen()\n  , grid = new contrib.grid({rows: 2, cols: 2, hideBorder: true, screen: screen})\n  , gauge1 = grid.set(0, 0, 1, 1, contrib.gauge, {showLabel: false, stack: [{percent: 30, stroke: 'green'}, {percent: 30, stroke: 'magenta'}, {percent: 40, stroke: 'cyan'}] })\n\nscreen.render()\n"
  },
  {
    "path": "examples/gauge.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../')\n  , screen = blessed.screen()\n  , gauge = contrib.gauge({label: 'Progress'})\n    \nscreen.append(gauge)\n\ngauge.setPercent(25)\n\nscreen.render()"
  },
  {
    "path": "examples/grid-no-border.js",
    "content": "\nvar blessed = require('blessed')\n  , contrib = require('../')\n  , screen = blessed.screen()\n  , grid = new contrib.grid({rows: 12, cols: 12, hideBorder: true, screen: screen})\n  , map = grid.set(0, 0, 4, 4, contrib.map, {})\n  , box = grid.set(4, 4, 4, 4, blessed.box, {content: 'My Box'})\n\nscreen.render()\n"
  },
  {
    "path": "examples/grid.js",
    "content": "\nvar blessed = require('blessed')\n  , contrib = require('../')\n  , screen = blessed.screen()\n  , grid = new contrib.grid({rows: 12, cols: 12, screen: screen})\n  , map = grid.set(0, 0, 4, 4, contrib.map, {label: 'World Map'})\n  , box = grid.set(4, 4, 4, 4, blessed.box, {content: 'My Box'})\n\nscreen.render()\n"
  },
  {
    "path": "examples/inline-data/bar.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../../')\n  , screen = blessed.screen()\n  , bar = contrib.bar(\n       { label: 'Server Utilization (%)'\n       , barWidth: 4\n       , barSpacing: 6\n       , xOffset: 0\n       , maxHeight: 9\n       , height: \"40%\"\n       , data: { titles: ['bar1', 'bar2']\n               , data: [5, 10]}\n               })\n\nscreen.append(bar)\n\nscreen.render()"
  },
  {
    "path": "examples/inline-data/donut.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../../')\n  , screen = blessed.screen()\n  , donut = contrib.donut(\n       {\n        data: [ { color: 'red', percent: '50', label: 'a'}\n              , { color: 'blue', percent: '20', label: 'b'}\n              , { color: 'yellow', percent: '80', label: 'c'}\n              ]\n       })\n\nscreen.append(donut)\n\nscreen.render()"
  },
  {
    "path": "examples/inline-data/gauge.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../../')\n  , screen = blessed.screen()\n  , gauge = contrib.gauge({label: 'Progress', percent: 25})\n    \nscreen.append(gauge)\nscreen.render()"
  },
  {
    "path": "examples/inline-data/lcd.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../../')\n  , screen = blessed.screen()\n  , grid = new contrib.grid({rows: 12, cols: 12, screen: screen})\n  , map = grid.set(0, 0, 4, 4, contrib.map, {label: 'World Map'})\n  , lcd = grid.set(4,4,4,4, contrib.lcd,\n    {\n      label: \"LCD Test\",\n      segmentWidth: 0.06,\n      segmentInterval: 0.11,\n      strokeWidth: 0.1,\n      elements: 5,\n      display: 3210,\n      elementSpacing: 4,\n      elementPadding: 2\n    })\n\n\nscreen.render()\n  \n"
  },
  {
    "path": "examples/inline-data/map.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../../')\n  , screen = blessed.screen()\n  , map = contrib.map({\n      label: 'World Map',\n      markers: \n         [ {\"lon\" : \"-79.0000\", \"lat\" : \"37.5000\", color: \"red\", char: \"X\" }\n         , {\"lon\" : \"79.0000\", \"lat\" : \"37.5000\", color: \"blue\", char: \"O\" }\n         ]\n   })\n    \nscreen.append(map)\n\nscreen.render()"
  },
  {
    "path": "examples/inline-data/markdown.js",
    "content": "\nvar blessed = require('blessed')\n  , contrib = require('../../')\n  , screen = blessed.screen()\n  , chalk = require('chalk')\n  , markdown = contrib.markdown({markdown: '# Hello \\n blessed-contrib renders markdown using `marked-terminal` '\n                                , style: { firstHeading: 'chalk.green.italic' }})\n\nscreen.append(markdown)\n\nscreen.render()\n"
  },
  {
    "path": "examples/inline-data/multi-line-chart.js",
    "content": "var blessed = require('blessed')\n, contrib = require('../../index')\n, screen = blessed.screen()\n, line = contrib.line(\n   { width: 80\n   , height: 30\n   , left: 15\n   , top: 12  \n   , xPadding: 5\n   , label: 'Title'\n   , showLegend: true\n   , legend: {width: 12}\n   , data: [ { title: 'us-east',\n             x: ['t1', 't2', 't3', 't4'],\n             y: [5, 1, 7, 5],\n             style: {\n              line: 'red'\n             }\n           }\n         , { title: 'us-west',\n             x: ['t1', 't2', 't3', 't4'],\n             y: [2, 4, 9, 8],\n             style: {line: 'yellow'}\n           }\n          , {title: 'eu-north-with-some-long-string', \n             x: ['t1', 't2', 't3', 't4'],\n             y: [22, 7, 12, 1],\n             style: {line: 'blue'}\n           }]\n\n   })\n\nscreen.append(line)\n\nscreen.key(['escape', 'q', 'C-c'], function(ch, key) {\n  return process.exit(0);\n});\n\nscreen.render()"
  },
  {
    "path": "examples/inline-data/picture.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../../')\n  , screen = blessed.screen()\n\nvar pic = contrib.picture(\n   { base64: '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'\n   , cols: 95\n   , onReady: ready\n   })\n\nfunction ready() { screen.render() }\n\nscreen.append(pic)\n\n\n\n"
  },
  {
    "path": "examples/inline-data/sparkline.js",
    "content": "\nvar blessed = require('blessed')\n  , contrib = require('../../')\n  , screen = blessed.screen()\n\nvar spark = contrib.sparkline(\n     { label: 'Sparkline'\n     , tags: true\n     , border: {type: \"line\", fg: \"cyan\"} \n     , width: '50%'\n     , height: '50%'\n     , style: { fg: 'blue' }\n     , data: { titles: [ 'Sparkline1', 'Sparkline2'], \n               data: [ [10, 20, 30, 20, 50, 70, 60, 30, 35, 38]\n                     , [40, 10, 40, 50, 20, 30, 20, 20, 19, 40] ]\n             }\n      })\n\nscreen.append(spark)\n\nscreen.render()\n\n"
  },
  {
    "path": "examples/inline-data/table.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../../')\n  , screen = blessed.screen()\n\nvar table = contrib.table(\n   { keys: true\n   , fg: 'white'\n   , interactive: false\n   , label: 'Active Processes'\n   , width: '30%'\n   , height: '30%'\n   , border: {type: \"line\", fg: \"cyan\"}\n   , columnSpacing: 10\n   , columnWidth: [16, 12]\n   , data: { headers: ['col1', 'col2']\n           , data: [ [1, 2] \n                   , [3, 4]\n                   , [5, 6] ]}\n    })\n\nscreen.append(table)\n\nscreen.key(['escape', 'q', 'C-c'], function(ch, key) {\n  return process.exit(0);\n});\n\nscreen.render()"
  },
  {
    "path": "examples/lcd.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../')\n  , screen = blessed.screen();\n  \n/*\n//these options need to be modified epending on the resulting positioning/size\n  options.segmentWidth = options.segmentWidth || 0.06; // how wide are the segments in % so 50% = 0.5\n  options.segmentInterval = options.segmentInterval || 0.11; // spacing between the segments in % so 50% = 0.5\n  options.strokeWidth = options.strokeWidth || 0.11; // spacing between the segments in % so 50% = 0.5\n\n//default display settings\n  options.elements = options.elements || 3; // how many elements in the display. or how many characters can be displayed.\n  options.display = options.display || 321; // what should be displayed before anything is set\n  options.elementSpacing = options.spacing || 4; // spacing between each element\n  options.elementPadding = options.padding || 2; // how far away from the edges to put the elements\n\n//coloring\n  options.color = options.color || \"white\";\n*/\n\n\nvar lcd = contrib.lcd({\n\tlabel: 'Test',\n\telements: 4\n});\n\nscreen.append(lcd);\n\nsetInterval(function(){\n\tvar colors = ['green','magenta','cyan','red','blue'];\n\tvar text = ['A','B','C','D','E','F','G','H','I','J','K','L'];\n\n\tvar value = Math.round(Math.random() * 1000);\n\tlcd.setDisplay(value + text[value%12]);\n\tlcd.setOptions({\n\t\tcolor: colors[value%5],\n\t\telementPadding: 5\n\t});\n\tscreen.render();\n}, 1000);\n\nscreen.key(['g'], function(ch, key) {\n\tlcd.increaseWidth();\n\tscreen.render();\n});\nscreen.key(['h'], function(ch, key) {\n\tlcd.decreaseWidth();\n\tscreen.render();\n});\nscreen.key(['t'], function(ch, key) {\n\tlcd.increaseInterval();\n\tscreen.render();\n});\nscreen.key(['y'], function(ch, key) {\n\tlcd.decreaseInterval();\n\tscreen.render();\n});\nscreen.key(['b'], function(ch, key) {\n\tlcd.increaseStroke();\n\tscreen.render();\n});\nscreen.key(['n'], function(ch, key) {\n\tlcd.decreaseStroke();\n\tscreen.render();\n});\n\nscreen.key(['escape', 'q', 'C-c'], function(ch, key) {\n\treturn process.exit(0);\n});\n\nscreen.render()"
  },
  {
    "path": "examples/line-abbreviate.js",
    "content": "var blessed = require('blessed')\n, contrib = require('../index')\n, screen = blessed.screen()\n, line = contrib.line(\n   { width: 80\n   , height: 30\n   , left: 15\n   , top: 12\n   , xPadding: 5\n   , label: 'Title'\n   , abbreviate: true\n   , style: { baseline: 'white' }\n   })\n\n, data = [ { title: 'us-east',\n             x: ['t1', 't2', 't3', 't4'],\n             y: [5, 8800, 99999, 3179000000],\n             style: {\n              line: 'red'\n             }\n           }\n        ]\n\n\nscreen.append(line) //must append before setting data\nline.setData(data)\n\nscreen.key(['escape', 'q', 'C-c'], function(ch, key) {\n  return process.exit(0);\n});\n\nscreen.render()\n"
  },
  {
    "path": "examples/line-fraction.js",
    "content": "var blessed = require('blessed')\n, contrib = require('../index')\n, screen = blessed.screen()\n, line = contrib.line(\n   { width: 80\n   , height: 30\n   , left: 15\n   , top: 12\n   , xPadding: 5\n   , label: 'Title'\n   , numYLabels: 7\n   //, wholeNumbersOnly: true\n   })\n\n, data = [ { title: 'us-east',\n             x: ['t1', 't2', 't3', 't4'],\n             y: [0, 0.0695652173913043, 0.11304347826087, 2],\n             style: {\n              line: 'red'\n             }\n           }\n        ]\n\n\nscreen.append(line) //must append before setting data\nline.setData(data)\n\nscreen.key(['escape', 'q', 'C-c'], function(ch, key) {\n  return process.exit(0);\n});\n\nscreen.render()\n"
  },
  {
    "path": "examples/line-random-colors.js",
    "content": "var blessed = require('blessed')\n, contrib = require('../index')\n\nfunction randomColor() {\n  return [Math.random() * 255,Math.random()*255, Math.random()*255]\n}\n\nvar screen = blessed.screen()\n, line = contrib.line(\n   { width: 80\n   , height: 30\n   , left: 15\n   , top: 12\n   , xPadding: 5\n   , minY: 30\n   , maxY: 90\n   , label: 'Title'\n   , style: { line: randomColor(), text: randomColor(), baseline: randomColor() }\n   })\n\n, data = [ { title: 'us-east',\n             x: ['t1', 't2', 't3', 't4'],\n             y: [50, 88, 72, 91],\n             style: {\n              line: 'red'\n             }\n           }\n        ]\n\nscreen.append(line) //must append before setting data\nline.setData(data)\n\nscreen.key(['escape', 'q', 'C-c'], function(ch, key) {\n  return process.exit(0);\n});\n\nscreen.render()\n"
  },
  {
    "path": "examples/line-start-above-zero.js",
    "content": "var blessed = require('blessed')\n, contrib = require('../index')\n, screen = blessed.screen()\n, line = contrib.line(\n   { width: 80\n   , height: 30\n   , left: 15\n   , top: 12\n   , xPadding: 5\n   , minY: 30\n   , label: 'Title'\n   , style: { baseline: 'white' }\n   })\n\n, data = [ { title: 'us-east',\n             x: ['t1', 't2', 't3', 't4'],\n             y: [50, 88, 72, 91],\n             style: {\n              line: 'red'\n             }\n           }\n        ]\n\n\nscreen.append(line) //must append before setting data\nline.setData(data)\n\nscreen.key(['escape', 'q', 'C-c'], function(ch, key) {\n  return process.exit(0);\n});\n\nscreen.render()\n"
  },
  {
    "path": "examples/line-zoomed-in.js",
    "content": "var blessed = require('blessed')\n, contrib = require('../index')\n, screen = blessed.screen()\n, line = contrib.line(\n   { width: 80\n   , height: 30\n   , left: 15\n   , top: 12\n   , xPadding: 5\n   , minY: 1000\n   , maxY: 1050\n   , label: 'Title'\n   , style: { baseline: 'white' }\n   })\n\n, data = [ { title: 'us-east',\n             x: ['t1', 't2', 't3', 't4'],\n             y: [1010, 1040, 1020, 1030],\n             style: {\n              line: 'red'\n             }\n           }\n        ]\n\n\nscreen.append(line) //must append before setting data\nline.setData(data)\n\nscreen.key(['escape', 'q', 'C-c'], function(ch, key) {\n  return process.exit(0);\n});\n\nscreen.render()\n"
  },
  {
    "path": "examples/log.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../')\n  , screen = blessed.screen()\n  , log = contrib.log(\n      { fg: \"green\"\n      , label: 'Server Log'      \n      , height: \"20%\"\n      , tags: true      \n      , border: {type: \"line\", fg: \"cyan\"} })\n    \nscreen.append(log)\n\nvar i = 0\nsetInterval(function() {log.log(\"new {red-fg}log{/red-fg} line \" + i++)}, 500)\n\nscreen.render()\n"
  },
  {
    "path": "examples/map.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../')\n  , screen = blessed.screen()\n  , map = contrib.map({label: 'World Map'})\n    \nscreen.append(map)\n\nmap.addMarker({\"lon\" : \"-79.0000\", \"lat\" : \"37.5000\", color: \"red\", char: \"X\" })\n\nscreen.render()"
  },
  {
    "path": "examples/markdown.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../')\n  , screen = blessed.screen()\n  , chalk = require('chalk')\n  , markdown = contrib.markdown()\n    \nscreen.append(markdown)\nmarkdown.setOptions({ firstHeading: chalk.red.italic })\nmarkdown.setMarkdown('# Hello \\n This is **markdown** printed in the `terminal` 11')\nscreen.render()"
  },
  {
    "path": "examples/marked-terminal.js",
    "content": "const blessed = require(\"blessed\")\nconst contrib = require(\"../\")\n\nconst screen = blessed.screen()\nconst markdown = contrib.markdown()\nscreen.append(markdown)\nmarkdown.setMarkdown(\"- [x] Checkbox\")\nscreen.render()\n"
  },
  {
    "path": "examples/multi-line-chart.js",
    "content": "var blessed = require('blessed')\n, contrib = require('../index')\n, screen = blessed.screen()\n, line = contrib.line(\n   { width: 80\n   , height: 30\n   , left: 15\n   , top: 12  \n   , xPadding: 5\n   , label: 'Title'\n   , showLegend: true\n   , legend: {width: 12}})\n, data = [ { title: 'us-east',\n             x: ['t1', 't2', 't3', 't4'],\n             y: [5, 1, 7, 5],\n             style: {\n              line: 'red'\n             }\n           }\n         , { title: 'us-west',\n             x: ['t1', 't2', 't3', 't4'],\n             y: [2, 4, 9, 8],\n             style: {line: 'yellow'}\n           }\n          , {title: 'eu-north-with-some-long-string', \n             x: ['t1', 't2', 't3', 't4'],\n             y: [22, 7, 12, 1],\n             style: {line: 'blue'}\n           }]\n\nscreen.append(line) //must append before setting data\nline.setData(data)\n\nscreen.key(['escape', 'q', 'C-c'], function(ch, key) {\n  return process.exit(0);\n});\n\nscreen.render()"
  },
  {
    "path": "examples/picture.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../')\n  , screen = blessed.screen()\n    \nvar pic = contrib.picture(\n   { file: './media/flower.png'\n   , cols: 95\n   , onReady: ready})\nfunction ready() { screen.render() }\n\nscreen.append(pic)\n\n"
  },
  {
    "path": "examples/sparkline.js",
    "content": "\nvar blessed = require('blessed')\n  , contrib = require('../')\n  , screen = blessed.screen()\n\nvar spark = contrib.sparkline(\n     { label: 'Sparkline'\n     , tags: true\n     , border: {type: \"line\", fg: \"cyan\"} \n     , width: '50%'\n     , height: '50%'\n     , style: { fg: 'blue' }})\n\nscreen.append(spark)\n\nspark.setData(\n   [ 'Sparkline1', 'Sparkline2'], \n   [ [10, 20, 30, 20, 50, 70, 60, 30, 35, 38]\n   , [40, 10, 40, 50, 20, 30, 20, 20, 19, 40]])\n\nscreen.render()\n\n"
  },
  {
    "path": "examples/stacked-bar.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../')\n  , screen = blessed.screen()\n  , bar = contrib.stackedBar(\n       { label: 'Server Utilization (%)'\n       , barWidth: 4\n       , barSpacing: 6\n       , xOffset: 0\n       //, maxValue: 15\n       , height: \"40%\"\n       , width: \"50%\"\n       , barBgColor: [ 'red', 'blue', 'green' ]})\n\nscreen.append(bar)\n\nbar.setData(\n       { barCategory: ['Q1', 'Q2', 'Q3', 'Q4']\n       , stackedCategory: ['US', 'EU', 'AP']\n       , data:\n          [ [ 7, 7, 5]\n          , [8, 2, 0]\n          , [0, 0, 0]\n          , [2, 3, 2] ]\n       })\n\nscreen.render()\n"
  },
  {
    "path": "examples/table-color.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../')\n  , screen = blessed.screen()\n  , colors = require('colors/safe');\n\nvar table = contrib.table(\n   { keys: true\n   , fg: 'white'\n   , selectedFg: 'white'\n   , selectedBg: 'blue'\n   , interactive: false\n   , label: 'Active Processes'\n   , width: '80%'\n   , height: '30%'\n   , border: {type: \"line\", fg: \"cyan\"}\n   , columnSpacing: 10\n   , columnWidth: [7, 12, 15]})\n\ntable.focus()\nscreen.append(table)\n\ntable.setData(\n { headers: ['col1', 'col2', 'col3']\n , data:\n  [ [colors.blue('1111'), '22222', '55555']\n  , ['33333', '44444', '66666'] ]})\n\nscreen.key(['escape', 'q', 'C-c'], function(ch, key) {\n  return process.exit(0);\n});\n\nscreen.render()\n"
  },
  {
    "path": "examples/table.js",
    "content": "var blessed = require('blessed')\n  , contrib = require('../')\n  , screen = blessed.screen()\n\nvar table = contrib.table(\n   { keys: true\n   , vi: true\n   , fg: 'white'\n   , selectedFg: 'white'\n   , selectedBg: 'blue'\n   , interactive: true\n   , label: 'Active Processes'\n   , width: '30%'\n   , height: '30%'\n   , border: {type: \"line\", fg: \"cyan\"}\n   , columnSpacing: 10\n   , columnWidth: [16, 12]})\n\ntable.focus()\nscreen.append(table)\n\ntable.setData(\n { headers: ['col1', 'col2']\n , data:\n  [ [1, 2]\n  , [3, 4]\n  , [5, 6]\n  , [7, 8] ]})\n\nscreen.key(['escape', 'q', 'C-c'], function(ch, key) {\n  return process.exit(0);\n});\n\nscreen.render()\n"
  },
  {
    "path": "index.d.ts",
    "content": "import * as Blessed from 'blessed'\nexport = BlessedContrib\ndeclare namespace BlessedContrib {\n\n    export type Optionals<T, K extends keyof T> = {\n        [P in keyof K]?: T[K]\n        }\n    export type Picker<T, K extends keyof T> = {\n        [P in K]: T[P];\n        };\n\n\n    export module Widgets {\n        import IHasOptions = Blessed.Widgets.IHasOptions;\n        import BoxOptions = Blessed.Widgets.BoxOptions;\n        import ListOptions = Blessed.Widgets.ListOptions;\n        import Types = Blessed.Widgets.Types;\n        import ListElementStyle = Blessed.Widgets.ListElementStyle;\n        import BoxElement = Blessed.Widgets.BoxElement;\n        import ListElement = Blessed.Widgets.ListElement;\n\n        export interface GridOptions {\n\n            top?: Types.TTopLeft;\n            left?: Types.TTopLeft;\n            right?: Types.TPosition;\n            bottom?: Types.TPosition;\n            rows?: number\n            cols?: number\n            screen: Blessed.Widgets.Screen\n            border?: Blessed.Widgets.Border\n            hideBorder?: boolean\n        }\n\n        export type WidgetOptions =\n            BoxOptions\n            | BarOptions\n            | StackedBarOptions\n            | CanvasOptions\n            | TreeOptions\n            | TableOptions\n            | PictureOptions\n            | MarkdownOptions\n            | MapOptions\n            | SparklineOptions\n            | LogOptions\n            | LcdOptions\n            | GaugeOptions\n            | GaugeListOptions\n            | DonutOptions\n\n\n        export type WidgetElements = BoxElement\n            | BarElement\n            | LineElement\n            | StackedBarElement\n            | CanvasElement\n            | TreeElement\n            | TableElement\n            | PictureElement\n            | MarkdownElement\n            | MapElement\n            | SparklineElement\n            | LogElement\n            | LcdElement\n            | GaugeElement\n            | GaugeListElement\n            | DonutElement\n\n\n        export class GridElement extends BoxElement implements IHasOptions<GridOptions> {\n            constructor(opts: GridOptions);\n\n            set<T extends (options?: TreeOptions) => S, S extends TreeElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: T, opt: TreeOptions): TreeElement\n            set<T extends (options?: TableOptions) => S, S extends TableElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: T, opt: TableOptions): TableElement\n            set<T extends (options?: PictureOptions) => S, S extends PictureElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: T, opt: PictureOptions): PictureElement\n            set<T extends (options?: MarkdownOptions) => S, S extends MarkdownElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: T, opt: MarkdownOptions): MarkdownElement\n            set<T extends (options?: MapOptions) => S, S extends MapElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: T, opt: MapOptions): MapElement\n            set<T extends (options?: LogOptions) => S, S extends LogElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: T, opt: LogOptions): LogElement\n            set<T extends (options?: LcdOptions) => S, S extends LcdElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: T, opt: LcdOptions): LcdElement\n            set<T extends (options?: GaugeOptions) => S, S extends GaugeElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: T, opt: GaugeOptions): GaugeElement\n            set<T extends (options?: GaugeListOptions) => S, S extends GaugeListElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: T, opt: GaugeListOptions): GaugeListElement\n            set<T extends (options?: DonutOptions) => S, S extends DonutElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: T, opt: DonutOptions): DonutElement\n\n            set<T extends (options?: BarOptions) => S, S extends BarElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: T, opt: BarOptions): BarElement\n            set<T extends (options?: LineOptions) => S, S extends LineElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: T, opt: LineOptions): LineElement\n            set<T extends (options?: StackedBarOptions) => S, S extends StackedBarElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: T, opt: StackedBarOptions): StackedBarElement\n            set<T extends (options?: CanvasOptions) => S, S extends CanvasElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: T, opt: CanvasOptions): CanvasElement\n\n\n            // set<T extends (options?: WidgetOptions) => S, S extends WidgetElements>(row: number, col: number, rowSpan: number, colSpan: number, obj: T, opt: WidgetOptions): WidgetElements\n            set<T, S>(...args:any[]): any\n\n            // set<K extends keyof Factories>(row: number, col: number, rowSpan: number, colSpan: number,\n            //     obj: T, opts?: P<T> ): P<T>\n            // set<A =BarOptions, T=BarElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: A, opts?: O): T //typeof bar\n            // set<A =Line, T=LineElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: A, opts?: O): T //typeof line\n            // set<A =StackedBar, T=StackedBarElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: A, opts?: O): T //typeof stackedBar\n            // set<A =Canvas, T=CanvasElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: A, opts?: O): T //typeof canvas\n            // set<A =Tree, T=TreeElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: A, opts?: O): T //typeof tree\n            // set<A =Table, T=TableElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: A, opts?: O): T //typeof table\n            // set<A =Picture, T=PictureElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: A, opts?: O): T //typeof picture\n            // set<A =Markdown, T=MarkdownElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: A, opts?: O): T //typeof markdown\n            // set<A =Map, T=MapElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: A, opts?: O): T //typeof map\n            // set<A =Log, T=LogElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: A, opts?: O): T //typeof log\n            // set<A =Lcd, T=LcdElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: A, opts?: O): T //typeof lcd\n            // set<A =Gauge, T=GaugeElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: A, opts?: O): T //typeof gauge\n            // set<A =GaugeList, T=GaugeListElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: A, opts?: O): T //typeof gaugeList\n            // set<A =Donut, T=DonutElement>(row: number, col: number, rowSpan: number, colSpan: number, obj: A, opts?: O): T //typeof donut\n\n            options: GridOptions;\n        }\n\n\n        export interface BarData {\n            titles?: string[],\n            data?: number[]\n        }\n\n        export interface BarOptions extends CanvasOptions<BarData> {\n            barWidth?: number\n            barSpacing?: number\n            xOffset?: number\n            maxHeight?: number\n            showText?: boolean\n            barBgColor?: string\n            barFgColor?: string\n        }\n\n\n        export class BarElement extends CanvasElement<BarData> implements IHasOptions<BarOptions> {\n            constructor(opts: BarOptions);\n\n            setData(data: BarData): void;\n\n            options: BarOptions;\n        }\n\n\n        export interface LineData {\n            title?: string\n            x?: string[]\n            y?: number[]\n            style?: {\n                line?: string\n                text?: string\n                baseline?: string\n            }\n        }\n\n        export interface LineOptions extends CanvasOptions<LineData[]> {\n            showNthLabel?: boolean\n            style?: {\n                line?: string\n                text?: string\n                baseline?: string\n            }\n            xLabelPadding?: number\n            xPadding?: number\n            numYLabels?: number\n            legend?: { width: number }\n            wholeNumbersOnly?: boolean\n            minY?: number\n            maxY?: number\n            label?: string\n        }\n\n        export class LineElement extends CanvasElement<LineData[]> implements IHasOptions<LineOptions> {\n            constructor(opts: LineOptions);\n\n            options: LineOptions;\n        }\n\n        export interface StackedBarData {\n            barCategory?: string[]\n            stackedCategory?: string[]\n            data?: Array<number[]>\n        }\n\n        export interface StackedBarOptions extends CanvasOptions<StackedBarData[]> {\n\n            barWidth?: number\n            barSpacing?: number\n            xOffset?: number\n            maxValue?: number\n            barBgColor?: string\n            showLegend?: boolean\n            legend?: any\n            showText?: boolean\n        }\n\n        export class StackedBarElement extends CanvasElement<StackedBarData[]> implements IHasOptions<StackedBarOptions> {\n            constructor(opts: StackedBarOptions)\n\n            options: StackedBarOptions;\n\n            addLegend(bars: any, x: number): void;\n        }\n\n\n        export interface CanvasOptions<D extends any=any>  extends BoxOptions {\n            canvasSize?: {\n                width?: number,\n                height?: number\n            }\n            data?: D\n        }\n\n        export class CanvasElement<D extends any=any> extends BoxElement implements IHasOptions<CanvasOptions> {\n            constructor(opts: CanvasOptions<D>)\n\n            options: CanvasOptions<D>;\n\n            calcSize(): void;\n\n            setData(data: D): void;\n            setData(titles: string[], data: D): void;\n\n            canvasSize: { width: number, height: number }\n        }\n\n        export interface DonutData {\n            percent?: string,\n            label?: string,\n            color?: string\n        }\n\n        export interface DonutOptions extends CanvasOptions<DonutData[]> {\n            stroke?: string\n            fill?: string\n            label?: string\n            radius?: number\n            arcWidth?: number\n            spacing?: number\n            remainColor?: string\n            yPadding?: number\n\n\n        }\n\n        export class DonutElement extends CanvasElement<DonutData[]> implements IHasOptions<DonutOptions> {\n            constructor(opts: DonutOptions)\n\n            options: DonutOptions;\n\n        }\n\n\n        export interface GaugeListOptions extends CanvasOptions {\n        }\n\n        export class GaugeListElement extends CanvasElement implements IHasOptions<GaugeListOptions> {\n            constructor(opts: GaugeListOptions)\n\n            options: GaugeListOptions;\n        }\n\n\n        export interface GaugeOptions extends CanvasOptions {\n            percent: number[]\n            stroke?: string\n            fill?: string\n            label?: string\n            stack?: any\n            showLabel?: boolean\n        }\n\n        export class GaugeElement extends CanvasElement implements IHasOptions<GaugeOptions> {\n            constructor(opts: GaugeOptions)\n\n            options: GaugeOptions;\n\n            setPercent(number: number): void;\n\n            setStack(stack: Array<{ percent: number, stroke: string }>): void;\n\n            setData(percent: number[]): void;\n            setData(percent: number): void;\n        }\n\n\n        export interface LcdOptions extends CanvasOptions {\n            segmentWidth?: number// how wide are the segments in % so 50% = 0.5\n            segmentInterval?: number// spacing between the segments in % so 50% = 0.550% = 0.5\n            strokeWidth?: number// spacing between the segments in % so 50% = 0.5\n            elements?: number// how many elements in the display. or how many characters can be displayed.\n            display?: number// what should be displayed before first call to setDisplay\n            elementSpacing?: number// spacing between each element\n            elementPadding?: number// how far away from the edges to put the elements\n            color?: 'white' // color for the segments\n            label?: 'Storage Remaining'\n        }\n\n        export class LcdElement extends CanvasElement implements IHasOptions<LcdOptions> {\n            constructor(opts: LcdOptions)\n\n            options: LcdOptions;\n\n            increaseWidth(): void;\n\n            decreaseWidth(): void;\n\n            increaseInterval(): void;\n\n            decreaseInterval(): void;\n\n            increaseStroke(): void;\n\n            decreaseStroke(): void;\n\n            setOptions(options: any): void;\n\n            setDisplay(display: any): void;\n        }\n\n        export interface LogOptions extends ListOptions<ListElementStyle> {\n            border: Blessed.Widgets.Border\n            bufferLength?: number\n            logLines?: string[]\n            interactive?: boolean\n        }\n\n        export class LogElement extends ListElement implements IHasOptions<LogOptions> {\n            constructor(opts: LogOptions);\n\n            options: LogOptions;\n\n            log(str: string): boolean;\n\n            emit(str:any): boolean;\n        }\n\n\n        export interface MapOptions extends CanvasOptions {\n        }\n\n        export class MapElement extends CanvasElement implements IHasOptions<MapOptions> {\n            constructor(opts: MapOptions)\n\n            options: MapOptions;\n        }\n\n\n        export interface SparklineOptions extends CanvasOptions<string[]> {\n        }\n\n        export class SparklineElement extends CanvasElement<string[]> implements IHasOptions<SparklineOptions> {\n            constructor(opts: CanvasOptions);\n\n            options: SparklineOptions;\n\n            setData(...str: any[]): void;\n        }\n\n        export interface MarkdownOptions extends CanvasOptions {\n          /** \n           * Markdown text to render.\n           */\n          markdown?: string;\n\n          markdownStyle?: any;\n        }\n\n        export class MarkdownElement extends CanvasElement implements IHasOptions<MarkdownOptions> {\n            constructor(opts: MarkdownOptions)\n\n            options: MarkdownOptions;\n\n            setOptions(options: any): void;\n\n            setMarkdown(markdown: string): void;\n        }\n\n\n        export interface PictureOptions extends CanvasOptions {\n        }\n\n        export class PictureElement extends CanvasElement implements IHasOptions<PictureOptions> {\n            constructor(opts: PictureOptions)\n\n            options: PictureOptions;\n        }\n\n        export interface TableData {\n            headers?: string[]\n            data?: Array<string[]>\n        }\n\n        export interface TableOptions extends CanvasOptions<TableData> {\n            parent?: any\n            bold?: string\n            columnSpacing?: number\n            columnWidth?: number[]\n            rows?: ListOptions<ListElementStyle>\n            selectedFg?: string\n            selectedBg?: string\n            label?: string\n            fg?: string\n            bg?: string\n            width?: string\n            height?: string\n            border?: object\n            interactive?: string\n        }\n\n        export class TableElement extends CanvasElement<TableData> implements IHasOptions<TableOptions> {\n            constructor(opts: TableOptions);\n\n            options: TableOptions;\n        }\n\n\n        export interface TreeNode {\n            name?: string,\n            children?: TreeChildren | ((node: TreeNode) => TreeChildren | Promise<TreeChildren>),\n            childrenContent?: TreeChildren,\n            extended?: boolean,\n            parent?: TreeNode,\n            [custom: string]: any\n        }\n\n        export type TreeChildren = Record<string, TreeNode>\n\n        export interface TreeOptions extends BoxOptions {\n            data?: any\n            extended?: boolean\n            keys?: string[]\n            template?: {\n                extend?: string\n                retract?: string\n                lines?: boolean\n            }\n        }\n\n        export class TreeElement extends BoxElement implements IHasOptions<TreeOptions> {\n            constructor(opts: TreeOptions)\n\n            rows: Blessed.Widgets.ListElement\n            nodeLines?: string[]\n            lineNbr?: number\n            data: any\n\n            options: TreeOptions;\n\n            setData(data: TreeNode): void\n        }\n\n\n    }\n\n    export module widget {\n\n        export class Grid extends Widgets.GridElement {}\n\n        export class Bar extends Widgets.BarElement {}\n\n        export class Line extends Widgets.LineElement {}\n\n        export class StackedBar extends Widgets.StackedBarElement {}\n\n        export class Canvas extends Widgets.CanvasElement {}\n\n        export class Tree extends Widgets.TreeElement {}\n\n        export class Table extends Widgets.TableElement {}\n\n        export class Picture extends Widgets.PictureElement {}\n\n        export class Markdown extends Widgets.MarkdownElement {}\n\n        export class Map extends Widgets.MapElement {}\n\n        export class Log extends Widgets.LogElement {}\n\n        export class Lcd extends Widgets.LcdElement {}\n\n        export class Gauge extends Widgets.GaugeElement {}\n\n        export class GaugeList extends Widgets.GaugeListElement {}\n\n        export class Donut extends Widgets.DonutElement {}\n\n        export class Sparkline extends Widgets.SparklineElement {}\n\n    }\n\n\n    export class grid extends Widgets.GridElement {}\n\n    export function line(options?: Widgets.LineOptions): Widgets.LineElement\n\n    export function bar(options?: Widgets.BarOptions): Widgets.BarElement\n\n    export function stackedBar(options?: Widgets.StackedBarOptions): Widgets.StackedBarElement\n\n    export function canvas(options?: Widgets.CanvasOptions): Widgets.CanvasElement\n\n    export function tree(options?: Widgets.TreeOptions): Widgets.TreeElement\n\n    export function table(options?: Widgets.TableOptions): Widgets.TableElement\n\n    export function picture(options?: Widgets.PictureOptions): Widgets.PictureElement\n\n    export function markdown(options?: Widgets.MarkdownOptions): Widgets.MarkdownElement\n\n    export function sparkline(options?: Widgets.SparklineOptions): Widgets.SparklineElement\n\n    export function map(options?: Widgets.MapOptions): Widgets.MapElement\n\n    export function log(options?: Widgets.LogOptions): Widgets.LogElement\n\n    export function lcd(options?: Widgets.LcdOptions): Widgets.LcdElement\n\n    export function gauge(options?: Widgets.GaugeOptions): Widgets.GaugeElement\n\n    export function gaugeList(options?: Widgets.GaugeListOptions): Widgets.GaugeListElement\n\n    export function donut(options?: Widgets.DonutOptions): Widgets.DonutElement\n\n}\n\n"
  },
  {
    "path": "index.js",
    "content": "\nexports.grid = require('./lib/layout/grid')\nexports.carousel = require('./lib/layout/carousel')\n\nexports.map = require('./lib/widget/map')\nexports.canvas = require('./lib/widget/canvas')\n\nexports.gauge = require('./lib/widget/gauge.js')\nexports.gaugeList = require('./lib/widget/gauge-list.js')\n\nexports.lcd = require('./lib/widget/lcd.js')\nexports.donut = require('./lib/widget/donut.js')\nexports.log = require('./lib/widget/log.js')\nexports.picture = require('./lib/widget/picture.js')\nexports.sparkline = require('./lib/widget/sparkline.js')\nexports.table = require('./lib/widget/table.js')\nexports.tree = require('./lib/widget/tree.js')\nexports.markdown = require('./lib/widget/markdown.js')\n\nexports.bar = require('./lib/widget/charts/bar')\nexports.stackedBar = require('./lib/widget/charts/stacked-bar')\nexports.line = require('./lib/widget/charts/line')\n\nexports.OutputBuffer = require('./lib/server-utils').OutputBuffer\nexports.InputBuffer = require('./lib/server-utils').InputBuffer\nexports.createScreen = require('./lib/server-utils').createScreen\nexports.serverError = require('./lib/server-utils').serverError\n"
  },
  {
    "path": "lib/layout/carousel.js",
    "content": "'use strict';\nfunction Carousel(pages, options) {\n  this.currPage = 0;\n  this.pages = pages;\n  this.options = options;\n  this.screen = this.options.screen;\n}\n\nCarousel.prototype.move = function() {\n  var i = this.screen.children.length;\n  while (i--) this.screen.children[i].detach();\n\n  this.pages[this.currPage](this.screen, this.currPage);\n  this.screen.render();\n};\n\nCarousel.prototype.next = function() {\n  this.currPage++;\n  if (this.currPage==this.pages.length){\n    if (!this.options.rotate) {\n      this.currPage--;\n      return;\n    } else {\n      this.currPage=0;\n    }\n  }\n  this.move();\n};\n\nCarousel.prototype.prev = function() {\n  this.currPage--;\n  if (this.currPage<0) {\n    if (!this.options.rotate) {\n      this.currPage++;\n      return;\n    } else {\n      this.currPage=this.pages.length-1;\n    }\n  }\n  this.move();\n};\n\nCarousel.prototype.home = function() {\n  this.currPage = 0;\n  this.move();\n};\n\nCarousel.prototype.end = function() {\n  this.currPage = this.pages.length -1;\n  this.move();\n};\n\nCarousel.prototype.start = function() {\n  var self = this;\n\n  this.move();\n\n  if (this.options.interval) {\n    setInterval(this.next.bind(this), this.options.interval);\n  }\n\n  if (this.options.controlKeys) {\n    this.screen.key(['right', 'left', 'home', 'end'], function(ch, key) {\n      if (key.name=='right') self.next();\n      if (key.name=='left') self.prev();\n      if (key.name=='home') self.home();\n      if (key.name=='end') self.end();\n    });\n  }\n\n};\n\nmodule.exports = Carousel;\n"
  },
  {
    "path": "lib/layout/grid.js",
    "content": "'use strict';\nvar utils = require('../utils');\n\nvar widgetSpacing = 0;\n\nfunction Grid(options) {\n  if (!options.screen) throw 'Error: A screen property must be specified in the grid options.\\r\\n' +\n                              'Note: Release 2.0.0 has breaking changes. Please refer to the README or to https://github.com/yaronn/blessed-contrib/issues/39';\n  this.options = options;\n  this.options.dashboardMargin = this.options.dashboardMargin || 0;\n  this.cellWidth = ((100 - this.options.dashboardMargin*2) / this.options.cols);\n  this.cellHeight = ((100  - this.options.dashboardMargin*2) / this.options.rows);\n}\n\nGrid.prototype.set = function(row, col, rowSpan, colSpan, obj, opts) {\n\n  if (obj instanceof Grid) {\n    throw 'Error: A Grid is not allowed to be nested inside another grid.\\r\\n' +\n            'Note: Release 2.0.0 has breaking changes. Please refer to the README or to https://github.com/yaronn/blessed-contrib/issues/39';\n  }\n\n  var top = row * this.cellHeight + this.options.dashboardMargin;\n  var left = col * this.cellWidth + this.options.dashboardMargin;\n\n  //var options = JSON.parse(JSON.stringify(opts));\n  var options = {};\n  options = utils.MergeRecursive(options, opts);\n  options.top = top + '%';\n  options.left = left + '%';\n  options.width = (this.cellWidth * colSpan - widgetSpacing) + '%';\n  options.height = (this.cellHeight * rowSpan - widgetSpacing) + '%';\n  if (!this.options.hideBorder)\n    options.border = {type: 'line', fg: this.options.color || 'cyan'};\n\n  var instance = obj(options);\n  this.options.screen.append(instance);\n  return instance;\n};\n\nmodule.exports = Grid;\n"
  },
  {
    "path": "lib/server-utils.js",
    "content": "'use strict';\nvar url = require('url')\n  , contrib = require('../index')\n  , blessed = require('blessed');\n\nfunction OutputBuffer(options) {\n  this.isTTY = true;\n  this.columns = options.cols;\n  this.rows = options.rows;\n  this.write = function(s) {\n    s = s.replace('\\x1b8', ''); //not clear from where in blessed this code comes from. It forces the terminal to clear and loose existing content.\n    options.res.write(s);\n  };\n\n  this.on = function() {};\n}\n\nfunction InputBuffer() {\n  this.isTTY = true;\n  this.isRaw = true;\n\n  this.emit = function() {};\n\n  this.setRawMode = function() {};\n  this.resume = function() {};\n  this.pause = function() {};\n\n  this.on = function() {};\n}\n\nfunction serverError(req, res, err) {\n  setTimeout(function() {\n    if (!res.headersSent) res.writeHead(500, {'Content-Type': 'text/plain'});\n    res.write('\\r\\n\\r\\n'+err+'\\r\\n\\r\\n');\n    //restore cursor\n    res.end('\\u001b[?25h');\n  }, 0);\n\n  return true;\n}\n\n\nfunction createScreen(req, res) {\n  var query = url.parse(req.url, true).query;\n\n  var cols = query.cols || 250;\n  var rows = query.rows || 50;\n\n  if (cols<=35 || cols>=500 || rows<=5 || rows>=300) {\n    serverError(req, res, 'cols must be bigger than 35 and rows must be bigger than 5');\n    return null;\n  }\n\n  res.writeHead(200, {'Content-Type': 'text/plain'});\n\n  var output = new contrib.OutputBuffer({res: res, cols: cols, rows: rows});\n  var input = new contrib.InputBuffer(); //required to run under forever since it replaces stdin to non-tty\n  var program = blessed.program({output: output, input: input});\n\n  if (query.terminal) program.terminal = query.terminal;\n  if (query.isOSX) program.isOSXTerm = query.isOSX;\n  if (query.isiTerm2) program.isiTerm2 = query.isiTerm2;\n\n  var screen = blessed.screen({program: program});\n  return screen;\n}\n\n\nexports.createScreen = createScreen;\nexports.OutputBuffer = OutputBuffer;\nexports.InputBuffer = InputBuffer;\nexports.serverError = serverError;\n"
  },
  {
    "path": "lib/utils.js",
    "content": "'use strict';\nvar x256 = require('x256');\n\n/*\n* Recursively merge properties of two objects\n*/\nfunction MergeRecursive(obj1, obj2) {\n  if (obj1==null) {\n    return obj2;\n  }\n  if (obj2==null) {\n    return obj1;\n  }\n\n  for (var p in obj2) {\n    try {\n      // property in destination object set; update its value\n      if ( obj2[p].constructor==Object ) {\n        obj1[p] = MergeRecursive(obj1[p], obj2[p]);\n\n      } else {\n        obj1[p] = obj2[p];\n\n      }\n\n    } catch(e) {\n      // property in destination object not set; create it and set its value\n      obj1[p] = obj2[p];\n\n    }\n  }\n\n  return obj1;\n}\n\n\nfunction getTypeName(thing){\n  if(thing===null)return '[object Null]'; // special case\n  return Object.prototype.toString.call(thing);\n}\n\nfunction abbreviateNumber(value) {\n  var newValue = value;\n  if (value >= 1000) {\n    var suffixes = ['', 'k', 'm', 'b','t'];\n    var suffixNum = Math.floor( (''+value).length/3 );\n    var shortValue = '';\n    for (var precision = 2; precision >= 1; precision--) {\n      shortValue = parseFloat( (suffixNum != 0 ? (value / Math.pow(1000,suffixNum) ) : value).toPrecision(precision));\n      var dotLessShortValue = (shortValue + '').replace(/[^a-zA-Z 0-9]+/g,'');\n      if (dotLessShortValue.length <= 2) {\n        break;\n      }\n    }\n    newValue = shortValue+suffixes[suffixNum];\n  }\n  return newValue;\n}\n\nfunction getColorCode(color) {\n  if (Array.isArray(color) && color.length == 3) {\n    return x256(color[0],color[1],color[2]);\n  } else {\n    return color;\n  }\n}\n\nexports.MergeRecursive = MergeRecursive;\nexports.getTypeName = getTypeName;\nexports.abbreviateNumber = abbreviateNumber;\nexports.getColorCode = getColorCode;\n\n"
  },
  {
    "path": "lib/widget/canvas.js",
    "content": "'use strict';\nvar blessed = require('blessed')\n  , Node = blessed.Node\n  , Box = blessed.Box\n  , InnerCanvas = require('drawille-canvas-blessed-contrib').Canvas;\n\nfunction Canvas(options, canvasType) {\n\n  var self = this;\n\n  if (!(this instanceof Node)) {\n    return new Canvas(options);\n  }\n\n  options = options || {};\n  this.options = options;\n  Box.call(this, options);\n\n  this.on('attach', function() {\n    self.calcSize();\n\n    self._canvas = new InnerCanvas(this.canvasSize.width, this.canvasSize.height, canvasType);\n    self.ctx = self._canvas.getContext();\n\n    if (self.options.data) {\n      self.setData(self.options.data);\n    }\n  });\n}\n\nCanvas.prototype = Object.create(Box.prototype);\n\nCanvas.prototype.type = 'canvas';\n\nCanvas.prototype.calcSize = function() {\n  this.canvasSize = {width: this.width*2-12, height: this.height*4};\n};\n\nCanvas.prototype.clear = function() {\n  this.ctx.clearRect(0, 0, this.canvasSize.width, this.canvasSize.height);\n};\n\nCanvas.prototype.render = function() {\n\n  this.clearPos(true);\n  var inner = this.ctx._canvas.frame();\n  this.setContent(inner);\n  return this._render();\n};\n\nmodule.exports = Canvas;\n"
  },
  {
    "path": "lib/widget/charts/bar.js",
    "content": "'use strict';\nvar blessed = require('blessed')\n  , Node = blessed.Node\n  , Canvas = require('../canvas');\n\nfunction Bar(options) {\n  if (!(this instanceof Node)) {\n    return new Bar(options);\n  }\n\n  var self = this;\n\n  Canvas.call(this, options, require('ansi-term'));\n\n  this.options.barWidth = this.options.barWidth || 6;\n  this.options.barSpacing = this.options.barSpacing || 9;\n\n  if ((this.options.barSpacing - this.options.barWidth) < 3) {\n    this.options.barSpacing = this.options.barWidth + 3;\n  }\n\n  this.options.xOffset = this.options.xOffset==null? 5 : this.options.xOffset;\n  if (this.options.showText === false)\n    this.options.showText = false;\n  else\n    this.options.showText = true;\n\n  this.on('attach', function() {\n    if (self.options.data) {\n      self.setData(self.options.data);\n    }\n  });\n}\n\nBar.prototype = Object.create(Canvas.prototype);\n\nBar.prototype.calcSize = function() {\n  this.canvasSize = {width: this.width-2, height: this.height};\n};\n\nBar.prototype.setData = function(bar) {\n\n  if (!this.ctx) {\n    throw 'error: canvas context does not exist. setData() for bar charts must be called after the chart has been added to the screen via screen.append()';\n  }\n\n  this.clear();\n\n  var c = this.ctx;\n  var max = Math.max.apply(Math, bar.data);\n  max = Math.max(max, this.options.maxHeight);\n  var x = this.options.xOffset;\n  var barY = this.canvasSize.height - 5;\n\n  for (var i = 0; i < bar.data.length; i++) {\n    var h = Math.round(barY * (bar.data[i] / max));\n\n    if (bar.data[i] > 0) {\n      c.strokeStyle = 'blue';\n      if (this.options.barBgColor)\n        c.strokeStyle = this.options.barBgColor;\n      c.fillRect(x, barY - h + 1, this.options.barWidth, h);\n    } else {\n      c.strokeStyle = 'normal';\n    }\n\n    c.fillStyle = 'white';\n    if (this.options.barFgColor)\n      c.fillStyle = this.options.barFgColor;\n    if (this.options.showText)\n      c.fillText(bar.data[i].toString(), x + 1, this.canvasSize.height - 4);\n    c.strokeStyle = 'normal';\n    c.fillStyle = 'white';\n    if (this.options.labelColor)\n      c.fillStyle = this.options.labelColor;\n    if (this.options.showText)\n      c.fillText(bar.titles[i], x + 1, this.canvasSize.height - 3);\n\n    x += this.options.barSpacing;\n  }\n};\n\nBar.prototype.getOptionsPrototype = function() {\n  return  {  barWidth: 1\n    ,  barSpacing: 1\n    ,  xOffset: 1\n    ,  maxHeight: 1\n    ,  data: { titles: ['s']\n      , data: [1]}\n  };\n};\n\nBar.prototype.type = 'bar';\n\nmodule.exports = Bar;\n"
  },
  {
    "path": "lib/widget/charts/line.js",
    "content": "'use strict';\nvar blessed = require('blessed')\n  , Node = blessed.Node\n  , Canvas = require('../canvas')\n  , utils = require('../../utils.js')\n  , _ = require('lodash');\n\nfunction Line(options) {\n  if (!(this instanceof Node)) {\n    return new Line(options);\n  }\n\n  options.showNthLabel = options.showNthLabel || 1;\n  options.style = options.style || {};\n  options.style.line = options.style.line || 'yellow';\n  options.style.text = options.style.text || 'green';\n  options.style.baseline = options.style.baseline || 'black';\n  options.xLabelPadding = options.xLabelPadding || 5;\n  options.xPadding = options.xPadding || 10;\n  options.numYLabels = options.numYLabels || 5;\n  options.legend = options.legend || {};\n  options.wholeNumbersOnly = options.wholeNumbersOnly || false;\n  options.minY = options.minY || 0;\n\n  Canvas.call(this, options);\n}\n\nLine.prototype = Object.create(Canvas.prototype);\n\nLine.prototype.calcSize = function() {\n  this.canvasSize = {width: this.width*2-12, height: this.height*4-8};\n};\n\nLine.prototype.type = 'line';\n\nLine.prototype.setData = function(data) {\n\n  if (!this.ctx) {\n    throw 'error: canvas context does not exist. setData() for line charts must be called after the chart has been added to the screen via screen.append()';\n  }\n\n  //compatability with older api\n  if (!Array.isArray(data)) data = [data];\n\n  var self = this;\n  var xLabelPadding = this.options.xLabelPadding;\n  var yLabelPadding = 3;\n  var xPadding = this.options.xPadding;\n  var yPadding = 11;\n  var c = this.ctx;\n  var labels = data[0].x;\n\n  function addLegend() {\n    if (!self.options.showLegend) return;\n    if (self.legend) self.remove(self.legend);\n    var legendWidth = self.options.legend.width || 15;\n    self.legend = blessed.box({\n      height: data.length+2,\n      top: 1,\n      width: legendWidth,\n      left: self.width-legendWidth-3,\n      content: '',\n      fg: 'green',\n      tags: true,\n      border: {\n        type: 'line',\n        fg: 'black'\n      },\n      style: {\n        fg: 'blue',\n      },\n      screen: self.screen\n    });\n\n    var legandText = '';\n    var maxChars = legendWidth-2;\n    for (let i=0; i<data.length; i++) {\n      var style = data[i].style || {};\n      var color = utils.getColorCode(style.line || self.options.style.line);\n      legandText += '{'+color+'-fg}'+ data[i].title.substring(0, maxChars)+'{/'+color+'-fg}\\r\\n';\n    }\n    self.legend.setContent(legandText);\n    self.append(self.legend);\n  }\n\n  //iteratee for lodash _.max\n  function getMaxY() {\n    if (self.options.maxY) {\n      return self.options.maxY;\n    }\n\n    var max = -Infinity;\n\n    for(let i = 0; i < data.length; i++) {\n      if (data[i].y.length) {\n        var current = _.max(data[i].y, parseFloat);\n        if (current > max) {\n          max = current;\n        }\n      }\n    }\n\n    return max + (max - self.options.minY) * 0.2;\n  }\n\n  function formatYLabel(value, max, min, numLabels, wholeNumbersOnly, abbreviate) {\n    var fixed = (((max - min) / numLabels) < 1 && value!=0 && !wholeNumbersOnly) ? 2 : 0;\n    var res = value.toFixed(fixed);\n    return abbreviate?utils.abbreviateNumber(res):res;\n  }\n\n  function getMaxXLabelPadding(numLabels, wholeNumbersOnly, abbreviate, min) {\n    var max = getMaxY();\n\n    return formatYLabel(max, max, min, numLabels, wholeNumbersOnly, abbreviate).length * 2;\n  }\n\n  var maxPadding = getMaxXLabelPadding(this.options.numYLabels, this.options.wholeNumbersOnly, this.options.abbreviate, this.options.minY);\n  if (xLabelPadding < maxPadding) {\n    xLabelPadding = maxPadding;\n  }\n\n  if ((xPadding - xLabelPadding) < 0) {\n    xPadding = xLabelPadding;\n  }\n\n  function getMaxX() {\n    var maxLength = 0;\n\n    for(var i = 0; i < labels.length; i++) {\n      if(labels[i] === undefined) {\n        // console.log(\"label[\" + i + \"] is undefined\");\n      } else if(labels[i].length > maxLength) {\n        maxLength = labels[i].length;\n      }\n    }\n\n    return maxLength;\n  }\n\n  function getXPixel(val) {\n    return ((self.canvasSize.width - xPadding) / labels.length) * val + (xPadding * 1.0) + 2;\n  }\n\n  function getYPixel(val, minY) {\n    var res = self.canvasSize.height - yPadding - (((self.canvasSize.height - yPadding) / (getMaxY()-minY)) * (val-minY));\n    res-=2; //to separate the baseline and the data line to separate chars so canvas will show separate colors\n    return res;\n  }\n\n  // Draw the line graph\n  function drawLine(values, style, minY) {\n    style = style || {};\n    var color = self.options.style.line;\n    c.strokeStyle = style.line || color;\n\n    c.moveTo(0, 0);\n    c.beginPath();\n    c.lineTo(getXPixel(0), getYPixel(values[0], minY));\n\n    for(var k = 1; k < values.length; k++) {\n      c.lineTo(getXPixel(k), getYPixel(values[k], minY));\n    }\n\n    c.stroke();\n  }\n\n  addLegend();\n\n  c.fillStyle = this.options.style.text;\n\n  c.clearRect(0, 0, this.canvasSize.width, this.canvasSize.height);\n\n\n  var yLabelIncrement = (getMaxY()-this.options.minY)/this.options.numYLabels;\n  if (this.options.wholeNumbersOnly) yLabelIncrement = Math.floor(yLabelIncrement);\n  //if (getMaxY()>=10) {\n  //  yLabelIncrement = yLabelIncrement + (10 - yLabelIncrement % 10)\n  //}\n\n  //yLabelIncrement = Math.max(yLabelIncrement, 1) // should not be zero\n\n  if (yLabelIncrement==0) yLabelIncrement = 1;\n\n  // Draw the Y value texts\n  var maxY = getMaxY();\n  for(var i = this.options.minY; i < maxY; i += yLabelIncrement) {\n    c.fillText(formatYLabel(i, maxY, this.options.minY, this.options.numYLabels, this.options.wholeNumbersOnly, this.options.abbreviate), xPadding - xLabelPadding, getYPixel(i, this.options.minY));\n  }\n\n  for (var h=0; h<data.length; h++) {\n    drawLine(data[h].y, data[h].style, this.options.minY);\n  }\n\n\n  c.strokeStyle = this.options.style.baseline;\n\n  // Draw the axises\n  c.beginPath();\n\n  c.lineTo(xPadding, 0);\n  c.lineTo(xPadding, this.canvasSize.height - yPadding);\n  c.lineTo(this.canvasSize.width, this.canvasSize.height - yPadding);\n\n  c.stroke();\n\n  // Draw the X value texts\n  var charsAvailable = (this.canvasSize.width - xPadding) / 2;\n  var maxLabelsPossible = charsAvailable / (getMaxX() + 2);\n  var pointsPerMaxLabel = Math.ceil(data[0].y.length / maxLabelsPossible);\n  var showNthLabel = this.options.showNthLabel;\n  if (showNthLabel < pointsPerMaxLabel) {\n    showNthLabel = pointsPerMaxLabel;\n  }\n\n  for(let i = 0; i < labels.length; i += showNthLabel) {\n    if((getXPixel(i) + (labels[i].length * 2)) <= this.canvasSize.width) {\n      c.fillText(labels[i], getXPixel(i), this.canvasSize.height - yPadding + yLabelPadding);\n    }\n  }\n\n};\n\nLine.prototype.getOptionsPrototype = function() {\n  return { width: 80\n    , height: 30\n    , left: 15\n    , top: 12\n    , xPadding: 5\n    , label: 'Title'\n    , showLegend: true\n    , legend: {width: 12}\n    , data: [ { title: 'us-east',\n      x: ['t1', 't2', 't3', 't4'],\n      y: [5, 1, 7, 5],\n      style: {\n        line: 'red'\n      }\n    }\n    , { title: 'us-west',\n      x: ['t1', 't2', 't3', 't4'],\n      y: [2, 4, 9, 8],\n      style: {line: 'yellow'}\n    }\n    , {title: 'eu-north-with-some-long-string',\n      x: ['t1', 't2', 't3', 't4'],\n      y: [22, 7, 12, 1],\n      style: {line: 'blue'}\n    }]\n\n  };\n};\n\nmodule.exports = Line;\n"
  },
  {
    "path": "lib/widget/charts/stacked-bar.js",
    "content": "'use strict';\nvar blessed = require('blessed')\n  , Node = blessed.Node\n  , Canvas = require('../canvas')\n  , utils = require('../../utils.js');\n\nfunction StackedBar(options) {\n  if (!(this instanceof Node)) {\n    return new StackedBar(options);\n  }\n\n  var self = this;\n  Canvas.call(this, options, require('ansi-term'));\n\n  this.options.barWidth = this.options.barWidth || 6;\n  this.options.barSpacing = this.options.barSpacing || 9;\n\n  if ((this.options.barSpacing - this.options.barWidth) < 3) {\n    this.options.barSpacing = this.options.barWidth + 3;\n  }\n\n  this.options.xOffset = this.options.xOffset==null? 5 : this.options.xOffset;\n  if (this.options.showText === false)\n    this.options.showText = false;\n  else\n    this.options.showText = true;\n\n  this.options.legend = this.options.legend || {};\n  if (this.options.showLegend === false)\n    this.options.showLegend = false;\n  else\n    this.options.showLegend = true;\n\n  this.on('attach', function() {\n    if (self.options.data) {\n      self.setData(self.options.data);\n    }\n  });\n}\n\nStackedBar.prototype = Object.create(Canvas.prototype);\n\nStackedBar.prototype.calcSize = function() {\n  this.canvasSize = {width: this.width-2, height: this.height};\n};\n\nStackedBar.prototype.getSummedBars = function(bars) {\n  var res = [];\n  bars.forEach(function(stackedValues) {\n    var sum = stackedValues.reduce(function(a,b) {\n      return a + b;\n    } , 0);\n    res.push(sum);\n  });\n  return res;\n};\n\nStackedBar.prototype.setData = function(bars) {\n\n  if (!this.ctx) {\n    throw 'error: canvas context does not exist. setData() for bar charts must be called after the chart has been added to the screen via screen.append()';\n  }\n\n  this.clear();\n\n  var summedBars = this.getSummedBars(bars.data);\n  var maxBarValue = Math.max.apply(Math, summedBars);\n  if (this.options.maxValue)\n    maxBarValue = Math.max(maxBarValue, this.options.maxValue);\n  var x = this.options.xOffset;\n  for (var i = 0; i < bars.data.length; i++) {\n    this.renderBar(x, bars.data[i], summedBars[i], maxBarValue, bars.barCategory[i]);\n    x += this.options.barSpacing;\n  }\n\n  this.addLegend(bars, x);\n};\n\nStackedBar.prototype.renderBar = function(x, bar, curBarSummedValue, maxBarValue, category) {\n/*\n  var c = this.ctx\n  c.strokeStyle = 'red';\n  c.fillRect(0,7,4,0)\n  c.strokeStyle = 'blue';\n  c.fillRect(0,4,4,1)\n  c.strokeStyle = 'green';\n  c.fillRect(5,7,4,2)\n  return\n*/\n  //first line is for label\n  const BUFFER_FROM_TOP = 2;\n  const BUFFER_FROM_BOTTOM = (this.options.border ? 2 : 0) + (this.options.showText ? 1 : 0);\n\n  var c = this.ctx;\n  c.strokeStyle = 'normal';\n  c.fillStyle = 'white';\n  if (this.options.labelColor)\n    c.fillStyle = this.options.labelColor;\n  if (this.options.showText) {\n    c.fillText(category, x + 1, this.canvasSize.height - BUFFER_FROM_BOTTOM);\n  }\n\n  if (curBarSummedValue < 0) return;\n  var maxBarHeight = this.canvasSize.height - BUFFER_FROM_TOP - BUFFER_FROM_BOTTOM;\n  var currentBarHeight = Math.round(maxBarHeight * (curBarSummedValue / maxBarValue));\n  //start painting from bottom of bar, section by section\n  var y = maxBarHeight + BUFFER_FROM_TOP;\n  var availableBarHeight = currentBarHeight;\n  for (var i=0; i < bar.length; i++) {\n    var currStackHeight = this.renderBarSection(\n      x,\n      y,\n      bar[i],\n      curBarSummedValue,\n      currentBarHeight,\n      availableBarHeight,\n      this.options.barBgColor[i]);\n    y -= currStackHeight;\n    availableBarHeight -= currStackHeight;\n  }\n};\n\nStackedBar.prototype.renderBarSection = function(\n  x,\n  y,\n  data,\n  curBarSummedValue,\n  currentBarHeight,\n  availableBarHeight,\n  bg) {\n  var c = this.ctx;\n\n  var currStackHeight = currentBarHeight <= 0?\n    0 :\n    Math.min(\n      availableBarHeight, //round() can make total stacks excceed curr bar height so we limit it\n      Math.round(currentBarHeight * (data / curBarSummedValue))\n    );\n  c.strokeStyle = bg;\n\n  if (currStackHeight>0) {\n    var calcY = y - currStackHeight;\n    /*fillRect starts from the point bottom of start point so we compensate*/\n    var calcHeight = Math.max(0, currStackHeight-1);\n    c.fillRect(\n      x,\n      calcY,\n      this.options.barWidth,\n      calcHeight\n    );\n\n    c.fillStyle = 'white';\n    if (this.options.barFgColor)\n      c.fillStyle = this.options.barFgColor;\n    if (this.options.showText) {\n      var str = utils.abbreviateNumber(data.toString());\n      c.fillText(\n        str,\n        Math.floor(x + this.options.barWidth/2 + str.length/2),\n        calcY + Math.round(calcHeight/2));\n    }\n  }\n\n  return currStackHeight;\n};\n\nStackedBar.prototype.getOptionsPrototype = function() {\n  return  {  barWidth: 1\n    ,  barSpacing: 1\n    ,  xOffset: 1\n    ,  maxValue: 1\n    ,  barBgColor: 's'\n    ,  data: { barCategory: ['s']\n      , stackedCategory: ['s']\n      , data: [ [ 1] ]\n    }\n  };\n};\n\n\n\nStackedBar.prototype.addLegend = function(bars, x) {\n  var self = this;\n  if (!self.options.showLegend) return;\n  if (self.legend) self.remove(self.legend);\n  var legendWidth = self.options.legend.width || 15;\n  self.legend = blessed.box({\n    height: bars.stackedCategory.length+2,\n    top: 1,\n    width: legendWidth,\n    left: x,\n    content: '',\n    fg: 'green',\n    tags: true,\n    border: {\n      type: 'line',\n      fg: 'black'\n    },\n    style: {\n      fg: 'blue',\n    },\n    screen: self.screen\n  });\n\n  var legandText = '';\n  var maxChars = legendWidth-2;\n  for (var i=0; i<bars.stackedCategory.length; i++) {\n    var color = utils.getColorCode(self.options.barBgColor[i]);\n    legandText += '{'+color+'-fg}'+ bars.stackedCategory[i].substring(0, maxChars)+'{/'+color+'-fg}\\r\\n';\n  }\n  self.legend.setContent(legandText);\n  self.append(self.legend);\n};\n\nStackedBar.prototype.type = 'bar';\n\nmodule.exports = StackedBar;\n"
  },
  {
    "path": "lib/widget/donut.js",
    "content": "'use strict';\nvar blessed = require('blessed')\n  , Node = blessed.Node\n  , Canvas = require('./canvas');\n\nfunction Donut(options) {\n  if (!(this instanceof Node)) {\n    return new Donut(options);\n  }\n\n  options = options || {};\n  this.options = options;\n  this.options.stroke = options.stroke || 'magenta';\n  this.options.fill = options.fill || 'white';\n  this.options.radius = options.radius || 14;\n  this.options.arcWidth = options.arcWidth || 4;\n  this.options.spacing = options.spacing || 2;\n  this.options.yPadding = options.yPadding || 2;\n  this.options.remainColor = options.remainColor || 'black';\n  this.options.data = options.data || [];\n\n  Canvas.call(this, options);\n\n  var self = this;\n  this.on('attach', function() {\n    this.setData(self.options.data);\n  });\n}\n\nDonut.prototype = Object.create(Canvas.prototype);\n\nDonut.prototype.calcSize = function() {\n  this.canvasSize = {width: Math.round(this.width*2-5), height: this.height*4-12};\n  if (this.canvasSize.width % 2 == 1)\n    this.canvasSize.width--;\n  if (this.canvasSize.height % 4 != 1)\n    this.canvasSize.height += (this.canvasSize.height % 4);\n};\n\nDonut.prototype.type = 'donut';\n\nvar cos = Math.cos;\nvar sin = Math.sin;\nvar pi = 3.141592635;\nDonut.prototype.setData = function(data){\n  this.update(data);\n};\nDonut.prototype.update = function(data) {\n\n  if (!this.ctx) {\n    throw 'error: canvas context does not exist. setData() for line charts must be called after the chart has been added to the screen via screen.append()';\n  }\n\n  var c = this.ctx;\n  c.save();\n  c.translate(0,-this.options.yPadding);\n\n  c.strokeStyle = this.options.stroke;\n  c.fillStyle = this.options.fill;\n\n  c.clearRect(0, 0, this.canvasSize.width, this.canvasSize.height);\n\n  var cheight = this.canvasSize.height;\n  var cwidth = this.canvasSize.width;\n\n  function makeRound(percent, radius, width, cx, cy, color){\n    var s = 0;\n    var points = 370;\n    c.strokeStyle = color || 'green';\n    while(s<radius){\n      if (s < (radius - width)) {\n        s++;\n        continue;\n      }\n      var slice = 2 * pi / points;\n      c.beginPath();\n      var p = parseFloat(percent*360);\n      for(var i = 0;i<=points;i++){\n        if (i>p) continue;\n        var si = i-90;\n        var a = slice * si;\n        c.lineTo(Math.round(cx+s*cos(a)), Math.round(cy+s*sin(a)));\n      }\n      c.stroke();\n      c.closePath();\n      s++;\n    }\n  }\n\n  var donuts = data.length;\n  var radius = this.options.radius;\n  var width = this.options.arcWidth;\n  var remainColor = this.options.remainColor;\n\n  var middle = cheight / 2;\n  var spacing = (cwidth - (donuts * radius * 2)) / (donuts + 1);\n\n  function drawDonut(label, percent, radius, width, cxx, middle, color, percentAltNumber){\n    makeRound(100, radius, width, cxx, middle, remainColor );\n    makeRound(percent, radius, width, cxx, middle, color);\n    var ptext = percentAltNumber ? percentAltNumber.toFixed(0) : parseFloat(percent*100).toFixed(0) + '%';\n    c.fillText(ptext, cxx - Math.round(parseFloat((c.measureText(ptext).width)/2)) + 3, middle);\n    c.fillText(label, cxx - Math.round(parseFloat((c.measureText(label).width)/2)) + 3, (middle + radius) + 5);\n  }\n\n  function makeDonut(stat, which){\n    var left = radius + (spacing * which) + (radius * 2 * (which - 1));\n    var percent = stat.percent;\n    if (percent > 1.001){\n      percent = parseFloat(percent / 100).toFixed(2);\n    }\n    var label = stat.label;\n    var percentAltNumber = stat.percentAltNumber;\n    var color = stat.color || 'green';\n    var cxx = left;\n    drawDonut(label, percent, radius, width, cxx, middle, color, percentAltNumber);\n  }\n  function makeDonuts(stats){\n    for(var l = 0; l<=stats.length-1;l++){\n      makeDonut(stats[l], l+1);\n    }\n  }\n\n  if (data.length){\n    makeDonuts(data);\n  }\n\n  this.currentData = data;\n\n  c.strokeStyle = 'magenta';\n\n  c.restore();\n  return;\n};\n\nDonut.prototype.getOptionsPrototype = function() {\n  return {\n    spacing: 1,\n    yPadding: 1,\n    radius: 1,\n    arcWidth: 1,\n    data: [ { color: 'red', percent: '50', label: 'a'}\n      , { color: 'blue', percent: '20', label: 'b'}\n      , { color: 'yellow', percent: '80', label: 'c'}\n    ]\n  };\n};\n\nmodule.exports = Donut;\n"
  },
  {
    "path": "lib/widget/gauge-list.js",
    "content": "'use strict';\nvar blessed = require('blessed')\n  , Node = blessed.Node\n  , Canvas = require('./canvas');\n\nfunction GaugeList(options) {\n  if (!(this instanceof Node)) {\n    return new GaugeList(options);\n  }\n\n  var self = this;\n\n  options = options || {};\n  self.options = options;\n  self.options.stroke = options.stroke || 'magenta';\n  self.options.fill = options.fill || 'white';\n  self.options.data = options.data || [];\n  self.options.showLabel = options.showLabel !== false;\n  self.options.gaugeSpacing = options.gaugeSpacing || 0;\n  self.options.gaugeHeight = options.gaugeHeight || 1;\n\n  Canvas.call(this, options, require('ansi-term'));\n\n  this.on('attach', function() {\n    var gauges = this.gauges = self.options.gauges;\n    this.setGauges(gauges);\n  });\n\n}\n\nGaugeList.prototype = Object.create(Canvas.prototype);\n\nGaugeList.prototype.calcSize = function() {\n  this.canvasSize = {width: this.width-2, height: this.height};\n};\n\nGaugeList.prototype.type = 'gauge';\n\nGaugeList.prototype.setData = function() {\n};\n\nGaugeList.prototype.setGauges = function(gauges) {\n\n  if (!this.ctx) {\n    throw 'error: canvas context does not exist. setData() for gauges must be called after the gauge has been added to the screen via screen.append()';\n  }\n\n  var c = this.ctx;\n  c.clearRect(0, 0, this.canvasSize.width, this.canvasSize.height);\n\n  for (var i=0; i<gauges.length; i++) {\n    this.setSingleGauge(gauges[i], i);\n  }\n\n};\n\nGaugeList.prototype.setSingleGauge = function(gauge, offset) {\n\n  var colors = ['green','magenta','cyan','red','blue'];\n  var stack = gauge.stack;\n\n  var c = this.ctx;\n  var leftStart = 3;\n  var textLeft = 5;\n\n  c.strokeStyle='normal';\n  c.fillStyle='white';\n  c.fillText(offset.toString(), 0, offset*(this.options.gaugeHeight+this.options.gaugeSpacing));\n\n  for (var i = 0; i < stack.length; i++) {\n    var currentStack = stack[i];\n\n    var percent;\n    if (typeof(currentStack) == typeof({})){\n      percent = currentStack.percent;\n    } else {\n      percent = currentStack;\n    }\n\n    c.strokeStyle = currentStack.stroke || colors[(i%colors.length)]; // use specified or choose from the array of colors\n    c.fillStyle = this.options.fill;//'white'\n\n    textLeft = 5;\n\n    var width = percent/100*(this.canvasSize.width-5);\n\n    c.fillRect(leftStart, offset*(this.options.gaugeHeight+this.options.gaugeSpacing), width, this.options.gaugeHeight-1);\n\n    textLeft = (width / 2) - 1;\n    // if (textLeft)\n    var textX = leftStart+textLeft;\n\n    if ((leftStart+width)<textX) {\n      c.strokeStyle = 'normal';\n    }\n    if (gauge.showLabel) c.fillText(percent+'%', textX, 3);\n\n    leftStart += width;\n  }\n};\n\nGaugeList.prototype.getOptionsPrototype = function() {\n  return {percent: 10};\n};\n\nmodule.exports = GaugeList;\n"
  },
  {
    "path": "lib/widget/gauge.js",
    "content": "'use strict';\nvar blessed = require('blessed')\n  , Node = blessed.Node\n  , Canvas = require('./canvas');\n\nfunction Gauge(options) {\n  if (!(this instanceof Node)) {\n    return new Gauge(options);\n  }\n\n  var self = this;\n\n  options = options || {};\n  self.options = options;\n  self.options.stroke = options.stroke || 'magenta';\n  self.options.fill = options.fill || 'white';\n  self.options.data = options.data || [];\n  self.options.showLabel = options.showLabel !== false;\n\n  Canvas.call(this, options, require('ansi-term'));\n\n  this.on('attach', function() {\n    if (self.options.stack) {\n      var stack = this.stack = self.options.stack;\n      this.setStack(stack);\n    } else {\n      var percent = this.percent = self.options.percent || 0;\n      this.setData(percent);\n    }\n  });\n}\n\nGauge.prototype = Object.create(Canvas.prototype);\n\nGauge.prototype.calcSize = function() {\n  this.canvasSize = {width: this.width-2, height: this.height};\n};\n\nGauge.prototype.type = 'gauge';\n\nGauge.prototype.setData = function(data){\n  if (typeof(data) == typeof([]) && data.length > 0){\n    this.setStack(data);\n  } else if(typeof(data) == typeof(1)) {\n    this.setPercent(data);\n  }\n};\n\nGauge.prototype.setPercent = function(percent) {\n\n  if (!this.ctx) {\n    throw 'error: canvas context does not exist. setData() for gauges must be called after the gauge has been added to the screen via screen.append()';\n  }\n\n  var c = this.ctx;\n\n  c.strokeStyle = this.options.stroke;//'magenta'\n  c.fillStyle = this.options.fill;//'white'\n\n  c.clearRect(0, 0, this.canvasSize.width, this.canvasSize.height);\n  if (percent < 1.001){\n    percent = percent * 100;\n  }\n  var width = percent/100*(this.canvasSize.width-3);\n  c.fillRect(1, 2, width, 2);\n\n  var textX = 7;\n  if (width<textX) {\n    c.strokeStyle = 'normal';\n  }\n\n  if (this.options.showLabel) c.fillText(Math.round(percent)+'%', textX, 3);\n};\n\nGauge.prototype.setStack = function(stack) {\n  var colors = ['green','magenta','cyan','red','blue'];\n\n  if (!this.ctx) {\n    throw 'error: canvas context does not exist. setData() for gauges must be called after the gauge has been added to the screen via screen.append()';\n  }\n\n  var c = this.ctx;\n  var leftStart = 1;\n  var textLeft = 5;\n  c.clearRect(0, 0, this.canvasSize.width, this.canvasSize.height);\n\n  for (var i = 0; i < stack.length; i++) {\n    var currentStack = stack[i];\n\n    let percent;\n    if (typeof(currentStack) == typeof({}))\n      percent = currentStack.percent;\n    else\n      percent = currentStack;\n\n    c.strokeStyle = currentStack.stroke || colors[(i%colors.length)]; // use specified or choose from the array of colors\n    c.fillStyle = this.options.fill;//'white'\n\n    textLeft = 5;\n    if (percent < 1.001){\n      percent = percent * 100;\n    }\n    var width = percent/100*(this.canvasSize.width-3);\n\n    c.fillRect(leftStart, 2, width, 2);\n\n    textLeft = (width / 2) - 1;\n    // if (textLeft)\n    var textX = leftStart+textLeft;\n\n    if ((leftStart+width)<textX) {\n      c.strokeStyle = 'normal';\n    }\n    if (this.options.showLabel) c.fillText(percent+'%', textX, 3);\n\n    leftStart += width;\n  }\n};\n\nGauge.prototype.getOptionsPrototype = function() {\n  return {percent: 10};\n};\n\n\nmodule.exports = Gauge;\n"
  },
  {
    "path": "lib/widget/lcd.js",
    "content": "'use strict';\nvar blessed = require('blessed')\n  , Node = blessed.Node\n  , Canvas = require('./canvas');\n\nfunction LCD(options) {\n  if (!(this instanceof Node)) {\n    return new LCD(options);\n  }\n  var self = this;\n\n  options = options || {};\n  self.options = options;\n\n  //these options need to be modified epending on the resulting positioning/size\n  self.options.segmentWidth = options.segmentWidth || 0.06; // how wide are the segments in % so 50% = 0.5\n  self.options.segmentInterval = options.segmentInterval || 0.11; // spacing between the segments in % so 50% = 0.5\n  self.options.strokeWidth = options.strokeWidth || 0.11; // spacing between the segments in % so 50% = 0.5\n\n  //default display settings\n  self.options.elements = options.elements || 3; // how many elements in the display. or how many characters can be displayed.\n  self.options.display = options.display || 321; // what should be displayed before anything is set\n  self.options.elementSpacing = options.spacing || 4; // spacing between each element\n  self.options.elementPadding = options.padding || 2; // how far away from the edges to put the elements\n\n  //coloring\n  self.options.color = options.color || 'white';\n\n  Canvas.call(this, options);\n\n  this.segment16 = null;\n\n  this.on('attach', function() {\n    var display = self.options.display || 1234;\n    if (!this.segment16)\n      this.segment16 = new SixteenSegment(this.options.elements, this.ctx, this.canvasSize.width, this.canvasSize.height, 0, 0, this.options);\n\n    this.setDisplay(display);\n  });\n}\n\nLCD.prototype = Object.create(Canvas.prototype);\n\nLCD.prototype.calcSize = function() {\n  this.canvasSize = {width: this.width*2-8, height: (this.height*4)-12};\n};\n\nLCD.prototype.type = 'lcd';\nLCD.prototype.increaseWidth = function(){\n  if (this.segment16){\n    this.segment16.SegmentWidth+=0.01;\n  }\n};\nLCD.prototype.decreaseWidth = function(){\n  if (this.segment16){\n    this.segment16.SegmentWidth-=0.01;\n  }\n};\nLCD.prototype.increaseInterval = function(){\n  if (this.segment16){\n    this.segment16.SegmentInterval+=0.01;\n  }\n};\nLCD.prototype.decreaseInterval = function(){\n  if (this.segment16){\n    this.segment16.SegmentInterval-=0.01;\n  }\n};\nLCD.prototype.increaseStroke = function(){\n  if (this.segment16){\n    this.segment16.StrokeWidth+=0.05;\n  }\n};\nLCD.prototype.decreaseStroke = function(){\n  if (this.segment16){\n    this.segment16.StrokeWidth-=0.05;\n  }\n};\nLCD.prototype.setOptions = function(options){\n  if (this.segment16){\n    this.segment16.setOptions(options);\n  }\n};\n\nLCD.prototype.setData = function(data){\n  this.setDisplay(data.toString());\n};\n\nLCD.prototype.getOptionsPrototype = function() {\n  return {\n    label: 'LCD Test',\n    segmentWidth: 0.06,\n    segmentInterval: 0.11,\n    strokeWidth: 0.1,\n    elements: 5,\n    display: 3210,\n    elementSpacing: 4,\n    elementPadding: 2\n  };\n};\n\nLCD.prototype.setDisplay = function(display) {\n\n  if (!this.ctx) {\n    throw 'error: canvas context does not exist. setData() for line charts must be called after the chart has been added to the screen via screen.append()';\n  }\n\n  this.ctx.clearRect(0, 0, this.canvasSize.width, this.canvasSize.height);\n\n  this.segment16.DisplayText(display);\n};\n\nfunction ElementArray(count) {\n  this.SetCount = SetCount;\n  this.SetText = SetText;\n  this.SetElementValue = SetElementValue;\n  this.NullMask = 0x10;\n  this.Elements = [];\n  this.SetCount(count || 0);\n\n  function SetCount(count) {\n    var c = parseInt(count, 10);\n    if (isNaN(c)) {\n      throw 'Invalid element count: ' + count;\n    }\n    this.Elements = [c];\n    for (var i = 0; i < c; i++) {\n      this.Elements[i] = 0;\n    }\n  }\n\n  function SetText(value, charMaps) {\n    // Get the string of the value passed in\n    if (value === null) {\n      value = '';\n    }\n    value = value.toString();\n\n    // Clear the elements\n    for (var i = 0; i < this.Elements.length; i++) {\n      this.SetElementValue(i, 0);\n    }\n    if (value.length === 0) {\n      return;\n    }\n    // Set the bitmask to dispay the proper character for each element\n    for (var e = 0; e < this.Elements.length && e < value.length; e++){\n      var c = value[e];\n      var mask = charMaps[c];\n      // Use blank of there is no bitmask for this character\n      if (mask === null || mask === undefined) {\n        mask = this.NullMask;\n      }\n      this.SetElementValue(e, mask);\n    }\n  }\n  function SetElementValue(i, value) {\n    if (i >= 0 && i < this.Elements.length){\n      this.Elements[i] = parseInt(value, 10);\n    }\n  }\n}\n\n//thx to https://github.com/Enderer/sixteensegment!!!\n//although it needed HEAVY rework since it was already somewhat busted ;-(\nfunction SixteenSegment(count, canvas, width, height, x, y, options){\n  this.ElementArray = new ElementArray(count);\n\n  this.SegmentWidth = options.segmentWidth;//(this.ElementWidth * 0.0015) * 5 //0.1;           // Width of segments (% of Element Width)\n  this.SegmentInterval = options.segmentInterval;//(this.ElementWidth * 0.0015) * 10 // 0.20;        // Spacing between segments (% of Element Width)\n  this.BevelWidth = 0.01;             // Size of corner bevel (% of Element Width)\n  this.SideBevelEnabled = true;      // Should the sides be beveled\n  this.StrokeLight = options.color;       // Color of an on segment outline\n\n  this.StrokeWidth = options.strokeWidth;               // Width of segment outline\n  this.Padding = options.elementPadding;                   // Padding around the display\n  this.Spacing = options.elementSpacing;                   // Spacing between elements\n\n  this.ElementWidth = (width - (this.Spacing*count))/count;\n  this.ElementHeight = height - (this.Padding*2);\n\n  // console.error(\"w %s h %s\", this.ElementWidth, this.ElementHeight);\n\n  this.FillLight = 'red';           // Color of an on segment\n  this.FillDark = 'cyan';             // Color of an off segment\n  this.StrokeDark = 'black';          // Color of an off segment outline\n\n  this.X = 0;\n  this.Y = 0;\n\n  this.ElementCount = count;\n\n  this.CalcElementDimensions = CalcElementDimensions;\n  this.FlipVertical = FlipVertical;\n  this.FlipHorizontal = FlipHorizontal;\n  this.CalcPoints = CalcPoints;\n  this.DisplayText = DisplayText;\n  this.Draw = Draw;\n  this.setOptions = setOptions;\n\n  this.Width = width || canvas.width;\n  this.Height = height || canvas.height;\n\n  this.Canvas = canvas;\n  this.CalcPoints();\n  this.ElementArray.SetCount(count);\n\n  function setOptions(options){\n    if (options.elements)\n      this.ElementArray.SetCount(options.elements);\n\n    this.SegmentWidth = options.segmentWidth || this.SegmentWidth;\n    this.SegmentInterval = options.segmentInterval || this.SegmentInterval;\n    this.BevelWidth = 0.01;\n    this.SideBevelEnabled = true;\n    this.StrokeLight = options.color || this.StrokeLight;\n\n    this.StrokeWidth = options.strokeWidth || this.StrokeWidth;\n    this.Padding = options.elementPadding || this.Padding;\n    this.Spacing = options.elementSpacing || this.Spacing;\n\n    this.ElementWidth = (width - (this.Spacing*count))/count;\n    this.ElementHeight = height - (this.Padding*2);\n  }\n\n  function DisplayText(value) {\n    // Recalculate points in case any settings changed\n    // console.error(\"si: %s, sw: %s\", this.SegmentInterval, this.SegmentWidth);\n    // console.error(\"st: %s\", this.StrokeWidth);\n    // Set the display patterns and draw the canvas\n    this.ElementArray.SetText(value, CharacterMasks);\n    this.CalcPoints();\n    this.Draw(this.Canvas, this.ElementArray.Elements);\n  }\n\n  function CalcElementDimensions() {\n    var n = this.ElementCount;\n    var h = this.ElementHeight;\n    h -= this.Padding * 2;\n\n    var w = this.Width;\n    w -= this.Spacing * (n - 1);\n    w -= this.Padding * 2;\n    w /= n;\n    var output = { Width: w, Height: h };\n    // console.error(output);\n    return output;\n  }\n\n  function FlipVertical(points, height) {\n    var flipped = [];\n    for(var i=0;i<points.length;i++) {\n      flipped[i] = {};\n      flipped[i].x = points[i].x;\n      flipped[i].y = height - points[i].y;\n    }\n    return flipped;\n  }\n\n  function FlipHorizontal(points, width) {\n    var flipped = [];\n    for(var i=0;i<points.length;i++) {\n      flipped[i] = {};\n      flipped[i].x = width - points[i].x;\n      flipped[i].y = points[i].y;\n    }\n    return flipped;\n  }\n\n  function Draw(context, elements) {\n    // Get the context and clear the area\n    context.clearRect(this.X, this.Y, this.Width, this.Height);\n    context.save();\n\n    // Calculate the width and spacing of each element\n    var elementWidth = this.CalcElementDimensions().Width;\n    // console.error(\"width: %s\", elementWidth);\n    // Offset to adjust for starting point and padding\n    context.translate(this.X, this.Y);\n    context.translate(this.Padding, this.Padding);\n\n    // Draw each segment of each element\n    for (var i = 0; i < elements.length; i++) {\n      var element = elements[i];\n      for (var s = 0; s < this.Points.length; s++) {\n        // Pick the on or off color based on the bitmask\n        var color = (element & 1 << s) ? this.FillLight : this.FillDark;\n        var stroke = (element & 1 << s) ? this.StrokeLight : this.StrokeDark;\n        if (stroke == this.StrokeDark) continue;\n        // console.error(\"c: %s, s: %s\", color, stroke);\n        context.lineWidth = this.StrokeWidth;\n        context.strokeStyle = stroke;\n        context.fillStyle = color;\n        context.moveTo(0,0);\n        context.beginPath();\n        context.moveTo(this.Points[s][0].x, this.Points[s][0].y);\n        // Create the segment path\n        var maxX = 0;\n        for(var p = 1; p < this.Points[s].length; p++) {\n          if (this.Points[s][p].x > maxX)\n            maxX = this.Points[s][p].x;\n          context.lineTo(Math.round(this.Points[s][p].x), Math.round(this.Points[s][p].y));\n        }\n        context.closePath();\n        context.fill();\n        context.stroke();\n        if (this.StrokeWidth > 0) {\n          context.stroke();\n        }\n      }\n      context.translate(elementWidth+this.Spacing, 0);\n    }\n    context.restore();\n  }\n\n  function CalcPoints() {\n    var w = this.ElementWidth,\n      h = this.ElementHeight,\n      sw = this.SegmentWidth * w,\n      si = this.SegmentInterval * w,\n      bw = this.BevelWidth * sw,\n      ib = (this.SideBevelEnabled) ? 1 : 0,\n      sf = sw * 0.8,\n      slope = h / w,\n      sqrt2 = Math.SQRT2,\n      sqrt3 = Math.sqrt(3);\n\n    // Base position of points w/out bevel and interval\n    var w0 = w / 2 - sw / 2,        h0 = 0,\n      w1 = w / 2,                 h1 = sw / 2,\n      w2 = w / 2 + sw / 2,        h2 = sw,\n      w3 = w - sw,                h3 = h / 2 - sw / 2,\n      w4 = w - sw / 2,            h4 = h / 2,\n      w5 = w,                     h5 = h / 2 + sw / 2;\n\n    // Order of segments stored in Points[][]\n    var A1 = 0, A2 = 1, B = 2,  C = 3,  D1 = 4, D2 = 5, E = 6,  F = 7,\n      G1 = 8, G2 = 9, H = 10, I = 11, J = 12, K = 13, L = 14, M = 15;\n\n    // Create the points array for all segments\n    var points = [];\n    points[A1] = [\n      { x: bw * 2 + si / sqrt2,           y: h0        },\n      { x: w1 - si / 2 - sw / 2 * ib,     y: h0        },\n      { x: w1 - si / 2,                   y: h1        },\n      { x: w0 - si / 2,                   y: h2        },\n      { x: sw + si / sqrt2,               y: h2        },\n      { x: bw + si / sqrt2,               y: h0 + bw   }\n    ];\n    points[G2] = [\n      { x: w2 + si / sqrt2,               y: h3        },\n      { x: w3 - si / 2 * sqrt3,           y: h3        },\n      { x: w4 - si / 2 * sqrt3,           y: h4        },\n      { x: w3 - si / 2 * sqrt3,           y: h5        },\n      { x: w2 + si / sqrt2,               y: h5        },\n      { x: w1 + si / sqrt2,               y: h4        }\n    ];\n    points[B] = [\n      { x: w5,           y: h0 + bw * 2 + si / sqrt2   },\n      { x: w5,           y: h4 - si / 2 - sw / 2 * ib  },\n      { x: w4,           y: h4 - si / 2                },\n      { x: w3,           y: h3 - si / 2                },\n      { x: w3,           y: h2 + si / sqrt2            },\n      { x: w5 - bw,      y: h0 + bw + si / sqrt2       }\n    ];\n    points[I] = [\n      { x: w2,           y: h2 + si / 2 * sqrt3        },\n      { x: w2,           y: h3 - si / sqrt2            },\n      { x: w1,           y: h4 - si / sqrt2            },\n      { x: w0,           y: h3 - si / sqrt2            },\n      { x: w0,           y: h2 + si / 2 * sqrt3        },\n      { x: w1,           y: h1 + si / 2 * sqrt3        }\n    ];\n    points[H] = [\n      { x: (sw + sf) / slope + si,        y: h2 + si              },\n      { x: w0 - si,                       y: w0 * slope - sf - si },\n      { x: w0 - si,                       y: h3 - si              },\n      { x: (h3 - sf) / slope - si,        y: h3 - si              },\n      { x: sw + si,                       y: h2 * slope + sf + si },\n      { x: sw + si,                       y: h2 + si              }\n    ];\n    points[A2] = this.FlipHorizontal(points[A1], w);    // A2\n    points[C]  = this.FlipVertical(points[2], h);       // C\n    points[D1] = this.FlipVertical(points[0], h);       // D1\n    points[D2] = this.FlipHorizontal(points[4], w);     // D2\n    points[E]  = this.FlipHorizontal(points[3], w);     // E\n    points[F]  = this.FlipHorizontal(points[2], w);     // F\n    points[G1] = this.FlipHorizontal(points[9], w);     // G1\n    points[J]  = this.FlipHorizontal(points[10], w);    // J\n    points[K]  = this.FlipVertical(points[12], h);      // K\n    points[L]  = this.FlipVertical(points[11], h);      // L\n    points[M]  = this.FlipVertical(points[10], h);      // M\n    this.Points = points;\n  }\n}\nvar CharacterMasks = (function() {\n  // Segment Bitmasks for individual segments.\n  // Binary Or them together to create bitmasks\n  // a1|a2|b|c|d1|d2|e|f|g1|g2|h|i|j|k|l|m\n  var a1 = 1 << 0,    a2 = 1 << 1,    b = 1 << 2,    c = 1 << 3,\n    d1 = 1 << 4,    d2 = 1 << 5,    e = 1 << 6,    f = 1 << 7,\n    g1 = 1 << 8,    g2 = 1 << 9,    h = 1 << 10,   i = 1 << 11,\n    j  = 1 << 12,   k  = 1 << 13,   l = 1 << 14,   m = 1 << 15;\n  // Character map associates characters with a bit pattern\n  return {\n    ' ' : 0,\n    ''  : 0,\n    '0' : a1|a2|b|c|d1|d2|e|f|j|m,\n    '1' : b|c|j,\n    '2' : a1|a2|b|d1|d2|e|g1|g2,\n    '3' : a1|a2|b|c|d1|d2|g2,\n    '4' : b|c|f|g1|g2,\n    '5' : a1|a2|c|d1|d2|f|g1|g2,\n    '6' : a1|a2|c|d1|d2|e|f|g1|g2,\n    '7' : a1|a2|b|c,\n    '8' : a1|a2|b|c|d1|d2|e|f|g1|g2,\n    '9' : a1|a2|b|c|f|g1|g2,\n    'A' : e|f|a1|a2|b|c|g1|g2,\n    'B' : a1|a2|b|c|d1|d2|g2|i|l,\n    'C' : a1|a2|f|e|d1|d2,\n    'D' : a1|a2|b|c|d1|d2|i|l,\n    'E' : a1|a2|f|e|d1|d2|g1|g2,\n    'F' : a1|a2|e|f|g1 ,\n    'G' : a1|a2|c|d1|d2|e|f|g2,\n    'H' : b|c|e|f|g1|g2,\n    'I' : a1|a2|d1|d2|i|l,\n    'J' : b|c|d1|d2|e,\n    'K' : e|f|g1|j|k,\n    'L' : d1|d2|e|f,\n    'M' : b|c|e|f|h|j,\n    'N' : b|c|e|f|h|k,\n    'O' : a1|a2|b|c|d1|d2|e|f,\n    'P' : a1|a2|b|e|f|g1|g2,\n    'Q' : a1|a2|b|c|d1|d2|e|f|k,\n    'R' : a1|a2|b|e|f|g1|g2|k,\n    'S' : a1|a2|c|d1|d2|f|g1|g2,\n    'T' : a1|a2|i|l,\n    'U' : b|c|d1|d2|e|f,\n    'V' : e|f|j|m,\n    'W' : b|c|e|f|k|m,\n    'X' : h|j|k|m,\n    'Y' : b|f|g1|g2|l,\n    'Z' : a1|a2|d1|d2|j|m,\n    '-' : g1|g2,\n    '?' : a1|a2|b|g2|l,\n    '+' : g1|g2|i|l,\n    '*' : g1|g2|h|i|j|k|l|m\n  };\n}());\n\nmodule.exports = LCD;\n"
  },
  {
    "path": "lib/widget/log.js",
    "content": "'use strict';\nvar blessed = require('blessed')\n  , Node = blessed.Node\n  , List = blessed.List;\n\nfunction Log(options) {\n  if (!(this instanceof Node)) {\n    return new Log(options);\n  }\n\n  options = options || {};\n  options.bufferLength = options.bufferLength || 30;\n  this.options = options;\n  List.call(this, options);\n\n  this.logLines = [];\n  this.interactive = false;\n}\n\nLog.prototype = Object.create(List.prototype);\n\nLog.prototype.log = function(str) {\n  this.logLines.push(str);\n  if (this.logLines.length>this.options.bufferLength) {\n    this.logLines.shift();\n  }\n  this.setItems(this.logLines);\n  this.scrollTo(this.logLines.length);\n};\n\nLog.prototype.type = 'log';\n\nmodule.exports = Log;\n"
  },
  {
    "path": "lib/widget/map.js",
    "content": "'use strict';\nvar blessed = require('blessed')\n  , Node = blessed.Node\n  , Canvas = require('./canvas')\n  , InnerMap = require('map-canvas');\n\nfunction Map(options) {\n  var self = this;\n\n  if (!(this instanceof Node)) {\n    return new Map(options);\n  }\n\n  Canvas.call(this, options);\n\n  this.on('attach', function() {\n\n    options.style = options.style || {};\n\n    var opts = { excludeAntartica: (options.excludeAntarctica === undefined) ? true : options.excludeAntarctica\n      , disableBackground: (options.disableBackground === undefined) ? true : options.disableBackground\n      , disableMapBackground: (options.disableMapBackground === undefined) ? true : options.disableMapBackground\n      , disableGraticule: (options.disableGraticule === undefined) ? true : options.disableGraticule\n      , disableFill: (options.disableFill === undefined) ? true : options.disableFill\n      , width: self.ctx._canvas.width\n      , height: self.ctx._canvas.height\n      , shapeColor: options.style.shapeColor || 'green'};\n\n    opts.startLon = options.startLon || undefined;\n    opts.endLon = options.endLon || undefined;\n    opts.startLat = options.startLat || undefined;\n    opts.endLat = options.endLat || undefined;\n    opts.region = options.region || undefined;\n    opts.labelSpace = options.labelSpace || 5;\n\n    this.ctx.strokeStyle= options.style.stroke || 'green';\n    this.ctx.fillStyle=options.style.fill || 'green';\n\n    self.innerMap = new InnerMap(opts, this._canvas);\n    self.innerMap.draw();\n\n    if (self.options.markers) {\n\n      for (var m in self.options.markers) {\n        self.addMarker(self.options.markers[m]);\n      }\n    }\n  });\n\n}\n\nMap.prototype = Object.create(Canvas.prototype);\n\nMap.prototype.calcSize = function() {\n  this.canvasSize = {width: this.width*2-12, height: this.height*4};\n};\n\nMap.prototype.type = 'map';\n\nMap.prototype.addMarker = function(options) {\n  if (!this.innerMap) {\n    throw 'error: canvas context does not exist. addMarker() for maps must be called after the map has been added to the screen via screen.append()';\n  }\n\n  this.innerMap.addMarker(options);\n};\n\nMap.prototype.getOptionsPrototype = function() {\n\n  return { startLon: 10\n    , endLon: 10\n    , startLat: 10\n    , endLat: 10\n    , region: 'us'\n    , markers:\n             [  {'lon' : '-79.0000', 'lat' : '37.5000', color: 'red', char: 'X' }\n               ,{'lon' : '79.0000', 'lat' : '37.5000', color: 'blue', char: 'O' }\n             ]\n  };\n};\n\nMap.prototype.clearMarkers = function() {\n  this.innerMap.draw();\n};\n\nmodule.exports = Map;\n"
  },
  {
    "path": "lib/widget/markdown.js",
    "content": "'use strict';\nvar blessed = require('blessed')\n  , Box = blessed.Box\n  , marked = require('marked')\n  , TerminalRenderer = require('marked-terminal')\n  , chalk = require('chalk');\n\n\nfunction Markdown(options) {\n  if (!(this instanceof Box)) {\n    return new Markdown(options);\n  }\n\n  options = options || {};\n\n  const markdownOptions = {\n    style: options.markdownStyle\n  };\n\n  this.evalStyles(markdownOptions);\n\n  this.setOptions(markdownOptions.style);\n\n  this.options = options;\n  Box.call(this, options);\n\n  if (options.markdown) this.setMarkdown(options.markdown);\n}\n\nMarkdown.prototype = Object.create(Box.prototype);\n\nMarkdown.prototype.setMarkdown = function(str) {\n  this.setContent(marked.parse(str));\n};\n\nMarkdown.prototype.setOptions = function(style) {\n  marked.setOptions({\n    renderer: new TerminalRenderer(style)\n  });\n};\n\nMarkdown.prototype.evalStyles = function(options) {\n  if (!options.style) return;\n  for (var st in options.style) {\n    if (typeof(options.style[st])!='string') continue;\n\n    var tokens = options.style[st].split('.');\n    options.style[st] = chalk;\n    for (var j=1; j<tokens.length; j++) {\n      options.style[st] = options.style[st][tokens[j]];\n    }\n  }\n};\n\nMarkdown.prototype.getOptionsPrototype = function() {\n  return {\n    markdown: 'string',\n    markdownStyle: 'object'\n  };\n};\n\nMarkdown.prototype.type = 'markdown';\n\nmodule.exports = Markdown;\n"
  },
  {
    "path": "lib/widget/picture.js",
    "content": "'use strict';\nvar blessed = require('blessed')\n  , Node = blessed.Node\n  , Box = blessed.Box\n  , pictureTube = require('picture-tuber')\n  , fs = require('fs')\n  , streams = require('memory-streams')\n  , MemoryStream = require('memorystream');\n\nfunction Picture(options) {\n  if (!(this instanceof Node)) {\n    return new Picture(options);\n  }\n\n  options = options || {};\n  options.cols = options.cols || 50;\n  this.options = options;\n\n  if (options.file || options.base64) {\n    this.setImage(options);\n  }\n\n  Box.call(this, options);\n}\n\nPicture.prototype = Object.create(Box.prototype);\n\nPicture.prototype.setImage = function(options) {\n\n  var tube = pictureTube( { cols: options.cols } );\n\n  if (options.file) fs.createReadStream(options.file).pipe(tube);\n  else if (options.base64) {\n    var memStream = new MemoryStream();\n    memStream.pipe(tube);\n    var buf = new Buffer(options.base64, 'base64');\n    memStream.write(buf);\n    memStream.end();\n  }\n\n  this.writer = new streams.WritableStream();\n  tube.pipe(this.writer);\n\n  tube.on('end', function() {\n    if (options.onReady) {\n      options.onReady();\n    }\n  });\n\n};\n\nPicture.prototype.render = function() {\n  this.setContent(this.writer.toString());\n  return this._render();\n};\n\nPicture.prototype.getOptionsPrototype = function() {\n\n  return { base64:'AAAA'\n    , cols: 1 };\n\n};\n\nPicture.prototype.type = 'picture';\n\nmodule.exports = Picture;\n"
  },
  {
    "path": "lib/widget/sparkline.js",
    "content": "'use strict';\nvar blessed = require('blessed')\n  , Node = blessed.Node\n  , Box = blessed.Box\n  , sparkline = require('sparkline');\n\nfunction Sparkline(options) {\n\n  var self = this;\n\n  if (!(this instanceof Node)) {\n    return new Sparkline(options);\n  }\n\n  options = options || {};\n  options.bufferLength = options.bufferLength || 30;\n  options.style = options.style || {};\n  options.style.titleFg = options.style.titleFg || 'white';\n  this.options = options;\n  Box.call(this, options);\n\n\n  this.on('attach', function() {\n    if (self.options.data) {\n      self.setData(self.options.data.titles, self.options.data.data);\n    }\n  });\n}\n\nSparkline.prototype = Object.create(Box.prototype);\n\nSparkline.prototype.setData = function(titles, datasets) {\n  var res = '\\r\\n';\n  for (var i=0; i<titles.length; i++) {\n    res += '{bold}{'+this.options.style.titleFg+'-fg}' + titles[i]+':{/'+this.options.style.titleFg+'-fg}{/bold}\\r\\n';\n    res += sparkline(datasets[i].slice(0, this.width-2)) + '\\r\\n\\r\\n';\n  }\n\n  this.setContent(res);\n};\n\nSparkline.prototype.getOptionsPrototype = function() {\n  return { label: 'Sparkline'\n    , tags: true\n    , border: {type: 'line', fg: 'cyan'}\n    , width: '50%'\n    , height: '50%'\n    , style: { fg: 'blue' }\n    , data: { titles: [ 'Sparkline1', 'Sparkline2'],\n      data: [ [10, 20, 30, 20, 50, 70, 60, 30, 35, 38]\n        , [40, 10, 40, 50, 20, 30, 20, 20, 19, 40] ]\n    }\n  };\n};\n\nSparkline.prototype.type = 'sparkline';\n\nmodule.exports = Sparkline;\n"
  },
  {
    "path": "lib/widget/table.js",
    "content": "'use strict';\nvar blessed = require('blessed')\n  , Node = blessed.Node\n  , Box = blessed.Box\n  , stripAnsi = require('strip-ansi');\n\nfunction Table(options) {\n\n  var self = this;\n\n  if (!(this instanceof Node)) {\n    return new Table(options);\n  }\n\n  if (Array.isArray(options.columnSpacing)) {\n    throw 'Error: columnSpacing cannot be an array.\\r\\n' +\n           'Note: From release 2.0.0 use property columnWidth instead of columnSpacing.\\r\\n' +\n           'Please refere to the README or to https://github.com/yaronn/blessed-contrib/issues/39';\n  }\n\n  if (!options.columnWidth) {\n    throw 'Error: A table must get columnWidth as a property. Please refer to the README.';\n  }\n\n  options = options || {};\n  options.columnSpacing = options.columnSpacing==null? 10 : options.columnSpacing;\n  options.bold = true;\n  options.selectedFg = options.selectedFg || 'white';\n  options.selectedBg = options.selectedBg || 'blue';\n  options.fg = options.fg || 'green';\n  options.bg = options.bg || '';\n  options.interactive = (typeof options.interactive === 'undefined') ? true : options.interactive;\n  this.options = options;\n  Box.call(this, options);\n\n  this.rows = blessed.list({\n    //height: 0,\n    top: 2,\n    width: 0,\n    left: 1,\n    style: { selected: {\n      fg: options.selectedFg\n      , bg: options.selectedBg\n    }\n    , item: {\n      fg: options.fg\n      , bg: options.bg\n    }},\n    keys: options.keys,\n    vi: options.vi,\n    mouse: options.mouse,\n    tags: true,\n    interactive: options.interactive,\n    screen: this.screen\n  });\n\n  this.append(this.rows);\n\n  this.on('attach', function() {\n    if (self.options.data) {\n      self.setData(self.options.data);\n    }\n  });\n\n}\n\nTable.prototype = Object.create(Box.prototype);\n\nTable.prototype.focus = function(){\n  this.rows.focus();\n};\n\nTable.prototype.render = function() {\n  if(this.screen.focused == this.rows)\n    this.rows.focus();\n\n  this.rows.width = this.width-3;\n  this.rows.height = this.height-4;\n  Box.prototype.render.call(this);\n};\n\n\nTable.prototype.setData = function(table) {\n  var self = this;\n\n  var dataToString = function(d) {\n    var str = '';\n    d.forEach(function(r, i) {\n      var colsize = self.options.columnWidth[i]\n        , strip = stripAnsi(r.toString())\n        , ansiLen = r.toString().length - strip.length\n        , spaceLength = colsize - strip.length + self.options.columnSpacing;\n      r = r.toString().substring(0, colsize + ansiLen); //compensate for ansi len\n      if (spaceLength < 0) {\n        spaceLength = 0;\n      }\n      var spaces = new Array(spaceLength).join(' ');\n      str += r + spaces;\n    });\n    return str;\n  };\n\n  var formatted = [];\n\n  table.data.forEach(function(d) {\n    var str = dataToString(d);\n    formatted.push(str);\n  });\n  this.setContent(dataToString(table.headers));\n  this.rows.setItems(formatted);\n};\n\nTable.prototype.getOptionsPrototype = function() {\n  return  { keys: true\n    , fg: 'white'\n    , interactive: false\n    , label: 'Active Processes'\n    , width: '30%'\n    , height: '30%'\n    , border: {type: 'line', fg: 'cyan'}\n    , columnSpacing: 10\n    , columnWidth: [16, 12]\n    , data: { headers: ['col1', 'col2']\n      , data: [ ['a', 'b']\n        , ['5', 'u']\n        , ['x', '16.1'] ]}\n  };\n};\n\nTable.prototype.type = 'table';\n\nmodule.exports = Table;\n"
  },
  {
    "path": "lib/widget/tree.js",
    "content": "'use strict';\nvar blessed = require('blessed'),\n  Node = blessed.Node,\n  Box = blessed.Box;\n\nfunction Tree(options) {\n  if (!(this instanceof Node)) {\n    return new Tree(options);\n  }\n\n  var self = this;\n  options = options || {};\n  options.bold = true;\n  this.options = options;\n  this.data = {};\n  this.nodeLines = [];\n  this.lineNbr = 0;\n  Box.call(this, options);\n\n  options.extended = options.extended || false;\n  options.keys = options.keys || ['+', 'space', 'enter'];\n\n  options.template = options.template || {};\n  options.template.extend = options.template.extend || ' [+]';\n  options.template.retract = options.template.retract || ' [-]';\n  options.template.lines = options.template.lines || false;\n\n  // Do not set height, since this create a bug where the first line is not always displayed\n  this.rows = blessed.list({\n    top: 1,\n    width: 0,\n    left: 1,\n    style: options.style,\n    padding: options.padding,\n    keys: true,\n    tags: options.tags,\n    input: options.input,\n    vi: options.vi,\n    ignoreKeys: options.ignoreKeys,\n    scrollable: options.scrollable,\n    mouse: options.mouse,\n    selectedBg: options.selectedBg || 'blue',\n    selectedFg: options.selectedFg || 'black',\n  });\n\n  this.append(this.rows);\n\n  this.rows.key(options.keys, function() {\n    var selectedNode = self.nodeLines[this.getItemIndex(this.selected)];\n    if (selectedNode.children) {\n      selectedNode.extended = !selectedNode.extended;\n      self.setData(self.data);\n      self.screen.render();\n    }\n\n    self.emit('select', selectedNode, this.getItemIndex(this.selected));\n  });\n\n}\n\nTree.prototype = Object.create(Box.prototype);\n\nTree.prototype.walk = function(node, treeDepth) {\n\n  var lines = [];\n\n  if (!node.parent) {\n    // root level\n    this.lineNbr = 0;\n    this.nodeLines.length = 0;\n    node.parent = null;\n  }\n\n  if (treeDepth === '' && node.name) {\n    this.lineNbr = 0;\n    this.nodeLines[this.lineNbr++] = node;\n    lines.push(node.name);\n    treeDepth = ' ';\n  }\n\n  node.depth = treeDepth.length - 1;\n\n  if (node.children && node.extended) {\n\n    var i = 0;\n\n    if (typeof node.children === 'function')\n      node.childrenContent = node.children(node);\n\n    if (!node.childrenContent)\n      node.childrenContent = node.children;\n\n    for (var child in node.childrenContent) {\n\n      if (!node.childrenContent[child].name)\n        node.childrenContent[child].name = child;\n\n      child = node.childrenContent[child];\n      child.parent = node;\n      child.position = i++;\n\n      if (typeof child.extended === 'undefined')\n        child.extended = this.options.extended;\n\n      if (typeof child.children === 'function')\n        child.childrenContent = child.children(child);\n      else\n        child.childrenContent = child.children;\n\n      var isLastChild = child.position === Object.keys(child.parent.childrenContent).length - 1;\n      var treePrefix;\n      var suffix = '';\n      if (isLastChild)\n        treePrefix = '└';\n      else\n        treePrefix = '├';\n\n      if (!child.childrenContent || Object.keys(child.childrenContent).length === 0) {\n        treePrefix += '─';\n      } else if (child.extended) {\n        treePrefix += '┬';\n        suffix = this.options.template.retract;\n      } else {\n        treePrefix += '─';\n        suffix = this.options.template.extend;\n      }\n\n      if (!this.options.template.lines) treePrefix = '|-';\n      if (this.options.template.spaces) treePrefix = ' ';\n\n      lines.push(treeDepth + treePrefix + child.name + suffix);\n\n      this.nodeLines[this.lineNbr++] = child;\n\n      var parentTree;\n      if (isLastChild || !this.options.template.lines)\n        parentTree = treeDepth + ' ';\n      else\n        parentTree = treeDepth + '│';\n\n      lines = lines.concat(this.walk(child, parentTree));\n    }\n  }\n  return lines;\n};\n\nTree.prototype.focus = function() {\n  this.rows.focus();\n};\n\nTree.prototype.render = function() {\n  if (this.screen.focused === this.rows) this.rows.focus();\n\n  this.rows.width = this.width - 3;\n  this.rows.height = this.height - 3;\n  Box.prototype.render.call(this);\n};\n\nTree.prototype.setData = function(nodes) {\n  this.data = nodes;\n  this.rows.setItems(this.walk(nodes, ''));\n};\n\nTree.prototype.type = 'tree';\n\nmodule.exports = Tree;\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"blessed-contrib\",\n  \"version\": \"4.11.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"types\": \"index.d.ts\",\n  \"scripts\": {\n    \"test\": \"npm run lint\",\n    \"lint\": \"eslint lib\",\n    \"lint:fix\": \"eslint lib --fix\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/yaronn/blessed-contrib.git\"\n  },\n  \"author\": \"Yaron Naveh (yaronn01@gmail.com)\",\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"@types/blessed\": \"^0.1.6\",\n    \"blessed\": \"0.1.54\",\n    \"colors\": \"^1.1.2\",\n    \"eslint\": \"^5.11.0\",\n    \"eslint-config-standard\": \"^12.0.0\",\n    \"eslint-plugin-import\": \"^2.14.0\",\n    \"eslint-plugin-node\": \"^8.0.0\",\n    \"eslint-plugin-promise\": \"^4.0.1\",\n    \"eslint-plugin-standard\": \"^4.0.0\"\n  },\n  \"dependencies\": {\n    \"ansi-term\": \">=0.0.2\",\n    \"chalk\": \"^1.1.0\",\n    \"drawille-canvas-blessed-contrib\": \">=0.1.3\",\n    \"lodash\": \"~>=4.17.21\",\n    \"map-canvas\": \">=0.1.5\",\n    \"marked\": \"^4.0.12\",\n    \"marked-terminal\": \"^5.1.1\",\n    \"memory-streams\": \"^0.1.0\",\n    \"memorystream\": \"^0.3.1\",\n    \"picture-tuber\": \"^1.0.1\",\n    \"sparkline\": \"^0.1.1\",\n    \"strip-ansi\": \"^3.0.0\",\n    \"term-canvas\": \"0.0.5\",\n    \"x256\": \">=0.0.1\"\n  }\n}\n"
  }
]