904118851 8 сар өмнө
parent
commit
cc35bda47a
100 өөрчлөгдсөн 16909 нэмэгдсэн , 804 устгасан
  1. 25 26
      0_RECEIVE_FACTORY/RECEIVE_FACTORY.js
  2. 17 56
      MAIN_SERVE_FACTORY/MAIN_SERVE_FACTORY.js
  3. 21 7
      MESSAGE_DISPATCH/MESSAGE_DISPATCH.js
  4. 9 1
      etc/config.json
  5. 36 12
      logs/combined.log
  6. 0 366
      logs/error.log
  7. 36 336
      logs/out.log
  8. 85 0
      node_modules/.package-lock.json
  9. 17 0
      node_modules/@acuminous/bitsyntax/.github/workflows/node-js-ci.yml
  10. 30 0
      node_modules/@acuminous/bitsyntax/.github/workflows/node-js-publish.yml
  11. 6 0
      node_modules/@acuminous/bitsyntax/LICENSE
  12. 21 0
      node_modules/@acuminous/bitsyntax/LICENSE-MIT
  13. 15 0
      node_modules/@acuminous/bitsyntax/Makefile
  14. 308 0
      node_modules/@acuminous/bitsyntax/README.md
  15. 10 0
      node_modules/@acuminous/bitsyntax/index.js
  16. 303 0
      node_modules/@acuminous/bitsyntax/lib/compile.js
  17. 142 0
      node_modules/@acuminous/bitsyntax/lib/constructor.js
  18. 67 0
      node_modules/@acuminous/bitsyntax/lib/grammar.pegjs
  19. 232 0
      node_modules/@acuminous/bitsyntax/lib/interp.js
  20. 32 0
      node_modules/@acuminous/bitsyntax/lib/parse.js
  21. 1173 0
      node_modules/@acuminous/bitsyntax/lib/parser.js
  22. 119 0
      node_modules/@acuminous/bitsyntax/lib/pattern.js
  23. 20 0
      node_modules/@acuminous/bitsyntax/node_modules/debug/LICENSE
  24. 481 0
      node_modules/@acuminous/bitsyntax/node_modules/debug/README.md
  25. 60 0
      node_modules/@acuminous/bitsyntax/node_modules/debug/package.json
  26. 271 0
      node_modules/@acuminous/bitsyntax/node_modules/debug/src/browser.js
  27. 274 0
      node_modules/@acuminous/bitsyntax/node_modules/debug/src/common.js
  28. 10 0
      node_modules/@acuminous/bitsyntax/node_modules/debug/src/index.js
  29. 263 0
      node_modules/@acuminous/bitsyntax/node_modules/debug/src/node.js
  30. 162 0
      node_modules/@acuminous/bitsyntax/node_modules/ms/index.js
  31. 21 0
      node_modules/@acuminous/bitsyntax/node_modules/ms/license.md
  32. 38 0
      node_modules/@acuminous/bitsyntax/node_modules/ms/package.json
  33. 59 0
      node_modules/@acuminous/bitsyntax/node_modules/ms/readme.md
  34. 21 0
      node_modules/@acuminous/bitsyntax/node_modules/safe-buffer/LICENSE
  35. 584 0
      node_modules/@acuminous/bitsyntax/node_modules/safe-buffer/README.md
  36. 187 0
      node_modules/@acuminous/bitsyntax/node_modules/safe-buffer/index.d.ts
  37. 62 0
      node_modules/@acuminous/bitsyntax/node_modules/safe-buffer/index.js
  38. 37 0
      node_modules/@acuminous/bitsyntax/node_modules/safe-buffer/package.json
  39. 36 0
      node_modules/@acuminous/bitsyntax/package.json
  40. 50 0
      node_modules/@acuminous/bitsyntax/test/consing.test.js
  41. 193 0
      node_modules/@acuminous/bitsyntax/test/matching.test.js
  42. 41 0
      node_modules/amqplib/.github/ISSUE_TEMPLATE/bug_report.md
  43. 59 0
      node_modules/amqplib/.github/workflows/publish.yml
  44. 51 0
      node_modules/amqplib/.github/workflows/test.yml
  45. 443 0
      node_modules/amqplib/CHANGELOG.md
  46. 6 0
      node_modules/amqplib/LICENSE
  47. 21 0
      node_modules/amqplib/LICENSE-MIT
  48. 49 0
      node_modules/amqplib/Makefile
  49. 156 0
      node_modules/amqplib/README.md
  50. 483 0
      node_modules/amqplib/bin/amqp-rabbitmq-0.9.1.json
  51. 722 0
      node_modules/amqplib/bin/generate-defs.js
  52. 22 0
      node_modules/amqplib/callback_api.js
  53. 16 0
      node_modules/amqplib/channel_api.js
  54. 22 0
      node_modules/amqplib/examples/direct_reply_to_client.js
  55. 25 0
      node_modules/amqplib/examples/direct_reply_to_server.js
  56. 40 0
      node_modules/amqplib/examples/headers.js
  57. 39 0
      node_modules/amqplib/examples/receive_generator.js
  58. 42 0
      node_modules/amqplib/examples/send_generators.js
  59. 70 0
      node_modules/amqplib/examples/ssl.js
  60. 40 0
      node_modules/amqplib/examples/stream_queues/README.md
  61. 14 0
      node_modules/amqplib/examples/stream_queues/package.json
  62. 55 0
      node_modules/amqplib/examples/stream_queues/receive_stream.js
  63. 38 0
      node_modules/amqplib/examples/stream_queues/send_stream.js
  64. 93 0
      node_modules/amqplib/examples/tutorials/README.md
  65. 28 0
      node_modules/amqplib/examples/tutorials/callback_api/emit_log.js
  66. 30 0
      node_modules/amqplib/examples/tutorials/callback_api/emit_log_direct.js
  67. 30 0
      node_modules/amqplib/examples/tutorials/callback_api/emit_log_topic.js
  68. 28 0
      node_modules/amqplib/examples/tutorials/callback_api/new_task.js
  69. 36 0
      node_modules/amqplib/examples/tutorials/callback_api/receive.js
  70. 42 0
      node_modules/amqplib/examples/tutorials/callback_api/receive_logs.js
  71. 57 0
      node_modules/amqplib/examples/tutorials/callback_api/receive_logs_direct.js
  72. 58 0
      node_modules/amqplib/examples/tutorials/callback_api/receive_logs_topic.js
  73. 51 0
      node_modules/amqplib/examples/tutorials/callback_api/rpc_client.js
  74. 55 0
      node_modules/amqplib/examples/tutorials/callback_api/rpc_server.js
  75. 28 0
      node_modules/amqplib/examples/tutorials/callback_api/send.js
  76. 39 0
      node_modules/amqplib/examples/tutorials/callback_api/worker.js
  77. 24 0
      node_modules/amqplib/examples/tutorials/emit_log.js
  78. 26 0
      node_modules/amqplib/examples/tutorials/emit_log_direct.js
  79. 26 0
      node_modules/amqplib/examples/tutorials/emit_log_topic.js
  80. 25 0
      node_modules/amqplib/examples/tutorials/new_task.js
  81. 16 0
      node_modules/amqplib/examples/tutorials/package.json
  82. 26 0
      node_modules/amqplib/examples/tutorials/receive.js
  83. 30 0
      node_modules/amqplib/examples/tutorials/receive_logs.js
  84. 38 0
      node_modules/amqplib/examples/tutorials/receive_logs_direct.js
  85. 39 0
      node_modules/amqplib/examples/tutorials/receive_logs_topic.js
  86. 49 0
      node_modules/amqplib/examples/tutorials/rpc_client.js
  87. 46 0
      node_modules/amqplib/examples/tutorials/rpc_server.js
  88. 31 0
      node_modules/amqplib/examples/tutorials/send.js
  89. 34 0
      node_modules/amqplib/examples/tutorials/worker.js
  90. 21 0
      node_modules/amqplib/examples/waitForConfirms.js
  91. 314 0
      node_modules/amqplib/lib/api_args.js
  92. 130 0
      node_modules/amqplib/lib/bitset.js
  93. 332 0
      node_modules/amqplib/lib/callback_model.js
  94. 506 0
      node_modules/amqplib/lib/channel.js
  95. 306 0
      node_modules/amqplib/lib/channel_model.js
  96. 345 0
      node_modules/amqplib/lib/codec.js
  97. 189 0
      node_modules/amqplib/lib/connect.js
  98. 675 0
      node_modules/amqplib/lib/connection.js
  99. 42 0
      node_modules/amqplib/lib/credentials.js
  100. 5077 0
      node_modules/amqplib/lib/defs.js

+ 25 - 26
0_RECEIVE_FACTORY/RECEIVE_FACTORY.js

@@ -3,7 +3,6 @@ const time_count = 250;
 const PROT = 9101
 var http = require('http');
 const redis_help = require('../src/use_redis');
-const moment = require('moment');
 const origin_data_controllers = require('../src/data_manager/Controllers/origin_data_controllers');
 var recv_data_list = []
 
@@ -29,30 +28,27 @@ async function processTask(){
         if(recv_data_list.length>0){
             const xml = recv_data_list.pop();
             let guajian_link = ''
-            let isGuaJian = parseInt(xml[是否挂件])==1
-            if(isGuaJian){
-                guajian_link = xml[挂件地址]
-                const result = await origin_data_controllers.getOriginData({video_id:xml[视频id]})
-                if(result.success){
-                    await origin_data_controllers.updateOriginData({video_id:xml[视频id]},{kepp_num:xml[收藏数],comment_num:xml[评论数],like_num:xml[点赞数],shared_num:xml[分享数],guajian_link:guajian_link})
-                }else{
-                    await origin_data_controllers.createOriginData(
-                        {
-                            video_id:xml[视频id],
-                            video_link:xml[视频链接],
-                            title:xml[标题],
-                            // publish_time:xml[发布时间],
-                            publish_time:excelDateToJs(xml[发布时间]),
-                            kepp_num:xml[收藏数],
-                            comment_num:xml[评论数],
-                            like_num:xml[点赞数],
-                            shared_num:xml[分享数],
-                            is_guajian:xml[是否挂件],
-                            guajian_link:guajian_link,
-                            status:0,
-                        }
-                    )
-                }
+            guajian_link = xml[挂件地址]
+            const result = await origin_data_controllers.getOriginData({video_id:xml[视频id]})
+            if(result.success){
+                await origin_data_controllers.updateOriginData({video_id:xml[视频id]},{kepp_num:xml[收藏数],comment_num:xml[评论数],like_num:xml[点赞数],shared_num:xml[分享数],guajian_link:guajian_link})
+            }else{
+                await origin_data_controllers.createOriginData(
+                    {
+                        video_id:xml[视频id],
+                        video_link:xml[视频链接],
+                        title:xml[标题],
+                        // publish_time:xml[发布时间],
+                        publish_time:excelDateToJs(xml[发布时间]),
+                        kepp_num:xml[收藏数],
+                        comment_num:xml[评论数],
+                        like_num:xml[点赞数],
+                        shared_num:xml[分享数],
+                        is_guajian:xml[是否挂件],
+                        guajian_link:guajian_link,
+                        status:0,
+                    }
+                )
             }
         }else{
             task_status = false;
@@ -67,7 +63,10 @@ CMD.startTask = function(data){
     task_status = true;
     let temp_list = JSON.parse(data)
     for (let index = 1; index < temp_list.length; index++) {
-        recv_data_list.push(temp_list[index])
+        let isGuaJian = parseInt(temp_list[index][是否挂件])==1
+        if(isGuaJian){
+            recv_data_list.push(temp_list[index])
+        }
     }
     console.log("temp_list.length:",temp_list.length)
     processTask()

+ 17 - 56
MAIN_SERVE_FACTORY/MAIN_SERVE_FACTORY.js

@@ -1,13 +1,27 @@
 const CMD = {}
-const PROT = 9111
-var http = require('http');
 const redis_help = require('../src/use_redis');
 const video_applet_product_controllers = require('../src/data_manager/Controllers/video_applet_product_controllers');
+const rabbitMq = require('../src/mq/rabbit-mq');
 
-CMD.init = function(){
+
+const messageHandler = async (msg) => {
+    CMD.start_task(msg['data']['data'])
+};
+
+// 启动消费者
+async function startConsumer() {
+    try {
+        await rabbitMq.consumerDirectMsg(messageHandler,"exchange_system","addMain");
+    } catch (error) {
+        console.error('启动消费者失败:', error);
+    }
+}
+
+CMD.init = async function(){
     redis_help.connect(()=>{
 
     })
+    await startConsumer();
 }
 
 
@@ -60,57 +74,4 @@ CMD.start_task = async function(msgBody){
     }
 }
 
-
-var server = http.createServer(function(req,res){
-
-    res.setHeader('Access-Control-Allow-Origin', '*'); // 允许所有域的请求,注意:在生产环境中应该限制为特定的域
-    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); // 允许的方法
-    res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); // 允许的头部
-    
-    let body = '';
-
-    // 监听数据块
-    req.on('data', chunk => {
-        body += chunk.toString(); // 将接收到的数据块转换为字符串并拼接
-    });
-
-    // 监听请求结束
-    req.on('end', async () => {
-        
-        if (req.method === 'POST') {
-            if (req.headers['content-type'] === 'application/json') {
-                try {
-                    // 解析 JSON 数据
-                    const jsonData = JSON.parse(body);
-                    console.log("recv msg:",jsonData)
-                    if(jsonData['fun']=="addMain"&&jsonData['cmd']=="filter_task"){
-                        CMD.start_task(jsonData['data']['data'])
-                        res.writeHead(200, {'Content-Type': 'application/json'});
-                        res.end(JSON.stringify({ msg: 'success!',code:10000,data:{}}));
-                    }else{
-                        res.writeHead(200, {'Content-Type': 'application/json'});
-                        res.end(JSON.stringify({ message: 'fun 错误',code:100}));
-                    }
-                } catch (error) {
-                    // 处理解析错误
-                    console.error('Error parsing JSON:', error);
-                    res.writeHead(200, {'Content-Type': 'application/json'});
-                    res.end(JSON.stringify({ error: 'Invalid JSON' }));
-                }
-            } else {
-                // 如果不是 JSON 内容类型,返回错误
-                res.writeHead(200, {'Content-Type': 'text/plain'});
-                res.end('Unsupported Media Type. Please send data as JSON.');
-            }
-        }else{
-            res.writeHead(200, {'Content-Type': 'text/plain'});
-            res.end(' Please Use Post.');
-        }
-        
-    });
-
-})
-server.listen(PROT,()=>{
-
-});  
 CMD.init()

+ 21 - 7
MESSAGE_DISPATCH/MESSAGE_DISPATCH.js

@@ -5,6 +5,7 @@ const redis_help = require('../src/use_redis');
 var axios = require('axios');
 const HttpClient = require('../src/HttpClient');
 const WebSocketClient = require('../src/WebSocketClient');
+const rabbitMq = require('../src/mq/rabbit-mq');
 console.log("运行 MESSAGE_DISPATCH")
 CMD.updateFilterConfig = async function(){
     const postData = {
@@ -96,6 +97,18 @@ function sendMessage(cmd,data){
         }
     }
 }
+async function sendMQMessage(message,routingKey = null) {
+    try {
+        if(routingKey!=null){
+            await rabbitMq.producerDirectMsg( message,"exchange_system",routingKey);
+        }else{
+            await rabbitMq.producerDirectMsg( message,"exchange_system");
+        }
+        console.log('消息发送成功');
+    } catch (error) {
+        console.error('发送消息失败:', error);
+    }
+}
 
 async function recvMessage(data){
     try {
@@ -121,13 +134,14 @@ async function recvMessage(data){
                     fun:json_msg.cmd,
                     data:json_msg
                 };
-                const client = new HttpClient({
-                    timeout: 5000,
-                    // headers: {
-                    //     'User-Agent': 'Custom User Agent'
-                    // }
-                });
-                const response = await client.post('http://127.0.0.1:9111',postData);
+                sendMQMessage(postData,json_msg.cmd)
+                // const client = new HttpClient({
+                //     timeout: 5000,
+                //     // headers: {
+                //     //     'User-Agent': 'Custom User Agent'
+                //     // }
+                // });
+                // const response = await client.post('http://127.0.0.1:9111',postData);
             break;
         }
         }catch(e){

+ 9 - 1
etc/config.json

@@ -1,5 +1,5 @@
 {
-    "isDebug":false,
+    "isDebug":true,
     "redis_config": {
         "host": "127.0.0.1",
         "port": 6379
@@ -63,5 +63,13 @@
     },
     "release_supdate_config":{
         "host":"http://192.168.0.165:9606"
+    },
+    "amqplib_config":{
+        "protocol": "amqp",
+        "hostname": "localhost",
+        "port": 5672,
+        "username": "admin",
+        "password": "123",
+        "vhost": "/"
     }
 }

+ 36 - 12
logs/combined.log

@@ -1,12 +1,36 @@
-2024-12-05T20:54:06: 
-2024-12-05T20:54:06: > heiyan@1.0.0 start
-2024-12-05T20:54:06: > node tg_factory_main.js
-2024-12-05T20:54:06: 
-2024-12-05T20:54:11: Connected to Redis
-2024-12-05T20:54:11: results: false
-2024-12-05T20:59:02: 
-2024-12-05T20:59:02: > heiyan@1.0.0 start
-2024-12-05T20:59:02: > node tg_factory_main.js
-2024-12-05T20:59:02: 
-2024-12-05T20:59:06: Connected to Redis
-2024-12-05T20:59:06: results: false
+2024-12-06T11:49:43: 
+2024-12-06T11:49:43: > heiyan@1.0.0 start
+2024-12-06T11:49:43: > node tg_factory_main.js
+2024-12-06T11:49:43: 
+2024-12-06T11:49:47: Connected to Redis
+2024-12-06T11:49:47: results: false
+2024-12-06T11:51:28: 
+2024-12-06T11:51:28: > heiyan@1.0.0 start
+2024-12-06T11:51:28: > node tg_factory_main.js
+2024-12-06T11:51:28: 
+2024-12-06T11:51:32: Connected to Redis
+2024-12-06T11:51:32: results: false
+2024-12-06T11:56:04: 
+2024-12-06T11:56:04: > heiyan@1.0.0 start
+2024-12-06T11:56:04: > node tg_factory_main.js
+2024-12-06T11:56:04: 
+2024-12-06T11:56:08: Connected to Redis
+2024-12-06T11:56:08: results: false
+2024-12-06T11:58:33: 
+2024-12-06T11:58:33: > heiyan@1.0.0 start
+2024-12-06T11:58:33: > node tg_factory_main.js
+2024-12-06T11:58:33: 
+2024-12-06T11:58:38: Connected to Redis
+2024-12-06T11:58:38: results: false
+2024-12-06T12:01:04: 
+2024-12-06T12:01:04: > heiyan@1.0.0 start
+2024-12-06T12:01:04: > node tg_factory_main.js
+2024-12-06T12:01:04: 
+2024-12-06T12:01:08: Connected to Redis
+2024-12-06T12:01:08: results: false
+2024-12-06T12:31:22: 
+2024-12-06T12:31:22: > heiyan@1.0.0 start
+2024-12-06T12:31:22: > node tg_factory_main.js
+2024-12-06T12:31:22: 
+2024-12-06T12:31:26: Connected to Redis
+2024-12-06T12:31:26: results: false

+ 0 - 366
logs/error.log

@@ -1,366 +0,0 @@
-2024-12-05T19:48:59: 2024-12-05T19:53:44: 2024-12-05T20:20:04: [0_RECEIVE_FACTORY] 错误: Error [ERR_IPC_CHANNEL_CLOSED]: Channel closed
-2024-12-05T20:20:04:     at target.send (node:internal/child_process:754:16)
-2024-12-05T20:20:04:     at /home/tg_factory/ProcessManager.js:142:25
-2024-12-05T20:20:04:     at Array.map (<anonymous>)
-2024-12-05T20:20:04:     at ProcessManager.shutdown (/home/tg_factory/ProcessManager.js:139:69)
-2024-12-05T20:20:04:     at process.<anonymous> (/home/tg_factory/ProcessManager.js:57:41)
-2024-12-05T20:20:04:     at process.emit (node:events:519:28) {
-2024-12-05T20:20:04:   code: 'ERR_IPC_CHANNEL_CLOSED'
-2024-12-05T20:20:04: }
-2024-12-05T20:20:04: [1_FILTER_FACTORY] 错误: Error [ERR_IPC_CHANNEL_CLOSED]: Channel closed
-2024-12-05T20:20:04:     at target.send (node:internal/child_process:754:16)
-2024-12-05T20:20:04:     at /home/tg_factory/ProcessManager.js:142:25
-2024-12-05T20:20:04:     at Array.map (<anonymous>)
-2024-12-05T20:20:04:     at ProcessManager.shutdown (/home/tg_factory/ProcessManager.js:139:69)
-2024-12-05T20:20:04:     at process.<anonymous> (/home/tg_factory/ProcessManager.js:57:41)
-2024-12-05T20:20:04:     at process.emit (node:events:519:28) {
-2024-12-05T20:20:04:   code: 'ERR_IPC_CHANNEL_CLOSED'
-2024-12-05T20:20:04: }
-2024-12-05T20:20:04: [2_PRODUCT_FACTORY] 错误: Error [ERR_IPC_CHANNEL_CLOSED]: Channel closed
-2024-12-05T20:20:04:     at target.send (node:internal/child_process:754:16)
-2024-12-05T20:20:04:     at /home/tg_factory/ProcessManager.js:142:25
-2024-12-05T20:20:04:     at Array.map (<anonymous>)
-2024-12-05T20:20:04:     at ProcessManager.shutdown (/home/tg_factory/ProcessManager.js:139:69)
-2024-12-05T20:20:04:     at process.<anonymous> (/home/tg_factory/ProcessManager.js:57:41)
-2024-12-05T20:20:04:     at process.emit (node:events:519:28) {
-2024-12-05T20:20:04:   code: 'ERR_IPC_CHANNEL_CLOSED'
-2024-12-05T20:20:04: }
-2024-12-05T20:20:04: [7_CHECK_AND_CREATE_URL_FACTORY] 错误: Error [ERR_IPC_CHANNEL_CLOSED]: Channel closed
-2024-12-05T20:20:04:     at target.send (node:internal/child_process:754:16)
-2024-12-05T20:20:04:     at /home/tg_factory/ProcessManager.js:142:25
-2024-12-05T20:20:04:     at Array.map (<anonymous>)
-2024-12-05T20:20:04:     at ProcessManager.shutdown (/home/tg_factory/ProcessManager.js:139:69)
-2024-12-05T20:20:04:     at process.<anonymous> (/home/tg_factory/ProcessManager.js:57:41)
-2024-12-05T20:20:04:     at process.emit (node:events:519:28) {
-2024-12-05T20:20:04:   code: 'ERR_IPC_CHANNEL_CLOSED'
-2024-12-05T20:20:04: }
-2024-12-05T20:52:51: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:52:51:         main()
-2024-12-05T20:52:51:         ^
-2024-12-05T20:52:51: 
-2024-12-05T20:52:51: ReferenceError: main is not defined
-2024-12-05T20:52:51:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:52:51:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:52:51:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:52:51: 
-2024-12-05T20:52:51: Node.js v20.17.0
-2024-12-05T20:52:53: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:52:53:         main()
-2024-12-05T20:52:53:         ^
-2024-12-05T20:52:53: 
-2024-12-05T20:52:53: ReferenceError: main is not defined
-2024-12-05T20:52:53:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:52:53:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:52:53:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:52:53: 
-2024-12-05T20:52:53: Node.js v20.17.0
-2024-12-05T20:52:54: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:52:54:         main()
-2024-12-05T20:52:54:         ^
-2024-12-05T20:52:54: 
-2024-12-05T20:52:54: ReferenceError: main is not defined
-2024-12-05T20:52:54:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:52:54:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:52:54:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:52:54: 
-2024-12-05T20:52:54: Node.js v20.17.0
-2024-12-05T20:52:56: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:52:56:         main()
-2024-12-05T20:52:56:         ^
-2024-12-05T20:52:56: 
-2024-12-05T20:52:56: ReferenceError: main is not defined
-2024-12-05T20:52:56:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:52:56:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:52:56:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:52:56: 
-2024-12-05T20:52:56: Node.js v20.17.0
-2024-12-05T20:52:57: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:52:57:         main()
-2024-12-05T20:52:57:         ^
-2024-12-05T20:52:57: 
-2024-12-05T20:52:57: ReferenceError: main is not defined
-2024-12-05T20:52:57:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:52:57:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:52:57:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:52:57: 
-2024-12-05T20:52:57: Node.js v20.17.0
-2024-12-05T20:52:58: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:52:58:         main()
-2024-12-05T20:52:58:         ^
-2024-12-05T20:52:58: 
-2024-12-05T20:52:58: ReferenceError: main is not defined
-2024-12-05T20:52:58:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:52:58:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:52:58:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:52:58: 
-2024-12-05T20:52:58: Node.js v20.17.0
-2024-12-05T20:53:00: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:00:         main()
-2024-12-05T20:53:00:         ^
-2024-12-05T20:53:00: 
-2024-12-05T20:53:00: ReferenceError: main is not defined
-2024-12-05T20:53:00:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:00:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:00:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:00: 
-2024-12-05T20:53:00: Node.js v20.17.0
-2024-12-05T20:53:01: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:01:         main()
-2024-12-05T20:53:01:         ^
-2024-12-05T20:53:01: 
-2024-12-05T20:53:01: ReferenceError: main is not defined
-2024-12-05T20:53:01:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:01:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:01:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:01: 
-2024-12-05T20:53:01: Node.js v20.17.0
-2024-12-05T20:53:02: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:02:         main()
-2024-12-05T20:53:02:         ^
-2024-12-05T20:53:02: 
-2024-12-05T20:53:02: ReferenceError: main is not defined
-2024-12-05T20:53:02:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:02:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:02:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:02: 
-2024-12-05T20:53:02: Node.js v20.17.0
-2024-12-05T20:53:04: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:04:         main()
-2024-12-05T20:53:04:         ^
-2024-12-05T20:53:04: 
-2024-12-05T20:53:04: ReferenceError: main is not defined
-2024-12-05T20:53:04:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:04:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:04:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:04: 
-2024-12-05T20:53:04: Node.js v20.17.0
-2024-12-05T20:53:05: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:05:         main()
-2024-12-05T20:53:05:         ^
-2024-12-05T20:53:05: 
-2024-12-05T20:53:05: ReferenceError: main is not defined
-2024-12-05T20:53:05:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:05:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:05:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:05: 
-2024-12-05T20:53:05: Node.js v20.17.0
-2024-12-05T20:53:07: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:07:         main()
-2024-12-05T20:53:07:         ^
-2024-12-05T20:53:07: 
-2024-12-05T20:53:07: ReferenceError: main is not defined
-2024-12-05T20:53:07:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:07:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:07:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:07: 
-2024-12-05T20:53:07: Node.js v20.17.0
-2024-12-05T20:53:08: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:08:         main()
-2024-12-05T20:53:08:         ^
-2024-12-05T20:53:08: 
-2024-12-05T20:53:08: ReferenceError: main is not defined
-2024-12-05T20:53:08:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:08:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:08:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:08: 
-2024-12-05T20:53:08: Node.js v20.17.0
-2024-12-05T20:53:09: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:09:         main()
-2024-12-05T20:53:09:         ^
-2024-12-05T20:53:09: 
-2024-12-05T20:53:09: ReferenceError: main is not defined
-2024-12-05T20:53:09:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:09:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:09:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:09: 
-2024-12-05T20:53:09: Node.js v20.17.0
-2024-12-05T20:53:10: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:10:         main()
-2024-12-05T20:53:10:         ^
-2024-12-05T20:53:10: 
-2024-12-05T20:53:10: ReferenceError: main is not defined
-2024-12-05T20:53:10:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:10:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:10:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:10: 
-2024-12-05T20:53:10: Node.js v20.17.0
-2024-12-05T20:53:12: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:12:         main()
-2024-12-05T20:53:12:         ^
-2024-12-05T20:53:12: 
-2024-12-05T20:53:12: ReferenceError: main is not defined
-2024-12-05T20:53:12:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:12:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:12:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:12: 
-2024-12-05T20:53:12: Node.js v20.17.0
-2024-12-05T20:53:13: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:13:         main()
-2024-12-05T20:53:13:         ^
-2024-12-05T20:53:13: 
-2024-12-05T20:53:13: ReferenceError: main is not defined
-2024-12-05T20:53:13:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:13:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:13:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:13: 
-2024-12-05T20:53:13: Node.js v20.17.0
-2024-12-05T20:53:14: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:14:         main()
-2024-12-05T20:53:14:         ^
-2024-12-05T20:53:14: 
-2024-12-05T20:53:14: ReferenceError: main is not defined
-2024-12-05T20:53:14:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:14:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:14:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:14: 
-2024-12-05T20:53:14: Node.js v20.17.0
-2024-12-05T20:53:16: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:16:         main()
-2024-12-05T20:53:16:         ^
-2024-12-05T20:53:16: 
-2024-12-05T20:53:16: ReferenceError: main is not defined
-2024-12-05T20:53:16:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:16:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:16:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:16: 
-2024-12-05T20:53:16: Node.js v20.17.0
-2024-12-05T20:53:17: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:17:         main()
-2024-12-05T20:53:17:         ^
-2024-12-05T20:53:17: 
-2024-12-05T20:53:17: ReferenceError: main is not defined
-2024-12-05T20:53:17:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:17:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:17:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:17: 
-2024-12-05T20:53:17: Node.js v20.17.0
-2024-12-05T20:53:18: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:18:         main()
-2024-12-05T20:53:18:         ^
-2024-12-05T20:53:18: 
-2024-12-05T20:53:18: ReferenceError: main is not defined
-2024-12-05T20:53:18:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:18:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:18:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:18: 
-2024-12-05T20:53:18: Node.js v20.17.0
-2024-12-05T20:53:20: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:20:         main()
-2024-12-05T20:53:20:         ^
-2024-12-05T20:53:20: 
-2024-12-05T20:53:20: ReferenceError: main is not defined
-2024-12-05T20:53:20:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:20:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:20:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:20: 
-2024-12-05T20:53:20: Node.js v20.17.0
-2024-12-05T20:53:21: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:21:         main()
-2024-12-05T20:53:21:         ^
-2024-12-05T20:53:21: 
-2024-12-05T20:53:21: ReferenceError: main is not defined
-2024-12-05T20:53:21:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:21:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:21:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:21: 
-2024-12-05T20:53:21: Node.js v20.17.0
-2024-12-05T20:53:22: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:22:         main()
-2024-12-05T20:53:22:         ^
-2024-12-05T20:53:22: 
-2024-12-05T20:53:22: ReferenceError: main is not defined
-2024-12-05T20:53:22:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:22:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:22:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:22: 
-2024-12-05T20:53:22: Node.js v20.17.0
-2024-12-05T20:53:24: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:24:         main()
-2024-12-05T20:53:24:         ^
-2024-12-05T20:53:24: 
-2024-12-05T20:53:24: ReferenceError: main is not defined
-2024-12-05T20:53:24:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:24:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:24:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:24: 
-2024-12-05T20:53:24: Node.js v20.17.0
-2024-12-05T20:53:25: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:25:         main()
-2024-12-05T20:53:25:         ^
-2024-12-05T20:53:25: 
-2024-12-05T20:53:25: ReferenceError: main is not defined
-2024-12-05T20:53:25:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:25:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:25:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:25: 
-2024-12-05T20:53:25: Node.js v20.17.0
-2024-12-05T20:53:27: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:27:         main()
-2024-12-05T20:53:27:         ^
-2024-12-05T20:53:27: 
-2024-12-05T20:53:27: ReferenceError: main is not defined
-2024-12-05T20:53:27:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:27:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:27:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:27: 
-2024-12-05T20:53:27: Node.js v20.17.0
-2024-12-05T20:53:28: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:28:         main()
-2024-12-05T20:53:28:         ^
-2024-12-05T20:53:28: 
-2024-12-05T20:53:28: ReferenceError: main is not defined
-2024-12-05T20:53:28:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:28:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:28:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:28: 
-2024-12-05T20:53:28: Node.js v20.17.0
-2024-12-05T20:53:29: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:29:         main()
-2024-12-05T20:53:29:         ^
-2024-12-05T20:53:29: 
-2024-12-05T20:53:29: ReferenceError: main is not defined
-2024-12-05T20:53:29:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:29:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:29:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:29: 
-2024-12-05T20:53:29: Node.js v20.17.0
-2024-12-05T20:53:31: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:31:         main()
-2024-12-05T20:53:31:         ^
-2024-12-05T20:53:31: 
-2024-12-05T20:53:31: ReferenceError: main is not defined
-2024-12-05T20:53:31:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:31:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:31:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:31: 
-2024-12-05T20:53:31: Node.js v20.17.0
-2024-12-05T20:53:32: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:32:         main()
-2024-12-05T20:53:32:         ^
-2024-12-05T20:53:32: 
-2024-12-05T20:53:32: ReferenceError: main is not defined
-2024-12-05T20:53:32:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:32:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:32:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:32: 
-2024-12-05T20:53:32: Node.js v20.17.0
-2024-12-05T20:53:34: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:34:         main()
-2024-12-05T20:53:34:         ^
-2024-12-05T20:53:34: 
-2024-12-05T20:53:34: ReferenceError: main is not defined
-2024-12-05T20:53:34:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:34:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:34:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:34: 
-2024-12-05T20:53:34: Node.js v20.17.0
-2024-12-05T20:53:35: /home/tg_factory/tg_factory_main.js:10
-2024-12-05T20:53:35:         main()
-2024-12-05T20:53:35:         ^
-2024-12-05T20:53:35: 
-2024-12-05T20:53:35: ReferenceError: main is not defined
-2024-12-05T20:53:35:     at /home/tg_factory/tg_factory_main.js:10:9
-2024-12-05T20:53:35:     at /home/tg_factory/src/use_redis.js:62:17
-2024-12-05T20:53:35:     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
-2024-12-05T20:53:35: 
-2024-12-05T20:53:35: Node.js v20.17.0

+ 36 - 336
logs/out.log

@@ -1,336 +1,36 @@
-2024-12-05T19:47:58: 
-> heiyan@1.0.0 start
-> node tg_factory_main.js
-
-2024-12-05T19:48:59: 2024-12-05T19:49:24: 
-> heiyan@1.0.0 start
-> node tg_factory_main.js
-
-2024-12-05T19:53:44: 2024-12-05T19:53:59: 
-> heiyan@1.0.0 start
-> node tg_factory_main.js
-
-2024-12-05T20:13:33: 
-> heiyan@1.0.0 start
-> node tg_factory_main.js
-
-2024-12-05T20:16:16: 
-> heiyan@1.0.0 start
-> node tg_factory_main.js
-
-2024-12-05T20:16:43: 
-2024-12-05T20:16:43: > heiyan@1.0.0 start
-2024-12-05T20:16:43: > node tg_factory_main.js
-2024-12-05T20:16:43: 
-2024-12-05T20:16:43: Connected to Redis
-2024-12-05T20:16:43: results: false
-2024-12-05T20:17:49: 
-2024-12-05T20:17:49: > heiyan@1.0.0 start
-2024-12-05T20:17:49: > node tg_factory_main.js
-2024-12-05T20:17:49: 
-2024-12-05T20:17:50: Connected to Redis
-2024-12-05T20:17:50: [0_RECEIVE_FACTORY] 已启动,PID: 21743
-2024-12-05T20:17:50: [1_FILTER_FACTORY] 已启动,PID: 21744
-2024-12-05T20:17:50: [2_PRODUCT_FACTORY] 已启动,PID: 21750
-2024-12-05T20:17:50: [5_CREATE_LINK_FACTORY] 已启动,PID: 21752
-2024-12-05T20:17:50: [7_CHECK_AND_CREATE_URL_FACTORY] 已启动,PID: 21759
-2024-12-05T20:17:50: [MESSAGE_DISPATCH] 已启动,PID: 21766
-2024-12-05T20:17:50: results: false
-2024-12-05T20:17:52: 运行检测链接生成程序:suc
-2024-12-05T20:17:52: send_data_server:sql_task_help
-2024-12-05T20:17:52: Connected to the MySQL server.
-2024-12-05T20:17:53: 运行创建链接程序:suc
-2024-12-05T20:17:54: Connected to Redis
-2024-12-05T20:17:54: 运行筛选程序:suc
-2024-12-05T20:17:54: MySQL pool initialized
-2024-12-05T20:17:54: MySQL pool initialized
-2024-12-05T20:17:54: Connected to Redis
-2024-12-05T20:17:54: 运行接收数据程序:suc
-2024-12-05T20:17:54: Connected to Redis
-2024-12-05T20:17:54: 运行 MESSAGE_DISPATCH
-2024-12-05T20:17:54: 运行消息中心程序:suc
-2024-12-05T20:17:54: 运行书籍筛选程序:suc
-2024-12-05T20:17:54: Connected to Redis
-2024-12-05T20:17:54: MySQL pool initialized
-2024-12-05T20:17:54: Connected to Redis
-2024-12-05T20:17:54: WebSocket connected
-2024-12-05T20:17:55: Received: {"cmd":"updateAppConfig"}
-2024-12-05T20:17:55: recvMessage: updateAppConfig
-2024-12-05T20:17:55: Received: {"cmd":"updateFilterConfig"}
-2024-12-05T20:17:55: recvMessage: updateFilterConfig
-2024-12-05T20:17:55: Received: {"cmd":"updateMainConfig"}
-2024-12-05T20:17:55: recvMessage: updateMainConfig
-2024-12-05T20:17:55: Received: {"cmd":"updatePlatformConfig"}
-2024-12-05T20:17:55: recvMessage: updatePlatformConfig
-2024-12-05T20:17:55: 登录成功
-2024-12-05T20:17:55: hei_yan_token: eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyaWQiOiIxMDg0NyIsImxvZ2luX3VzZXJfa2V5IjoiNzFmZjQ5Y2YtZDZmNi00Njc2LWFhOTYtZjI3YzM1OTFhNWFiIn0.fKA_TmrxzJ4rYkQbj3mCdrahnI7iN-HuqGf8Rh-pstgR6TEFNvLEIaKzcztyaGNZcVrnwBmL1q-caWtte1z4Bw
-2024-12-05T20:18:24: Received: pong
-2024-12-05T20:18:54: Received: pong
-2024-12-05T20:19:24: Received: pong
-2024-12-05T20:19:54: Received: pong
-2024-12-05T20:20:04: 开始关闭所有工作进程...
-2024-12-05T20:20:04: 正在关闭 0_RECEIVE_FACTORY...
-2024-12-05T20:20:04: 正在关闭 1_FILTER_FACTORY...
-2024-12-05T20:20:04: 正在关闭 2_PRODUCT_FACTORY...
-2024-12-05T20:20:04: 正在关闭 5_CREATE_LINK_FACTORY...
-2024-12-05T20:20:04: 正在关闭 7_CHECK_AND_CREATE_URL_FACTORY...
-2024-12-05T20:20:04: 正在关闭 MESSAGE_DISPATCH...
-2024-12-05T20:20:04: 开始关闭所有工作进程...
-2024-12-05T20:20:04: 正在关闭 0_RECEIVE_FACTORY...
-2024-12-05T20:20:04: 正在关闭 1_FILTER_FACTORY...
-2024-12-05T20:20:04: 正在关闭 2_PRODUCT_FACTORY...
-2024-12-05T20:20:04: 正在关闭 5_CREATE_LINK_FACTORY...
-2024-12-05T20:20:04: 正在关闭 7_CHECK_AND_CREATE_URL_FACTORY...
-2024-12-05T20:20:04: 正在关闭 MESSAGE_DISPATCH...
-2024-12-05T20:20:04: [0_RECEIVE_FACTORY] 退出,代码: null, 信号: SIGINT
-2024-12-05T20:20:04: [1_FILTER_FACTORY] 退出,代码: null, 信号: SIGINT
-2024-12-05T20:20:04: [2_PRODUCT_FACTORY] 退出,代码: null, 信号: SIGINT
-2024-12-05T20:20:04: [5_CREATE_LINK_FACTORY] 退出,代码: null, 信号: SIGINT
-2024-12-05T20:20:04: [7_CHECK_AND_CREATE_URL_FACTORY] 退出,代码: null, 信号: SIGINT
-2024-12-05T20:20:04: [MESSAGE_DISPATCH] 退出,代码: null, 信号: SIGINT
-2024-12-05T20:20:04: 所有工作进程已关闭
-2024-12-05T20:20:08: 
-2024-12-05T20:20:08: > heiyan@1.0.0 start
-2024-12-05T20:20:08: > node tg_factory_main.js
-2024-12-05T20:20:08: 
-2024-12-05T20:20:09: Connected to Redis
-2024-12-05T20:20:09: [0_RECEIVE_FACTORY] 已启动,PID: 21925
-2024-12-05T20:20:09: [1_FILTER_FACTORY] 已启动,PID: 21931
-2024-12-05T20:20:09: [2_PRODUCT_FACTORY] 已启动,PID: 21932
-2024-12-05T20:20:09: [5_CREATE_LINK_FACTORY] 已启动,PID: 21940
-2024-12-05T20:20:09: [7_CHECK_AND_CREATE_URL_FACTORY] 已启动,PID: 21946
-2024-12-05T20:20:09: [MESSAGE_DISPATCH] 已启动,PID: 21953
-2024-12-05T20:20:09: results: false
-2024-12-05T20:20:10: 运行检测链接生成程序:suc
-2024-12-05T20:20:10: send_data_server:sql_task_help
-2024-12-05T20:20:10: Connected to the MySQL server.
-2024-12-05T20:20:11: 运行接收数据程序:suc
-2024-12-05T20:20:11: Connected to Redis
-2024-12-05T20:20:12: 运行书籍筛选程序:suc
-2024-12-05T20:20:12: Connected to Redis
-2024-12-05T20:20:12: MySQL pool initialized
-2024-12-05T20:20:12: 运行筛选程序:suc
-2024-12-05T20:20:12: MySQL pool initialized
-2024-12-05T20:20:12: Connected to Redis
-2024-12-05T20:20:13: 运行创建链接程序:suc
-2024-12-05T20:20:13: 运行 MESSAGE_DISPATCH
-2024-12-05T20:20:13: 运行消息中心程序:suc
-2024-12-05T20:20:13: Connected to Redis
-2024-12-05T20:20:13: MySQL pool initialized
-2024-12-05T20:20:13: Connected to Redis
-2024-12-05T20:20:13: WebSocket connected
-2024-12-05T20:20:13: Received: {"cmd":"updateAppConfig"}
-2024-12-05T20:20:13: recvMessage: updateAppConfig
-2024-12-05T20:20:13: Received: {"cmd":"updateFilterConfig"}
-2024-12-05T20:20:13: recvMessage: updateFilterConfig
-2024-12-05T20:20:13: Received: {"cmd":"updateMainConfig"}
-2024-12-05T20:20:13: recvMessage: updateMainConfig
-2024-12-05T20:20:13: Received: {"cmd":"updatePlatformConfig"}
-2024-12-05T20:20:13: recvMessage: updatePlatformConfig
-2024-12-05T20:20:14: 登录成功
-2024-12-05T20:20:14: hei_yan_token: eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyaWQiOiIxMDg0NyIsImxvZ2luX3VzZXJfa2V5IjoiYTk1MDU3ZGItNWU0NS00NWVlLTg1YmMtNGI4YTA5Y2I0NWM4In0.DpaTx_YNcgOh5UBrl3dWykG1TutJsKCvj4D3T6lIaST_jH3F64fkyAf0luupfLASiSP6kiI23DWzlFhxwivOBQ
-2024-12-05T20:20:43: Received: pong
-2024-12-05T20:20:50: 开始关闭所有工作进程...
-2024-12-05T20:20:50: 正在关闭 0_RECEIVE_FACTORY...
-2024-12-05T20:20:50: 正在关闭 1_FILTER_FACTORY...
-2024-12-05T20:20:50: 正在关闭 2_PRODUCT_FACTORY...
-2024-12-05T20:20:50: 正在关闭 5_CREATE_LINK_FACTORY...
-2024-12-05T20:20:50: 正在关闭 7_CHECK_AND_CREATE_URL_FACTORY...
-2024-12-05T20:20:50: 正在关闭 MESSAGE_DISPATCH...
-2024-12-05T20:20:50: 开始关闭所有工作进程...
-2024-12-05T20:20:50: 正在关闭 0_RECEIVE_FACTORY...
-2024-12-05T20:20:50: 正在关闭 1_FILTER_FACTORY...
-2024-12-05T20:20:50: 正在关闭 2_PRODUCT_FACTORY...
-2024-12-05T20:20:50: 正在关闭 5_CREATE_LINK_FACTORY...
-2024-12-05T20:20:50: 正在关闭 7_CHECK_AND_CREATE_URL_FACTORY...
-2024-12-05T20:20:50: 正在关闭 MESSAGE_DISPATCH...
-2024-12-05T20:20:50: [7_CHECK_AND_CREATE_URL_FACTORY] 退出,代码: null, 信号: SIGINT
-2024-12-05T20:20:50: [5_CREATE_LINK_FACTORY] 退出,代码: null, 信号: SIGINT
-2024-12-05T20:20:50: [0_RECEIVE_FACTORY] 退出,代码: null, 信号: SIGINT
-2024-12-05T20:20:50: [1_FILTER_FACTORY] 退出,代码: null, 信号: SIGINT
-2024-12-05T20:20:50: [2_PRODUCT_FACTORY] 退出,代码: null, 信号: SIGINT
-2024-12-05T20:20:50: [MESSAGE_DISPATCH] 退出,代码: null, 信号: SIGINT
-2024-12-05T20:20:50: 所有工作进程已关闭
-2024-12-05T20:52:47: 
-2024-12-05T20:52:47: > heiyan@1.0.0 start
-2024-12-05T20:52:47: > node tg_factory_main.js
-2024-12-05T20:52:47: 
-2024-12-05T20:52:51: Connected to Redis
-2024-12-05T20:52:52: 
-2024-12-05T20:52:52: > heiyan@1.0.0 start
-2024-12-05T20:52:52: > node tg_factory_main.js
-2024-12-05T20:52:52: 
-2024-12-05T20:52:53: Connected to Redis
-2024-12-05T20:52:54: 
-2024-12-05T20:52:54: > heiyan@1.0.0 start
-2024-12-05T20:52:54: > node tg_factory_main.js
-2024-12-05T20:52:54: 
-2024-12-05T20:52:54: Connected to Redis
-2024-12-05T20:52:55: 
-2024-12-05T20:52:55: > heiyan@1.0.0 start
-2024-12-05T20:52:55: > node tg_factory_main.js
-2024-12-05T20:52:55: 
-2024-12-05T20:52:56: Connected to Redis
-2024-12-05T20:52:56: 
-2024-12-05T20:52:56: > heiyan@1.0.0 start
-2024-12-05T20:52:56: > node tg_factory_main.js
-2024-12-05T20:52:56: 
-2024-12-05T20:52:57: Connected to Redis
-2024-12-05T20:52:58: 
-2024-12-05T20:52:58: > heiyan@1.0.0 start
-2024-12-05T20:52:58: > node tg_factory_main.js
-2024-12-05T20:52:58: 
-2024-12-05T20:52:58: Connected to Redis
-2024-12-05T20:52:59: 
-2024-12-05T20:52:59: > heiyan@1.0.0 start
-2024-12-05T20:52:59: > node tg_factory_main.js
-2024-12-05T20:52:59: 
-2024-12-05T20:53:00: Connected to Redis
-2024-12-05T20:53:00: 
-2024-12-05T20:53:00: > heiyan@1.0.0 start
-2024-12-05T20:53:00: > node tg_factory_main.js
-2024-12-05T20:53:00: 
-2024-12-05T20:53:01: Connected to Redis
-2024-12-05T20:53:02: 
-2024-12-05T20:53:02: > heiyan@1.0.0 start
-2024-12-05T20:53:02: > node tg_factory_main.js
-2024-12-05T20:53:02: 
-2024-12-05T20:53:02: Connected to Redis
-2024-12-05T20:53:03: 
-2024-12-05T20:53:03: > heiyan@1.0.0 start
-2024-12-05T20:53:03: > node tg_factory_main.js
-2024-12-05T20:53:03: 
-2024-12-05T20:53:04: Connected to Redis
-2024-12-05T20:53:04: 
-2024-12-05T20:53:04: > heiyan@1.0.0 start
-2024-12-05T20:53:04: > node tg_factory_main.js
-2024-12-05T20:53:04: 
-2024-12-05T20:53:05: Connected to Redis
-2024-12-05T20:53:06: 
-2024-12-05T20:53:06: > heiyan@1.0.0 start
-2024-12-05T20:53:06: > node tg_factory_main.js
-2024-12-05T20:53:06: 
-2024-12-05T20:53:07: Connected to Redis
-2024-12-05T20:53:07: 
-2024-12-05T20:53:07: > heiyan@1.0.0 start
-2024-12-05T20:53:07: > node tg_factory_main.js
-2024-12-05T20:53:07: 
-2024-12-05T20:53:08: Connected to Redis
-2024-12-05T20:53:08: 
-2024-12-05T20:53:08: > heiyan@1.0.0 start
-2024-12-05T20:53:08: > node tg_factory_main.js
-2024-12-05T20:53:08: 
-2024-12-05T20:53:09: Connected to Redis
-2024-12-05T20:53:10: 
-2024-12-05T20:53:10: > heiyan@1.0.0 start
-2024-12-05T20:53:10: > node tg_factory_main.js
-2024-12-05T20:53:10: 
-2024-12-05T20:53:10: Connected to Redis
-2024-12-05T20:53:11: 
-2024-12-05T20:53:11: > heiyan@1.0.0 start
-2024-12-05T20:53:11: > node tg_factory_main.js
-2024-12-05T20:53:11: 
-2024-12-05T20:53:12: Connected to Redis
-2024-12-05T20:53:12: 
-2024-12-05T20:53:12: > heiyan@1.0.0 start
-2024-12-05T20:53:12: > node tg_factory_main.js
-2024-12-05T20:53:12: 
-2024-12-05T20:53:13: Connected to Redis
-2024-12-05T20:53:14: 
-2024-12-05T20:53:14: > heiyan@1.0.0 start
-2024-12-05T20:53:14: > node tg_factory_main.js
-2024-12-05T20:53:14: 
-2024-12-05T20:53:14: Connected to Redis
-2024-12-05T20:53:15: 
-2024-12-05T20:53:15: > heiyan@1.0.0 start
-2024-12-05T20:53:15: > node tg_factory_main.js
-2024-12-05T20:53:15: 
-2024-12-05T20:53:16: Connected to Redis
-2024-12-05T20:53:16: 
-2024-12-05T20:53:16: > heiyan@1.0.0 start
-2024-12-05T20:53:16: > node tg_factory_main.js
-2024-12-05T20:53:16: 
-2024-12-05T20:53:17: Connected to Redis
-2024-12-05T20:53:18: 
-2024-12-05T20:53:18: > heiyan@1.0.0 start
-2024-12-05T20:53:18: > node tg_factory_main.js
-2024-12-05T20:53:18: 
-2024-12-05T20:53:18: Connected to Redis
-2024-12-05T20:53:19: 
-2024-12-05T20:53:19: > heiyan@1.0.0 start
-2024-12-05T20:53:19: > node tg_factory_main.js
-2024-12-05T20:53:19: 
-2024-12-05T20:53:20: Connected to Redis
-2024-12-05T20:53:20: 
-2024-12-05T20:53:20: > heiyan@1.0.0 start
-2024-12-05T20:53:20: > node tg_factory_main.js
-2024-12-05T20:53:20: 
-2024-12-05T20:53:21: Connected to Redis
-2024-12-05T20:53:22: 
-2024-12-05T20:53:22: > heiyan@1.0.0 start
-2024-12-05T20:53:22: > node tg_factory_main.js
-2024-12-05T20:53:22: 
-2024-12-05T20:53:22: Connected to Redis
-2024-12-05T20:53:23: 
-2024-12-05T20:53:23: > heiyan@1.0.0 start
-2024-12-05T20:53:23: > node tg_factory_main.js
-2024-12-05T20:53:23: 
-2024-12-05T20:53:24: Connected to Redis
-2024-12-05T20:53:24: 
-2024-12-05T20:53:24: > heiyan@1.0.0 start
-2024-12-05T20:53:24: > node tg_factory_main.js
-2024-12-05T20:53:24: 
-2024-12-05T20:53:25: Connected to Redis
-2024-12-05T20:53:26: 
-2024-12-05T20:53:26: > heiyan@1.0.0 start
-2024-12-05T20:53:26: > node tg_factory_main.js
-2024-12-05T20:53:26: 
-2024-12-05T20:53:27: Connected to Redis
-2024-12-05T20:53:27: 
-2024-12-05T20:53:27: > heiyan@1.0.0 start
-2024-12-05T20:53:27: > node tg_factory_main.js
-2024-12-05T20:53:27: 
-2024-12-05T20:53:28: Connected to Redis
-2024-12-05T20:53:28: 
-2024-12-05T20:53:28: > heiyan@1.0.0 start
-2024-12-05T20:53:28: > node tg_factory_main.js
-2024-12-05T20:53:28: 
-2024-12-05T20:53:29: Connected to Redis
-2024-12-05T20:53:30: 
-2024-12-05T20:53:30: > heiyan@1.0.0 start
-2024-12-05T20:53:30: > node tg_factory_main.js
-2024-12-05T20:53:30: 
-2024-12-05T20:53:31: Connected to Redis
-2024-12-05T20:53:31: 
-2024-12-05T20:53:31: > heiyan@1.0.0 start
-2024-12-05T20:53:31: > node tg_factory_main.js
-2024-12-05T20:53:31: 
-2024-12-05T20:53:32: Connected to Redis
-2024-12-05T20:53:33: 
-2024-12-05T20:53:33: > heiyan@1.0.0 start
-2024-12-05T20:53:33: > node tg_factory_main.js
-2024-12-05T20:53:33: 
-2024-12-05T20:53:34: Connected to Redis
-2024-12-05T20:53:34: 
-2024-12-05T20:53:34: > heiyan@1.0.0 start
-2024-12-05T20:53:34: > node tg_factory_main.js
-2024-12-05T20:53:34: 
-2024-12-05T20:53:35: Connected to Redis
-2024-12-05T20:53:36: 
-2024-12-05T20:53:36: > heiyan@1.0.0 start
-2024-12-05T20:53:36: > node tg_factory_main.js
-2024-12-05T20:53:36: 
-2024-12-05T20:53:37: Connected to Redis
-2024-12-05T20:53:37: results: false
-2024-12-05T20:54:06: 
-2024-12-05T20:54:06: > heiyan@1.0.0 start
-2024-12-05T20:54:06: > node tg_factory_main.js
-2024-12-05T20:54:06: 
-2024-12-05T20:54:11: Connected to Redis
-2024-12-05T20:54:11: results: false
-2024-12-05T20:59:02: 
-2024-12-05T20:59:02: > heiyan@1.0.0 start
-2024-12-05T20:59:02: > node tg_factory_main.js
-2024-12-05T20:59:02: 
-2024-12-05T20:59:06: Connected to Redis
-2024-12-05T20:59:06: results: false
+2024-12-06T11:49:43: 
+2024-12-06T11:49:43: > heiyan@1.0.0 start
+2024-12-06T11:49:43: > node tg_factory_main.js
+2024-12-06T11:49:43: 
+2024-12-06T11:49:47: Connected to Redis
+2024-12-06T11:49:47: results: false
+2024-12-06T11:51:28: 
+2024-12-06T11:51:28: > heiyan@1.0.0 start
+2024-12-06T11:51:28: > node tg_factory_main.js
+2024-12-06T11:51:28: 
+2024-12-06T11:51:32: Connected to Redis
+2024-12-06T11:51:32: results: false
+2024-12-06T11:56:04: 
+2024-12-06T11:56:04: > heiyan@1.0.0 start
+2024-12-06T11:56:04: > node tg_factory_main.js
+2024-12-06T11:56:04: 
+2024-12-06T11:56:08: Connected to Redis
+2024-12-06T11:56:08: results: false
+2024-12-06T11:58:33: 
+2024-12-06T11:58:33: > heiyan@1.0.0 start
+2024-12-06T11:58:33: > node tg_factory_main.js
+2024-12-06T11:58:33: 
+2024-12-06T11:58:38: Connected to Redis
+2024-12-06T11:58:38: results: false
+2024-12-06T12:01:04: 
+2024-12-06T12:01:04: > heiyan@1.0.0 start
+2024-12-06T12:01:04: > node tg_factory_main.js
+2024-12-06T12:01:04: 
+2024-12-06T12:01:08: Connected to Redis
+2024-12-06T12:01:08: results: false
+2024-12-06T12:31:22: 
+2024-12-06T12:31:22: > heiyan@1.0.0 start
+2024-12-06T12:31:22: > node tg_factory_main.js
+2024-12-06T12:31:22: 
+2024-12-06T12:31:26: Connected to Redis
+2024-12-06T12:31:26: results: false

+ 85 - 0
node_modules/.package-lock.json

@@ -4,6 +4,49 @@
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
+    "node_modules/@acuminous/bitsyntax": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmmirror.com/@acuminous/bitsyntax/-/bitsyntax-0.1.2.tgz",
+      "integrity": "sha512-29lUK80d1muEQqiUsSo+3A0yP6CdspgC95EnKBMi22Xlwt79i/En4Vr67+cXhU+cZjbti3TgGGC5wy1stIywVQ==",
+      "license": "MIT",
+      "dependencies": {
+        "buffer-more-ints": "~1.0.0",
+        "debug": "^4.3.4",
+        "safe-buffer": "~5.1.2"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/@acuminous/bitsyntax/node_modules/debug": {
+      "version": "4.3.7",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.7.tgz",
+      "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+      "license": "MIT",
+      "dependencies": {
+        "ms": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@acuminous/bitsyntax/node_modules/ms": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+      "license": "MIT"
+    },
+    "node_modules/@acuminous/bitsyntax/node_modules/safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+      "license": "MIT"
+    },
     "node_modules/@img/sharp-libvips-linux-x64": {
       "version": "1.0.4",
       "resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz",
@@ -218,6 +261,20 @@
         "url": "https://github.com/sponsors/epoberezkin"
       }
     },
+    "node_modules/amqplib": {
+      "version": "0.10.5",
+      "resolved": "https://registry.npmmirror.com/amqplib/-/amqplib-0.10.5.tgz",
+      "integrity": "sha512-Dx5zmy0Ur+Q7LPPdhz+jx5IzmJBoHd15tOeAfQ8SuvEtyPJ20hBemhOBA4b1WeORCRa0ENM/kHCzmem1w/zHvQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@acuminous/bitsyntax": "^0.1.2",
+        "buffer-more-ints": "~1.0.0",
+        "url-parse": "~1.5.10"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/array-flatten": {
       "version": "1.1.1",
       "resolved": "https://registry.npmmirror.com/array-flatten/-/array-flatten-1.1.1.tgz",
@@ -343,6 +400,12 @@
         "npm": "1.2.8000 || >= 1.4.16"
       }
     },
+    "node_modules/buffer-more-ints": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz",
+      "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==",
+      "license": "MIT"
+    },
     "node_modules/bytes": {
       "version": "3.1.2",
       "resolved": "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz",
@@ -1570,6 +1633,12 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/querystringify": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmmirror.com/querystringify/-/querystringify-2.2.0.tgz",
+      "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
+      "license": "MIT"
+    },
     "node_modules/range-parser": {
       "version": "1.2.1",
       "resolved": "https://registry.npmmirror.com/range-parser/-/range-parser-1.2.1.tgz",
@@ -1693,6 +1762,12 @@
         "node": ">=0.6"
       }
     },
+    "node_modules/requires-port": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/requires-port/-/requires-port-1.0.0.tgz",
+      "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+      "license": "MIT"
+    },
     "node_modules/safe-buffer": {
       "version": "5.2.1",
       "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -2042,6 +2117,16 @@
         "punycode": "^2.1.0"
       }
     },
+    "node_modules/url-parse": {
+      "version": "1.5.10",
+      "resolved": "https://registry.npmmirror.com/url-parse/-/url-parse-1.5.10.tgz",
+      "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
+      "license": "MIT",
+      "dependencies": {
+        "querystringify": "^2.1.1",
+        "requires-port": "^1.0.0"
+      }
+    },
     "node_modules/utils-merge": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz",

+ 17 - 0
node_modules/@acuminous/bitsyntax/.github/workflows/node-js-ci.yml

@@ -0,0 +1,17 @@
+name: Node.js CI
+
+on: [push]
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        node-version: [12.x, 14.x, 16.x, 18.x]
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions/setup-node@v2
+        with:
+          node-version: ${{ matrix.node-version }}
+      - run: npm ci
+      - run: npm test

+ 30 - 0
node_modules/@acuminous/bitsyntax/.github/workflows/node-js-publish.yml

@@ -0,0 +1,30 @@
+name: Node.js Publish
+
+on:
+  release:
+    types: [created]
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions/setup-node@v2
+        with:
+          node-version: "16.x"
+      - run: npm ci
+      - run: npm test
+
+  publish-npm:
+    needs: build
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions/setup-node@v2
+        with:
+          node-version: "16.x"
+          registry-url: https://registry.npmjs.org/
+      - run: npm ci
+      - run: npm publish --access public
+        env:
+          NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}

+ 6 - 0
node_modules/@acuminous/bitsyntax/LICENSE

@@ -0,0 +1,6 @@
+bitsyntax-js copyright (c) 2012-2014
+                           Michael Bridgen <mikeb@squaremobius.net>
+
+This package, "bitsyntax-js", is licensed under the MIT License. A
+copy may be found in the file LICENSE-MIT in this directory, or
+downloaded from http://opensource.org/licenses/MIT.

+ 21 - 0
node_modules/@acuminous/bitsyntax/LICENSE-MIT

@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2012-2014 Michael Bridgen <mikeb@squaremobius.net>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 15 - 0
node_modules/@acuminous/bitsyntax/Makefile

@@ -0,0 +1,15 @@
+.PHONY: test all
+
+GRAMMAR=lib/grammar.pegjs
+PEGJS=./node_modules/.bin/pegjs
+
+all: lib/parser.js
+
+lib/parser.js: $(PEGJS)
+	 $(PEGJS) $(GRAMMAR) $@
+
+$(PEGJS):
+	npm install
+
+test: lib/parser.js
+	./node_modules/.bin/zUnit

+ 308 - 0
node_modules/@acuminous/bitsyntax/README.md

@@ -0,0 +1,308 @@
+# Byte-wise matching for Node.JS
+
+[![Node.js CI](https://github.com/acuminous/bitsyntax-js/workflows/Node.js%20CI/badge.svg)](https://github.com/acuminous/bitsyntax-js/actions?query=workflow%3A%22Node.js+CI%22)
+[![NPM version](https://img.shields.io/npm/v/bitsyntax.svg?style=flat-square)](https://www.npmjs.com/package/@acuminous/bitsyntax)
+[![NPM downloads](https://img.shields.io/npm/dm/bitsyntax.svg?style=flat-square)](https://www.npmjs.com/package/@acuminous/bitsyntax)
+
+Gives a compact syntax for parsing and constructing byte buffers,
+derived from [Erlang's bit
+syntax](http://www.erlang.org/doc/programming_examples/bit_syntax.html#id64858).
+
+```js
+var bitsyntax = require('bitsyntax');
+var pattern = bitsyntax.matcher('len:8/integer, str:len/binary');
+var bound = pattern(new Buffer([4, 0x41, 0x42, 0x43, 0x44]));
+bound.str
+// => <Buffer 41 42 43 44>
+```
+
+A typical use of this is parsing byte streams from sockets. For
+example, size-prefixed frames:
+
+```js
+var framePattern = bitsyntax.matcher('len:32/integer, frame:len/binary, rest/binary');
+socket.on('data', function process(data) {
+  var m;
+  if (m = framePattern(data)) {
+    emit('frame', m.frame);
+    process(m.rest);
+  }
+  else {
+    stashForNextData(data);
+  }
+});
+```
+
+Patterns can also be used to construct byte buffers from supplied
+values:
+
+```js
+var spdyDataFrame = require('bitsyntax')
+  .builder('streamId:32, flags:8, length:24, data/binary');
+
+spdyDataFrame({streamId:5, flags:0, length:bin.length, data:bin});
+```
+
+One or more segments of a pattern may also be supplied in multiple
+arguments, if that is more convenient; this makes it easier to split a
+long pattern over lines:
+
+```js
+var p = bitsyntax.matcher('size:8, payload:size/binary',
+                          'rest/binary');
+```
+
+## API
+
+### `matcher`
+
+Compiles a pattern as a string (or strings), to a function that will
+return either a map of bindings, or `false`, given a buffer and
+optionally an environment. The environment contains values for bound
+variables in the pattern (if there are any).
+
+```js
+var p = bitsyntax.matcher('header:headerSize/binary, rest/binary');
+var b = p(new Buffer([1, 2, 3, 4, 5]), {headerSize: 3});
+b.header
+// => <Buffer 01 02 03>
+```
+
+A matcher will return `false` if the supplied buffer does not match
+the pattern; for example, if it has too few bytes, or a literal is not
+present.
+
+```js
+var p = bitsyntax.matcher('"foo=", str/binary');
+p(new Buffer("bar=humbug"));
+// => false
+```
+
+### `parse` and `match`
+
+When composed, equivalent to `matcher`; may be useful if you want to
+examine the internal structure of patterns.
+
+`parse` takes strings as for `matcher`, and returns the internal
+representation of the pattern. `match` takes this representation, a
+buffer, and optionally an environment, and returns the bindings or
+`false` (as with `matcher`).
+
+```js
+var p = bitsyntax.parse('header:headerSize/binary',
+                        'rest/binary');
+var b = bitsyntax.match(p, new Buffer([1, 2, 3, 4, 5]),
+                          {headerSize: 3});
+b.header
+// => <Buffer 01 02 03>
+```
+
+### `builder`
+
+Takes a pattern and returns a function that will construct a byte
+buffer, given values for the variables mentioned in the pattern.
+
+```js
+var cons = bitsyntax.builder('size:8, bin/binary');
+cons({size:6, bin:new Buffer('foobar')});
+// => <Buffer 06 66 6f 6f 62 61 72>
+```
+
+Patterns supplied to builders are slightly different to patterns
+supplied for matching, as noted below.
+
+### `build`
+
+Takes a parsed pattern and a map of variable values, and returns a
+buffer. As with `match`, may be useful to debug patterns.
+
+```js
+var pattern = bitsyntax.parse('size:8, bin:size/binary');
+bitsyntax.build(pattern, {size:6, bin: new Buffer('foobar')});
+// => <Buffer 06 66 6f 6f 62 61 72>
+```
+
+### `write`
+
+Writes variable values into a buffer, at an offset, according to the
+parsed pattern given. Returns the finishing offset, i.e., the supplied
+offset plus the number of bytes written.
+
+```js
+var pattern = bitsyntax.parse('size:8, bin/binary');
+var buf = new Buffer(7);
+bitsyntax.write(buf, 0, pattern,
+                {size:6, bin: new Buffer('foobar')});
+// => 7
+buf
+// => <Buffer 06 66 6f 6f 62 61 72>
+```
+
+## Patterns
+
+Patterns are sequences of segments, each matching a value. Segments
+have the general form
+
+     value:size/type_specifier_list
+
+The size and type specifier list may be omitted, giving three extra
+variations:
+
+    value
+    value:size
+    value/type_specifier_list
+
+The type specifier list is a list of keywords separated by
+hyphens. Type specifiers are described below.
+
+Patterns are generally supplied as strings, with a comma-separated
+series of segments.
+
+### Variable or value
+
+The first part of a segment gives a variable name or a literal
+value. If a variable name is given, the value matched by the segment
+will be bound to that variable name for the rest of the pattern. If a
+literal value is given, the matched value must equal that value. If a
+variable's value is given in the environment, the matched value must
+equal the provided value.
+
+When used in a builder, the literal value will be copied into the
+buffer according to the type it is given. A variable name indicates a
+slot into which a value supplied to the builder will be copied.
+
+The special variable name `_` discards the value matched; i.e., it
+simply skips over the appropriate number of bits in the input. '_' is
+not allowed in builder patterns.
+
+### Size and unit
+
+The size of a segment is given following the value or variable,
+separated with a colon:
+
+    foo:32
+
+The unit is given in the list of specifiers as `'unit' and
+an integer from 0..256, separated by a colon:
+
+    foo:4/integer-unit:8
+
+The size is the number of units in the value; the unit is given as a
+number of bits. Unit can be of use, for example, when you want to
+match integers of a number of bytes rather than a number of bits.
+
+For integers and floats, the default unit is 1 bit; to keep things
+aligned on byte boundaries, `unit * size` must currently be a multiple
+of 8. For binaries the default unit is 8, and the unit must be a
+multiple of 8.
+
+If the size is omitted and the type is integer, the size defaults to
+8. If the size is omitted and the type is binary, the segment will
+match all remaining bytes in the input; such a segment may only be
+used at the end of a pattern, when matching.
+
+The size may also be given as an integer variable matched earlier in
+the pattern, as in the example given at the top. When constructing, a
+size may be a variable referring to the supplied environment.
+
+In builders, numbers will be rounded, masked or padded to fit the size
+and units given; for example, `'256:8'` gives the binary `Buffer<00>`
+because the lowest eight bits are 0; `'255:16` gives the binary
+`Buffer<00 ff>`.
+
+### Type name specifier
+
+One of `integer`, `binary`, `string`, `float`. If not given, the
+default is `integer`.
+
+An integer is a big- or little-endian, signed or unsigned
+integer. Integers up to 32 bits are supported. Signed integers are
+two's complement format. In JavaScript, only integers between -(2^53)
+and 2^53 can be represented, and bitwise operators are only defined on
+32-bit signed integers.
+
+A binary is simply a byte buffer; usually this will result in a slice
+of the input buffer being returned, so beware mutation.
+
+A string is a UTF8 string consisting of the given number of bytes.
+
+A float is a 32- or 64-bit IEEE754 floating-point value (this is the
+standard JavaScript uses, as do Java and Erlang).
+
+### Endianness specifier
+
+Integers may be big- or little-endian; this refers to which 'end' of
+the bytes making up the integer are most significant. In network
+protocols integers are usually big-endian, meaning the first
+(left-most) byte is the most significant, but this is not always the
+case.
+
+A specifier of `big` means the integer will be parsed (or written into
+the result) as big-endian, and `little` means the integer will be
+parsed or written as little-endian. The default is big-endian.
+
+### Signedness specifier
+
+Integer segments may include a specifier of `signed` or `unsigned`. A
+signed integer is parsed as two's complement format. The default is
+unsigned.
+
+Signedness is ignored in builders.
+
+### Literal strings
+
+A quoted string appearing in a pattern is a shorthand for the bytes in
+its UTF8 encoding. For example,
+
+    "foobar", _/binary
+
+matches any buffer that starts with the bytes `0x66, 0x6f, 0x6f, 0x62,
+0x61, 0x72`.
+
+When used in a builder, a quoted string is copied into the result as
+the bytes of its UTF8 encoding.
+
+## Examples
+
+In the following the matched bytes are given in array notation for
+convenience. Bear in mind that `match()` actually takes a buffer for
+the bytes to match against. The phrase "returns X as Y" or "binds X as
+Y" means the return value is an object with value X mapped to the key
+Y.
+
+    54
+
+Matches the single byte `54`.
+
+    54:32
+
+Matches the bytes [0,0,0,54].
+
+    54:32/little
+
+Matches the bytes [54,0,0,0].
+
+    54:4/unit:8
+
+Matches the bytes [0,0,0,54].
+
+    int:32/signed
+
+Matches a binary of four bytes, and returns a signed 32-bit integer as
+`int`.
+
+    len:16, str:len/binary
+
+Matches a binary of `2 + len` bytes, and returns an unsigned 16-bit
+integer as `len` and a buffer of length `len` as `str`.
+
+    len:16, _:len/binary, rest/binary
+
+Matches a binary of at least `2 + len` bytes, binds an unsigned 16-bit
+integer as `len`, ignores the next `len` bytes, and binds the
+remaining (possibly zero-length) binary as `rest`.
+
+    s:8, key:s/binary, value/binary
+
+When given the environment `{s:6, key: "foobar"}`, will match a binary
+starting with [6, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, ...].

+ 10 - 0
node_modules/@acuminous/bitsyntax/index.js

@@ -0,0 +1,10 @@
+'use strict';
+
+module.exports.parse = require('./lib/parse').parse;
+module.exports.match = require('./lib/interp').match;
+module.exports.build = require('./lib/constructor').build;
+module.exports.write = require('./lib/constructor').write;
+
+module.exports.matcher = module.exports.compile =
+  require('./lib/compile').compile;
+module.exports.builder = require('./lib/compile').compile_builder;

+ 303 - 0
node_modules/@acuminous/bitsyntax/lib/compile.js

@@ -0,0 +1,303 @@
+// Compile patterns to recognisers and constructors
+
+'use strict';
+
+require('buffer-more-ints');
+var $ = require('util').format;
+
+var parse = require('./parse').parse;
+var interp = require('./interp'),
+  parse_int = interp.parse_int,
+  parse_float = interp.parse_float;
+var construct = require('./constructor'),
+  write_int = construct.write_int,
+  write_float = construct.write_float;
+
+var Buffer = require('safe-buffer').Buffer;
+
+var lines = [];
+function $start() {
+  lines = [];
+}
+function $line(/* format , args */) {
+  lines.push($.apply(null, arguments));
+}
+function $result() {
+  return lines.join('\n');
+}
+
+function bits_expr(segment) {
+  if (typeof segment.size === 'string') {
+    return $('%s * %d', var_name(segment.size), segment.unit);
+  }
+  else {
+    return (segment.size * segment.unit).toString();
+  }
+}
+
+function get_number(segment) {
+  $line('bits = %s;\n', bits_expr(segment));
+  var parser = (segment.type === 'integer') ?
+    'parse_int' : 'parse_float';
+  var be = segment.bigendian, sg = segment.signed;
+  $line("byteoffset = offset / 8; offset += bits");
+  $line("if (offset > binsize) { return false; }");
+  $line("else { result = %s(bin, byteoffset, bits / 8, %s, %s); }",
+        parser, be, sg);
+}
+
+function get_binary(segment) {
+  $line("byteoffset = offset / 8;");
+  if (segment.size === true) {
+    $line("offset = binsize;");
+    $line("result = bin.slice(byteoffset);");
+  }
+  else {
+    $line("bits = %s;", bits_expr(segment));
+    $line("offset += bits;");
+    $line("if (offset > binsize) { return false; }");
+    $line("else { result = bin.slice(byteoffset,",
+          "byteoffset + bits / 8); }");
+  }
+}
+
+function get_string(segment) {
+  $line("byteoffset = offset / 8;");
+  var strlen = segment.value.length;
+  var strlenbits = strlen * 8;
+  $line("offset += %d;", strlenbits);
+  $line("if (offset > binsize) { return false; }");
+  $line("else { result = bin.toString(byteoffset,",
+        $("byteoffset + %d); }", strlen));
+}
+
+function skip_bits(segment) {
+  if (typeof segment.size === 'string') {
+    // Damn. Have to look up the size.
+    $line("var skipbits = %s * %d;",
+          var_name(segment.size), segment.unit);
+    $line("if (offset + skipbits > binsize) { return false; }");
+    $line("else { offset += skipbits; }");
+  }
+  else if (segment.size === true) {
+    $line("if (offset % 8 === 0) { offset = binsize; }");
+    $line("else { return false; }");
+  }
+  else {
+    var bits = segment.unit * segment.size;
+    $line("if (offset + %d > binsize) { return false; }", bits);
+    $line("else { offset += %d; }", bits);
+  }
+}
+
+function match_seg(segment) {
+  if (segment.name === '_') {
+    skip_bits(segment);
+  }
+  else {
+    var assign_result;
+    switch (segment.type) {
+    case 'integer':
+    case 'float':
+      get_number(segment);
+      break;
+    case 'binary':
+      get_binary(segment);
+      break;
+    case 'string':
+      get_string(segment);
+      break;
+    }
+    $line("if (result === false) return false;");
+    if (segment.name) {
+      // variable is given a value in the environment
+      $line("else if (%s !== undefined) {", var_name(segment.name));
+      // .. and it is not the same as that matched
+      $line("if (%s != result) return false;",
+            var_name(segment.name));
+      $line("}");
+      // variable is free
+      $line('else %s = result;', var_name(segment.name));
+    }
+    else {
+      var repr = JSON.stringify(segment.value);
+      $line("else if (result != %s) return false;", repr);
+    }
+  }
+}
+
+function var_name(name) {
+  return  'var_' + name;
+}
+
+function variables(segments) {
+  var names = {};
+  for (var i = 0; i < segments.length; i++) {
+    var name = segments[i].name;
+    if (name && name !== '_') {
+      names[name] = true;
+    }
+    name = segments[i].size;
+    if (typeof name === 'string') {
+      names[name] = true;
+    }
+  }
+  return Object.keys(names);
+}
+
+function compile_pattern(segments) {
+  $start();
+  $line("return function(binary, env) {");
+  $line("'use strict';");
+  $line("var bin = binary, env = env || {};");
+  $line("var offset = 0, binsize = bin.length * 8;");
+  $line("var bits, result, byteoffset;");
+  var varnames = variables(segments);
+  for (var v = 0; v < varnames.length; v++) {
+    var name = varnames[v];
+    $line("var %s = env['%s'];", var_name(name), name);
+  }
+
+  var len = segments.length;
+  for (var i = 0; i < len; i++) {
+    var segment = segments[i];
+    $line("// " + JSON.stringify(segment));
+    match_seg(segment);
+  }
+
+  $line("if (offset == binsize) {");
+  $line("return {");
+  for (var v = 0; v < varnames.length; v++) {
+    var name = varnames[v];
+    $line("%s: %s,", name, var_name(name));
+  }
+  $line('};');
+  $line('}'); // if offset == binsize
+  $line("else return false;");
+  $line("}"); // end function
+
+  var fn = new Function('parse_int', 'parse_float', $result());
+  return fn(parse_int, parse_float);
+}
+
+
+function write_seg(segment) {
+  switch (segment.type) {
+  case 'string':
+    $line("offset += buf.write(%s, offset, 'utf8');",
+          JSON.stringify(segment.value));
+    break;
+  case 'binary':
+    $line("val = bindings['%s'];", segment.name);
+    if (segment.size === true) {
+      $line('size = val.length;');
+    }
+    else if (typeof segment.size === 'string') {
+      $line("size = (bindings['%s'] * %d) / 8;",
+            segment.size, segment.unit);
+    }
+    else {
+      $line("size = %d;", (segment.size * segment.unit) / 8);
+    }
+    $line('val.copy(buf, offset, 0, size);');
+    $line('offset += size;');
+    break;
+  case 'integer':
+  case 'float':
+    write_number(segment);
+    break;
+  }
+}
+
+function write_number(segment) {
+  if (segment.name) {
+    $line("val = bindings['%s'];", segment.name);
+  }
+  else {
+    $line("val = %d", segment.value);
+  }
+  var writer = (segment.type === 'integer') ?
+    'write_int' : 'write_float';
+  if (typeof segment.size === 'string') {
+    $line("size = (bindings['%s'] * %d) / 8;",
+          segment.size, segment.unit);
+  }
+  else {
+    $line('size = %d;', (segment.size * segment.unit) / 8);
+  }
+  $line('%s(buf, val, offset, size, %s);',
+        writer, segment.bigendian);
+  $line('offset += size;');
+}
+
+function size_of(segments) {
+  var variable = [];
+  var fixed = 0;
+
+  for (var i = 0; i < segments.length; i++) {
+    var segment = segments[i];
+    if (typeof segment.size === 'string' ||
+        segment.size === true) {
+      variable.push(segment);
+    }
+    else if (segment.type === 'string') {
+      fixed += Buffer.byteLength(segment.value);
+    }
+    else {
+      fixed += (segment.size * segment.unit) / 8;
+    }
+  }
+
+  $line('var buffersize = %d;', fixed);
+
+  if (variable.length > 0) {
+    for (var j = 0; j < variable.length; j++) {
+      var segment = variable[j];
+      if (segment.size === true) {
+        $line("buffersize += bindings['%s'].length;", segment.name);
+      }
+      else {
+        $line("buffersize += (bindings['%s'] * %d) / 8;",
+              segment.size, segment.unit);
+      }
+    }
+  }
+}
+
+function emit_write(segments) {
+  $line('var val, size;');
+
+  var len = segments.length;
+  for (var i = 0; i < len; i++) {
+    var segment = segments[i];
+    $line('// %s', JSON.stringify(segment));
+    write_seg(segment);
+  }
+}
+
+function compile_ctor(segments) {
+  $start();
+  $line('return function(bindings) {');
+  $line("'use strict';");
+  size_of(segments);
+  $line('var buf = Buffer.alloc(buffersize);');
+  $line('var offset = 0;');
+  emit_write(segments);
+  $line('return buf;');
+  $line('}'); // end function
+
+  return new Function('write_int', 'write_float', 'Buffer',
+                      $result())(write_int, write_float, Buffer);
+}
+
+module.exports.compile_pattern = compile_pattern;
+module.exports.compile = function() {
+  var str = [].join.call(arguments, ',');
+  var p = parse(str);
+  return compile_pattern(p);
+};
+module.exports.compile_builder = function() {
+  var str = [].join.call(arguments, ',');
+  var p = parse(str);
+  return compile_ctor(p);
+};

+ 142 - 0
node_modules/@acuminous/bitsyntax/lib/constructor.js

@@ -0,0 +1,142 @@
+// -*- js-indent-level: 2 -*-
+
+// Constructors given patterns
+
+'use strict';
+
+var ints = require('buffer-more-ints');
+var Buffer = require('safe-buffer').Buffer;
+
+// Interpret the pattern, writing values into a buffer
+function write(buf, offset, pattern, bindings) {
+  for (var i=0, len = pattern.length; i < len; i++) {
+    var segment = pattern[i];
+    switch (segment.type) {
+    case 'string':
+      offset += buf.write(segment.value, offset, 'utf8');
+      break;
+    case 'binary':
+      offset += writeBinary(segment, buf, offset, bindings);
+      break;
+    case 'integer':
+      offset += writeInteger(segment, buf, offset, bindings);
+      break;
+    case 'float':
+      offset += writeFloat(segment, buf, offset, bindings);
+      break;
+    }
+  }
+  return offset;
+}
+
+function build(pattern, bindings) {
+  var bufsize = size_of(pattern, bindings);
+  var buf = Buffer.alloc(bufsize);
+  write(buf, 0, pattern, bindings);
+  return buf;
+}
+
+// In bytes
+function size_of_segment(segment, bindings) {
+  // size refers to a variable
+  if (typeof segment.size === 'string') {
+    return (bindings[segment.size] * segment.unit) / 8;
+  }
+  if (segment.type === 'string') {
+    return Buffer.byteLength(segment.value, 'utf8');
+  }
+  if (segment.type === 'binary' && segment.size === true) {
+    var val = bindings[segment.name];
+    return val.length;
+  }
+  return (segment.size * segment.unit) / 8;
+}
+
+// size of the to-be-constructed binary, in bytes
+function size_of(segments, bindings) {
+  var size = 0;
+  for (var i=0, len = segments.length; i < len; i++) {
+    size += size_of_segment(segments[i], bindings);
+  }
+  return size;
+}
+
+function writeBinary(segment, buf, offset, bindings) {
+  var bin = bindings[segment.name];
+  var size = size_of_segment(segment, bindings);
+  bin.copy(buf, offset, 0, size);
+  return size;
+}
+
+// TODO in ff might use the noAssert argument to Buffer.write*() but
+// need to check that it does the right thing wrt little-endian
+
+function writeInteger(segment, buf, offset, bindings) {
+  var value = (segment.name) ? bindings[segment.name] : segment.value;
+  var size = size_of_segment(segment, bindings);
+  return write_int(buf, value, offset, size, segment.bigendian);
+}
+
+function write_int(buf, value, offset, size, bigendian) {
+  switch (size) {
+  case 1:
+    buf.writeUInt8(value, offset);
+    break;
+  case 2:
+    (bigendian) ?
+      buf.writeUInt16BE(value, offset) :
+      buf.writeUInt16LE(value, offset);
+    break;
+  case 4:
+    (bigendian) ?
+      buf.writeUInt32BE(value, offset) :
+      buf.writeUInt32LE(value, offset);
+    break;
+  case 8:
+    (bigendian) ?
+      ints.writeUInt64BE(buf, value, offset) :
+      ints.writeUInt64LE(buf, value, offset);
+    break;
+  default:
+    throw new Error("integer size * unit must be 8, 16, 32 or 64");
+  }
+  return size;
+}
+
+function writeFloat(segment, buf, offset, bindings) {
+  var value = (segment.name) ? bindings[segment.name] : segment.value;
+  var size = size_of_segment(segment, bindings);
+  return write_float(buf, value, offset, size, segment.bigendian);
+}
+
+function write_float(buf, value, offset, size, bigendian) {
+  if (size === 4) {
+    (bigendian) ?
+      buf.writeFloatBE(value, offset) :
+      buf.writeFloatLE(value, offset);
+  }
+  else if (size === 8) {
+    (bigendian) ?
+      buf.writeDoubleBE(value, offset) :
+      buf.writeDoubleLE(value, offset);
+  }
+  else {
+    throw new Error("float size * unit must be 32 or 64");
+  }
+  return size;
+}
+
+var parse = require('./parse').parse;
+
+module.exports.write = write;
+module.exports.build = build;
+module.exports.write_int = write_int;
+module.exports.write_float = write_float;
+
+module.exports.builder = function(pstr) {
+  pstr = (arguments.length > 1) ? [].join.call(arguments, ',') : pstr;
+  var pattern = parse(pstr);
+  return function(vars) {
+    return build(pattern, vars);
+  };
+};

+ 67 - 0
node_modules/@acuminous/bitsyntax/lib/grammar.pegjs

@@ -0,0 +1,67 @@
+
+start
+    = ws head:segment tail:segmentTail* { tail.unshift(head); return tail; }
+
+segmentTail
+    = ws ',' ws seg:segment { return seg; }
+
+segment
+    = str:string { return {string: str}; }
+    / v:identifier size:size ? specs:specifierList ?
+      { return {name: v, size: size, specifiers: specs}; }
+    / v:number size:size ? specs:specifierList ?
+      { return {value: v, size: size, specifiers: specs}; }
+
+string
+  = '"' '"'             { return "";    }
+  / '"' chars:chars '"' { return chars; }
+
+/* From JSON example
+https://github.com/dmajda/pegjs/blob/master/examples/json.pegjs */
+
+chars
+  = chars:char+ { return chars.join(""); }
+
+char
+  = [^"\\\0-\x1F\x7f]
+  / '\\"'  { return '"';  }
+  / "\\\\" { return "\\"; }
+  / "\\/"  { return "/";  }
+  / "\\b"  { return "\b"; }
+  / "\\f"  { return "\f"; }
+  / "\\n"  { return "\n"; }
+  / "\\r"  { return "\r"; }
+  / "\\t"  { return "\t"; }
+  / "\\u" h1:hexDigit h2:hexDigit h3:hexDigit h4:hexDigit {
+      return String.fromCharCode(parseInt("0x" + h1 + h2 + h3 + h4));
+    }
+
+hexDigit
+  = [0-9a-fA-F]
+
+identifier
+    = (head:[_a-zA-Z] tail:[_a-zA-Z0-9]*) { return head + tail.join(''); }
+
+number
+    = '0' { return 0; }
+    / head:[1-9] tail:[0-9]* { return parseInt(head + tail.join('')); }
+
+size
+    = ':' num:number { return num; }
+    / ':' id:identifier { return id; }
+
+specifierList
+    = '/' head:specifier tail:specifierTail* { tail.unshift(head); return tail; }
+
+specifierTail
+    = '-' spec:specifier { return spec; }
+
+specifier
+    = 'little' / 'big' / 'signed' / 'unsigned'
+    / 'integer' / 'binary' / 'float'
+    / unit
+
+unit
+    = 'unit:' num:number { return 'unit:' + num; }
+
+ws = [ \t\n]*

+ 232 - 0
node_modules/@acuminous/bitsyntax/lib/interp.js

@@ -0,0 +1,232 @@
+// -*- js-indent: 2 -*-
+// Interpreter for bit syntax AST.
+// Grammar:
+//
+// pattern   := segment ("," segment)*
+// segment   := (value | var) (":" size)? ("/" specifier ("-" specifier)*)? | string
+// var       := "_" | identifier
+// size      := integer | var
+// specifier := "little" | "big" | "signed" | "unsigned" | "unit" ":" 0..256 | type
+// type      := "integer" | "binary" | "float"
+//
+// where integer has the obvious meaning, and identifier is anything
+// other than "_" that fits the JavaScript identifier specification.
+//
+
+// We'll use an object to represent each segment, and an array of
+// segments for a pattern. We won't try to optimise for groups of
+// patterns; we'll just step through each to see if it works. We rely
+// a hypothetical prior step to check that it's a valid pattern.
+
+// ? compile to intermediate instructions ?
+
+// A segment looks like
+// {
+//    type: string, // 'string' is special case
+//    size: integer | true, // true means 'all remaining'
+//    name: string | null, // (may be '_')
+//    value: value | null, // either name OR value
+//    unit: integer,
+//    signed: boolean,
+//    bigendian: boolean
+// }
+
+'use strict';
+
+var ints    = require('buffer-more-ints'),
+    debug   = require('debug')('bitsyntax-Interpreter');
+
+function parse_int(bin, off, sizeInBytes, bigendian, signed) {
+  switch (sizeInBytes) {
+  case 1:
+    return (signed) ? bin.readInt8(off) : bin.readUInt8(off);
+  case 2:
+    return (bigendian) ?
+      (signed) ? bin.readInt16BE(off) : bin.readUInt16BE(off) :
+      (signed) ? bin.readInt16LE(off) : bin.readUInt16LE(off);
+  case 4:
+    return (bigendian) ?
+      (signed) ? bin.readInt32BE(off) : bin.readUInt32BE(off) :
+      (signed) ? bin.readInt32LE(off) : bin.readUInt32LE(off);
+  case 8:
+    return (bigendian) ?
+      ((signed) ? ints.readInt64BE : ints.readUInt64BE)(bin, off) :
+      ((signed) ? ints.readInt64LE : ints.readUInt64LE)(bin, off);
+  default:
+    throw "Integers must be 8-, 16-, 32- or 64-bit";
+  }
+}
+
+function parse_float(bin, off, sizeInBytes, bigendian) {
+  switch (sizeInBytes) {
+  case 4:
+    return (bigendian) ? bin.readFloatBE(off) : bin.readFloatLE(off);
+  case 8:
+    return (bigendian) ? bin.readDoubleBE(off) : bin.readDoubleLE(off);
+  default:
+    throw "Floats must be 32- or 64-bit";
+  }
+}
+
+function size_of(segment, bound) {
+  var size = segment.size;
+  if (typeof size === 'string') {
+    return bound[size];
+  }
+  else {
+    return size;
+  }
+}
+
+function new_scope(env) {
+  function scope() {};
+  scope.prototype = env;
+  return new scope();
+}
+
+function bindings(scope) {
+  var s = {};
+  for (var k in scope) {
+    if (scope.hasOwnProperty(k)) {
+      s[k] = scope[k];
+    }
+  }
+  return s;
+}
+
+function match(pattern, binary, boundvars) {
+  var offset = 0, vars = new_scope(boundvars);
+  var binsize = binary.length * 8;
+
+  function skip_bits(segment) {
+    debug("skip bits"); debug(segment);
+    var size = size_of(segment, vars);
+    if (size === true) {
+      if (offset % 8 === 0) {
+        offset = binsize;
+        return true;
+      }
+      else {
+        return false;
+      }
+    }
+
+    var bits = segment.unit * size;
+    if (offset + bits > binsize) {
+      return false;
+    }
+    else {
+      offset += bits;
+    }
+  }
+
+  function get_integer(segment) {
+    debug("get_integer"); debug(segment);
+    // let's do only multiples of eight bits for now
+    var unit = segment.unit, size = size_of(segment, vars);
+    var bitsize = size * unit;
+    var byteoffset = offset / 8; // NB assumes aligned
+    offset += bitsize;
+    if (bitsize % 8 > 0 || (offset > binsize)) {
+      return false;
+    }
+    else {
+      return parse_int(binary, byteoffset, bitsize / 8,
+                       segment.bigendian, segment.signed);
+    }
+  }
+
+  function get_float(segment) {
+    debug("get_float"); debug(segment);
+    var unit = segment.unit; var size = size_of(segment, vars);
+    var bitsize = size * unit;
+    var byteoffset = offset / 8; // assume aligned
+    offset += bitsize;
+    if (offset > binsize) {
+      return false;
+    }
+    else {
+      return parse_float(binary, byteoffset,
+                         bitsize / 8, segment.bigendian);
+    }
+  }
+
+  function get_binary(segment) {
+    debug("get_binary"); debug(segment);
+    var unit = segment.unit, size = size_of(segment, vars);
+    var byteoffset = offset / 8; // NB alignment
+
+    if (size === true) {
+      offset = binsize;
+      return binary.slice(byteoffset);
+    }
+    else {
+      var bitsize = size * unit;
+      if (bitsize % 8 > 0 || (offset + bitsize) > binsize) {
+        return false;
+      }
+      else {
+        offset += bitsize;
+        return binary.slice(byteoffset, byteoffset + bitsize / 8);
+      }
+    }
+  }
+
+  function get_string(segment) {
+    debug("get_string"); debug(segment);
+    var len = segment.value.length;
+    var byteoffset = offset / 8;
+
+    offset += len * 8;
+    if (offset > binsize) {
+      return false;
+    }
+    // FIXME bytes vs UTF8 characters
+    return binary.slice(byteoffset, byteoffset + len).toString('utf8');
+  }
+
+  var patternlen = pattern.length;
+  for (var i = 0;  i < patternlen; i++) {
+    var segment = pattern[i];
+    var result = false;
+    if (segment.name === '_') {
+      result = skip_bits(segment);
+    }
+    else {
+      switch (segment.type) {
+      case 'string':
+        result = get_string(segment);
+        break;
+      case 'integer':
+        result = get_integer(segment);
+        break;
+      case 'float':
+        result = get_float(segment);
+        break;
+      case 'binary':
+        result = get_binary(segment);
+        break;
+      }
+
+      if (result === false) {
+        return false;
+      }
+      else if (segment.name) {
+        vars[segment.name] = result;
+      }
+      else if (segment.value != result) {
+        return false;
+      }
+    }
+  }
+  if (offset == binsize) {
+    return bindings(vars);
+  }
+  else {
+    return false;
+  }
+}
+
+module.exports.match = match;
+module.exports.parse_int = parse_int;
+module.exports.parse_float = parse_float;

+ 32 - 0
node_modules/@acuminous/bitsyntax/lib/parse.js

@@ -0,0 +1,32 @@
+// Parse patterns in string form into the form we use for interpreting
+// (and later, for compiling).
+
+'use strict';
+
+var ast = require('./pattern');
+var parser = require('./parser');
+
+function parse_pattern(string) {
+  var segments = parser.parse(string);
+  for (var i=0, len = segments.length; i < len; i++) {
+    var s = segments[i];
+    if (s.string != undefined) {
+      segments[i] = ast.string(s.string);
+    }
+    else if (s.value != undefined) {
+      segments[i] = ast.value(s.value, s.size, s.specifiers);
+    }
+    else if (s.name != undefined) {
+      segments[i] = ast.variable(s.name, s.size, s.specifiers);
+    }
+    else {
+      throw "Unknown segment " + s;
+    }
+  }
+  return segments;
+}
+
+module.exports.parse = function() {
+  var str = [].join.call(arguments, ',');
+  return parse_pattern(str);
+};

+ 1173 - 0
node_modules/@acuminous/bitsyntax/lib/parser.js

@@ -0,0 +1,1173 @@
+module.exports = (function(){
+  /*
+   * Generated by PEG.js 0.7.0.
+   *
+   * http://pegjs.majda.cz/
+   */
+  
+  function quote(s) {
+    /*
+     * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a
+     * string literal except for the closing quote character, backslash,
+     * carriage return, line separator, paragraph separator, and line feed.
+     * Any character may appear in the form of an escape sequence.
+     *
+     * For portability, we also escape escape all control and non-ASCII
+     * characters. Note that "\0" and "\v" escape sequences are not used
+     * because JSHint does not like the first and IE the second.
+     */
+     return '"' + s
+      .replace(/\\/g, '\\\\')  // backslash
+      .replace(/"/g, '\\"')    // closing quote character
+      .replace(/\x08/g, '\\b') // backspace
+      .replace(/\t/g, '\\t')   // horizontal tab
+      .replace(/\n/g, '\\n')   // line feed
+      .replace(/\f/g, '\\f')   // form feed
+      .replace(/\r/g, '\\r')   // carriage return
+      .replace(/[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g, escape)
+      + '"';
+  }
+  
+  var result = {
+    /*
+     * Parses the input with a generated parser. If the parsing is successfull,
+     * returns a value explicitly or implicitly specified by the grammar from
+     * which the parser was generated (see |PEG.buildParser|). If the parsing is
+     * unsuccessful, throws |PEG.parser.SyntaxError| describing the error.
+     */
+    parse: function(input, startRule) {
+      var parseFunctions = {
+        "start": parse_start,
+        "segmentTail": parse_segmentTail,
+        "segment": parse_segment,
+        "string": parse_string,
+        "chars": parse_chars,
+        "char": parse_char,
+        "hexDigit": parse_hexDigit,
+        "identifier": parse_identifier,
+        "number": parse_number,
+        "size": parse_size,
+        "specifierList": parse_specifierList,
+        "specifierTail": parse_specifierTail,
+        "specifier": parse_specifier,
+        "unit": parse_unit,
+        "ws": parse_ws
+      };
+      
+      if (startRule !== undefined) {
+        if (parseFunctions[startRule] === undefined) {
+          throw new Error("Invalid rule name: " + quote(startRule) + ".");
+        }
+      } else {
+        startRule = "start";
+      }
+      
+      var pos = 0;
+      var reportFailures = 0;
+      var rightmostFailuresPos = 0;
+      var rightmostFailuresExpected = [];
+      
+      function padLeft(input, padding, length) {
+        var result = input;
+        
+        var padLength = length - input.length;
+        for (var i = 0; i < padLength; i++) {
+          result = padding + result;
+        }
+        
+        return result;
+      }
+      
+      function escape(ch) {
+        var charCode = ch.charCodeAt(0);
+        var escapeChar;
+        var length;
+        
+        if (charCode <= 0xFF) {
+          escapeChar = 'x';
+          length = 2;
+        } else {
+          escapeChar = 'u';
+          length = 4;
+        }
+        
+        return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length);
+      }
+      
+      function matchFailed(failure) {
+        if (pos < rightmostFailuresPos) {
+          return;
+        }
+        
+        if (pos > rightmostFailuresPos) {
+          rightmostFailuresPos = pos;
+          rightmostFailuresExpected = [];
+        }
+        
+        rightmostFailuresExpected.push(failure);
+      }
+      
+      function parse_start() {
+        var result0, result1, result2, result3;
+        var pos0, pos1;
+        
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_ws();
+        if (result0 !== null) {
+          result1 = parse_segment();
+          if (result1 !== null) {
+            result2 = [];
+            result3 = parse_segmentTail();
+            while (result3 !== null) {
+              result2.push(result3);
+              result3 = parse_segmentTail();
+            }
+            if (result2 !== null) {
+              result0 = [result0, result1, result2];
+            } else {
+              result0 = null;
+              pos = pos1;
+            }
+          } else {
+            result0 = null;
+            pos = pos1;
+          }
+        } else {
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, head, tail) { tail.unshift(head); return tail; })(pos0, result0[1], result0[2]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
+        return result0;
+      }
+      
+      function parse_segmentTail() {
+        var result0, result1, result2, result3;
+        var pos0, pos1;
+        
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_ws();
+        if (result0 !== null) {
+          if (input.charCodeAt(pos) === 44) {
+            result1 = ",";
+            pos++;
+          } else {
+            result1 = null;
+            if (reportFailures === 0) {
+              matchFailed("\",\"");
+            }
+          }
+          if (result1 !== null) {
+            result2 = parse_ws();
+            if (result2 !== null) {
+              result3 = parse_segment();
+              if (result3 !== null) {
+                result0 = [result0, result1, result2, result3];
+              } else {
+                result0 = null;
+                pos = pos1;
+              }
+            } else {
+              result0 = null;
+              pos = pos1;
+            }
+          } else {
+            result0 = null;
+            pos = pos1;
+          }
+        } else {
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, seg) { return seg; })(pos0, result0[3]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
+        return result0;
+      }
+      
+      function parse_segment() {
+        var result0, result1, result2;
+        var pos0, pos1;
+        
+        pos0 = pos;
+        result0 = parse_string();
+        if (result0 !== null) {
+          result0 = (function(offset, str) { return {string: str}; })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
+        if (result0 === null) {
+          pos0 = pos;
+          pos1 = pos;
+          result0 = parse_identifier();
+          if (result0 !== null) {
+            result1 = parse_size();
+            result1 = result1 !== null ? result1 : "";
+            if (result1 !== null) {
+              result2 = parse_specifierList();
+              result2 = result2 !== null ? result2 : "";
+              if (result2 !== null) {
+                result0 = [result0, result1, result2];
+              } else {
+                result0 = null;
+                pos = pos1;
+              }
+            } else {
+              result0 = null;
+              pos = pos1;
+            }
+          } else {
+            result0 = null;
+            pos = pos1;
+          }
+          if (result0 !== null) {
+            result0 = (function(offset, v, size, specs) { return {name: v, size: size, specifiers: specs}; })(pos0, result0[0], result0[1], result0[2]);
+          }
+          if (result0 === null) {
+            pos = pos0;
+          }
+          if (result0 === null) {
+            pos0 = pos;
+            pos1 = pos;
+            result0 = parse_number();
+            if (result0 !== null) {
+              result1 = parse_size();
+              result1 = result1 !== null ? result1 : "";
+              if (result1 !== null) {
+                result2 = parse_specifierList();
+                result2 = result2 !== null ? result2 : "";
+                if (result2 !== null) {
+                  result0 = [result0, result1, result2];
+                } else {
+                  result0 = null;
+                  pos = pos1;
+                }
+              } else {
+                result0 = null;
+                pos = pos1;
+              }
+            } else {
+              result0 = null;
+              pos = pos1;
+            }
+            if (result0 !== null) {
+              result0 = (function(offset, v, size, specs) { return {value: v, size: size, specifiers: specs}; })(pos0, result0[0], result0[1], result0[2]);
+            }
+            if (result0 === null) {
+              pos = pos0;
+            }
+          }
+        }
+        return result0;
+      }
+      
+      function parse_string() {
+        var result0, result1, result2;
+        var pos0, pos1;
+        
+        pos0 = pos;
+        pos1 = pos;
+        if (input.charCodeAt(pos) === 34) {
+          result0 = "\"";
+          pos++;
+        } else {
+          result0 = null;
+          if (reportFailures === 0) {
+            matchFailed("\"\\\"\"");
+          }
+        }
+        if (result0 !== null) {
+          if (input.charCodeAt(pos) === 34) {
+            result1 = "\"";
+            pos++;
+          } else {
+            result1 = null;
+            if (reportFailures === 0) {
+              matchFailed("\"\\\"\"");
+            }
+          }
+          if (result1 !== null) {
+            result0 = [result0, result1];
+          } else {
+            result0 = null;
+            pos = pos1;
+          }
+        } else {
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset) { return "";    })(pos0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
+        if (result0 === null) {
+          pos0 = pos;
+          pos1 = pos;
+          if (input.charCodeAt(pos) === 34) {
+            result0 = "\"";
+            pos++;
+          } else {
+            result0 = null;
+            if (reportFailures === 0) {
+              matchFailed("\"\\\"\"");
+            }
+          }
+          if (result0 !== null) {
+            result1 = parse_chars();
+            if (result1 !== null) {
+              if (input.charCodeAt(pos) === 34) {
+                result2 = "\"";
+                pos++;
+              } else {
+                result2 = null;
+                if (reportFailures === 0) {
+                  matchFailed("\"\\\"\"");
+                }
+              }
+              if (result2 !== null) {
+                result0 = [result0, result1, result2];
+              } else {
+                result0 = null;
+                pos = pos1;
+              }
+            } else {
+              result0 = null;
+              pos = pos1;
+            }
+          } else {
+            result0 = null;
+            pos = pos1;
+          }
+          if (result0 !== null) {
+            result0 = (function(offset, chars) { return chars; })(pos0, result0[1]);
+          }
+          if (result0 === null) {
+            pos = pos0;
+          }
+        }
+        return result0;
+      }
+      
+      function parse_chars() {
+        var result0, result1;
+        var pos0;
+        
+        pos0 = pos;
+        result1 = parse_char();
+        if (result1 !== null) {
+          result0 = [];
+          while (result1 !== null) {
+            result0.push(result1);
+            result1 = parse_char();
+          }
+        } else {
+          result0 = null;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, chars) { return chars.join(""); })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
+        return result0;
+      }
+      
+      function parse_char() {
+        var result0, result1, result2, result3, result4;
+        var pos0, pos1;
+        
+        if (/^[^"\\\0-\x1F]/.test(input.charAt(pos))) {
+          result0 = input.charAt(pos);
+          pos++;
+        } else {
+          result0 = null;
+          if (reportFailures === 0) {
+            matchFailed("[^\"\\\\\\0-\\x1F]");
+          }
+        }
+        if (result0 === null) {
+          pos0 = pos;
+          if (input.substr(pos, 2) === "\\\"") {
+            result0 = "\\\"";
+            pos += 2;
+          } else {
+            result0 = null;
+            if (reportFailures === 0) {
+              matchFailed("\"\\\\\\\"\"");
+            }
+          }
+          if (result0 !== null) {
+            result0 = (function(offset) { return '"';  })(pos0);
+          }
+          if (result0 === null) {
+            pos = pos0;
+          }
+          if (result0 === null) {
+            pos0 = pos;
+            if (input.substr(pos, 2) === "\\\\") {
+              result0 = "\\\\";
+              pos += 2;
+            } else {
+              result0 = null;
+              if (reportFailures === 0) {
+                matchFailed("\"\\\\\\\\\"");
+              }
+            }
+            if (result0 !== null) {
+              result0 = (function(offset) { return "\\"; })(pos0);
+            }
+            if (result0 === null) {
+              pos = pos0;
+            }
+            if (result0 === null) {
+              pos0 = pos;
+              if (input.substr(pos, 2) === "\\/") {
+                result0 = "\\/";
+                pos += 2;
+              } else {
+                result0 = null;
+                if (reportFailures === 0) {
+                  matchFailed("\"\\\\/\"");
+                }
+              }
+              if (result0 !== null) {
+                result0 = (function(offset) { return "/";  })(pos0);
+              }
+              if (result0 === null) {
+                pos = pos0;
+              }
+              if (result0 === null) {
+                pos0 = pos;
+                if (input.substr(pos, 2) === "\\b") {
+                  result0 = "\\b";
+                  pos += 2;
+                } else {
+                  result0 = null;
+                  if (reportFailures === 0) {
+                    matchFailed("\"\\\\b\"");
+                  }
+                }
+                if (result0 !== null) {
+                  result0 = (function(offset) { return "\b"; })(pos0);
+                }
+                if (result0 === null) {
+                  pos = pos0;
+                }
+                if (result0 === null) {
+                  pos0 = pos;
+                  if (input.substr(pos, 2) === "\\f") {
+                    result0 = "\\f";
+                    pos += 2;
+                  } else {
+                    result0 = null;
+                    if (reportFailures === 0) {
+                      matchFailed("\"\\\\f\"");
+                    }
+                  }
+                  if (result0 !== null) {
+                    result0 = (function(offset) { return "\f"; })(pos0);
+                  }
+                  if (result0 === null) {
+                    pos = pos0;
+                  }
+                  if (result0 === null) {
+                    pos0 = pos;
+                    if (input.substr(pos, 2) === "\\n") {
+                      result0 = "\\n";
+                      pos += 2;
+                    } else {
+                      result0 = null;
+                      if (reportFailures === 0) {
+                        matchFailed("\"\\\\n\"");
+                      }
+                    }
+                    if (result0 !== null) {
+                      result0 = (function(offset) { return "\n"; })(pos0);
+                    }
+                    if (result0 === null) {
+                      pos = pos0;
+                    }
+                    if (result0 === null) {
+                      pos0 = pos;
+                      if (input.substr(pos, 2) === "\\r") {
+                        result0 = "\\r";
+                        pos += 2;
+                      } else {
+                        result0 = null;
+                        if (reportFailures === 0) {
+                          matchFailed("\"\\\\r\"");
+                        }
+                      }
+                      if (result0 !== null) {
+                        result0 = (function(offset) { return "\r"; })(pos0);
+                      }
+                      if (result0 === null) {
+                        pos = pos0;
+                      }
+                      if (result0 === null) {
+                        pos0 = pos;
+                        if (input.substr(pos, 2) === "\\t") {
+                          result0 = "\\t";
+                          pos += 2;
+                        } else {
+                          result0 = null;
+                          if (reportFailures === 0) {
+                            matchFailed("\"\\\\t\"");
+                          }
+                        }
+                        if (result0 !== null) {
+                          result0 = (function(offset) { return "\t"; })(pos0);
+                        }
+                        if (result0 === null) {
+                          pos = pos0;
+                        }
+                        if (result0 === null) {
+                          pos0 = pos;
+                          pos1 = pos;
+                          if (input.substr(pos, 2) === "\\u") {
+                            result0 = "\\u";
+                            pos += 2;
+                          } else {
+                            result0 = null;
+                            if (reportFailures === 0) {
+                              matchFailed("\"\\\\u\"");
+                            }
+                          }
+                          if (result0 !== null) {
+                            result1 = parse_hexDigit();
+                            if (result1 !== null) {
+                              result2 = parse_hexDigit();
+                              if (result2 !== null) {
+                                result3 = parse_hexDigit();
+                                if (result3 !== null) {
+                                  result4 = parse_hexDigit();
+                                  if (result4 !== null) {
+                                    result0 = [result0, result1, result2, result3, result4];
+                                  } else {
+                                    result0 = null;
+                                    pos = pos1;
+                                  }
+                                } else {
+                                  result0 = null;
+                                  pos = pos1;
+                                }
+                              } else {
+                                result0 = null;
+                                pos = pos1;
+                              }
+                            } else {
+                              result0 = null;
+                              pos = pos1;
+                            }
+                          } else {
+                            result0 = null;
+                            pos = pos1;
+                          }
+                          if (result0 !== null) {
+                            result0 = (function(offset, h1, h2, h3, h4) {
+                                return String.fromCharCode(parseInt("0x" + h1 + h2 + h3 + h4));
+                              })(pos0, result0[1], result0[2], result0[3], result0[4]);
+                          }
+                          if (result0 === null) {
+                            pos = pos0;
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+        return result0;
+      }
+      
+      function parse_hexDigit() {
+        var result0;
+        
+        if (/^[0-9a-fA-F]/.test(input.charAt(pos))) {
+          result0 = input.charAt(pos);
+          pos++;
+        } else {
+          result0 = null;
+          if (reportFailures === 0) {
+            matchFailed("[0-9a-fA-F]");
+          }
+        }
+        return result0;
+      }
+      
+      function parse_identifier() {
+        var result0, result1, result2;
+        var pos0, pos1;
+        
+        pos0 = pos;
+        pos1 = pos;
+        if (/^[_a-zA-Z]/.test(input.charAt(pos))) {
+          result0 = input.charAt(pos);
+          pos++;
+        } else {
+          result0 = null;
+          if (reportFailures === 0) {
+            matchFailed("[_a-zA-Z]");
+          }
+        }
+        if (result0 !== null) {
+          result1 = [];
+          if (/^[_a-zA-Z0-9]/.test(input.charAt(pos))) {
+            result2 = input.charAt(pos);
+            pos++;
+          } else {
+            result2 = null;
+            if (reportFailures === 0) {
+              matchFailed("[_a-zA-Z0-9]");
+            }
+          }
+          while (result2 !== null) {
+            result1.push(result2);
+            if (/^[_a-zA-Z0-9]/.test(input.charAt(pos))) {
+              result2 = input.charAt(pos);
+              pos++;
+            } else {
+              result2 = null;
+              if (reportFailures === 0) {
+                matchFailed("[_a-zA-Z0-9]");
+              }
+            }
+          }
+          if (result1 !== null) {
+            result0 = [result0, result1];
+          } else {
+            result0 = null;
+            pos = pos1;
+          }
+        } else {
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, head, tail) { return head + tail.join(''); })(pos0, result0[0], result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
+        return result0;
+      }
+      
+      function parse_number() {
+        var result0, result1, result2;
+        var pos0, pos1;
+        
+        pos0 = pos;
+        if (input.charCodeAt(pos) === 48) {
+          result0 = "0";
+          pos++;
+        } else {
+          result0 = null;
+          if (reportFailures === 0) {
+            matchFailed("\"0\"");
+          }
+        }
+        if (result0 !== null) {
+          result0 = (function(offset) { return 0; })(pos0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
+        if (result0 === null) {
+          pos0 = pos;
+          pos1 = pos;
+          if (/^[1-9]/.test(input.charAt(pos))) {
+            result0 = input.charAt(pos);
+            pos++;
+          } else {
+            result0 = null;
+            if (reportFailures === 0) {
+              matchFailed("[1-9]");
+            }
+          }
+          if (result0 !== null) {
+            result1 = [];
+            if (/^[0-9]/.test(input.charAt(pos))) {
+              result2 = input.charAt(pos);
+              pos++;
+            } else {
+              result2 = null;
+              if (reportFailures === 0) {
+                matchFailed("[0-9]");
+              }
+            }
+            while (result2 !== null) {
+              result1.push(result2);
+              if (/^[0-9]/.test(input.charAt(pos))) {
+                result2 = input.charAt(pos);
+                pos++;
+              } else {
+                result2 = null;
+                if (reportFailures === 0) {
+                  matchFailed("[0-9]");
+                }
+              }
+            }
+            if (result1 !== null) {
+              result0 = [result0, result1];
+            } else {
+              result0 = null;
+              pos = pos1;
+            }
+          } else {
+            result0 = null;
+            pos = pos1;
+          }
+          if (result0 !== null) {
+            result0 = (function(offset, head, tail) { return parseInt(head + tail.join('')); })(pos0, result0[0], result0[1]);
+          }
+          if (result0 === null) {
+            pos = pos0;
+          }
+        }
+        return result0;
+      }
+      
+      function parse_size() {
+        var result0, result1;
+        var pos0, pos1;
+        
+        pos0 = pos;
+        pos1 = pos;
+        if (input.charCodeAt(pos) === 58) {
+          result0 = ":";
+          pos++;
+        } else {
+          result0 = null;
+          if (reportFailures === 0) {
+            matchFailed("\":\"");
+          }
+        }
+        if (result0 !== null) {
+          result1 = parse_number();
+          if (result1 !== null) {
+            result0 = [result0, result1];
+          } else {
+            result0 = null;
+            pos = pos1;
+          }
+        } else {
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, num) { return num; })(pos0, result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
+        if (result0 === null) {
+          pos0 = pos;
+          pos1 = pos;
+          if (input.charCodeAt(pos) === 58) {
+            result0 = ":";
+            pos++;
+          } else {
+            result0 = null;
+            if (reportFailures === 0) {
+              matchFailed("\":\"");
+            }
+          }
+          if (result0 !== null) {
+            result1 = parse_identifier();
+            if (result1 !== null) {
+              result0 = [result0, result1];
+            } else {
+              result0 = null;
+              pos = pos1;
+            }
+          } else {
+            result0 = null;
+            pos = pos1;
+          }
+          if (result0 !== null) {
+            result0 = (function(offset, id) { return id; })(pos0, result0[1]);
+          }
+          if (result0 === null) {
+            pos = pos0;
+          }
+        }
+        return result0;
+      }
+      
+      function parse_specifierList() {
+        var result0, result1, result2, result3;
+        var pos0, pos1;
+        
+        pos0 = pos;
+        pos1 = pos;
+        if (input.charCodeAt(pos) === 47) {
+          result0 = "/";
+          pos++;
+        } else {
+          result0 = null;
+          if (reportFailures === 0) {
+            matchFailed("\"/\"");
+          }
+        }
+        if (result0 !== null) {
+          result1 = parse_specifier();
+          if (result1 !== null) {
+            result2 = [];
+            result3 = parse_specifierTail();
+            while (result3 !== null) {
+              result2.push(result3);
+              result3 = parse_specifierTail();
+            }
+            if (result2 !== null) {
+              result0 = [result0, result1, result2];
+            } else {
+              result0 = null;
+              pos = pos1;
+            }
+          } else {
+            result0 = null;
+            pos = pos1;
+          }
+        } else {
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, head, tail) { tail.unshift(head); return tail; })(pos0, result0[1], result0[2]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
+        return result0;
+      }
+      
+      function parse_specifierTail() {
+        var result0, result1;
+        var pos0, pos1;
+        
+        pos0 = pos;
+        pos1 = pos;
+        if (input.charCodeAt(pos) === 45) {
+          result0 = "-";
+          pos++;
+        } else {
+          result0 = null;
+          if (reportFailures === 0) {
+            matchFailed("\"-\"");
+          }
+        }
+        if (result0 !== null) {
+          result1 = parse_specifier();
+          if (result1 !== null) {
+            result0 = [result0, result1];
+          } else {
+            result0 = null;
+            pos = pos1;
+          }
+        } else {
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, spec) { return spec; })(pos0, result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
+        return result0;
+      }
+      
+      function parse_specifier() {
+        var result0;
+        
+        if (input.substr(pos, 6) === "little") {
+          result0 = "little";
+          pos += 6;
+        } else {
+          result0 = null;
+          if (reportFailures === 0) {
+            matchFailed("\"little\"");
+          }
+        }
+        if (result0 === null) {
+          if (input.substr(pos, 3) === "big") {
+            result0 = "big";
+            pos += 3;
+          } else {
+            result0 = null;
+            if (reportFailures === 0) {
+              matchFailed("\"big\"");
+            }
+          }
+          if (result0 === null) {
+            if (input.substr(pos, 6) === "signed") {
+              result0 = "signed";
+              pos += 6;
+            } else {
+              result0 = null;
+              if (reportFailures === 0) {
+                matchFailed("\"signed\"");
+              }
+            }
+            if (result0 === null) {
+              if (input.substr(pos, 8) === "unsigned") {
+                result0 = "unsigned";
+                pos += 8;
+              } else {
+                result0 = null;
+                if (reportFailures === 0) {
+                  matchFailed("\"unsigned\"");
+                }
+              }
+              if (result0 === null) {
+                if (input.substr(pos, 7) === "integer") {
+                  result0 = "integer";
+                  pos += 7;
+                } else {
+                  result0 = null;
+                  if (reportFailures === 0) {
+                    matchFailed("\"integer\"");
+                  }
+                }
+                if (result0 === null) {
+                  if (input.substr(pos, 6) === "binary") {
+                    result0 = "binary";
+                    pos += 6;
+                  } else {
+                    result0 = null;
+                    if (reportFailures === 0) {
+                      matchFailed("\"binary\"");
+                    }
+                  }
+                  if (result0 === null) {
+                    if (input.substr(pos, 5) === "float") {
+                      result0 = "float";
+                      pos += 5;
+                    } else {
+                      result0 = null;
+                      if (reportFailures === 0) {
+                        matchFailed("\"float\"");
+                      }
+                    }
+                    if (result0 === null) {
+                      result0 = parse_unit();
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+        return result0;
+      }
+      
+      function parse_unit() {
+        var result0, result1;
+        var pos0, pos1;
+        
+        pos0 = pos;
+        pos1 = pos;
+        if (input.substr(pos, 5) === "unit:") {
+          result0 = "unit:";
+          pos += 5;
+        } else {
+          result0 = null;
+          if (reportFailures === 0) {
+            matchFailed("\"unit:\"");
+          }
+        }
+        if (result0 !== null) {
+          result1 = parse_number();
+          if (result1 !== null) {
+            result0 = [result0, result1];
+          } else {
+            result0 = null;
+            pos = pos1;
+          }
+        } else {
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, num) { return 'unit:' + num; })(pos0, result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
+        return result0;
+      }
+      
+      function parse_ws() {
+        var result0, result1;
+        
+        result0 = [];
+        if (/^[ \t\n]/.test(input.charAt(pos))) {
+          result1 = input.charAt(pos);
+          pos++;
+        } else {
+          result1 = null;
+          if (reportFailures === 0) {
+            matchFailed("[ \\t\\n]");
+          }
+        }
+        while (result1 !== null) {
+          result0.push(result1);
+          if (/^[ \t\n]/.test(input.charAt(pos))) {
+            result1 = input.charAt(pos);
+            pos++;
+          } else {
+            result1 = null;
+            if (reportFailures === 0) {
+              matchFailed("[ \\t\\n]");
+            }
+          }
+        }
+        return result0;
+      }
+      
+      
+      function cleanupExpected(expected) {
+        expected.sort();
+        
+        var lastExpected = null;
+        var cleanExpected = [];
+        for (var i = 0; i < expected.length; i++) {
+          if (expected[i] !== lastExpected) {
+            cleanExpected.push(expected[i]);
+            lastExpected = expected[i];
+          }
+        }
+        return cleanExpected;
+      }
+      
+      function computeErrorPosition() {
+        /*
+         * The first idea was to use |String.split| to break the input up to the
+         * error position along newlines and derive the line and column from
+         * there. However IE's |split| implementation is so broken that it was
+         * enough to prevent it.
+         */
+        
+        var line = 1;
+        var column = 1;
+        var seenCR = false;
+        
+        for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) {
+          var ch = input.charAt(i);
+          if (ch === "\n") {
+            if (!seenCR) { line++; }
+            column = 1;
+            seenCR = false;
+          } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") {
+            line++;
+            column = 1;
+            seenCR = true;
+          } else {
+            column++;
+            seenCR = false;
+          }
+        }
+        
+        return { line: line, column: column };
+      }
+      
+      
+      var result = parseFunctions[startRule]();
+      
+      /*
+       * The parser is now in one of the following three states:
+       *
+       * 1. The parser successfully parsed the whole input.
+       *
+       *    - |result !== null|
+       *    - |pos === input.length|
+       *    - |rightmostFailuresExpected| may or may not contain something
+       *
+       * 2. The parser successfully parsed only a part of the input.
+       *
+       *    - |result !== null|
+       *    - |pos < input.length|
+       *    - |rightmostFailuresExpected| may or may not contain something
+       *
+       * 3. The parser did not successfully parse any part of the input.
+       *
+       *   - |result === null|
+       *   - |pos === 0|
+       *   - |rightmostFailuresExpected| contains at least one failure
+       *
+       * All code following this comment (including called functions) must
+       * handle these states.
+       */
+      if (result === null || pos !== input.length) {
+        var offset = Math.max(pos, rightmostFailuresPos);
+        var found = offset < input.length ? input.charAt(offset) : null;
+        var errorPosition = computeErrorPosition();
+        
+        throw new this.SyntaxError(
+          cleanupExpected(rightmostFailuresExpected),
+          found,
+          offset,
+          errorPosition.line,
+          errorPosition.column
+        );
+      }
+      
+      return result;
+    },
+    
+    /* Returns the parser source code. */
+    toSource: function() { return this._source; }
+  };
+  
+  /* Thrown when a parser encounters a syntax error. */
+  
+  result.SyntaxError = function(expected, found, offset, line, column) {
+    function buildMessage(expected, found) {
+      var expectedHumanized, foundHumanized;
+      
+      switch (expected.length) {
+        case 0:
+          expectedHumanized = "end of input";
+          break;
+        case 1:
+          expectedHumanized = expected[0];
+          break;
+        default:
+          expectedHumanized = expected.slice(0, expected.length - 1).join(", ")
+            + " or "
+            + expected[expected.length - 1];
+      }
+      
+      foundHumanized = found ? quote(found) : "end of input";
+      
+      return "Expected " + expectedHumanized + " but " + foundHumanized + " found.";
+    }
+    
+    this.name = "SyntaxError";
+    this.expected = expected;
+    this.found = found;
+    this.message = buildMessage(expected, found);
+    this.offset = offset;
+    this.line = line;
+    this.column = column;
+  };
+  
+  result.SyntaxError.prototype = Error.prototype;
+  
+  return result;
+})();

+ 119 - 0
node_modules/@acuminous/bitsyntax/lib/pattern.js

@@ -0,0 +1,119 @@
+// -*- js-indent-level: 2 -*-
+// Constructing patterns
+
+'use strict';
+
+function set(values) {
+  var s = {};
+  for (var i in values) {
+    if (!Object.prototype.hasOwnProperty.call(values, i)) continue;
+    s[values[i]] = 1;
+  }
+  return s;
+}
+
+// Construct a segment bound to a variable, e.g., from a segment like
+// "Len:32/unsigned-big". `specifiers0` is an array.
+function variable(name, size, specifiers0) {
+  var specifiers = set(specifiers0);
+  var segment = {name: name};
+  segment.type = type_in(specifiers);
+  specs(segment, segment.type, specifiers);
+  segment.size = size_of(segment, segment.type, size, segment.unit);
+  return segment;
+}
+
+module.exports.variable = variable;
+module.exports.rest = function() {
+  return variable('_', true, ['binary']);
+}
+
+// Construct a segment with a literal value, e.g., from a segment like
+// "206". `specifiers0` is an array.
+
+function value(val, size, specifiers0) {
+  var specifiers = set(specifiers0);
+  var segment = {value: val};
+  segment.type = type_in(specifiers);
+  // TODO check type v. value ..
+  specs(segment, segment.type, specifiers);
+  segment.size = size_of(segment, segment.type, size, segment.unit);
+  return segment;
+}
+
+module.exports.value = value;
+
+// A string can appear as a literal, but it must appear without
+// specifiers.
+function string(val) {
+  return {value: val, type: 'string'};
+}
+module.exports.string = string;
+
+var TYPES = {'integer': 1, 'binary': 1, 'float': 1};
+function type_in(specifiers) {
+  for (var t in specifiers) {
+    if (!Object.prototype.hasOwnProperty.call(specifiers, t)) continue;
+    if (TYPES[t]) { return t; }
+  }
+  return 'integer';
+}
+
+function specs(segment, type, specifiers) {
+  switch (type) {
+  case 'integer':
+    segment.signed = signed_in(specifiers);
+    // fall through
+  case 'float':
+    segment.bigendian = endian_in(specifiers);
+    // fall through
+  default:
+    segment.unit = unit_in(specifiers, segment.type);
+  }
+  return segment;
+}
+
+function endian_in(specifiers) {
+  // default is big, but I have chosen true = bigendian
+  return !specifiers['little'];
+}
+
+function signed_in(specifiers) {
+  // this time I got it right; default is unsigned
+  return specifiers['signed'];
+}
+
+function unit_in(specifiers, type) {
+  for (var s in specifiers) {
+    if (!Object.prototype.hasOwnProperty.call(specifiers, s)) continue;
+    if (s.substr(0, 5) == 'unit:') {
+      var unit = parseInt(s.substr(5));
+      // TODO check sane for type
+      return unit;
+    }
+  }
+  // OK defaults then
+  switch (type) {
+  case 'binary':
+    return 8;
+  case 'integer':
+  case 'float':
+    return 1;
+  }
+}
+
+function size_of(segment, type, size, unit) {
+  if (size !== undefined && size !== '') {
+    return size;
+  }
+  else {
+    switch (type) {
+    case 'integer':
+      return 8;
+    case 'float':
+      return 64;
+    case 'binary':
+      return true;
+    }
+  }
+}

+ 20 - 0
node_modules/@acuminous/bitsyntax/node_modules/debug/LICENSE

@@ -0,0 +1,20 @@
+(The MIT License)
+
+Copyright (c) 2014-2017 TJ Holowaychuk <tj@vision-media.ca>
+Copyright (c) 2018-2021 Josh Junon
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+and associated documentation files (the 'Software'), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+

+ 481 - 0
node_modules/@acuminous/bitsyntax/node_modules/debug/README.md

@@ -0,0 +1,481 @@
+# debug
+[![OpenCollective](https://opencollective.com/debug/backers/badge.svg)](#backers)
+[![OpenCollective](https://opencollective.com/debug/sponsors/badge.svg)](#sponsors)
+
+<img width="647" src="https://user-images.githubusercontent.com/71256/29091486-fa38524c-7c37-11e7-895f-e7ec8e1039b6.png">
+
+A tiny JavaScript debugging utility modelled after Node.js core's debugging
+technique. Works in Node.js and web browsers.
+
+## Installation
+
+```bash
+$ npm install debug
+```
+
+## Usage
+
+`debug` exposes a function; simply pass this function the name of your module, and it will return a decorated version of `console.error` for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole.
+
+Example [_app.js_](./examples/node/app.js):
+
+```js
+var debug = require('debug')('http')
+  , http = require('http')
+  , name = 'My App';
+
+// fake app
+
+debug('booting %o', name);
+
+http.createServer(function(req, res){
+  debug(req.method + ' ' + req.url);
+  res.end('hello\n');
+}).listen(3000, function(){
+  debug('listening');
+});
+
+// fake worker of some kind
+
+require('./worker');
+```
+
+Example [_worker.js_](./examples/node/worker.js):
+
+```js
+var a = require('debug')('worker:a')
+  , b = require('debug')('worker:b');
+
+function work() {
+  a('doing lots of uninteresting work');
+  setTimeout(work, Math.random() * 1000);
+}
+
+work();
+
+function workb() {
+  b('doing some work');
+  setTimeout(workb, Math.random() * 2000);
+}
+
+workb();
+```
+
+The `DEBUG` environment variable is then used to enable these based on space or
+comma-delimited names.
+
+Here are some examples:
+
+<img width="647" alt="screen shot 2017-08-08 at 12 53 04 pm" src="https://user-images.githubusercontent.com/71256/29091703-a6302cdc-7c38-11e7-8304-7c0b3bc600cd.png">
+<img width="647" alt="screen shot 2017-08-08 at 12 53 38 pm" src="https://user-images.githubusercontent.com/71256/29091700-a62a6888-7c38-11e7-800b-db911291ca2b.png">
+<img width="647" alt="screen shot 2017-08-08 at 12 53 25 pm" src="https://user-images.githubusercontent.com/71256/29091701-a62ea114-7c38-11e7-826a-2692bedca740.png">
+
+#### Windows command prompt notes
+
+##### CMD
+
+On Windows the environment variable is set using the `set` command.
+
+```cmd
+set DEBUG=*,-not_this
+```
+
+Example:
+
+```cmd
+set DEBUG=* & node app.js
+```
+
+##### PowerShell (VS Code default)
+
+PowerShell uses different syntax to set environment variables.
+
+```cmd
+$env:DEBUG = "*,-not_this"
+```
+
+Example:
+
+```cmd
+$env:DEBUG='app';node app.js
+```
+
+Then, run the program to be debugged as usual.
+
+npm script example:
+```js
+  "windowsDebug": "@powershell -Command $env:DEBUG='*';node app.js",
+```
+
+## Namespace Colors
+
+Every debug instance has a color generated for it based on its namespace name.
+This helps when visually parsing the debug output to identify which debug instance
+a debug line belongs to.
+
+#### Node.js
+
+In Node.js, colors are enabled when stderr is a TTY. You also _should_ install
+the [`supports-color`](https://npmjs.org/supports-color) module alongside debug,
+otherwise debug will only use a small handful of basic colors.
+
+<img width="521" src="https://user-images.githubusercontent.com/71256/29092181-47f6a9e6-7c3a-11e7-9a14-1928d8a711cd.png">
+
+#### Web Browser
+
+Colors are also enabled on "Web Inspectors" that understand the `%c` formatting
+option. These are WebKit web inspectors, Firefox ([since version
+31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/))
+and the Firebug plugin for Firefox (any version).
+
+<img width="524" src="https://user-images.githubusercontent.com/71256/29092033-b65f9f2e-7c39-11e7-8e32-f6f0d8e865c1.png">
+
+
+## Millisecond diff
+
+When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls.
+
+<img width="647" src="https://user-images.githubusercontent.com/71256/29091486-fa38524c-7c37-11e7-895f-e7ec8e1039b6.png">
+
+When stdout is not a TTY, `Date#toISOString()` is used, making it more useful for logging the debug information as shown below:
+
+<img width="647" src="https://user-images.githubusercontent.com/71256/29091956-6bd78372-7c39-11e7-8c55-c948396d6edd.png">
+
+
+## Conventions
+
+If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser".  If you append a "*" to the end of your name, it will always be enabled regardless of the setting of the DEBUG environment variable.  You can then use it for normal output as well as debug output.
+
+## Wildcards
+
+The `*` character may be used as a wildcard. Suppose for example your library has
+debuggers named "connect:bodyParser", "connect:compress", "connect:session",
+instead of listing all three with
+`DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do
+`DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.
+
+You can also exclude specific debuggers by prefixing them with a "-" character.
+For example, `DEBUG=*,-connect:*` would include all debuggers except those
+starting with "connect:".
+
+## Environment Variables
+
+When running through Node.js, you can set a few environment variables that will
+change the behavior of the debug logging:
+
+| Name      | Purpose                                         |
+|-----------|-------------------------------------------------|
+| `DEBUG`   | Enables/disables specific debugging namespaces. |
+| `DEBUG_HIDE_DATE` | Hide date from debug output (non-TTY).  |
+| `DEBUG_COLORS`| Whether or not to use colors in the debug output. |
+| `DEBUG_DEPTH` | Object inspection depth.                    |
+| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. |
+
+
+__Note:__ The environment variables beginning with `DEBUG_` end up being
+converted into an Options object that gets used with `%o`/`%O` formatters.
+See the Node.js documentation for
+[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options)
+for the complete list.
+
+## Formatters
+
+Debug uses [printf-style](https://wikipedia.org/wiki/Printf_format_string) formatting.
+Below are the officially supported formatters:
+
+| Formatter | Representation |
+|-----------|----------------|
+| `%O`      | Pretty-print an Object on multiple lines. |
+| `%o`      | Pretty-print an Object all on a single line. |
+| `%s`      | String. |
+| `%d`      | Number (both integer and float). |
+| `%j`      | JSON. Replaced with the string '[Circular]' if the argument contains circular references. |
+| `%%`      | Single percent sign ('%'). This does not consume an argument. |
+
+
+### Custom formatters
+
+You can add custom formatters by extending the `debug.formatters` object.
+For example, if you wanted to add support for rendering a Buffer as hex with
+`%h`, you could do something like:
+
+```js
+const createDebug = require('debug')
+createDebug.formatters.h = (v) => {
+  return v.toString('hex')
+}
+
+// …elsewhere
+const debug = createDebug('foo')
+debug('this is hex: %h', new Buffer('hello world'))
+//   foo this is hex: 68656c6c6f20776f726c6421 +0ms
+```
+
+
+## Browser Support
+
+You can build a browser-ready script using [browserify](https://github.com/substack/node-browserify),
+or just use the [browserify-as-a-service](https://wzrd.in/) [build](https://wzrd.in/standalone/debug@latest),
+if you don't want to build it yourself.
+
+Debug's enable state is currently persisted by `localStorage`.
+Consider the situation shown below where you have `worker:a` and `worker:b`,
+and wish to debug both. You can enable this using `localStorage.debug`:
+
+```js
+localStorage.debug = 'worker:*'
+```
+
+And then refresh the page.
+
+```js
+a = debug('worker:a');
+b = debug('worker:b');
+
+setInterval(function(){
+  a('doing some work');
+}, 1000);
+
+setInterval(function(){
+  b('doing some work');
+}, 1200);
+```
+
+In Chromium-based web browsers (e.g. Brave, Chrome, and Electron), the JavaScript console will—by default—only show messages logged by `debug` if the "Verbose" log level is _enabled_.
+
+<img width="647" src="https://user-images.githubusercontent.com/7143133/152083257-29034707-c42c-4959-8add-3cee850e6fcf.png">
+
+## Output streams
+
+  By default `debug` will log to stderr, however this can be configured per-namespace by overriding the `log` method:
+
+Example [_stdout.js_](./examples/node/stdout.js):
+
+```js
+var debug = require('debug');
+var error = debug('app:error');
+
+// by default stderr is used
+error('goes to stderr!');
+
+var log = debug('app:log');
+// set this namespace to log via console.log
+log.log = console.log.bind(console); // don't forget to bind to console!
+log('goes to stdout');
+error('still goes to stderr!');
+
+// set all output to go via console.info
+// overrides all per-namespace log settings
+debug.log = console.info.bind(console);
+error('now goes to stdout via console.info');
+log('still goes to stdout, but via console.info now');
+```
+
+## Extend
+You can simply extend debugger 
+```js
+const log = require('debug')('auth');
+
+//creates new debug instance with extended namespace
+const logSign = log.extend('sign');
+const logLogin = log.extend('login');
+
+log('hello'); // auth hello
+logSign('hello'); //auth:sign hello
+logLogin('hello'); //auth:login hello
+```
+
+## Set dynamically
+
+You can also enable debug dynamically by calling the `enable()` method :
+
+```js
+let debug = require('debug');
+
+console.log(1, debug.enabled('test'));
+
+debug.enable('test');
+console.log(2, debug.enabled('test'));
+
+debug.disable();
+console.log(3, debug.enabled('test'));
+
+```
+
+print :   
+```
+1 false
+2 true
+3 false
+```
+
+Usage :  
+`enable(namespaces)`  
+`namespaces` can include modes separated by a colon and wildcards.
+   
+Note that calling `enable()` completely overrides previously set DEBUG variable : 
+
+```
+$ DEBUG=foo node -e 'var dbg = require("debug"); dbg.enable("bar"); console.log(dbg.enabled("foo"))'
+=> false
+```
+
+`disable()`
+
+Will disable all namespaces. The functions returns the namespaces currently
+enabled (and skipped). This can be useful if you want to disable debugging
+temporarily without knowing what was enabled to begin with.
+
+For example:
+
+```js
+let debug = require('debug');
+debug.enable('foo:*,-foo:bar');
+let namespaces = debug.disable();
+debug.enable(namespaces);
+```
+
+Note: There is no guarantee that the string will be identical to the initial
+enable string, but semantically they will be identical.
+
+## Checking whether a debug target is enabled
+
+After you've created a debug instance, you can determine whether or not it is
+enabled by checking the `enabled` property:
+
+```javascript
+const debug = require('debug')('http');
+
+if (debug.enabled) {
+  // do stuff...
+}
+```
+
+You can also manually toggle this property to force the debug instance to be
+enabled or disabled.
+
+## Usage in child processes
+
+Due to the way `debug` detects if the output is a TTY or not, colors are not shown in child processes when `stderr` is piped. A solution is to pass the `DEBUG_COLORS=1` environment variable to the child process.  
+For example:
+
+```javascript
+worker = fork(WORKER_WRAP_PATH, [workerPath], {
+  stdio: [
+    /* stdin: */ 0,
+    /* stdout: */ 'pipe',
+    /* stderr: */ 'pipe',
+    'ipc',
+  ],
+  env: Object.assign({}, process.env, {
+    DEBUG_COLORS: 1 // without this settings, colors won't be shown
+  }),
+});
+
+worker.stderr.pipe(process.stderr, { end: false });
+```
+
+
+## Authors
+
+ - TJ Holowaychuk
+ - Nathan Rajlich
+ - Andrew Rhyne
+ - Josh Junon
+
+## Backers
+
+Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/debug#backer)]
+
+<a href="https://opencollective.com/debug/backer/0/website" target="_blank"><img src="https://opencollective.com/debug/backer/0/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/1/website" target="_blank"><img src="https://opencollective.com/debug/backer/1/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/2/website" target="_blank"><img src="https://opencollective.com/debug/backer/2/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/3/website" target="_blank"><img src="https://opencollective.com/debug/backer/3/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/4/website" target="_blank"><img src="https://opencollective.com/debug/backer/4/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/5/website" target="_blank"><img src="https://opencollective.com/debug/backer/5/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/6/website" target="_blank"><img src="https://opencollective.com/debug/backer/6/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/7/website" target="_blank"><img src="https://opencollective.com/debug/backer/7/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/8/website" target="_blank"><img src="https://opencollective.com/debug/backer/8/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/9/website" target="_blank"><img src="https://opencollective.com/debug/backer/9/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/10/website" target="_blank"><img src="https://opencollective.com/debug/backer/10/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/11/website" target="_blank"><img src="https://opencollective.com/debug/backer/11/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/12/website" target="_blank"><img src="https://opencollective.com/debug/backer/12/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/13/website" target="_blank"><img src="https://opencollective.com/debug/backer/13/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/14/website" target="_blank"><img src="https://opencollective.com/debug/backer/14/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/15/website" target="_blank"><img src="https://opencollective.com/debug/backer/15/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/16/website" target="_blank"><img src="https://opencollective.com/debug/backer/16/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/17/website" target="_blank"><img src="https://opencollective.com/debug/backer/17/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/18/website" target="_blank"><img src="https://opencollective.com/debug/backer/18/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/19/website" target="_blank"><img src="https://opencollective.com/debug/backer/19/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/20/website" target="_blank"><img src="https://opencollective.com/debug/backer/20/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/21/website" target="_blank"><img src="https://opencollective.com/debug/backer/21/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/22/website" target="_blank"><img src="https://opencollective.com/debug/backer/22/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/23/website" target="_blank"><img src="https://opencollective.com/debug/backer/23/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/24/website" target="_blank"><img src="https://opencollective.com/debug/backer/24/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/25/website" target="_blank"><img src="https://opencollective.com/debug/backer/25/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/26/website" target="_blank"><img src="https://opencollective.com/debug/backer/26/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/27/website" target="_blank"><img src="https://opencollective.com/debug/backer/27/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/28/website" target="_blank"><img src="https://opencollective.com/debug/backer/28/avatar.svg"></a>
+<a href="https://opencollective.com/debug/backer/29/website" target="_blank"><img src="https://opencollective.com/debug/backer/29/avatar.svg"></a>
+
+
+## Sponsors
+
+Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/debug#sponsor)]
+
+<a href="https://opencollective.com/debug/sponsor/0/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/0/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/1/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/1/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/2/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/2/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/3/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/3/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/4/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/4/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/5/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/5/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/6/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/6/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/7/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/7/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/8/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/8/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/9/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/9/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/10/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/10/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/11/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/11/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/12/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/12/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/13/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/13/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/14/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/14/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/15/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/15/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/16/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/16/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/17/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/17/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/18/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/18/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/19/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/19/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/20/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/20/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/21/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/21/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/22/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/22/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/23/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/23/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/24/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/24/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/25/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/25/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/26/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/26/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/27/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/27/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/28/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/28/avatar.svg"></a>
+<a href="https://opencollective.com/debug/sponsor/29/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/29/avatar.svg"></a>
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2014-2017 TJ Holowaychuk &lt;tj@vision-media.ca&gt;
+Copyright (c) 2018-2021 Josh Junon
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 60 - 0
node_modules/@acuminous/bitsyntax/node_modules/debug/package.json

@@ -0,0 +1,60 @@
+{
+  "name": "debug",
+  "version": "4.3.7",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/debug-js/debug.git"
+  },
+  "description": "Lightweight debugging utility for Node.js and the browser",
+  "keywords": [
+    "debug",
+    "log",
+    "debugger"
+  ],
+  "files": [
+    "src",
+    "LICENSE",
+    "README.md"
+  ],
+  "author": "Josh Junon (https://github.com/qix-)",
+  "contributors": [
+    "TJ Holowaychuk <tj@vision-media.ca>",
+    "Nathan Rajlich <nathan@tootallnate.net> (http://n8.io)",
+    "Andrew Rhyne <rhyneandrew@gmail.com>"
+  ],
+  "license": "MIT",
+  "scripts": {
+    "lint": "xo",
+    "test": "npm run test:node && npm run test:browser && npm run lint",
+    "test:node": "istanbul cover _mocha -- test.js test.node.js",
+    "test:browser": "karma start --single-run",
+    "test:coverage": "cat ./coverage/lcov.info | coveralls"
+  },
+  "dependencies": {
+    "ms": "^2.1.3"
+  },
+  "devDependencies": {
+    "brfs": "^2.0.1",
+    "browserify": "^16.2.3",
+    "coveralls": "^3.0.2",
+    "istanbul": "^0.4.5",
+    "karma": "^3.1.4",
+    "karma-browserify": "^6.0.0",
+    "karma-chrome-launcher": "^2.2.0",
+    "karma-mocha": "^1.3.0",
+    "mocha": "^5.2.0",
+    "mocha-lcov-reporter": "^1.2.0",
+    "sinon": "^14.0.0",
+    "xo": "^0.23.0"
+  },
+  "peerDependenciesMeta": {
+    "supports-color": {
+      "optional": true
+    }
+  },
+  "main": "./src/index.js",
+  "browser": "./src/browser.js",
+  "engines": {
+    "node": ">=6.0"
+  }
+}

+ 271 - 0
node_modules/@acuminous/bitsyntax/node_modules/debug/src/browser.js

@@ -0,0 +1,271 @@
+/* eslint-env browser */
+
+/**
+ * This is the web browser implementation of `debug()`.
+ */
+
+exports.formatArgs = formatArgs;
+exports.save = save;
+exports.load = load;
+exports.useColors = useColors;
+exports.storage = localstorage();
+exports.destroy = (() => {
+	let warned = false;
+
+	return () => {
+		if (!warned) {
+			warned = true;
+			console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
+		}
+	};
+})();
+
+/**
+ * Colors.
+ */
+
+exports.colors = [
+	'#0000CC',
+	'#0000FF',
+	'#0033CC',
+	'#0033FF',
+	'#0066CC',
+	'#0066FF',
+	'#0099CC',
+	'#0099FF',
+	'#00CC00',
+	'#00CC33',
+	'#00CC66',
+	'#00CC99',
+	'#00CCCC',
+	'#00CCFF',
+	'#3300CC',
+	'#3300FF',
+	'#3333CC',
+	'#3333FF',
+	'#3366CC',
+	'#3366FF',
+	'#3399CC',
+	'#3399FF',
+	'#33CC00',
+	'#33CC33',
+	'#33CC66',
+	'#33CC99',
+	'#33CCCC',
+	'#33CCFF',
+	'#6600CC',
+	'#6600FF',
+	'#6633CC',
+	'#6633FF',
+	'#66CC00',
+	'#66CC33',
+	'#9900CC',
+	'#9900FF',
+	'#9933CC',
+	'#9933FF',
+	'#99CC00',
+	'#99CC33',
+	'#CC0000',
+	'#CC0033',
+	'#CC0066',
+	'#CC0099',
+	'#CC00CC',
+	'#CC00FF',
+	'#CC3300',
+	'#CC3333',
+	'#CC3366',
+	'#CC3399',
+	'#CC33CC',
+	'#CC33FF',
+	'#CC6600',
+	'#CC6633',
+	'#CC9900',
+	'#CC9933',
+	'#CCCC00',
+	'#CCCC33',
+	'#FF0000',
+	'#FF0033',
+	'#FF0066',
+	'#FF0099',
+	'#FF00CC',
+	'#FF00FF',
+	'#FF3300',
+	'#FF3333',
+	'#FF3366',
+	'#FF3399',
+	'#FF33CC',
+	'#FF33FF',
+	'#FF6600',
+	'#FF6633',
+	'#FF9900',
+	'#FF9933',
+	'#FFCC00',
+	'#FFCC33'
+];
+
+/**
+ * Currently only WebKit-based Web Inspectors, Firefox >= v31,
+ * and the Firebug extension (any Firefox version) are known
+ * to support "%c" CSS customizations.
+ *
+ * TODO: add a `localStorage` variable to explicitly enable/disable colors
+ */
+
+// eslint-disable-next-line complexity
+function useColors() {
+	// NB: In an Electron preload script, document will be defined but not fully
+	// initialized. Since we know we're in Chrome, we'll just detect this case
+	// explicitly
+	if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
+		return true;
+	}
+
+	// Internet Explorer and Edge do not support colors.
+	if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
+		return false;
+	}
+
+	let m;
+
+	// Is webkit? http://stackoverflow.com/a/16459606/376773
+	// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
+	return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
+		// Is firebug? http://stackoverflow.com/a/398120/376773
+		(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
+		// Is firefox >= v31?
+		// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
+		(typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31) ||
+		// Double check webkit in userAgent just in case we are in a worker
+		(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
+}
+
+/**
+ * Colorize log arguments if enabled.
+ *
+ * @api public
+ */
+
+function formatArgs(args) {
+	args[0] = (this.useColors ? '%c' : '') +
+		this.namespace +
+		(this.useColors ? ' %c' : ' ') +
+		args[0] +
+		(this.useColors ? '%c ' : ' ') +
+		'+' + module.exports.humanize(this.diff);
+
+	if (!this.useColors) {
+		return;
+	}
+
+	const c = 'color: ' + this.color;
+	args.splice(1, 0, c, 'color: inherit');
+
+	// The final "%c" is somewhat tricky, because there could be other
+	// arguments passed either before or after the %c, so we need to
+	// figure out the correct index to insert the CSS into
+	let index = 0;
+	let lastC = 0;
+	args[0].replace(/%[a-zA-Z%]/g, match => {
+		if (match === '%%') {
+			return;
+		}
+		index++;
+		if (match === '%c') {
+			// We only are interested in the *last* %c
+			// (the user may have provided their own)
+			lastC = index;
+		}
+	});
+
+	args.splice(lastC, 0, c);
+}
+
+/**
+ * Invokes `console.debug()` when available.
+ * No-op when `console.debug` is not a "function".
+ * If `console.debug` is not available, falls back
+ * to `console.log`.
+ *
+ * @api public
+ */
+exports.log = console.debug || console.log || (() => {});
+
+/**
+ * Save `namespaces`.
+ *
+ * @param {String} namespaces
+ * @api private
+ */
+function save(namespaces) {
+	try {
+		if (namespaces) {
+			exports.storage.setItem('debug', namespaces);
+		} else {
+			exports.storage.removeItem('debug');
+		}
+	} catch (error) {
+		// Swallow
+		// XXX (@Qix-) should we be logging these?
+	}
+}
+
+/**
+ * Load `namespaces`.
+ *
+ * @return {String} returns the previously persisted debug modes
+ * @api private
+ */
+function load() {
+	let r;
+	try {
+		r = exports.storage.getItem('debug');
+	} catch (error) {
+		// Swallow
+		// XXX (@Qix-) should we be logging these?
+	}
+
+	// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
+	if (!r && typeof process !== 'undefined' && 'env' in process) {
+		r = process.env.DEBUG;
+	}
+
+	return r;
+}
+
+/**
+ * Localstorage attempts to return the localstorage.
+ *
+ * This is necessary because safari throws
+ * when a user disables cookies/localstorage
+ * and you attempt to access it.
+ *
+ * @return {LocalStorage}
+ * @api private
+ */
+
+function localstorage() {
+	try {
+		// TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
+		// The Browser also has localStorage in the global context.
+		return localStorage;
+	} catch (error) {
+		// Swallow
+		// XXX (@Qix-) should we be logging these?
+	}
+}
+
+module.exports = require('./common')(exports);
+
+const {formatters} = module.exports;
+
+/**
+ * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
+ */
+
+formatters.j = function (v) {
+	try {
+		return JSON.stringify(v);
+	} catch (error) {
+		return '[UnexpectedJSONParseError]: ' + error.message;
+	}
+};

+ 274 - 0
node_modules/@acuminous/bitsyntax/node_modules/debug/src/common.js

@@ -0,0 +1,274 @@
+
+/**
+ * This is the common logic for both the Node.js and web browser
+ * implementations of `debug()`.
+ */
+
+function setup(env) {
+	createDebug.debug = createDebug;
+	createDebug.default = createDebug;
+	createDebug.coerce = coerce;
+	createDebug.disable = disable;
+	createDebug.enable = enable;
+	createDebug.enabled = enabled;
+	createDebug.humanize = require('ms');
+	createDebug.destroy = destroy;
+
+	Object.keys(env).forEach(key => {
+		createDebug[key] = env[key];
+	});
+
+	/**
+	* The currently active debug mode names, and names to skip.
+	*/
+
+	createDebug.names = [];
+	createDebug.skips = [];
+
+	/**
+	* Map of special "%n" handling functions, for the debug "format" argument.
+	*
+	* Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
+	*/
+	createDebug.formatters = {};
+
+	/**
+	* Selects a color for a debug namespace
+	* @param {String} namespace The namespace string for the debug instance to be colored
+	* @return {Number|String} An ANSI color code for the given namespace
+	* @api private
+	*/
+	function selectColor(namespace) {
+		let hash = 0;
+
+		for (let i = 0; i < namespace.length; i++) {
+			hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
+			hash |= 0; // Convert to 32bit integer
+		}
+
+		return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
+	}
+	createDebug.selectColor = selectColor;
+
+	/**
+	* Create a debugger with the given `namespace`.
+	*
+	* @param {String} namespace
+	* @return {Function}
+	* @api public
+	*/
+	function createDebug(namespace) {
+		let prevTime;
+		let enableOverride = null;
+		let namespacesCache;
+		let enabledCache;
+
+		function debug(...args) {
+			// Disabled?
+			if (!debug.enabled) {
+				return;
+			}
+
+			const self = debug;
+
+			// Set `diff` timestamp
+			const curr = Number(new Date());
+			const ms = curr - (prevTime || curr);
+			self.diff = ms;
+			self.prev = prevTime;
+			self.curr = curr;
+			prevTime = curr;
+
+			args[0] = createDebug.coerce(args[0]);
+
+			if (typeof args[0] !== 'string') {
+				// Anything else let's inspect with %O
+				args.unshift('%O');
+			}
+
+			// Apply any `formatters` transformations
+			let index = 0;
+			args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {
+				// If we encounter an escaped % then don't increase the array index
+				if (match === '%%') {
+					return '%';
+				}
+				index++;
+				const formatter = createDebug.formatters[format];
+				if (typeof formatter === 'function') {
+					const val = args[index];
+					match = formatter.call(self, val);
+
+					// Now we need to remove `args[index]` since it's inlined in the `format`
+					args.splice(index, 1);
+					index--;
+				}
+				return match;
+			});
+
+			// Apply env-specific formatting (colors, etc.)
+			createDebug.formatArgs.call(self, args);
+
+			const logFn = self.log || createDebug.log;
+			logFn.apply(self, args);
+		}
+
+		debug.namespace = namespace;
+		debug.useColors = createDebug.useColors();
+		debug.color = createDebug.selectColor(namespace);
+		debug.extend = extend;
+		debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release.
+
+		Object.defineProperty(debug, 'enabled', {
+			enumerable: true,
+			configurable: false,
+			get: () => {
+				if (enableOverride !== null) {
+					return enableOverride;
+				}
+				if (namespacesCache !== createDebug.namespaces) {
+					namespacesCache = createDebug.namespaces;
+					enabledCache = createDebug.enabled(namespace);
+				}
+
+				return enabledCache;
+			},
+			set: v => {
+				enableOverride = v;
+			}
+		});
+
+		// Env-specific initialization logic for debug instances
+		if (typeof createDebug.init === 'function') {
+			createDebug.init(debug);
+		}
+
+		return debug;
+	}
+
+	function extend(namespace, delimiter) {
+		const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
+		newDebug.log = this.log;
+		return newDebug;
+	}
+
+	/**
+	* Enables a debug mode by namespaces. This can include modes
+	* separated by a colon and wildcards.
+	*
+	* @param {String} namespaces
+	* @api public
+	*/
+	function enable(namespaces) {
+		createDebug.save(namespaces);
+		createDebug.namespaces = namespaces;
+
+		createDebug.names = [];
+		createDebug.skips = [];
+
+		let i;
+		const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
+		const len = split.length;
+
+		for (i = 0; i < len; i++) {
+			if (!split[i]) {
+				// ignore empty strings
+				continue;
+			}
+
+			namespaces = split[i].replace(/\*/g, '.*?');
+
+			if (namespaces[0] === '-') {
+				createDebug.skips.push(new RegExp('^' + namespaces.slice(1) + '$'));
+			} else {
+				createDebug.names.push(new RegExp('^' + namespaces + '$'));
+			}
+		}
+	}
+
+	/**
+	* Disable debug output.
+	*
+	* @return {String} namespaces
+	* @api public
+	*/
+	function disable() {
+		const namespaces = [
+			...createDebug.names.map(toNamespace),
+			...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace)
+		].join(',');
+		createDebug.enable('');
+		return namespaces;
+	}
+
+	/**
+	* Returns true if the given mode name is enabled, false otherwise.
+	*
+	* @param {String} name
+	* @return {Boolean}
+	* @api public
+	*/
+	function enabled(name) {
+		if (name[name.length - 1] === '*') {
+			return true;
+		}
+
+		let i;
+		let len;
+
+		for (i = 0, len = createDebug.skips.length; i < len; i++) {
+			if (createDebug.skips[i].test(name)) {
+				return false;
+			}
+		}
+
+		for (i = 0, len = createDebug.names.length; i < len; i++) {
+			if (createDebug.names[i].test(name)) {
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	/**
+	* Convert regexp to namespace
+	*
+	* @param {RegExp} regxep
+	* @return {String} namespace
+	* @api private
+	*/
+	function toNamespace(regexp) {
+		return regexp.toString()
+			.substring(2, regexp.toString().length - 2)
+			.replace(/\.\*\?$/, '*');
+	}
+
+	/**
+	* Coerce `val`.
+	*
+	* @param {Mixed} val
+	* @return {Mixed}
+	* @api private
+	*/
+	function coerce(val) {
+		if (val instanceof Error) {
+			return val.stack || val.message;
+		}
+		return val;
+	}
+
+	/**
+	* XXX DO NOT USE. This is a temporary stub function.
+	* XXX It WILL be removed in the next major release.
+	*/
+	function destroy() {
+		console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
+	}
+
+	createDebug.enable(createDebug.load());
+
+	return createDebug;
+}
+
+module.exports = setup;

+ 10 - 0
node_modules/@acuminous/bitsyntax/node_modules/debug/src/index.js

@@ -0,0 +1,10 @@
+/**
+ * Detect Electron renderer / nwjs process, which is node, but we should
+ * treat as a browser.
+ */
+
+if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) {
+	module.exports = require('./browser.js');
+} else {
+	module.exports = require('./node.js');
+}

+ 263 - 0
node_modules/@acuminous/bitsyntax/node_modules/debug/src/node.js

@@ -0,0 +1,263 @@
+/**
+ * Module dependencies.
+ */
+
+const tty = require('tty');
+const util = require('util');
+
+/**
+ * This is the Node.js implementation of `debug()`.
+ */
+
+exports.init = init;
+exports.log = log;
+exports.formatArgs = formatArgs;
+exports.save = save;
+exports.load = load;
+exports.useColors = useColors;
+exports.destroy = util.deprecate(
+	() => {},
+	'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'
+);
+
+/**
+ * Colors.
+ */
+
+exports.colors = [6, 2, 3, 4, 5, 1];
+
+try {
+	// Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json)
+	// eslint-disable-next-line import/no-extraneous-dependencies
+	const supportsColor = require('supports-color');
+
+	if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {
+		exports.colors = [
+			20,
+			21,
+			26,
+			27,
+			32,
+			33,
+			38,
+			39,
+			40,
+			41,
+			42,
+			43,
+			44,
+			45,
+			56,
+			57,
+			62,
+			63,
+			68,
+			69,
+			74,
+			75,
+			76,
+			77,
+			78,
+			79,
+			80,
+			81,
+			92,
+			93,
+			98,
+			99,
+			112,
+			113,
+			128,
+			129,
+			134,
+			135,
+			148,
+			149,
+			160,
+			161,
+			162,
+			163,
+			164,
+			165,
+			166,
+			167,
+			168,
+			169,
+			170,
+			171,
+			172,
+			173,
+			178,
+			179,
+			184,
+			185,
+			196,
+			197,
+			198,
+			199,
+			200,
+			201,
+			202,
+			203,
+			204,
+			205,
+			206,
+			207,
+			208,
+			209,
+			214,
+			215,
+			220,
+			221
+		];
+	}
+} catch (error) {
+	// Swallow - we only care if `supports-color` is available; it doesn't have to be.
+}
+
+/**
+ * Build up the default `inspectOpts` object from the environment variables.
+ *
+ *   $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js
+ */
+
+exports.inspectOpts = Object.keys(process.env).filter(key => {
+	return /^debug_/i.test(key);
+}).reduce((obj, key) => {
+	// Camel-case
+	const prop = key
+		.substring(6)
+		.toLowerCase()
+		.replace(/_([a-z])/g, (_, k) => {
+			return k.toUpperCase();
+		});
+
+	// Coerce string value into JS value
+	let val = process.env[key];
+	if (/^(yes|on|true|enabled)$/i.test(val)) {
+		val = true;
+	} else if (/^(no|off|false|disabled)$/i.test(val)) {
+		val = false;
+	} else if (val === 'null') {
+		val = null;
+	} else {
+		val = Number(val);
+	}
+
+	obj[prop] = val;
+	return obj;
+}, {});
+
+/**
+ * Is stdout a TTY? Colored output is enabled when `true`.
+ */
+
+function useColors() {
+	return 'colors' in exports.inspectOpts ?
+		Boolean(exports.inspectOpts.colors) :
+		tty.isatty(process.stderr.fd);
+}
+
+/**
+ * Adds ANSI color escape codes if enabled.
+ *
+ * @api public
+ */
+
+function formatArgs(args) {
+	const {namespace: name, useColors} = this;
+
+	if (useColors) {
+		const c = this.color;
+		const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c);
+		const prefix = `  ${colorCode};1m${name} \u001B[0m`;
+
+		args[0] = prefix + args[0].split('\n').join('\n' + prefix);
+		args.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\u001B[0m');
+	} else {
+		args[0] = getDate() + name + ' ' + args[0];
+	}
+}
+
+function getDate() {
+	if (exports.inspectOpts.hideDate) {
+		return '';
+	}
+	return new Date().toISOString() + ' ';
+}
+
+/**
+ * Invokes `util.formatWithOptions()` with the specified arguments and writes to stderr.
+ */
+
+function log(...args) {
+	return process.stderr.write(util.formatWithOptions(exports.inspectOpts, ...args) + '\n');
+}
+
+/**
+ * Save `namespaces`.
+ *
+ * @param {String} namespaces
+ * @api private
+ */
+function save(namespaces) {
+	if (namespaces) {
+		process.env.DEBUG = namespaces;
+	} else {
+		// If you set a process.env field to null or undefined, it gets cast to the
+		// string 'null' or 'undefined'. Just delete instead.
+		delete process.env.DEBUG;
+	}
+}
+
+/**
+ * Load `namespaces`.
+ *
+ * @return {String} returns the previously persisted debug modes
+ * @api private
+ */
+
+function load() {
+	return process.env.DEBUG;
+}
+
+/**
+ * Init logic for `debug` instances.
+ *
+ * Create a new `inspectOpts` object in case `useColors` is set
+ * differently for a particular `debug` instance.
+ */
+
+function init(debug) {
+	debug.inspectOpts = {};
+
+	const keys = Object.keys(exports.inspectOpts);
+	for (let i = 0; i < keys.length; i++) {
+		debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];
+	}
+}
+
+module.exports = require('./common')(exports);
+
+const {formatters} = module.exports;
+
+/**
+ * Map %o to `util.inspect()`, all on a single line.
+ */
+
+formatters.o = function (v) {
+	this.inspectOpts.colors = this.useColors;
+	return util.inspect(v, this.inspectOpts)
+		.split('\n')
+		.map(str => str.trim())
+		.join(' ');
+};
+
+/**
+ * Map %O to `util.inspect()`, allowing multiple lines if needed.
+ */
+
+formatters.O = function (v) {
+	this.inspectOpts.colors = this.useColors;
+	return util.inspect(v, this.inspectOpts);
+};

+ 162 - 0
node_modules/@acuminous/bitsyntax/node_modules/ms/index.js

@@ -0,0 +1,162 @@
+/**
+ * Helpers.
+ */
+
+var s = 1000;
+var m = s * 60;
+var h = m * 60;
+var d = h * 24;
+var w = d * 7;
+var y = d * 365.25;
+
+/**
+ * Parse or format the given `val`.
+ *
+ * Options:
+ *
+ *  - `long` verbose formatting [false]
+ *
+ * @param {String|Number} val
+ * @param {Object} [options]
+ * @throws {Error} throw an error if val is not a non-empty string or a number
+ * @return {String|Number}
+ * @api public
+ */
+
+module.exports = function (val, options) {
+  options = options || {};
+  var type = typeof val;
+  if (type === 'string' && val.length > 0) {
+    return parse(val);
+  } else if (type === 'number' && isFinite(val)) {
+    return options.long ? fmtLong(val) : fmtShort(val);
+  }
+  throw new Error(
+    'val is not a non-empty string or a valid number. val=' +
+      JSON.stringify(val)
+  );
+};
+
+/**
+ * Parse the given `str` and return milliseconds.
+ *
+ * @param {String} str
+ * @return {Number}
+ * @api private
+ */
+
+function parse(str) {
+  str = String(str);
+  if (str.length > 100) {
+    return;
+  }
+  var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
+    str
+  );
+  if (!match) {
+    return;
+  }
+  var n = parseFloat(match[1]);
+  var type = (match[2] || 'ms').toLowerCase();
+  switch (type) {
+    case 'years':
+    case 'year':
+    case 'yrs':
+    case 'yr':
+    case 'y':
+      return n * y;
+    case 'weeks':
+    case 'week':
+    case 'w':
+      return n * w;
+    case 'days':
+    case 'day':
+    case 'd':
+      return n * d;
+    case 'hours':
+    case 'hour':
+    case 'hrs':
+    case 'hr':
+    case 'h':
+      return n * h;
+    case 'minutes':
+    case 'minute':
+    case 'mins':
+    case 'min':
+    case 'm':
+      return n * m;
+    case 'seconds':
+    case 'second':
+    case 'secs':
+    case 'sec':
+    case 's':
+      return n * s;
+    case 'milliseconds':
+    case 'millisecond':
+    case 'msecs':
+    case 'msec':
+    case 'ms':
+      return n;
+    default:
+      return undefined;
+  }
+}
+
+/**
+ * Short format for `ms`.
+ *
+ * @param {Number} ms
+ * @return {String}
+ * @api private
+ */
+
+function fmtShort(ms) {
+  var msAbs = Math.abs(ms);
+  if (msAbs >= d) {
+    return Math.round(ms / d) + 'd';
+  }
+  if (msAbs >= h) {
+    return Math.round(ms / h) + 'h';
+  }
+  if (msAbs >= m) {
+    return Math.round(ms / m) + 'm';
+  }
+  if (msAbs >= s) {
+    return Math.round(ms / s) + 's';
+  }
+  return ms + 'ms';
+}
+
+/**
+ * Long format for `ms`.
+ *
+ * @param {Number} ms
+ * @return {String}
+ * @api private
+ */
+
+function fmtLong(ms) {
+  var msAbs = Math.abs(ms);
+  if (msAbs >= d) {
+    return plural(ms, msAbs, d, 'day');
+  }
+  if (msAbs >= h) {
+    return plural(ms, msAbs, h, 'hour');
+  }
+  if (msAbs >= m) {
+    return plural(ms, msAbs, m, 'minute');
+  }
+  if (msAbs >= s) {
+    return plural(ms, msAbs, s, 'second');
+  }
+  return ms + ' ms';
+}
+
+/**
+ * Pluralization helper.
+ */
+
+function plural(ms, msAbs, n, name) {
+  var isPlural = msAbs >= n * 1.5;
+  return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
+}

+ 21 - 0
node_modules/@acuminous/bitsyntax/node_modules/ms/license.md

@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2020 Vercel, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 38 - 0
node_modules/@acuminous/bitsyntax/node_modules/ms/package.json

@@ -0,0 +1,38 @@
+{
+  "name": "ms",
+  "version": "2.1.3",
+  "description": "Tiny millisecond conversion utility",
+  "repository": "vercel/ms",
+  "main": "./index",
+  "files": [
+    "index.js"
+  ],
+  "scripts": {
+    "precommit": "lint-staged",
+    "lint": "eslint lib/* bin/*",
+    "test": "mocha tests.js"
+  },
+  "eslintConfig": {
+    "extends": "eslint:recommended",
+    "env": {
+      "node": true,
+      "es6": true
+    }
+  },
+  "lint-staged": {
+    "*.js": [
+      "npm run lint",
+      "prettier --single-quote --write",
+      "git add"
+    ]
+  },
+  "license": "MIT",
+  "devDependencies": {
+    "eslint": "4.18.2",
+    "expect.js": "0.3.1",
+    "husky": "0.14.3",
+    "lint-staged": "5.0.0",
+    "mocha": "4.0.1",
+    "prettier": "2.0.5"
+  }
+}

+ 59 - 0
node_modules/@acuminous/bitsyntax/node_modules/ms/readme.md

@@ -0,0 +1,59 @@
+# ms
+
+![CI](https://github.com/vercel/ms/workflows/CI/badge.svg)
+
+Use this package to easily convert various time formats to milliseconds.
+
+## Examples
+
+```js
+ms('2 days')  // 172800000
+ms('1d')      // 86400000
+ms('10h')     // 36000000
+ms('2.5 hrs') // 9000000
+ms('2h')      // 7200000
+ms('1m')      // 60000
+ms('5s')      // 5000
+ms('1y')      // 31557600000
+ms('100')     // 100
+ms('-3 days') // -259200000
+ms('-1h')     // -3600000
+ms('-200')    // -200
+```
+
+### Convert from Milliseconds
+
+```js
+ms(60000)             // "1m"
+ms(2 * 60000)         // "2m"
+ms(-3 * 60000)        // "-3m"
+ms(ms('10 hours'))    // "10h"
+```
+
+### Time Format Written-Out
+
+```js
+ms(60000, { long: true })             // "1 minute"
+ms(2 * 60000, { long: true })         // "2 minutes"
+ms(-3 * 60000, { long: true })        // "-3 minutes"
+ms(ms('10 hours'), { long: true })    // "10 hours"
+```
+
+## Features
+
+- Works both in [Node.js](https://nodejs.org) and in the browser
+- If a number is supplied to `ms`, a string with a unit is returned
+- If a string that contains the number is supplied, it returns it as a number (e.g.: it returns `100` for `'100'`)
+- If you pass a string with a number and a valid unit, the number of equivalent milliseconds is returned
+
+## Related Packages
+
+- [ms.macro](https://github.com/knpwrs/ms.macro) - Run `ms` as a macro at build-time.
+
+## Caught a Bug?
+
+1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device
+2. Link the package to the global module directory: `npm link`
+3. Within the module you want to test your local development instance of ms, just link it to the dependencies: `npm link ms`. Instead of the default one from npm, Node.js will now use your clone of ms!
+
+As always, you can run the tests using: `npm test`

+ 21 - 0
node_modules/@acuminous/bitsyntax/node_modules/safe-buffer/LICENSE

@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) Feross Aboukhadijeh
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 584 - 0
node_modules/@acuminous/bitsyntax/node_modules/safe-buffer/README.md

@@ -0,0 +1,584 @@
+# safe-buffer [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url]
+
+[travis-image]: https://img.shields.io/travis/feross/safe-buffer/master.svg
+[travis-url]: https://travis-ci.org/feross/safe-buffer
+[npm-image]: https://img.shields.io/npm/v/safe-buffer.svg
+[npm-url]: https://npmjs.org/package/safe-buffer
+[downloads-image]: https://img.shields.io/npm/dm/safe-buffer.svg
+[downloads-url]: https://npmjs.org/package/safe-buffer
+[standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg
+[standard-url]: https://standardjs.com
+
+#### Safer Node.js Buffer API
+
+**Use the new Node.js Buffer APIs (`Buffer.from`, `Buffer.alloc`,
+`Buffer.allocUnsafe`, `Buffer.allocUnsafeSlow`) in all versions of Node.js.**
+
+**Uses the built-in implementation when available.**
+
+## install
+
+```
+npm install safe-buffer
+```
+
+## usage
+
+The goal of this package is to provide a safe replacement for the node.js `Buffer`.
+
+It's a drop-in replacement for `Buffer`. You can use it by adding one `require` line to
+the top of your node.js modules:
+
+```js
+var Buffer = require('safe-buffer').Buffer
+
+// Existing buffer code will continue to work without issues:
+
+new Buffer('hey', 'utf8')
+new Buffer([1, 2, 3], 'utf8')
+new Buffer(obj)
+new Buffer(16) // create an uninitialized buffer (potentially unsafe)
+
+// But you can use these new explicit APIs to make clear what you want:
+
+Buffer.from('hey', 'utf8') // convert from many types to a Buffer
+Buffer.alloc(16) // create a zero-filled buffer (safe)
+Buffer.allocUnsafe(16) // create an uninitialized buffer (potentially unsafe)
+```
+
+## api
+
+### Class Method: Buffer.from(array)
+<!-- YAML
+added: v3.0.0
+-->
+
+* `array` {Array}
+
+Allocates a new `Buffer` using an `array` of octets.
+
+```js
+const buf = Buffer.from([0x62,0x75,0x66,0x66,0x65,0x72]);
+  // creates a new Buffer containing ASCII bytes
+  // ['b','u','f','f','e','r']
+```
+
+A `TypeError` will be thrown if `array` is not an `Array`.
+
+### Class Method: Buffer.from(arrayBuffer[, byteOffset[, length]])
+<!-- YAML
+added: v5.10.0
+-->
+
+* `arrayBuffer` {ArrayBuffer} The `.buffer` property of a `TypedArray` or
+  a `new ArrayBuffer()`
+* `byteOffset` {Number} Default: `0`
+* `length` {Number} Default: `arrayBuffer.length - byteOffset`
+
+When passed a reference to the `.buffer` property of a `TypedArray` instance,
+the newly created `Buffer` will share the same allocated memory as the
+TypedArray.
+
+```js
+const arr = new Uint16Array(2);
+arr[0] = 5000;
+arr[1] = 4000;
+
+const buf = Buffer.from(arr.buffer); // shares the memory with arr;
+
+console.log(buf);
+  // Prints: <Buffer 88 13 a0 0f>
+
+// changing the TypedArray changes the Buffer also
+arr[1] = 6000;
+
+console.log(buf);
+  // Prints: <Buffer 88 13 70 17>
+```
+
+The optional `byteOffset` and `length` arguments specify a memory range within
+the `arrayBuffer` that will be shared by the `Buffer`.
+
+```js
+const ab = new ArrayBuffer(10);
+const buf = Buffer.from(ab, 0, 2);
+console.log(buf.length);
+  // Prints: 2
+```
+
+A `TypeError` will be thrown if `arrayBuffer` is not an `ArrayBuffer`.
+
+### Class Method: Buffer.from(buffer)
+<!-- YAML
+added: v3.0.0
+-->
+
+* `buffer` {Buffer}
+
+Copies the passed `buffer` data onto a new `Buffer` instance.
+
+```js
+const buf1 = Buffer.from('buffer');
+const buf2 = Buffer.from(buf1);
+
+buf1[0] = 0x61;
+console.log(buf1.toString());
+  // 'auffer'
+console.log(buf2.toString());
+  // 'buffer' (copy is not changed)
+```
+
+A `TypeError` will be thrown if `buffer` is not a `Buffer`.
+
+### Class Method: Buffer.from(str[, encoding])
+<!-- YAML
+added: v5.10.0
+-->
+
+* `str` {String} String to encode.
+* `encoding` {String} Encoding to use, Default: `'utf8'`
+
+Creates a new `Buffer` containing the given JavaScript string `str`. If
+provided, the `encoding` parameter identifies the character encoding.
+If not provided, `encoding` defaults to `'utf8'`.
+
+```js
+const buf1 = Buffer.from('this is a tést');
+console.log(buf1.toString());
+  // prints: this is a tést
+console.log(buf1.toString('ascii'));
+  // prints: this is a tC)st
+
+const buf2 = Buffer.from('7468697320697320612074c3a97374', 'hex');
+console.log(buf2.toString());
+  // prints: this is a tést
+```
+
+A `TypeError` will be thrown if `str` is not a string.
+
+### Class Method: Buffer.alloc(size[, fill[, encoding]])
+<!-- YAML
+added: v5.10.0
+-->
+
+* `size` {Number}
+* `fill` {Value} Default: `undefined`
+* `encoding` {String} Default: `utf8`
+
+Allocates a new `Buffer` of `size` bytes. If `fill` is `undefined`, the
+`Buffer` will be *zero-filled*.
+
+```js
+const buf = Buffer.alloc(5);
+console.log(buf);
+  // <Buffer 00 00 00 00 00>
+```
+
+The `size` must be less than or equal to the value of
+`require('buffer').kMaxLength` (on 64-bit architectures, `kMaxLength` is
+`(2^31)-1`). Otherwise, a [`RangeError`][] is thrown. A zero-length Buffer will
+be created if a `size` less than or equal to 0 is specified.
+
+If `fill` is specified, the allocated `Buffer` will be initialized by calling
+`buf.fill(fill)`. See [`buf.fill()`][] for more information.
+
+```js
+const buf = Buffer.alloc(5, 'a');
+console.log(buf);
+  // <Buffer 61 61 61 61 61>
+```
+
+If both `fill` and `encoding` are specified, the allocated `Buffer` will be
+initialized by calling `buf.fill(fill, encoding)`. For example:
+
+```js
+const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64');
+console.log(buf);
+  // <Buffer 68 65 6c 6c 6f 20 77 6f 72 6c 64>
+```
+
+Calling `Buffer.alloc(size)` can be significantly slower than the alternative
+`Buffer.allocUnsafe(size)` but ensures that the newly created `Buffer` instance
+contents will *never contain sensitive data*.
+
+A `TypeError` will be thrown if `size` is not a number.
+
+### Class Method: Buffer.allocUnsafe(size)
+<!-- YAML
+added: v5.10.0
+-->
+
+* `size` {Number}
+
+Allocates a new *non-zero-filled* `Buffer` of `size` bytes.  The `size` must
+be less than or equal to the value of `require('buffer').kMaxLength` (on 64-bit
+architectures, `kMaxLength` is `(2^31)-1`). Otherwise, a [`RangeError`][] is
+thrown. A zero-length Buffer will be created if a `size` less than or equal to
+0 is specified.
+
+The underlying memory for `Buffer` instances created in this way is *not
+initialized*. The contents of the newly created `Buffer` are unknown and
+*may contain sensitive data*. Use [`buf.fill(0)`][] to initialize such
+`Buffer` instances to zeroes.
+
+```js
+const buf = Buffer.allocUnsafe(5);
+console.log(buf);
+  // <Buffer 78 e0 82 02 01>
+  // (octets will be different, every time)
+buf.fill(0);
+console.log(buf);
+  // <Buffer 00 00 00 00 00>
+```
+
+A `TypeError` will be thrown if `size` is not a number.
+
+Note that the `Buffer` module pre-allocates an internal `Buffer` instance of
+size `Buffer.poolSize` that is used as a pool for the fast allocation of new
+`Buffer` instances created using `Buffer.allocUnsafe(size)` (and the deprecated
+`new Buffer(size)` constructor) only when `size` is less than or equal to
+`Buffer.poolSize >> 1` (floor of `Buffer.poolSize` divided by two). The default
+value of `Buffer.poolSize` is `8192` but can be modified.
+
+Use of this pre-allocated internal memory pool is a key difference between
+calling `Buffer.alloc(size, fill)` vs. `Buffer.allocUnsafe(size).fill(fill)`.
+Specifically, `Buffer.alloc(size, fill)` will *never* use the internal Buffer
+pool, while `Buffer.allocUnsafe(size).fill(fill)` *will* use the internal
+Buffer pool if `size` is less than or equal to half `Buffer.poolSize`. The
+difference is subtle but can be important when an application requires the
+additional performance that `Buffer.allocUnsafe(size)` provides.
+
+### Class Method: Buffer.allocUnsafeSlow(size)
+<!-- YAML
+added: v5.10.0
+-->
+
+* `size` {Number}
+
+Allocates a new *non-zero-filled* and non-pooled `Buffer` of `size` bytes.  The
+`size` must be less than or equal to the value of
+`require('buffer').kMaxLength` (on 64-bit architectures, `kMaxLength` is
+`(2^31)-1`). Otherwise, a [`RangeError`][] is thrown. A zero-length Buffer will
+be created if a `size` less than or equal to 0 is specified.
+
+The underlying memory for `Buffer` instances created in this way is *not
+initialized*. The contents of the newly created `Buffer` are unknown and
+*may contain sensitive data*. Use [`buf.fill(0)`][] to initialize such
+`Buffer` instances to zeroes.
+
+When using `Buffer.allocUnsafe()` to allocate new `Buffer` instances,
+allocations under 4KB are, by default, sliced from a single pre-allocated
+`Buffer`. This allows applications to avoid the garbage collection overhead of
+creating many individually allocated Buffers. This approach improves both
+performance and memory usage by eliminating the need to track and cleanup as
+many `Persistent` objects.
+
+However, in the case where a developer may need to retain a small chunk of
+memory from a pool for an indeterminate amount of time, it may be appropriate
+to create an un-pooled Buffer instance using `Buffer.allocUnsafeSlow()` then
+copy out the relevant bits.
+
+```js
+// need to keep around a few small chunks of memory
+const store = [];
+
+socket.on('readable', () => {
+  const data = socket.read();
+  // allocate for retained data
+  const sb = Buffer.allocUnsafeSlow(10);
+  // copy the data into the new allocation
+  data.copy(sb, 0, 0, 10);
+  store.push(sb);
+});
+```
+
+Use of `Buffer.allocUnsafeSlow()` should be used only as a last resort *after*
+a developer has observed undue memory retention in their applications.
+
+A `TypeError` will be thrown if `size` is not a number.
+
+### All the Rest
+
+The rest of the `Buffer` API is exactly the same as in node.js.
+[See the docs](https://nodejs.org/api/buffer.html).
+
+
+## Related links
+
+- [Node.js issue: Buffer(number) is unsafe](https://github.com/nodejs/node/issues/4660)
+- [Node.js Enhancement Proposal: Buffer.from/Buffer.alloc/Buffer.zalloc/Buffer() soft-deprecate](https://github.com/nodejs/node-eps/pull/4)
+
+## Why is `Buffer` unsafe?
+
+Today, the node.js `Buffer` constructor is overloaded to handle many different argument
+types like `String`, `Array`, `Object`, `TypedArrayView` (`Uint8Array`, etc.),
+`ArrayBuffer`, and also `Number`.
+
+The API is optimized for convenience: you can throw any type at it, and it will try to do
+what you want.
+
+Because the Buffer constructor is so powerful, you often see code like this:
+
+```js
+// Convert UTF-8 strings to hex
+function toHex (str) {
+  return new Buffer(str).toString('hex')
+}
+```
+
+***But what happens if `toHex` is called with a `Number` argument?***
+
+### Remote Memory Disclosure
+
+If an attacker can make your program call the `Buffer` constructor with a `Number`
+argument, then they can make it allocate uninitialized memory from the node.js process.
+This could potentially disclose TLS private keys, user data, or database passwords.
+
+When the `Buffer` constructor is passed a `Number` argument, it returns an
+**UNINITIALIZED** block of memory of the specified `size`. When you create a `Buffer` like
+this, you **MUST** overwrite the contents before returning it to the user.
+
+From the [node.js docs](https://nodejs.org/api/buffer.html#buffer_new_buffer_size):
+
+> `new Buffer(size)`
+>
+> - `size` Number
+>
+> The underlying memory for `Buffer` instances created in this way is not initialized.
+> **The contents of a newly created `Buffer` are unknown and could contain sensitive
+> data.** Use `buf.fill(0)` to initialize a Buffer to zeroes.
+
+(Emphasis our own.)
+
+Whenever the programmer intended to create an uninitialized `Buffer` you often see code
+like this:
+
+```js
+var buf = new Buffer(16)
+
+// Immediately overwrite the uninitialized buffer with data from another buffer
+for (var i = 0; i < buf.length; i++) {
+  buf[i] = otherBuf[i]
+}
+```
+
+
+### Would this ever be a problem in real code?
+
+Yes. It's surprisingly common to forget to check the type of your variables in a
+dynamically-typed language like JavaScript.
+
+Usually the consequences of assuming the wrong type is that your program crashes with an
+uncaught exception. But the failure mode for forgetting to check the type of arguments to
+the `Buffer` constructor is more catastrophic.
+
+Here's an example of a vulnerable service that takes a JSON payload and converts it to
+hex:
+
+```js
+// Take a JSON payload {str: "some string"} and convert it to hex
+var server = http.createServer(function (req, res) {
+  var data = ''
+  req.setEncoding('utf8')
+  req.on('data', function (chunk) {
+    data += chunk
+  })
+  req.on('end', function () {
+    var body = JSON.parse(data)
+    res.end(new Buffer(body.str).toString('hex'))
+  })
+})
+
+server.listen(8080)
+```
+
+In this example, an http client just has to send:
+
+```json
+{
+  "str": 1000
+}
+```
+
+and it will get back 1,000 bytes of uninitialized memory from the server.
+
+This is a very serious bug. It's similar in severity to the
+[the Heartbleed bug](http://heartbleed.com/) that allowed disclosure of OpenSSL process
+memory by remote attackers.
+
+
+### Which real-world packages were vulnerable?
+
+#### [`bittorrent-dht`](https://www.npmjs.com/package/bittorrent-dht)
+
+[Mathias Buus](https://github.com/mafintosh) and I
+([Feross Aboukhadijeh](http://feross.org/)) found this issue in one of our own packages,
+[`bittorrent-dht`](https://www.npmjs.com/package/bittorrent-dht). The bug would allow
+anyone on the internet to send a series of messages to a user of `bittorrent-dht` and get
+them to reveal 20 bytes at a time of uninitialized memory from the node.js process.
+
+Here's
+[the commit](https://github.com/feross/bittorrent-dht/commit/6c7da04025d5633699800a99ec3fbadf70ad35b8)
+that fixed it. We released a new fixed version, created a
+[Node Security Project disclosure](https://nodesecurity.io/advisories/68), and deprecated all
+vulnerable versions on npm so users will get a warning to upgrade to a newer version.
+
+#### [`ws`](https://www.npmjs.com/package/ws)
+
+That got us wondering if there were other vulnerable packages. Sure enough, within a short
+period of time, we found the same issue in [`ws`](https://www.npmjs.com/package/ws), the
+most popular WebSocket implementation in node.js.
+
+If certain APIs were called with `Number` parameters instead of `String` or `Buffer` as
+expected, then uninitialized server memory would be disclosed to the remote peer.
+
+These were the vulnerable methods:
+
+```js
+socket.send(number)
+socket.ping(number)
+socket.pong(number)
+```
+
+Here's a vulnerable socket server with some echo functionality:
+
+```js
+server.on('connection', function (socket) {
+  socket.on('message', function (message) {
+    message = JSON.parse(message)
+    if (message.type === 'echo') {
+      socket.send(message.data) // send back the user's message
+    }
+  })
+})
+```
+
+`socket.send(number)` called on the server, will disclose server memory.
+
+Here's [the release](https://github.com/websockets/ws/releases/tag/1.0.1) where the issue
+was fixed, with a more detailed explanation. Props to
+[Arnout Kazemier](https://github.com/3rd-Eden) for the quick fix. Here's the
+[Node Security Project disclosure](https://nodesecurity.io/advisories/67).
+
+
+### What's the solution?
+
+It's important that node.js offers a fast way to get memory otherwise performance-critical
+applications would needlessly get a lot slower.
+
+But we need a better way to *signal our intent* as programmers. **When we want
+uninitialized memory, we should request it explicitly.**
+
+Sensitive functionality should not be packed into a developer-friendly API that loosely
+accepts many different types. This type of API encourages the lazy practice of passing
+variables in without checking the type very carefully.
+
+#### A new API: `Buffer.allocUnsafe(number)`
+
+The functionality of creating buffers with uninitialized memory should be part of another
+API. We propose `Buffer.allocUnsafe(number)`. This way, it's not part of an API that
+frequently gets user input of all sorts of different types passed into it.
+
+```js
+var buf = Buffer.allocUnsafe(16) // careful, uninitialized memory!
+
+// Immediately overwrite the uninitialized buffer with data from another buffer
+for (var i = 0; i < buf.length; i++) {
+  buf[i] = otherBuf[i]
+}
+```
+
+
+### How do we fix node.js core?
+
+We sent [a PR to node.js core](https://github.com/nodejs/node/pull/4514) (merged as
+`semver-major`) which defends against one case:
+
+```js
+var str = 16
+new Buffer(str, 'utf8')
+```
+
+In this situation, it's implied that the programmer intended the first argument to be a
+string, since they passed an encoding as a second argument. Today, node.js will allocate
+uninitialized memory in the case of `new Buffer(number, encoding)`, which is probably not
+what the programmer intended.
+
+But this is only a partial solution, since if the programmer does `new Buffer(variable)`
+(without an `encoding` parameter) there's no way to know what they intended. If `variable`
+is sometimes a number, then uninitialized memory will sometimes be returned.
+
+### What's the real long-term fix?
+
+We could deprecate and remove `new Buffer(number)` and use `Buffer.allocUnsafe(number)` when
+we need uninitialized memory. But that would break 1000s of packages.
+
+~~We believe the best solution is to:~~
+
+~~1. Change `new Buffer(number)` to return safe, zeroed-out memory~~
+
+~~2. Create a new API for creating uninitialized Buffers. We propose: `Buffer.allocUnsafe(number)`~~
+
+#### Update
+
+We now support adding three new APIs:
+
+- `Buffer.from(value)` - convert from any type to a buffer
+- `Buffer.alloc(size)` - create a zero-filled buffer
+- `Buffer.allocUnsafe(size)` - create an uninitialized buffer with given size
+
+This solves the core problem that affected `ws` and `bittorrent-dht` which is
+`Buffer(variable)` getting tricked into taking a number argument.
+
+This way, existing code continues working and the impact on the npm ecosystem will be
+minimal. Over time, npm maintainers can migrate performance-critical code to use
+`Buffer.allocUnsafe(number)` instead of `new Buffer(number)`.
+
+
+### Conclusion
+
+We think there's a serious design issue with the `Buffer` API as it exists today. It
+promotes insecure software by putting high-risk functionality into a convenient API
+with friendly "developer ergonomics".
+
+This wasn't merely a theoretical exercise because we found the issue in some of the
+most popular npm packages.
+
+Fortunately, there's an easy fix that can be applied today. Use `safe-buffer` in place of
+`buffer`.
+
+```js
+var Buffer = require('safe-buffer').Buffer
+```
+
+Eventually, we hope that node.js core can switch to this new, safer behavior. We believe
+the impact on the ecosystem would be minimal since it's not a breaking change.
+Well-maintained, popular packages would be updated to use `Buffer.alloc` quickly, while
+older, insecure packages would magically become safe from this attack vector.
+
+
+## links
+
+- [Node.js PR: buffer: throw if both length and enc are passed](https://github.com/nodejs/node/pull/4514)
+- [Node Security Project disclosure for `ws`](https://nodesecurity.io/advisories/67)
+- [Node Security Project disclosure for`bittorrent-dht`](https://nodesecurity.io/advisories/68)
+
+
+## credit
+
+The original issues in `bittorrent-dht`
+([disclosure](https://nodesecurity.io/advisories/68)) and
+`ws` ([disclosure](https://nodesecurity.io/advisories/67)) were discovered by
+[Mathias Buus](https://github.com/mafintosh) and
+[Feross Aboukhadijeh](http://feross.org/).
+
+Thanks to [Adam Baldwin](https://github.com/evilpacket) for helping disclose these issues
+and for his work running the [Node Security Project](https://nodesecurity.io/).
+
+Thanks to [John Hiesey](https://github.com/jhiesey) for proofreading this README and
+auditing the code.
+
+
+## license
+
+MIT. Copyright (C) [Feross Aboukhadijeh](http://feross.org)

+ 187 - 0
node_modules/@acuminous/bitsyntax/node_modules/safe-buffer/index.d.ts

@@ -0,0 +1,187 @@
+declare module "safe-buffer" {
+  export class Buffer {
+    length: number
+    write(string: string, offset?: number, length?: number, encoding?: string): number;
+    toString(encoding?: string, start?: number, end?: number): string;
+    toJSON(): { type: 'Buffer', data: any[] };
+    equals(otherBuffer: Buffer): boolean;
+    compare(otherBuffer: Buffer, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): number;
+    copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number;
+    slice(start?: number, end?: number): Buffer;
+    writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
+    writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
+    writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
+    writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
+    readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number;
+    readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number;
+    readIntLE(offset: number, byteLength: number, noAssert?: boolean): number;
+    readIntBE(offset: number, byteLength: number, noAssert?: boolean): number;
+    readUInt8(offset: number, noAssert?: boolean): number;
+    readUInt16LE(offset: number, noAssert?: boolean): number;
+    readUInt16BE(offset: number, noAssert?: boolean): number;
+    readUInt32LE(offset: number, noAssert?: boolean): number;
+    readUInt32BE(offset: number, noAssert?: boolean): number;
+    readInt8(offset: number, noAssert?: boolean): number;
+    readInt16LE(offset: number, noAssert?: boolean): number;
+    readInt16BE(offset: number, noAssert?: boolean): number;
+    readInt32LE(offset: number, noAssert?: boolean): number;
+    readInt32BE(offset: number, noAssert?: boolean): number;
+    readFloatLE(offset: number, noAssert?: boolean): number;
+    readFloatBE(offset: number, noAssert?: boolean): number;
+    readDoubleLE(offset: number, noAssert?: boolean): number;
+    readDoubleBE(offset: number, noAssert?: boolean): number;
+    swap16(): Buffer;
+    swap32(): Buffer;
+    swap64(): Buffer;
+    writeUInt8(value: number, offset: number, noAssert?: boolean): number;
+    writeUInt16LE(value: number, offset: number, noAssert?: boolean): number;
+    writeUInt16BE(value: number, offset: number, noAssert?: boolean): number;
+    writeUInt32LE(value: number, offset: number, noAssert?: boolean): number;
+    writeUInt32BE(value: number, offset: number, noAssert?: boolean): number;
+    writeInt8(value: number, offset: number, noAssert?: boolean): number;
+    writeInt16LE(value: number, offset: number, noAssert?: boolean): number;
+    writeInt16BE(value: number, offset: number, noAssert?: boolean): number;
+    writeInt32LE(value: number, offset: number, noAssert?: boolean): number;
+    writeInt32BE(value: number, offset: number, noAssert?: boolean): number;
+    writeFloatLE(value: number, offset: number, noAssert?: boolean): number;
+    writeFloatBE(value: number, offset: number, noAssert?: boolean): number;
+    writeDoubleLE(value: number, offset: number, noAssert?: boolean): number;
+    writeDoubleBE(value: number, offset: number, noAssert?: boolean): number;
+    fill(value: any, offset?: number, end?: number): this;
+    indexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number;
+    lastIndexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number;
+    includes(value: string | number | Buffer, byteOffset?: number, encoding?: string): boolean;
+
+    /**
+     * Allocates a new buffer containing the given {str}.
+     *
+     * @param str String to store in buffer.
+     * @param encoding encoding to use, optional.  Default is 'utf8'
+     */
+     constructor (str: string, encoding?: string);
+    /**
+     * Allocates a new buffer of {size} octets.
+     *
+     * @param size count of octets to allocate.
+     */
+    constructor (size: number);
+    /**
+     * Allocates a new buffer containing the given {array} of octets.
+     *
+     * @param array The octets to store.
+     */
+    constructor (array: Uint8Array);
+    /**
+     * Produces a Buffer backed by the same allocated memory as
+     * the given {ArrayBuffer}.
+     *
+     *
+     * @param arrayBuffer The ArrayBuffer with which to share memory.
+     */
+    constructor (arrayBuffer: ArrayBuffer);
+    /**
+     * Allocates a new buffer containing the given {array} of octets.
+     *
+     * @param array The octets to store.
+     */
+    constructor (array: any[]);
+    /**
+     * Copies the passed {buffer} data onto a new {Buffer} instance.
+     *
+     * @param buffer The buffer to copy.
+     */
+    constructor (buffer: Buffer);
+    prototype: Buffer;
+    /**
+     * Allocates a new Buffer using an {array} of octets.
+     *
+     * @param array
+     */
+    static from(array: any[]): Buffer;
+    /**
+     * When passed a reference to the .buffer property of a TypedArray instance,
+     * the newly created Buffer will share the same allocated memory as the TypedArray.
+     * The optional {byteOffset} and {length} arguments specify a memory range
+     * within the {arrayBuffer} that will be shared by the Buffer.
+     *
+     * @param arrayBuffer The .buffer property of a TypedArray or a new ArrayBuffer()
+     * @param byteOffset
+     * @param length
+     */
+    static from(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): Buffer;
+    /**
+     * Copies the passed {buffer} data onto a new Buffer instance.
+     *
+     * @param buffer
+     */
+    static from(buffer: Buffer): Buffer;
+    /**
+     * Creates a new Buffer containing the given JavaScript string {str}.
+     * If provided, the {encoding} parameter identifies the character encoding.
+     * If not provided, {encoding} defaults to 'utf8'.
+     *
+     * @param str
+     */
+    static from(str: string, encoding?: string): Buffer;
+    /**
+     * Returns true if {obj} is a Buffer
+     *
+     * @param obj object to test.
+     */
+    static isBuffer(obj: any): obj is Buffer;
+    /**
+     * Returns true if {encoding} is a valid encoding argument.
+     * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex'
+     *
+     * @param encoding string to test.
+     */
+    static isEncoding(encoding: string): boolean;
+    /**
+     * Gives the actual byte length of a string. encoding defaults to 'utf8'.
+     * This is not the same as String.prototype.length since that returns the number of characters in a string.
+     *
+     * @param string string to test.
+     * @param encoding encoding used to evaluate (defaults to 'utf8')
+     */
+    static byteLength(string: string, encoding?: string): number;
+    /**
+     * Returns a buffer which is the result of concatenating all the buffers in the list together.
+     *
+     * If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer.
+     * If the list has exactly one item, then the first item of the list is returned.
+     * If the list has more than one item, then a new Buffer is created.
+     *
+     * @param list An array of Buffer objects to concatenate
+     * @param totalLength Total length of the buffers when concatenated.
+     *   If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly.
+     */
+    static concat(list: Buffer[], totalLength?: number): Buffer;
+    /**
+     * The same as buf1.compare(buf2).
+     */
+    static compare(buf1: Buffer, buf2: Buffer): number;
+    /**
+     * Allocates a new buffer of {size} octets.
+     *
+     * @param size count of octets to allocate.
+     * @param fill if specified, buffer will be initialized by calling buf.fill(fill).
+     *    If parameter is omitted, buffer will be filled with zeros.
+     * @param encoding encoding used for call to buf.fill while initalizing
+     */
+    static alloc(size: number, fill?: string | Buffer | number, encoding?: string): Buffer;
+    /**
+     * Allocates a new buffer of {size} octets, leaving memory not initialized, so the contents
+     * of the newly created Buffer are unknown and may contain sensitive data.
+     *
+     * @param size count of octets to allocate
+     */
+    static allocUnsafe(size: number): Buffer;
+    /**
+     * Allocates a new non-pooled buffer of {size} octets, leaving memory not initialized, so the contents
+     * of the newly created Buffer are unknown and may contain sensitive data.
+     *
+     * @param size count of octets to allocate
+     */
+    static allocUnsafeSlow(size: number): Buffer;
+  }
+}

+ 62 - 0
node_modules/@acuminous/bitsyntax/node_modules/safe-buffer/index.js

@@ -0,0 +1,62 @@
+/* eslint-disable node/no-deprecated-api */
+var buffer = require('buffer')
+var Buffer = buffer.Buffer
+
+// alternative to using Object.keys for old browsers
+function copyProps (src, dst) {
+  for (var key in src) {
+    dst[key] = src[key]
+  }
+}
+if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
+  module.exports = buffer
+} else {
+  // Copy properties from require('buffer')
+  copyProps(buffer, exports)
+  exports.Buffer = SafeBuffer
+}
+
+function SafeBuffer (arg, encodingOrOffset, length) {
+  return Buffer(arg, encodingOrOffset, length)
+}
+
+// Copy static methods from Buffer
+copyProps(Buffer, SafeBuffer)
+
+SafeBuffer.from = function (arg, encodingOrOffset, length) {
+  if (typeof arg === 'number') {
+    throw new TypeError('Argument must not be a number')
+  }
+  return Buffer(arg, encodingOrOffset, length)
+}
+
+SafeBuffer.alloc = function (size, fill, encoding) {
+  if (typeof size !== 'number') {
+    throw new TypeError('Argument must be a number')
+  }
+  var buf = Buffer(size)
+  if (fill !== undefined) {
+    if (typeof encoding === 'string') {
+      buf.fill(fill, encoding)
+    } else {
+      buf.fill(fill)
+    }
+  } else {
+    buf.fill(0)
+  }
+  return buf
+}
+
+SafeBuffer.allocUnsafe = function (size) {
+  if (typeof size !== 'number') {
+    throw new TypeError('Argument must be a number')
+  }
+  return Buffer(size)
+}
+
+SafeBuffer.allocUnsafeSlow = function (size) {
+  if (typeof size !== 'number') {
+    throw new TypeError('Argument must be a number')
+  }
+  return buffer.SlowBuffer(size)
+}

+ 37 - 0
node_modules/@acuminous/bitsyntax/node_modules/safe-buffer/package.json

@@ -0,0 +1,37 @@
+{
+  "name": "safe-buffer",
+  "description": "Safer Node.js Buffer API",
+  "version": "5.1.2",
+  "author": {
+    "name": "Feross Aboukhadijeh",
+    "email": "feross@feross.org",
+    "url": "http://feross.org"
+  },
+  "bugs": {
+    "url": "https://github.com/feross/safe-buffer/issues"
+  },
+  "devDependencies": {
+    "standard": "*",
+    "tape": "^4.0.0"
+  },
+  "homepage": "https://github.com/feross/safe-buffer",
+  "keywords": [
+    "buffer",
+    "buffer allocate",
+    "node security",
+    "safe",
+    "safe-buffer",
+    "security",
+    "uninitialized"
+  ],
+  "license": "MIT",
+  "main": "index.js",
+  "types": "index.d.ts",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/feross/safe-buffer.git"
+  },
+  "scripts": {
+    "test": "standard && tape test/*.js"
+  }
+}

+ 36 - 0
node_modules/@acuminous/bitsyntax/package.json

@@ -0,0 +1,36 @@
+{
+  "author": "Michael Bridgen <mikeb@squaremobius.net>",
+  "name": "@acuminous/bitsyntax",
+  "description": "Pattern-matching on byte buffers",
+  "license": "MIT",
+  "version": "0.1.2",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/acuminous/bitsyntax-js.git"
+  },
+  "main": "./index",
+  "scripts": {
+    "test": "make test",
+    "prepublish": "make all"
+  },
+  "engines": {
+    "node": ">=0.8"
+  },
+  "dependencies": {
+    "buffer-more-ints": "~1.0.0",
+    "debug": "^4.3.4",
+    "safe-buffer": "~5.1.2"
+  },
+  "devDependencies": {
+    "pegjs": "^0.7.0",
+    "zunit": "^3.2.1"
+  },
+  "bugs": {
+    "url": "https://github.com/acuminous/bitsyntax-js/issues"
+  },
+  "homepage": "https://github.com/acuminous/bitsyntax-js#readme",
+  "directories": {
+    "lib": "lib",
+    "test": "test"
+  }
+}

+ 50 - 0
node_modules/@acuminous/bitsyntax/test/consing.test.js

@@ -0,0 +1,50 @@
+var syntax = require('zunit').syntax;
+var assert = require('assert');
+var parse = require('..').parse;
+var build = require('..').build;
+var builder = require('..').builder;
+var write = require('..').write;
+
+var Buffer = require('safe-buffer').Buffer;
+var suite = syntax.describe;
+var test = syntax.it;
+
+TEST_CASES = [
+  ['n:8', {n:255}, [255]],
+  ['n:16', {n: 0xf0f0}, [240, 240]],
+  ['n:32', {n: 0x12345678}, [18,52,86,120]],
+  ['n:64', {n: 0xffffffffffffffff}, [255,255,255,255,255,255,255,255]],
+
+  ['n:8, s/binary', {n: 255, s: Buffer.from("foobar")}, [255, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]],
+  ['n:8, "foobar", m:8', {n: 255, m:0}, [255, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0]],
+  ['n:8, s:n/binary', {n:6, s: Buffer.from('foobar')}, [6, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]],
+  ['n:8, s:n/binary', {n:4, s: Buffer.from('foobar')}, [4, 0x66, 0x6f, 0x6f, 0x62]],
+  ['n:size', {n:4, size:8}, [4]],
+  ['206:n/unit:8', {n:1}, [206]]
+];
+
+function bufferToArray(buf) {
+  return Array.prototype.slice.call(buf);
+}
+
+suite("Construction", function() {
+  TEST_CASES.forEach(function(c) {
+    var p = parse(c[0]);
+    test(c[0], function() {
+      assert.deepEqual(c[2], bufferToArray(build(p, c[1])));
+    });
+    test(c[0], function() {
+      var buf = Buffer.alloc(1024);
+      var end = write(buf, 7, p, c[1]);
+      buf = buf.slice(7, end);
+      assert.deepEqual(c[2], bufferToArray(buf));
+    });
+    test(c[0], function() {
+      var cons = builder(c[0]);
+      var buf = cons(c[1]);
+      assert.deepEqual(c[2], bufferToArray(buf));
+    });
+
+  });
+
+});

+ 193 - 0
node_modules/@acuminous/bitsyntax/test/matching.test.js

@@ -0,0 +1,193 @@
+var syntax = require('zunit').syntax;
+var match = require('..').match;
+var parse = require('..').parse;
+var compile = require('..').matcher;
+var assert = require('assert');
+
+var Buffer = require('safe-buffer').Buffer;
+var suite = syntax.describe;
+var test = syntax.it;
+
+Object.prototype.AMQPLIB_ISSUE_453 = 123123123
+
+var INT_TESTS = [
+    ['n:8',
+     [[[255], 255]]],
+    ['n:8/signed',
+     [[[255], -1]]],
+    ['n:1/unit:8',
+     [[[129], 129]]],
+    ['n:1/unit:8-signed',
+     [[[129], -127]]],
+
+    ['n:16',
+     [[[1, 255], 511]]],
+    ['n:16/signed',
+     [[[255, 65], -191]]],
+    ['n:16/little',
+     [[[255, 1], 511]]],
+    ['n:16/signed-little',
+     [[[65, 255], -191]]],
+
+    ['n:32',
+     [[[45, 23, 97, 102], 756506982]]],
+    ['n:32/signed',
+     [[[245, 23, 97, 102], -183017114]]],
+    ['n:32/little',
+     [[[245, 23, 97, 102], 1717639157]]],
+    ['n:32/signed-little',
+     [[[245, 23, 97, 129], -2124343307]]],
+
+    ['n:4/signed-little-unit:8',
+     [[[245, 23, 97, 129], -2124343307]]],
+
+    ['n:64',
+     [[[1,2,3,4,5,6,7,8], 72623859790382856]]],
+    ['n:64/signed',
+     [[[255,2,3,4,5,6,7,8], -71491328285473016]]],
+    ['n:64/little',
+     [[[1,2,3,4,5,6,7,8], 578437695752307201]]],
+    ['n:64/little-signed',
+     [[[1,2,3,4,5,6,7,255], -70080650589044223]]],
+    ['n:8/signed-unit:8-little',
+     [[[1,2,3,4,5,6,7,255], -70080650589044223]]],
+];
+
+suite("Integer",
+      function() {
+
+        INT_TESTS.forEach(function(p) {
+          var pattern = parse(p[0]);
+          var cpattern = compile(p[0]);
+          p[1].forEach(function(tc) {
+            test(p[0], function() {
+              assert.deepEqual({n: tc[1]}, match(pattern, Buffer.from(tc[0])));
+            });
+            test(p[0], function() {
+              assert.deepEqual({n: tc[1]}, cpattern(Buffer.from(tc[0])));
+            });
+          });
+        });
+      });
+
+
+// test cases largely constructed in Erlang using e.g.,
+// Pi = math:pi(), <<Pi:32/float>>.
+FLOAT_TESTS = [
+  ['n:32/float',
+   [[[64,73,15,219], Math.PI],
+    [[0, 0, 0, 0], 0.0 ]]],
+
+  ['n:64/float',
+   [[[64,9,33,251,84,68,45,24], Math.PI],
+    [[0, 0, 0, 0, 0, 0, 0, 0], 0.0]]],
+
+  ['n:32/float-little',
+   [[[219, 15, 73, 64], Math.PI],
+    [[0, 0, 0, 0], 0.0]]],
+
+  ['n:64/float-little',
+   [[[24, 45, 68, 84, 251, 33, 9, 64], Math.PI],
+    [[0, 0, 0, 0, 0, 0, 0, 0], 0.0]]],
+
+  ['n:4/float-unit:8',
+   [[[64,73,15,219], Math.PI],
+    [[0, 0, 0, 0], 0.0]]]
+];
+
+suite("Float",
+      function() {
+        var precision = 0.00001;
+        FLOAT_TESTS.forEach(function(p) {
+          var pattern = parse(p[0]);
+          var cpattern = compile(p[0]);
+          p[1].forEach(function(tc) {
+            test(p[0], function() {
+              var m = match(pattern, Buffer.from(tc[0]));
+              assert.ok(m.n !== undefined);
+              assert.ok(Math.abs(tc[1] - m.n) < precision);
+            });
+            test(p[0], function() {
+              var m = cpattern(Buffer.from(tc[0]));
+              assert.ok(m.n !== undefined);
+              assert.ok(Math.abs(tc[1] - m.n) < precision);
+            });
+          });
+        });
+      });
+
+BINARY_TESTS = [
+  ['n:0/unit:8-binary', []],
+  ['n:1/unit:8-binary', [93]],
+  ['n:5/unit:8-binary', [1, 2, 3, 4, 5]],
+  ['n:32/unit:1-binary', [255, 254, 253, 252]]
+];
+
+suite("Binary",
+      function() {
+        BINARY_TESTS.forEach(function(p) {
+          var pattern = parse(p[0]);
+          var cpattern = compile(p[0]);
+          var prest = p[0] + ', _/binary';
+          var patternrest = parse(prest);
+          var cpatternrest = compile(prest);
+          test(p[0], function() {
+            assert.deepEqual({n: Buffer.from(p[1])},
+                             match(pattern, Buffer.from(p[1])));
+            assert.deepEqual({n: Buffer.from(p[1])},
+                             cpattern(Buffer.from(p[1])));
+          });
+          test(prest, function() {
+            var plusgarbage = p[1].concat([5, 98, 23, 244]);
+            assert.deepEqual({n: Buffer.from(p[1])},
+                             match(patternrest, Buffer.from(plusgarbage)));
+            assert.deepEqual({n: Buffer.from(p[1])},
+                             cpatternrest(Buffer.from(plusgarbage)));
+          });
+        });
+      });
+
+var VAR_TESTS = [
+  ['size, n:size',
+   [[[8, 5], 5],
+    [[32, 0, 0, 0, 167], 167]]],
+
+  ['size, n:size/binary',
+   [[[2, 5, 6], Buffer.from([5, 6])]]],
+
+  ['a, b:a, n:b',
+   [[[8, 32, 0, 0, 2, 100], 612]]]
+];
+
+suite("Environment",
+      function() {
+        VAR_TESTS.forEach(function(p) {
+          var pattern = parse(p[0]);
+          var cpattern = compile(p[0]);
+          p[1].forEach(function(tc) {
+            test(p[0], function() {
+              assert.deepEqual(tc[1], match(pattern, Buffer.from(tc[0])).n);
+            });
+            test(p[0], function() {
+              assert.deepEqual(tc[1], cpattern(Buffer.from(tc[0])).n);
+            });
+          });
+        });
+      });
+
+STRING_TESTS = [
+  ['"foobar", n:8', "foobarA", 'A'.charCodeAt(0)],
+  ['n:8, "foobar", _/binary', "CfoobarGARBAGE", 'C'.charCodeAt(0)],
+  ['"foo, :-bar\\"", n:8, "another"', 'foo, :-bar"Zanother', 'Z'.charCodeAt(0)]
+];
+
+suite("String",
+      function() {
+        STRING_TESTS.forEach(function(p) {
+          var pattern = parse(p[0]);
+          test(p[0], function() {
+            var res = match(pattern, Buffer.from(p[1]));
+            assert.equal(res.n, p[2]);
+          });
+        });
+      });

+ 41 - 0
node_modules/amqplib/.github/ISSUE_TEMPLATE/bug_report.md

@@ -0,0 +1,41 @@
+---
+name: Bug report / Support request
+about: Report a bug or ask for help
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+Before reporting a bug or requesting support please... 
+
+1. Read the troubleshooting guide
+
+   - https://amqp-node.github.io/amqplib/#troubleshooting
+
+2. Search for existing open and closed issues
+
+   - https://github.com/amqp-node/amqplib/issues?q=is%3Aissue+TYPE+YOUR+KEYWORDS+HERE
+
+3. Ensure you are familiar with the amqplib Channel API and RabbitMQ basics
+
+   - https://amqp-node.github.io/amqplib/channel_api.html
+   - https://www.cloudamqp.com/blog/part1-rabbitmq-for-beginners-what-is-rabbitmq.html
+   - https://www.rabbitmq.com/tutorials/amqp-concepts.html
+
+If the above does not help, please provide as much of the following information as is relevant...
+
+  - A clear and concise description of the problem
+  - RabbitMQ version
+  - amqplib version
+  - Node.js version
+  - The simplest possible code snippet that demonstrates the problem
+  - A stack trace
+
+Please format code snippets and/or stack traces using GitHub Markdown
+
+  - https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks).
+
+Thank you
+
+

+ 59 - 0
node_modules/amqplib/.github/workflows/publish.yml

@@ -0,0 +1,59 @@
+name: Publish
+
+on:
+  release:
+    types: [created]
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    services:
+      rabbitmq:
+        image: rabbitmq:3-alpine
+        ports:
+          - 5672:5672
+
+    strategy:
+      matrix:
+        node-version: [10.x, 12.x, 14.x, 16.x, 18.x, 20.x]
+        # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
+
+    steps:
+      - uses: actions/checkout@v3
+
+      - name: Use Node.js ${{ matrix.node-version }}
+        uses: actions/setup-node@v3
+        with:
+          node-version: ${{ matrix.node-version }}
+          cache: "npm"
+
+      - run: npm ci
+
+      - run: |
+          n=0
+          while :
+          do
+            sleep 5
+            echo 'HELO\n\n\n\n' | nc localhost 5672 | grep AMQP
+            [[ $? = 0 ]] && break || ((n++))
+            (( n >= 5 )) && break
+          done
+
+      - run: echo 'HELO\n\n\n\n' | nc localhost 5672 | grep AMQP
+
+      - run: make test
+
+  publish:
+    needs: build
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions/setup-node@v3
+        with:
+          node-version: '20.x'
+          cache: "npm"
+          registry-url: https://registry.npmjs.org/
+      - run: npm ci
+      - run: npm publish --dry-run
+        env:
+          NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}

+ 51 - 0
node_modules/amqplib/.github/workflows/test.yml

@@ -0,0 +1,51 @@
+# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
+
+name: Node.js CI
+
+on:
+  push:
+    branches: [main]
+  pull_request:
+    branches: [main]
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    services:
+      rabbitmq:
+        image: rabbitmq:3.12-alpine
+        ports:
+          - 5672:5672
+
+    strategy:
+      matrix:
+        node-version: [10.x, 12.x, 14.x, 16.x, 18.x, 20.x]
+        # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
+
+    steps:
+      - uses: actions/checkout@v2
+      - name: Use Node.js ${{ matrix.node-version }}
+        uses: actions/setup-node@v2
+        with:
+          node-version: ${{ matrix.node-version }}
+          cache: "npm"
+
+      # Install all prerequisites
+      - run: npm ci
+
+      # Ensure RabbitMQ is available before continuing
+      - run: |
+          n=0
+          while :
+          do
+            sleep 5
+            echo 'HELO\n\n\n\n' | nc localhost 5672 | grep AMQP
+            [[ $? = 0 ]] && break || ((n++))
+            (( n >= 5 )) && break
+          done
+
+      - run: echo 'HELO\n\n\n\n' | nc localhost 5672 | grep AMQP
+
+      # Run the tests
+      - run: make test

+ 443 - 0
node_modules/amqplib/CHANGELOG.md

@@ -0,0 +1,443 @@
+# Change log for amqplib
+
+## Changes in v0.10.5
+
+    git log v0.10.4..v0.10.5
+
+- Removed readable stream - See https://github.com/amqp-node/amqplib/issues/729
+- Added support for unsigned integers - See https://github.com/amqp-node/amqplib/pull/773
+- Committed protocol definitions - See https://github.com/amqp-node/amqplib/commit/0a87ee480311633cff41e43350a90cb3c1221506
+
+## Changes in v0.10.4
+
+- Improve stream example as per https://github.com/amqp-node/amqplib/issues/722
+- Added support for RabbitMQ's connection update-secret operation. See https://github.com/amqp-node/amqplib/issues/755
+
+## Changes in v0.10.3
+
+    git log v0.10.2..v0.10.3
+
+- Use @acuminous/bitsyntax fork. See https://github.com/amqp-node/amqplib/issues/453
+
+## Changes in v0.10.2
+
+    git log v0.10.1..v0.10.2
+
+- Use Buffer.allocUnsafe when sending messages to improve performance ([PR
+  695](https://github.com/amqp-node/amqplib/pull/695), thank you
+  @chkimes and @Uzlopak)
+
+## Changes in v0.10.1
+
+    git log v0.10.0..v0.10.1
+
+ * Allow servername to be specified via socket options as discussed in
+   [issue 697](https://github.com/squaremo/amqp.node/issues/697)
+
+## Changes in v0.10.0
+
+    git log v0.9.1..v0.10.0
+
+ * Use Native promises ([PR
+   689](https://github.com/amqp-node/amqplib/pull/689), thank you
+   @mohd-akram and @kibertoad)
+
+## Changes in v0.9.1
+
+    git log v0.9.0..v0.9.1
+
+ * Assorted readme changes
+ * Use Array.prototype.push.apply instead of concat in Mux ([PR
+   658](https://github.com/squaremo/amqp.node/pull/658), thank you
+   @Uzlopak and @kibertoad)
+ * Use Map instead of Object for BaseChannel.consumers ([PR
+   660](https://github.com/squaremo/amqp.node/pull/660), thank you
+   @Uzlopak)
+ * Delete consumer callback after cancellation to free memory ([PR
+   659](https://github.com/squaremo/amqp.node/pull/659), thank you
+   @Uzlopak and @kibertoad)
+
+
+## Changes in v0.9.0
+
+    git log v0.8.0..v0.9.0
+
+ * Update mocha and replace the deprecated istanbul with nyc ([PR
+   681](https://github.com/squaremo/amqp.node/pull/681)
+ * Update url-parse ([PR
+   675](https://github.com/squaremo/amqp.node/pull/675), thank you
+   @suhail-n and @kibertoad)
+ * fix: done called twice on invalid options ([PR
+   667](https://github.com/squaremo/amqp.node/pull/667), thank you
+   @luddd3 and @kibertoad)
+ * Close connection to server on connect errors ([PR
+   647](https://github.com/squaremo/amqp.node/pull/647), thank you
+   @luddd3 and @kibertoad)
+ * Modernise channel_model.js ([PR
+   635](https://github.com/squaremo/amqp.node/pull/635), thank you
+   @kibertoad and @jimmywarting)
+ * Bring package-lock.json up to date ([PR
+   653](https://github.com/squaremo/amqp.node/pull/653)
+ * Update url-parse ([PR
+   652](https://github.com/squaremo/amqp.node/pull/652), thank you
+   @giorgioatanasov and @buffolander)
+ * Modernise channel_model.js ([PR
+   651](https://github.com/squaremo/amqp.node/pull/651), thank you
+   for the review @kibertoad)
+ * Modernise bitset.js ([PR
+   634](https://github.com/squaremo/amqp.node/pull/634), thank you
+   @kibertoad and @jimmywarting)
+ * :warning: Drop CI for node versions below 10 ([PR
+   631](https://github.com/squaremo/amqp.node/pull/631), thank you
+   for the review @kibertoad)
+ * Replace safe-buffer dependency with native buffers ([PR
+   628](https://github.com/squaremo/amqp.node/pull/628), thank you
+   @kibertoad and @jimmywarting)
+
+## Changes in v0.8.0
+
+    git log v0.7.1..v0.8.0
+
+ * :warning: Support for NodeJS prior to v10 is dropped :warning: ([PR
+   615](https://github.com/squaremo/amqp.node/pull/615), thank you
+   @xamgore and everyone who helped there)
+ * Use hostname as TLS servername, to help with using servers behind
+   load balancers ([PR
+   567](https://github.com/squaremo/amqp.node/pull/567), thanks to
+   @carlhoerberg and commenters)
+
+## Changes in v0.7.1
+
+    git log v0.7.0..v0.7.1
+
+ * Update url-parse (and others) ([PR
+   607](https://github.com/squaremo/amqp.node/pull/545), thanks
+   @ThomasGawlitza)
+
+## Changes in v0.7.0
+
+    git log v0.6.0..v0.7.0
+
+ * Extend support to Node.js v15
+ * Fix use of stream.write in tests
+
+## Changes in v0.6.0
+
+    git log v0.5.6..v0.6.0
+
+ * Extend support to Node.js v14
+
+## Changes in v0.5.6
+
+    git log v0.5.5..v0.5.6
+
+ * Increase size of encoding space for message headers, to fit e.g.,
+   JWT ([PR 545](https://github.com/squaremo/amqp.node/pull/545));
+   thanks @twatson83
+ * Switch to a non-deprecated UUID module ([PR
+   528](https://github.com/squaremo/amqp.node/pull/528)); thanks to
+   @StrayBird-ATSH
+ * Fix a bug in multiplexing that caused an assertion to fail ([PR
+   503](https://github.com/squaremo/amqp.node/pull/503)); thanks
+   @johanneswuerbach
+
+## Changes in v0.5.5
+
+    git log v0.5.3..v0.5.5
+
+**NB** this includes a minor but possibly breaking change: after [PR
+498](https://github.com/squaremo/amqp.node/pull/498), all confirmation
+promises still unresolved will be rejected when their associated
+channel is closed.
+
+ * Generate defs in `npm prepare` rather than `npm prepublish` so that
+  e.g., amqplib can be installed via git ([part of PR
+  498](https://github.com/squaremo/amqp.node/pull/498))
+ * Reject all pending confirmations when the channel is closed ([PR
+  498](https://github.com/squaremo/amqp.node/pull/498)); thanks
+  @johanneswuerbach
+ * Update supported NodeJS versions in package.json ([PR
+   525](https://github.com/squaremo/amqp.node/pull/525)); thanks
+   @tingwai
+
+## (Deprecated v0.5.4)
+
+This release was mistakenly published without the generated file
+`./defs.js`. It has been deprecated in favour of v0.5.5.
+
+## Changes in v0.5.3
+
+    git log v0.5.2..v0.5.3
+
+ * Bump bitsyntax to remove some `Buffer` misuse deprecation notices
+ ([PR 480])(https://github.com/squaremo/amqp.node/pull/480)
+ * Test on node 11.1
+  ([PR 473])(https://github.com/squaremo/amqp.node/pull/464); thanks
+  @kibertoad
+ * Updated various dependencies
+ * Support queue mode during assertQueue
+   ([PR 464])(https://github.com/squaremo/amqp.node/pull/464); thanks
+   @JoeTheFkingFrypan
+ * Expose serverProperties in the connection object
+   ([PR 452])(https://github.com/squaremo/amqp.node/pull/452); thanks
+   @jfromaniello
+ * Test on Node 10
+   ([PR 454])(https://github.com/squaremo/amqp.node/pull/454); thanks
+   @kibertoad
+ * Support amqplain credentials
+   ([PR 451])(https://github.com/squaremo/amqp.node/pull/451); thanks
+   @jfromaniello
+ * Decorate channel errors with methodId and classId
+   ([PR 447])(https://github.com/squaremo/amqp.node/pull/447); thanks
+   @MitMaro
+ * Resolve issues caused by Node 10 `readable` changes
+   ([PR 442])(https://github.com/squaremo/amqp.node/pull/442)
+ * Bump uglify to 2.6.x and node to 9.1 due to nodejs/node#16781.
+   ([PR 439])(https://github.com/squaremo/amqp.node/pull/439)
+ * Updated README with more modern Buffer syntax
+   ([PR 438](https://github.com/squaremo/amqp.node/pull/438); thanks
+   @ravshansbox
+ * Support overflow option to assert queue
+   ([PR 436])(https://github.com/squaremo/amqp.node/pull/436); thanks
+   to @honestserpent
+ * Replace instances of keyword `await`
+   ([PR 396])(https://github.com/squaremo/amqp.node/pull/396),
+   as discussed in
+   [issue 235](https://github.com/squaremo/amqp.node/issues/235)
+ * Use 3rd party url for better decoding of username/password
+   ([PR 395])(https://github.com/squaremo/amqp.node/pull/395),
+   as discussed in
+   [issue 385](https://github.com/squaremo/amqp.node/issues/385))
+
+## Changes in v0.5.2
+
+    git log v0.5.1..v0.5.2
+
+ * Increase encoding buffer to accommodate large header values
+   ([PR 367](https://github.com/squaremo/amqp.node/pull/367))
+ * Bring code up to date with new Buffer interface
+   ([PR 350](https://github.com/squaremo/amqp.node/pull/350))
+ * Fix dangling connection problem
+   ([PR 340](https://github.com/squaremo/amqp.node/pull/340))
+ * Clear up URL credentials parsing
+   ([PR 330](https://github.com/squaremo/amqp.node/pull/330))
+ * Allow connection params to be suppied in object
+   ([PR 304](https://github.com/squaremo/amqp.node/pull/304))
+ * Support explicit numeric types in field tables (e.g., headers)
+   ([PR 389](https://github.com/squaremo/amqp.node/pull/389), from a
+   suggestion in
+   [issue 358](https://github.com/squaremo/amqp.node/issues/358))
+
+Thank you to all contributors, of PRs, issues and comments.
+
+## Changes in v0.5.1
+
+    git log v0.5.0..v0.5.1
+
+ * Fix mistake in closeBecause
+   ([PR 298](https://github.com/squaremo/amqp.node/pull/298); thanks
+   to @lholznagel and others who reported the issue, and to @nfantone
+   for the rapid fix)
+
+## Changes in v0.5.0
+
+    git log v0.4.2..v0.5.0
+
+ * Port to use bluebird rather than when.js
+   ([PR 295](https://github.com/squaremo/amqp.node/pull/295); thanks
+   to @nfantone, and special mention to @myndzi for #158)
+ * Fixed a problem with using `channel.get` in the callback model
+   ([PR 283](https://github.com/squaremo/amqp.node/pull/283); good
+   catch, @shanksauce)
+ * Added an example that uses generators (thanks @rudijs)
+ * Fixed a link in the comments relating to heartbeats (thanks
+   @tapickell)
+
+## Changes in v0.4.2
+
+   git log v0.4.1..v0.4.2
+
+ * Better documentation and examples
+ * Replace uses of ES6 keyword 'await'
+
+## Changes in v0.4.1
+
+   git log v0.4.0..v0.4.1
+
+ * Tested in Node.JS 0.8 through 4.2 and 5.5
+ * Emit an error with the 'close' event if server-initiated
+
+## Changes in v0.4.0
+
+   git log v0.3.2..v0.4.0
+
+ * Tested on Node.JS 0.8 through 4.0 (and intervening io.js releases)
+ * Change meaning of 'b' fields in tables to match RabbitMQ (and AMQP
+   specification)
+ * Can now pass an object in place of connection URL
+   ([PR 159](https://github.com/squaremo/amqp.node/pull/159); thanks
+   to @ben-page)
+ * Operator-initiated connection close no longer results in 'error'
+   event
+   ([issue 110](https://github.com/squaremo/amqp.node/issues/110))
+ * Channel and Connection errors have now a `.code` field with the
+   AMQP reply-code, which may help distinguish error cases
+   ([PR 150](https://github.com/squaremo/amqp.node/pull/150); thanks
+   to @hippich)
+ * Connection.close will resolve to an error if the connection is
+   already closed
+   ([issue 181](https://github.com/squaremo/amqp.node/issues/181))
+ * Connection establishment will resolve with an error if the
+   TCP-level connection or the handshake times out
+   ([PR 169](https://github.com/squaremo/amqp.node/pull/169); thanks
+   to @zweifisch and @RoCat, who both submitted fixes)
+ * Add the `maxPriority` option as an alias for the `'x-max-priority'`
+   queue argument
+   ([PR 180](https://github.com/squaremo/amqp.node/pull/180); thanks
+   to @ebardes)
+
+## Changes in v0.3.2 (since v0.3.1)
+
+   git log v0.3.1..v0.3.2
+
+ * Make the engine specification more flexible to admit io.js releases
+
+## Changes in v0.3.1 (since v0.3.0)
+
+   git log v0.3.0..v0.3.1
+
+### Fixes
+
+ * Fail in the right way when a channel cannot be allocated [issue
+ 129](https://github.com/squaremo/amqp.node/issues/129)
+ * Make `waitForConfirms` work properly in callback API [PR
+   116](https://github.com/squaremo/amqp.node/pull/116)
+
+### Enhancements
+
+ * Two new options while connecting:
+   [timeout](https://github.com/squaremo/amqp.node/pull/118) and [keep
+   alive](https://github.com/squaremo/amqp.node/pull/125) (thanks to
+   @rexxars and @jcrugzz respectively)
+
+## Changes in v0.3.0 (since v0.2.1)
+
+   git log v0.2.1..v0.3.0
+
+### Enhancements
+
+ * Allow additional client properties to be set for a connection
+   [Issue 98](https://github.com/squaremo/amqp.node/issues/98) and
+   [PR 80](https://github.com/squaremo/amqp.node/pull/80)
+ * New method in channel API to wait for all unconfirmed messages
+   [Issue 89](https://github.com/squaremo/amqp.node/issues/89)
+ * Now supports RabbitMQ's `EXTERNAL` authentication plugin
+   [Issue 105](https://github.com/squaremo/amqp.node/issues/105)
+
+## Changes in v0.2.1 (since v0.2.0)
+
+### Fixes
+
+ * Do tuning negotation properly [PR
+   84](https://github.com/squaremo/amqp.node/pull/84)
+
+## Changes in v0.2.0 (since v0.1.3)
+
+    git log v0.1.3..v0.2.0
+
+### Fixes
+
+ * Correctly deal with missing fields (issue 48)
+
+### Enhancements
+
+ * Added a callback-oriented API, parallel to the existing,
+   promise-oriented API.
+ * The response to assertExchange now contains the exchange name,
+   analagous to assertQueue (issue 49)
+ * The channel method `prefetch` now has a global flag, to be
+   [compatible with newer RabbitMQ][rabbitmq-prefetch-global].
+
+## Changes in v0.1.3 (since v0.1.2)
+
+    git log v0.1.2..v0.1.3
+
+### Enhancements
+
+ * Add support in the API for using Basic.Reject rather than
+   Basic.Nack, the latter of which is a RabbitMQ extension and not in
+   older versions of RabbitMQ.
+
+## Changes in v0.1.2 (since v0.1.1)
+
+    git log v0.1.1..v0.1.2
+
+### Fixes
+
+ * Restore support for publishing zero-length messages
+
+### Enhancements
+
+ * Recognise [authentication failures][rabbitmq-auth-failure]
+ * An option to set TCP_NODELAY on connection sockets
+
+## Changes in v0.1.1 (since v0.1.0)
+
+    git log v0.1.0..v0.1.1
+
+### Fixes
+
+ * Safer frame construction, no longer relies on allocating a large,
+   fixed-size buffer and hoping it's big enough
+ * The ports of RabbitMQ tutorials now avoid a race between publishing
+   and closing the connection
+
+### Enhancements
+
+ * Support for RabbitMQ's consumer priority extension
+ * Support for RabbitMQ's connnection.blocked extension
+ * Better write speed from batching frames for small messages
+ * Other minor efficiency gains in method encoding and decoding
+ * Channel and connection state errors (e.g., trying to write when
+   closed) include a stack trace from when they moved to that state
+ * The `arguments` table, passed as an option to some methods, can
+   include fields in its prototype chain
+ * Provide the more accurately named `persistent` as a near equivalent
+   of `deliveryMode`
+
+## Changes in v0.1.0 (since v0.0.2)
+
+    git log v0.0.2..v0.1.0
+
+### Breaking changes
+
+ * Consumer callbacks are invoked with `null` if the consumer is
+   cancelled (see
+   [RabbitMQ's consumer cancel notification][rabbitmq-consumer-cancel])
+ * In confirm channels, instead of `#publish` and `#sendToQueue`
+   returning promises, they return a boolean as for normal channels,
+   and take a Node.JS-style `function (err, ok)` callback for the
+   server ack or nack
+
+### Fixes
+
+ * Overlapping channel and connection close frames are dealt with
+   gracefully
+ * Exceptions thrown in consumer callbacks are raised as `'error'`
+   events
+ * Zero-size messages are handled
+ * Avoid monkey-patching `Buffer`, and eschew
+   `require('util')._extend`
+
+### Enhancements
+
+ * Channels now behave like `Writable` streams with regard to `#publish`
+   and `#sendToQueue`, returning a boolean from those methods and
+   emitting `'drain'`
+ * Connections now multiplex frames from channels fairly
+ * Low-level channel machinery is now fully callback-based
+
+
+[rabbitmq-consumer-cancel]: http://www.rabbitmq.com/consumer-cancel.html
+[rabbitmq-auth-failure]: http://www.rabbitmq.com/auth-notification.html
+[rabbitmq-prefetch-global]: http://www.rabbitmq.com/consumer-prefetch.html

+ 6 - 0
node_modules/amqplib/LICENSE

@@ -0,0 +1,6 @@
+amqplib copyright (c) 2013, 2014
+                      Michael Bridgen <mikeb@squaremobius.net>
+
+This package, "amqplib", is licensed under the MIT License. A copy may
+be found in the file LICENSE-MIT in this directory, or downloaded from
+http://opensource.org/licenses/MIT.

+ 21 - 0
node_modules/amqplib/LICENSE-MIT

@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2013, 2014 Michael Bridgen <mikeb@squaremobius.net>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 49 - 0
node_modules/amqplib/Makefile

@@ -0,0 +1,49 @@
+RABBITMQ_SRC_VERSION=v3.12.13
+JSON=amqp-rabbitmq-0.9.1.json
+AMQP_JSON=https://raw.githubusercontent.com/rabbitmq/rabbitmq-server/$(RABBITMQ_SRC_VERSION)/deps/rabbitmq_codegen/$(JSON)
+
+NODEJS_VERSIONS='10.21' '11.15' '12.18' '13.14' '14.5' '15.8' '16.3.0' '18.1.0' '20.10.0'
+
+MOCHA=./node_modules/.bin/mocha
+_MOCHA=./node_modules/.bin/_mocha
+UGLIFY=./node_modules/.bin/uglifyjs
+NYC=./node_modules/.bin/nyc
+
+.PHONY: test test-all-nodejs coverage lib/defs.js
+
+error:
+	@echo "Please choose one of the following targets: test, test-all-nodejs, coverage, lib/defs.js"
+	@exit 1
+
+test:
+	$(MOCHA) --check-leaks -u tdd --exit test/
+
+test-all-nodejs:
+	for v in $(NODEJS_VERSIONS); \
+		do echo "-- Node version $$v --"; \
+		nave use $$v $(MOCHA) -u tdd --exit -R progress test; \
+		done
+
+coverage: $(NYC)
+	$(NYC) --clean --reporter=lcov --reporter=text $(_MOCHA) -u tdd --exit -R progress test/
+	@echo "HTML report at file://$$(pwd)/coverage/lcov-report/index.html"
+
+lib/defs.js: clean bin/generate-defs test
+
+clean:
+	rm -f lib/defs.js bin/amqp-rabbitmq-0.9.1.json
+
+bin/generate-defs: $(UGLIFY) bin/generate-defs.js bin/amqp-rabbitmq-0.9.1.json
+	(cd bin; node ./generate-defs.js > ../lib/defs.js)
+	$(UGLIFY) ./lib/defs.js -o ./lib/defs.js \
+		-c 'sequences=false' --comments \
+		-b 'indent-level=2' 2>&1 | (grep -v 'WARN' || true)
+
+bin/amqp-rabbitmq-0.9.1.json:
+	curl -L $(AMQP_JSON) > $@
+
+$(ISTANBUL):
+	npm install
+
+$(UGLIFY):
+	npm install

+ 156 - 0
node_modules/amqplib/README.md

@@ -0,0 +1,156 @@
+# AMQP 0-9-1 library and client for Node.JS
+
+[![NPM version](https://img.shields.io/npm/v/amqplib.svg?style=flat-square)](https://www.npmjs.com/package/amqplib)
+[![NPM downloads](https://img.shields.io/npm/dm/amqplib.svg?style=flat-square)](https://www.npmjs.com/package/amqplib)
+[![Node.js CI](https://github.com/amqp-node/amqplib/workflows/Node.js%20CI/badge.svg)](https://github.com/amqp-node/amqplib/actions?query=workflow%3A%22Node.js+CI%22)
+[![amqplib](https://snyk.io/advisor/npm-package/amqplib/badge.svg)](https://snyk.io/advisor/npm-package/amqplib)
+
+    npm install amqplib
+
+ * [Change log][changelog]
+ * [GitHub pages][gh-pages]
+ * [API reference][gh-pages-apiref]
+ * [Troubleshooting][gh-pages-trouble]
+ * [Examples from RabbitMQ tutorials][tutes]
+
+A library for making AMQP 0-9-1 clients for Node.JS, and an AMQP 0-9-1 client for Node.JS v10+.
+
+This library does not implement [AMQP
+1.0](https://github.com/squaremo/amqp.node/issues/63) or [AMQP
+0-10](https://github.com/squaremo/amqp.node/issues/94).
+
+Project status:
+
+ - Expected to work
+ - Complete high-level and low-level APIs (i.e., all bits of the protocol)
+ - Stable APIs
+ - A fair few tests
+ - Measured test coverage
+ - Ports of the [RabbitMQ tutorials][rabbitmq-tutes] as [examples][tutes]
+ - Used in production
+
+Still working on:
+
+ - Getting to 100% (or very close to 100%) test coverage
+
+## Callback API example
+
+```javascript
+const amqplib = require('amqplib/callback_api');
+const queue = 'tasks';
+
+amqplib.connect('amqp://localhost', (err, conn) => {
+  if (err) throw err;
+
+  // Listener
+  conn.createChannel((err, ch2) => {
+    if (err) throw err;
+
+    ch2.assertQueue(queue);
+
+    ch2.consume(queue, (msg) => {
+      if (msg !== null) {
+        console.log(msg.content.toString());
+        ch2.ack(msg);
+      } else {
+        console.log('Consumer cancelled by server');
+      }
+    });
+  });
+
+  // Sender
+  conn.createChannel((err, ch1) => {
+    if (err) throw err;
+
+    ch1.assertQueue(queue);
+
+    setInterval(() => {
+      ch1.sendToQueue(queue, Buffer.from('something to do'));
+    }, 1000);
+  });
+});
+```
+
+## Promise/Async API example
+
+```javascript
+const amqplib = require('amqplib');
+
+(async () => {
+  const queue = 'tasks';
+  const conn = await amqplib.connect('amqp://localhost');
+
+  const ch1 = await conn.createChannel();
+  await ch1.assertQueue(queue);
+
+  // Listener
+  ch1.consume(queue, (msg) => {
+    if (msg !== null) {
+      console.log('Received:', msg.content.toString());
+      ch1.ack(msg);
+    } else {
+      console.log('Consumer cancelled by server');
+    }
+  });
+
+  // Sender
+  const ch2 = await conn.createChannel();
+
+  setInterval(() => {
+    ch2.sendToQueue(queue, Buffer.from('something to do'));
+  }, 1000);
+})();
+
+```
+
+## Running tests
+
+    npm test
+
+To run the tests RabbitMQ is required. Either install it with your package
+manager, or use [docker][] to run a RabbitMQ instance.
+
+    docker run -d --name amqp.test -p 5672:5672 rabbitmq
+
+If prefer not to run RabbitMQ locally it is also possible to use a
+instance of RabbitMQ hosted elsewhere. Use the `URL` environment
+variable to configure a different amqp host to connect to. You may
+also need to do this if docker is not on localhost; e.g., if it's
+running in docker-machine.
+
+One public host is dev.rabbitmq.com:
+
+    URL=amqp://dev.rabbitmq.com npm test
+
+**NB** You may experience test failures due to timeouts if using the
+dev.rabbitmq.com instance.
+
+You can run it under different versions of Node.JS using [nave][]:
+
+    nave use 10 npm test
+
+or run the tests on all supported versions of Node.JS in one go:
+
+    make test-all-nodejs
+
+(which also needs `nave` installed, of course).
+
+Lastly, setting the environment variable `LOG_ERRORS` will cause the
+tests to output error messages encountered, to the console; this is
+really only useful for checking the kind and formatting of the errors.
+
+    LOG_ERRORS=true npm test
+
+## Test coverage
+
+    make coverage
+    open file://`pwd`/coverage/lcov-report/index.html
+
+[gh-pages]: https://amqp-node.github.io/amqplib/
+[gh-pages-apiref]: https://amqp-node.github.io/amqplib/channel_api.html
+[gh-pages-trouble]: https://amqp-node.github.io/amqplib/#troubleshooting
+[nave]: https://github.com/isaacs/nave
+[tutes]: https://github.com/amqp-node/amqplib/tree/main/examples/tutorials
+[rabbitmq-tutes]: http://www.rabbitmq.com/getstarted.html
+[changelog]: https://github.com/amqp-node/amqplib/blob/main/CHANGELOG.md
+[docker]: https://www.docker.com/

+ 483 - 0
node_modules/amqplib/bin/amqp-rabbitmq-0.9.1.json

@@ -0,0 +1,483 @@
+{
+    "name": "AMQP",
+    "major-version": 0,
+    "minor-version": 9,
+    "revision": 1,
+    "port": 5672,
+    "copyright": [
+        "Copyright (C) 2008-2020 VMware, Inc. or its affiliates.\n",
+        "\n",
+        "Permission is hereby granted, free of charge, to any person\n",
+        "obtaining a copy of this file (the \"Software\"), to deal in the\n",
+        "Software without restriction, including without limitation the \n",
+        "rights to use, copy, modify, merge, publish, distribute, \n",
+        "sublicense, and/or sell copies of the Software, and to permit \n",
+        "persons to whom the Software is furnished to do so, subject to \n",
+        "the following conditions:\n",
+        "\n",
+        "The above copyright notice and this permission notice shall be\n",
+        "included in all copies or substantial portions of the Software.\n",
+        "\n",
+        "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n",
+        "EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n",
+        "OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n",
+        "NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n",
+        "HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n",
+        "WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n",
+        "FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n",
+        "OTHER DEALINGS IN THE SOFTWARE.\n",
+        "\n",
+        "Class information entered from amqp_xml0-8.pdf and domain types from amqp-xml-doc0-9.pdf\n",
+        "Updated for 0-9-1 by Tony Garnock-Jones\n",
+        "\n",
+        "b3cb053f15e7b98808c0ccc67f23cb3e  amqp_xml0-8.pdf\n",
+        "http://twiststandards.org/?option=com_docman&task=cat_view&gid=28&Itemid=90\n",
+        "8444db91e2949dbecfb2585e9eef6d64  amqp-xml-doc0-9.pdf\n",
+        "https://jira.amqp.org/confluence/download/attachments/720900/amqp-xml-doc0-9.pdf?version=1\n"],
+
+    "domains": [
+        ["bit", "bit"],
+        ["channel-id", "longstr"],
+        ["class-id", "short"],
+        ["consumer-tag", "shortstr"],
+        ["delivery-tag", "longlong"],
+        ["destination", "shortstr"],
+        ["duration", "longlong"],
+        ["exchange-name", "shortstr"],
+        ["long", "long"],
+        ["longlong", "longlong"],
+        ["longstr", "longstr"],
+        ["message-count", "long"],
+        ["method-id", "short"],
+        ["no-ack", "bit"],
+        ["no-local", "bit"],
+        ["octet", "octet"],
+        ["offset", "longlong"],
+        ["path", "shortstr"],
+        ["peer-properties", "table"],
+        ["queue-name", "shortstr"],
+        ["redelivered", "bit"],
+        ["reference", "longstr"],
+        ["reject-code", "short"],
+        ["reject-text", "shortstr"],
+        ["reply-code", "short"],
+        ["reply-text", "shortstr"],
+        ["security-token", "longstr"],
+        ["short", "short"],
+        ["shortstr", "shortstr"],
+        ["table", "table"],
+        ["timestamp", "timestamp"]
+    ],
+
+    "constants": [
+        {"name": "FRAME-METHOD", "value": 1},
+        {"name": "FRAME-HEADER", "value": 2},
+        {"name": "FRAME-BODY", "value": 3},
+        {"name": "FRAME-HEARTBEAT", "value": 8},
+        {"name": "FRAME-MIN-SIZE", "value": 4096},
+        {"name": "FRAME-END", "value": 206},
+        {"name": "REPLY-SUCCESS", "value": 200},
+        {"name": "CONTENT-TOO-LARGE", "value": 311, "class": "soft-error"},
+        {"name": "NO-ROUTE", "value": 312, "class": "soft-error"},
+        {"name": "NO-CONSUMERS", "value": 313, "class": "soft-error"},
+        {"name": "ACCESS-REFUSED", "value": 403, "class": "soft-error"},
+        {"name": "NOT-FOUND", "value": 404, "class": "soft-error"},
+        {"name": "RESOURCE-LOCKED", "value": 405, "class": "soft-error"},
+        {"name": "PRECONDITION-FAILED", "value": 406, "class": "soft-error"},
+        {"name": "CONNECTION-FORCED", "value": 320, "class": "hard-error"},
+        {"name": "INVALID-PATH", "value": 402, "class": "hard-error"},
+        {"name": "FRAME-ERROR", "value": 501, "class": "hard-error"},
+        {"name": "SYNTAX-ERROR", "value": 502, "class": "hard-error"},
+        {"name": "COMMAND-INVALID", "value": 503, "class": "hard-error"},
+        {"name": "CHANNEL-ERROR", "value": 504, "class": "hard-error"},
+        {"name": "UNEXPECTED-FRAME", "value": 505, "class": "hard-error"},
+        {"name": "RESOURCE-ERROR", "value": 506, "class": "hard-error"},
+        {"name": "NOT-ALLOWED", "value": 530, "class": "hard-error"},
+        {"name": "NOT-IMPLEMENTED", "value": 540, "class": "hard-error"},
+        {"name": "INTERNAL-ERROR", "value": 541, "class": "hard-error"}
+    ],
+
+    "classes": [
+        {
+            "id": 60,
+            "methods": [{"id": 10,
+                         "arguments": [{"type": "long", "name": "prefetch-size", "default-value": 0},
+                                       {"type": "short", "name": "prefetch-count", "default-value": 0},
+                                       {"type": "bit", "name": "global", "default-value": false}],
+                         "name": "qos",
+                         "synchronous" : true},
+                        {"id": 11,
+                         "arguments": [],
+                         "name": "qos-ok"},
+                        {"id": 20,
+                         "arguments": [{"domain": "short", "name": "ticket", "default-value": 0},
+                                       {"domain": "queue-name", "name": "queue", "default-value": ""},
+                                       {"type": "shortstr", "name": "consumer-tag", "default-value": ""},
+                                       {"type": "bit", "name": "no-local", "default-value": false},
+                                       {"type": "bit", "name": "no-ack", "default-value": false},
+                                       {"type": "bit", "name": "exclusive", "default-value": false},
+                                       {"type": "bit", "name": "nowait", "default-value": false},
+                                       {"type": "table", "name": "arguments", "default-value": {}}],
+                         "name": "consume",
+                         "synchronous" : true},
+                        {"id": 21,
+                         "arguments": [{"type": "shortstr", "name": "consumer-tag"}],
+                         "name": "consume-ok"},
+                        {"id": 30,
+                         "arguments": [{"type": "shortstr", "name": "consumer-tag"},
+                                       {"type": "bit", "name": "nowait", "default-value": false}],
+                         "name": "cancel",
+                         "synchronous" : true},
+                        {"id": 31,
+                         "arguments": [{"type": "shortstr", "name": "consumer-tag"}],
+                         "name": "cancel-ok"},
+                        {"content": true,
+                         "id": 40,
+                         "arguments": [{"type": "short", "name": "ticket", "default-value": 0},
+                                       {"domain": "exchange-name", "name": "exchange", "default-value": ""},
+                                       {"type": "shortstr", "name": "routing-key", "default-value": ""},
+                                       {"type": "bit", "name": "mandatory", "default-value": false},
+                                       {"type": "bit", "name": "immediate", "default-value": false}],
+                         "name": "publish"},
+                        {"content": true,
+                         "id": 50,
+                         "arguments": [{"type": "short", "name": "reply-code"},
+                                       {"type": "shortstr", "name": "reply-text", "default-value": ""},
+                                       {"domain": "exchange-name", "name": "exchange"},
+                                       {"type": "shortstr", "name": "routing-key"}],
+                         "name": "return"},
+                        {"content": true,
+                         "id": 60,
+                         "arguments": [{"type": "shortstr", "name": "consumer-tag"},
+                                       {"type": "longlong", "name": "delivery-tag"},
+                                       {"type": "bit", "name": "redelivered", "default-value": false},
+                                       {"domain": "exchange-name", "name": "exchange"},
+                                       {"type": "shortstr", "name": "routing-key"}],
+                         "name": "deliver"},
+                        {"id": 70,
+                         "arguments": [{"type": "short", "name": "ticket", "default-value": 0},
+                                       {"domain": "queue-name", "name": "queue", "default-value": ""},
+                                       {"type": "bit", "name": "no-ack", "default-value": false}],
+                         "name": "get",
+                         "synchronous" : true},
+                        {"content": true,
+                         "id": 71,
+                         "arguments": [{"type": "longlong", "name": "delivery-tag"},
+                                       {"type": "bit", "name": "redelivered", "default-value": false},
+                                       {"domain": "exchange-name", "name": "exchange"},
+                                       {"type": "shortstr", "name": "routing-key"},
+                                       {"domain": "message-count", "name": "message-count"}],
+                         "name": "get-ok"},
+                        {"id": 72,
+                         "arguments": [{"type": "shortstr", "name": "cluster-id", "default-value": ""}],
+                         "name": "get-empty"},
+                        {"id": 80,
+                         "arguments": [{"type": "longlong", "name": "delivery-tag", "default-value": 0},
+                                       {"type": "bit", "name": "multiple", "default-value": false}],
+                         "name": "ack"},
+                        {"id": 90,
+                         "arguments": [{"type": "longlong", "name": "delivery-tag"},
+                                       {"type": "bit", "name": "requeue", "default-value": true}],
+                         "name": "reject"},
+                        {"id": 100,
+                         "arguments": [{"type": "bit", "name": "requeue", "default-value": false}],
+                         "name": "recover-async"},
+                        {"id": 110,
+                         "arguments": [{"type": "bit", "name": "requeue", "default-value": false}],
+                         "name": "recover",
+                         "synchronous" : true},
+                        {"id": 111,
+                         "arguments": [],
+                         "name": "recover-ok"},
+                        {"id": 120,
+                         "arguments": [{"type": "longlong", "name": "delivery-tag", "default-value": 0},
+                                       {"type": "bit", "name": "multiple", "default-value": false},
+                                       {"type": "bit", "name": "requeue", "default-value": true}],
+                         "name": "nack"}],
+            "name": "basic",
+            "properties": [{"type": "shortstr", "name": "content-type"},
+                           {"type": "shortstr", "name": "content-encoding"},
+                           {"type": "table", "name": "headers"},
+                           {"type": "octet", "name": "delivery-mode"},
+                           {"type": "octet", "name": "priority"},
+                           {"type": "shortstr", "name": "correlation-id"},
+                           {"type": "shortstr", "name": "reply-to"},
+                           {"type": "shortstr", "name": "expiration"},
+                           {"type": "shortstr", "name": "message-id"},
+                           {"type": "timestamp", "name": "timestamp"},
+                           {"type": "shortstr", "name": "type"},
+                           {"type": "shortstr", "name": "user-id"},
+                           {"type": "shortstr", "name": "app-id"},
+                           {"type": "shortstr", "name": "cluster-id"}]
+        },
+        {
+            "id": 10,
+            "methods": [{"id": 10,
+                         "arguments": [{"type": "octet", "name": "version-major", "default-value": 0},
+                                       {"type": "octet", "name": "version-minor", "default-value": 9},
+                                       {"domain": "peer-properties", "name": "server-properties"},
+                                       {"type": "longstr", "name": "mechanisms", "default-value": "PLAIN"},
+                                       {"type": "longstr", "name": "locales", "default-value": "en_US"}],
+                         "name": "start",
+                         "synchronous" : true},
+                        {"id": 11,
+                         "arguments": [{"domain": "peer-properties", "name": "client-properties"},
+                                       {"type": "shortstr", "name": "mechanism", "default-value": "PLAIN"},
+                                       {"type": "longstr", "name": "response"},
+                                       {"type": "shortstr", "name": "locale", "default-value": "en_US"}],
+                         "name": "start-ok"},
+                        {"id": 20,
+                         "arguments": [{"type": "longstr", "name": "challenge"}],
+                         "name": "secure",
+                         "synchronous" : true},
+                        {"id": 21,
+                         "arguments": [{"type": "longstr", "name": "response"}],
+                         "name": "secure-ok"},
+                        {"id": 30,
+                         "arguments": [{"type": "short", "name": "channel-max", "default-value": 0},
+                                       {"type": "long", "name": "frame-max", "default-value": 0},
+                                       {"type": "short", "name": "heartbeat", "default-value": 0}],
+                         "name": "tune",
+                         "synchronous" : true},
+                        {"id": 31,
+                         "arguments": [{"type": "short", "name": "channel-max", "default-value": 0},
+                                       {"type": "long", "name": "frame-max", "default-value": 0},
+                                       {"type": "short", "name": "heartbeat", "default-value": 0}],
+                         "name": "tune-ok"},
+                        {"id": 40,
+                         "arguments": [{"type": "shortstr", "name": "virtual-host", "default-value": "/"},
+                                       {"type": "shortstr", "name": "capabilities", "default-value": ""},
+                                       {"type": "bit", "name": "insist", "default-value": false}],
+                         "name": "open",
+                         "synchronous" : true},
+                        {"id": 41,
+                         "arguments": [{"type": "shortstr", "name": "known-hosts", "default-value": ""}],
+                         "name": "open-ok"},
+                        {"id": 50,
+                         "arguments": [{"type": "short", "name": "reply-code"},
+                                       {"type": "shortstr", "name": "reply-text", "default-value": ""},
+                                       {"type": "short", "name": "class-id"},
+                                       {"type": "short", "name": "method-id"}],
+                         "name": "close",
+                         "synchronous" : true},
+                        {"id": 51,
+                         "arguments": [],
+                         "name": "close-ok"},
+                        {"id": 60,
+                         "arguments": [{"type": "shortstr", "name": "reason", "default-value": ""}],
+                         "name": "blocked"},
+                        {"id": 61,
+                         "arguments": [],
+                         "name": "unblocked"},
+                        {"id": 70,
+                         "arguments": [{"type": "longstr", "name": "new-secret"},
+                                       {"type": "shortstr", "name": "reason"}],
+                         "name": "update-secret",
+                         "synchronous" : true},
+                        {"id": 71,
+                         "arguments": [],
+                         "name": "update-secret-ok"}
+           ],
+            "name": "connection",
+            "properties": []
+        },
+        {
+            "id": 20,
+            "methods": [{"id": 10,
+                         "arguments": [{"type": "shortstr", "name": "out-of-band", "default-value": ""}],
+                         "name": "open",
+                         "synchronous" : true},
+                        {"id": 11,
+                         "arguments": [{"type": "longstr", "name": "channel-id", "default-value": ""}],
+                         "name": "open-ok"},
+                        {"id": 20,
+                         "arguments": [{"type": "bit", "name": "active"}],
+                         "name": "flow",
+                         "synchronous" : true},
+                        {"id": 21,
+                         "arguments": [{"type": "bit", "name": "active"}],
+                         "name": "flow-ok"},
+                        {"id": 40,
+                         "arguments": [{"type": "short", "name": "reply-code"},
+                                       {"type": "shortstr", "name": "reply-text", "default-value": ""},
+                                       {"type": "short", "name": "class-id"},
+                                       {"type": "short", "name": "method-id"}],
+                         "name": "close",
+                         "synchronous" : true},
+                        {"id": 41,
+                         "arguments": [],
+                         "name": "close-ok"}],
+            "name": "channel"
+        },
+        {
+            "id": 30,
+            "methods": [{"id": 10,
+                         "arguments": [{"type": "shortstr", "name": "realm", "default-value": "/data"},
+                                       {"type": "bit", "name": "exclusive", "default-value": false},
+                                       {"type": "bit", "name": "passive", "default-value": true},
+                                       {"type": "bit", "name": "active", "default-value": true},
+                                       {"type": "bit", "name": "write", "default-value": true},
+                                       {"type": "bit", "name": "read", "default-value": true}],
+                         "name": "request",
+                         "synchronous" : true},
+                        {"id": 11,
+                    "arguments": [{"type": "short", "name": "ticket", "default-value": 1}],
+                         "name": "request-ok"}],
+            "name": "access"
+        },
+        {
+            "id": 40,
+            "methods": [{"id": 10,
+                         "arguments": [{"type": "short", "name": "ticket", "default-value": 0},
+                                       {"domain": "exchange-name", "name": "exchange"},
+                                       {"type": "shortstr", "name": "type", "default-value": "direct"},
+                                       {"type": "bit", "name": "passive", "default-value": false},
+                                       {"type": "bit", "name": "durable", "default-value": false},
+                                       {"type": "bit", "name": "auto-delete", "default-value": false},
+                                       {"type": "bit", "name": "internal", "default-value": false},
+                                       {"type": "bit", "name": "nowait", "default-value": false},
+                                       {"type": "table", "name": "arguments", "default-value": {}}],
+                         "name": "declare",
+                         "synchronous" : true},
+                        {"id": 11,
+                         "arguments": [],
+                         "name": "declare-ok"},
+                        {"id": 20,
+                         "arguments": [{"type": "short", "name": "ticket", "default-value": 0},
+                                       {"domain": "exchange-name", "name": "exchange"},
+                                       {"type": "bit", "name": "if-unused", "default-value": false},
+                                       {"type": "bit", "name": "nowait", "default-value": false}],
+                         "name": "delete",
+                         "synchronous" : true},
+                        {"id": 21,
+                         "arguments": [],
+                         "name": "delete-ok"},
+                        {"id": 30,
+                         "arguments": [{"type": "short", "name": "ticket", "default-value": 0},
+                                       {"domain": "exchange-name", "name": "destination"},
+                                       {"domain": "exchange-name", "name": "source"},
+                                       {"type": "shortstr", "name": "routing-key", "default-value": ""},
+                                       {"type": "bit", "name": "nowait", "default-value": false},
+                                       {"type": "table", "name": "arguments", "default-value": {}}],
+                         "name": "bind",
+                         "synchronous" : true},
+                        {"id": 31,
+                         "arguments": [],
+                         "name": "bind-ok"},
+                        {"id": 40,
+                         "arguments": [{"type": "short", "name": "ticket", "default-value": 0},
+                                       {"domain": "exchange-name", "name": "destination"},
+                                       {"domain": "exchange-name", "name": "source"},
+                                       {"type": "shortstr", "name": "routing-key", "default-value": ""},
+                                       {"type": "bit", "name": "nowait", "default-value": false},
+                                       {"type": "table", "name": "arguments", "default-value": {}}],
+                         "name": "unbind",
+                         "synchronous" : true},
+                        {"id": 51,
+                         "arguments": [],
+                         "name": "unbind-ok"}],
+            "name": "exchange"
+        },
+        {
+            "id": 50,
+            "methods": [{"id": 10,
+                         "arguments": [{"type": "short", "name": "ticket", "default-value": 0},
+                                       {"domain": "queue-name", "name": "queue", "default-value": ""},
+                                       {"type": "bit", "name": "passive", "default-value": false},
+                                       {"type": "bit", "name": "durable", "default-value": false},
+                                       {"type": "bit", "name": "exclusive", "default-value": false},
+                                       {"type": "bit", "name": "auto-delete", "default-value": false},
+                                       {"type": "bit", "name": "nowait", "default-value": false},
+                                       {"type": "table", "name": "arguments", "default-value": {}}],
+                         "name": "declare",
+                         "synchronous" : true},
+                        {"id": 11,
+                         "arguments": [{"domain": "queue-name", "name": "queue"},
+                                       {"domain": "message-count", "name": "message-count"},
+                                       {"type": "long", "name": "consumer-count"}],
+                         "name": "declare-ok"},
+                        {"id": 20,
+                         "arguments": [{"type": "short", "name": "ticket", "default-value": 0},
+                                       {"domain": "queue-name", "name": "queue", "default-value": ""},
+                                       {"domain": "exchange-name", "name": "exchange"},
+                                       {"type": "shortstr", "name": "routing-key", "default-value": ""},
+                                       {"type": "bit", "name": "nowait", "default-value": false},
+                                       {"type": "table", "name": "arguments", "default-value": {}}],
+                         "name": "bind",
+                         "synchronous" : true},
+                        {"id": 21,
+                         "arguments": [],
+                         "name": "bind-ok"},
+                        {"id": 30,
+                         "arguments": [{"type": "short", "name": "ticket", "default-value": 0},
+                                       {"domain": "queue-name", "name": "queue", "default-value": ""},
+                                       {"type": "bit", "name": "nowait", "default-value": false}],
+                         "name": "purge",
+                         "synchronous" : true},
+                        {"id": 31,
+                         "arguments": [{"domain": "message-count", "name": "message-count"}],
+                         "name": "purge-ok"},
+                        {"id": 40,
+                         "arguments": [{"type": "short", "name": "ticket", "default-value": 0},
+                                       {"domain": "queue-name", "name": "queue", "default-value": ""},
+                                       {"type": "bit", "name": "if-unused", "default-value": false},
+                                       {"type": "bit", "name": "if-empty", "default-value": false},
+                                       {"type": "bit", "name": "nowait", "default-value": false}],
+                         "name": "delete",
+                         "synchronous" : true},
+                        {"id": 41,
+                         "arguments": [{"domain": "message-count", "name": "message-count"}],
+                         "name": "delete-ok"},
+                        {"id": 50,
+                         "arguments": [{"type": "short", "name": "ticket", "default-value": 0},
+                                       {"domain": "queue-name", "name": "queue", "default-value": ""},
+                                       {"domain": "exchange-name", "name": "exchange"},
+                                       {"type": "shortstr", "name": "routing-key", "default-value": ""},
+                                       {"type": "table", "name": "arguments", "default-value": {}}],
+                         "name": "unbind",
+                         "synchronous" : true},
+                        {"id": 51,
+                         "arguments": [],
+                         "name": "unbind-ok"}
+                        ],
+            "name": "queue"
+        },
+        {
+            "id": 90,
+            "methods": [{"id": 10,
+                         "arguments": [],
+                         "name": "select",
+                         "synchronous" : true},
+                        {"id": 11,
+                         "arguments": [],
+                         "name": "select-ok"},
+                        {"id": 20,
+                         "arguments": [],
+                         "name": "commit",
+                         "synchronous" : true},
+                        {"id": 21,
+                         "arguments": [],
+                         "name": "commit-ok"},
+                        {"id": 30,
+                         "arguments": [],
+                         "name": "rollback",
+                         "synchronous" : true},
+                        {"id": 31,
+                         "arguments": [],
+                         "name": "rollback-ok"}],
+            "name": "tx"
+        },
+        {
+            "id": 85,
+            "methods": [{"id": 10,
+                         "arguments": [
+                             {"type": "bit", "name": "nowait", "default-value": false}],
+                         "name": "select",
+                         "synchronous": true},
+                        {"id": 11,
+                         "arguments": [],
+                         "name": "select-ok"}],
+            "name": "confirm"
+        }
+    ]
+}

+ 722 - 0
node_modules/amqplib/bin/generate-defs.js

@@ -0,0 +1,722 @@
+var FS = require('fs');
+var format = require('util').format;
+
+var defs = require('./amqp-rabbitmq-0.9.1.json');
+
+var FRAME_OVERHEAD = 8; // type + channel + size + frame-end
+
+var METHOD_OVERHEAD = FRAME_OVERHEAD + 4;
+// F_O + classId + methodId
+
+var PROPERTIES_OVERHEAD = FRAME_OVERHEAD + 4 + 8 + 2;
+// F_O + classId + weight + content size + flags
+
+
+var out = process.stdout;
+
+function printf() {
+  out.write(format.apply(format, arguments), 'utf8');
+}
+
+function nl() { out.write('\n'); }
+function println() { printf.apply(printf, arguments); nl(); }
+
+function isEmptyObject(val) {
+  return (val != null && typeof val === 'object' &&
+          Object.keys(val).length === 0);
+}
+
+function stringifyValue(val) {
+  return (isEmptyObject(val)) ? 'EMPTY_OBJECT' :
+    JSON.stringify(val);
+}
+
+var constants = {};
+var constant_strs = {};
+
+for (var i = 0, len = defs.constants.length; i < len; i++) {
+  var cdef = defs.constants[i];
+  constants[constantName(cdef)] = cdef.value;
+  constant_strs[cdef.value] = cdef.name;
+}
+
+function constantName(def) {
+  return def.name.replace(/-/g, '_');
+}
+
+function methodName(clazz, method) {
+  return initial(clazz.name) + method.name.split('-').map(initial).join('');
+}
+
+function propertyName(dashed) {
+  var parts = dashed.split('-');
+  return parts[0] + parts.slice(1).map(initial).join('');
+}
+
+function initial(part) {
+  return part.charAt(0).toUpperCase() + part.substr(1);
+}
+
+function argument(a) {
+  var type = a.type || domains[a.domain];
+  var friendlyName = propertyName(a.name);
+  return {type: type, name: friendlyName, default: a['default-value']};
+}
+
+var domains = {};
+for (var i=0, len = defs.domains.length; i < len; i++) {
+  var dom = defs.domains[i];
+  domains[dom[0]] = dom[1];
+}
+
+var methods = {};
+var propertieses = {};
+
+for (var i = 0, len = defs.classes.length; i < len; i++) {
+  var clazz = defs.classes[i];
+  for (var j = 0, num = clazz.methods.length; j < num; j++) {
+    var method = clazz.methods[j];
+    var name = methodName(clazz, method);
+    var info = 'methodInfo' + name;
+
+    methods[name] = {
+      id: methodId(clazz, method),
+      name: name,
+      methodId: method.id,
+      clazzId: clazz.id,
+      clazz: clazz.name,
+      args: method['arguments'].map(argument),
+      isReply: method.answer,
+      encoder: 'encode' + name,
+      decoder: 'decode' + name,
+      info: info
+    };
+  }
+  if (clazz.properties && clazz.properties.length > 0) {
+    var name = propertiesName(clazz);
+    var props = clazz.properties;
+    propertieses[name] = {
+      id: clazz.id,
+      name: name,
+      encoder: 'encode' + name,
+      decoder: 'decode' + name,
+      info: 'propertiesInfo' + name,
+      args: props.map(argument),
+    };
+  }
+}
+
+// OK let's get emitting
+
+println(
+'/** @preserve This file is generated by the script\n',
+'* ../bin/generate-defs.js, which is not in general included in a\n',
+'* distribution, but is available in the source repository e.g. at\n',
+'* https://github.com/squaremo/amqp.node/\n',
+'*/');
+
+println("'use strict';"); nl();
+nl()
+println('var codec = require("./codec");');
+println('var ints = require("buffer-more-ints");');
+println('var encodeTable = codec.encodeTable;');
+println('var decodeFields = codec.decodeFields;');
+nl();
+
+println('var SCRATCH = Buffer.alloc(65536);');
+println('var EMPTY_OBJECT = Object.freeze({});');
+
+println('module.exports.constants = %s',
+        JSON.stringify(constants));
+nl();
+println('module.exports.constant_strs = %s',
+        JSON.stringify(constant_strs));
+nl();
+println('module.exports.FRAME_OVERHEAD = %d;', FRAME_OVERHEAD);
+nl();
+
+println('module.exports.decode = function(id, buf) {');
+println('switch (id) {');
+for (var m in methods) {
+  var method = methods[m];
+  println('case %d: return %s(buf);', method.id, method.decoder);
+}
+for (var p in propertieses) {
+  var props = propertieses[p];
+  println('case %d: return %s(buf);', props.id,  props.decoder);
+}
+println('default: throw new Error("Unknown class/method ID");');
+println('}}'); nl();
+
+println('module.exports.encodeMethod =',
+        'function(id, channel, fields) {');
+println('switch (id) {');
+for (var m in methods) {
+  var method = methods[m];
+  println('case %d: return %s(channel, fields);',
+          method.id, method.encoder);
+}
+println('default: throw new Error("Unknown class/method ID");');
+println('}}'); nl();
+
+println('module.exports.encodeProperties ='
+        , 'function(id, channel, size, fields) {');
+println('switch (id) {');
+for (var p in propertieses) {
+  var props = propertieses[p];
+  println('case %d: return %s(channel, size, fields);',
+          props.id, props.encoder);
+}
+println('default: throw new Error("Unknown class/properties ID");');
+println('}}'); nl();
+
+println('module.exports.info = function(id) {');
+println('switch(id) {');
+for (var m in methods) {
+  var method = methods[m];
+  println('case %d: return %s; ', method.id, method.info);
+}
+for (var p in propertieses) {
+  var properties = propertieses[p];
+  println('case %d: return %s', properties.id, properties.info);
+}
+println('default: throw new Error("Unknown class/method ID");');
+println('}}'); nl();
+
+for (var m in methods) {
+  var method = methods[m];
+  println('module.exports.%s = %d;', m, method.id);
+  decoderFn(method); nl();
+  encoderFn(method); nl();
+  infoObj(method); nl();
+}
+
+for (var p in propertieses) {
+  var properties = propertieses[p];
+  println('module.exports.%s = %d;', p, properties.id);
+  encodePropsFn(properties); nl();
+  decodePropsFn(properties); nl();
+  infoObj(properties); nl();
+}
+
+function methodId(clazz, method) {
+  return (clazz.id << 16) + method.id;
+}
+
+function propertiesName(clazz) {
+  return initial(clazz.name) + 'Properties';
+}
+
+function valTypeTest(arg) {
+  switch (arg.type) {
+  // everything is booleany
+  case 'bit':       return 'true'
+  case 'octet':
+  case 'short':
+  case 'long':
+  case 'longlong':
+  case 'timestamp': return "typeof val === 'number' && !isNaN(val)";
+  case 'shortstr':  return "typeof val === 'string' &&" +
+      " Buffer.byteLength(val) < 256";
+  case 'longstr':   return "Buffer.isBuffer(val)";
+  case 'table':     return "typeof val === 'object'";
+  }
+}
+
+function typeDesc(t) {
+  switch (t) {
+  case 'bit':       return 'booleany';
+  case 'octet':
+  case 'short':
+  case 'long':
+  case 'longlong':
+  case 'timestamp': return "a number (but not NaN)";
+  case 'shortstr':  return "a string (up to 255 chars)";
+  case 'longstr':   return "a Buffer";
+  case 'table':     return "an object";
+  }
+}
+
+function defaultValueRepr(arg) {
+  switch (arg.type) {
+  case 'longstr':
+    return format("Buffer.from(%s)", JSON.stringify(arg.default));
+  default:
+    // assumes no tables as defaults
+    return JSON.stringify(arg.default);
+  }
+}
+
+// Emit code to assign the arg value to `val`.
+function assignArg(a) {
+  println("val = fields['%s'];", a.name);
+}
+
+function assignOrDefault(a) {
+  println("val = fields['%s'];", a.name);
+  println("if (val === undefined) val = %s;", defaultValueRepr(a));
+}
+
+// Emit code for assigning an argument value to `val`, checking that
+// it exists (if it does not have a default) and is the correct
+// type.
+function checkAssignArg(a) {
+  assignArg(a);
+  println('if (val === undefined) {');
+  if (a.default !== undefined) {
+    println('val = %s;', defaultValueRepr(a));
+  }
+  else {
+    println('throw new Error("Missing value for mandatory field \'%s\'");', a.name);
+  }
+  println('}'); // undefined test
+  println('else if (!(%s)) {', valTypeTest(a));
+  println('throw new TypeError(');
+  println('"Field \'%s\' is the wrong type; must be %s");',
+          a.name, typeDesc(a.type));
+  println('}'); // type test
+}
+
+// Emit code for encoding `val` as a table and assign to a fresh
+// variable (based on the arg name). I use a scratch buffer to compose
+// the encoded table, otherwise I'd have to do a size calculation pass
+// first. I can get away with this only because 1. the encoding
+// procedures are not re-entrant; and, 2. I copy the result into
+// another buffer before returning. `scratchOffset`, `val`, `len` are
+// expected to have been declared.
+function assignTable(a) {
+  var varname = tableVar(a);
+  println(
+    "len = encodeTable(SCRATCH, val, scratchOffset);");
+  println('var %s = SCRATCH.slice(scratchOffset, scratchOffset + len);', varname);
+  println('scratchOffset += len;');
+}
+
+function tableVar(a) {
+  return a.name + '_encoded';
+}
+
+function stringLenVar(a) {
+  return a.name + '_len';
+}
+
+function assignStringLen(a) {
+  var v = stringLenVar(a);
+  // Assumes the value or default is in val
+  println("var %s = Buffer.byteLength(val, 'utf8');", v);
+}
+
+
+function encoderFn(method) {
+  var args = method['args'];
+  println('function %s(channel, fields) {', method.encoder);
+  println('var offset = 0, val = null, bits = 0, varyingSize = 0;');
+  println('var len, scratchOffset = 0;');
+
+  // Encoding is split into two parts. Some fields have a fixed size
+  // (e.g., integers of a specific width), while some have a size that
+  // depends on the datum (e.g., strings). Each field will therefore
+  // either 1. contribute to the fixed size; or 2. emit code to
+  // calculate the size (and possibly the encoded value, in the case
+  // of tables).
+  var fixedSize = METHOD_OVERHEAD;
+
+  var bitsInARow = 0;
+
+  for (var i=0, len = args.length; i < len; i++) {
+    var arg = args[i];
+
+    if (arg.type != 'bit') bitsInARow = 0;
+
+    switch (arg.type) {
+    // varying size
+    case 'shortstr':
+      checkAssignArg(arg);
+      assignStringLen(arg);
+      println("varyingSize += %s;", stringLenVar(arg));
+      fixedSize += 1;
+      break;
+    case 'longstr':
+      checkAssignArg(arg);
+      println("varyingSize += val.length;");
+      fixedSize += 4;
+      break;
+    case 'table':
+      // For a table we have to encode the table before we can see its
+      // length.
+      checkAssignArg(arg);
+      assignTable(arg);
+      println('varyingSize += %s.length;', tableVar(arg));
+      break;
+
+    // fixed size
+    case 'octet': fixedSize += 1; break;
+    case 'short': fixedSize += 2; break;
+    case 'long': fixedSize += 4; break;
+    case 'longlong': //fall through
+    case 'timestamp':
+      fixedSize += 8; break;
+    case 'bit':
+      bitsInARow ++;
+      // open a fresh pack o' bits
+      if (bitsInARow === 1) fixedSize += 1;
+      // just used a pack; reset
+      else if (bitsInARow === 8) bitsInARow = 0;
+      break;
+    }
+  }
+
+  println('var buffer = Buffer.alloc(%d + varyingSize);', fixedSize);
+
+  println('buffer[0] = %d;', constants.FRAME_METHOD);
+  println('buffer.writeUInt16BE(channel, 1);');
+  // skip size for now, we'll write it in when we know
+  println('buffer.writeUInt32BE(%d, 7);', method.id);
+  println('offset = 11;');
+
+  bitsInARow = 0;
+
+  for (var i = 0, len = args.length; i < len; i++) {
+    var a = args[i];
+
+    // Flush any collected bits before doing a new field
+    if (a.type != 'bit' && bitsInARow > 0) {
+      bitsInARow = 0;
+      println('buffer[offset] = bits; offset++; bits = 0;');
+    }
+
+    switch (a.type) {
+    case 'octet':
+      checkAssignArg(a);
+      println('buffer.writeUInt8(val, offset); offset++;');
+      break;
+    case 'short':
+      checkAssignArg(a);
+      println('buffer.writeUInt16BE(val, offset); offset += 2;');
+      break;
+    case 'long':
+      checkAssignArg(a);
+      println('buffer.writeUInt32BE(val, offset); offset += 4;');
+      break;
+    case 'longlong':
+    case 'timestamp':
+      checkAssignArg(a);
+      println('ints.writeUInt64BE(buffer, val, offset); offset += 8;');
+      break;
+    case 'bit':
+      checkAssignArg(a);
+      println('if (val) bits += %d;', 1 << bitsInARow);
+      if (bitsInARow === 7) { // I don't think this ever happens, but whatever
+        println('buffer[offset] = bits; offset++; bits = 0;');
+        bitsInARow = 0;
+      }
+      else bitsInARow++;
+      break;
+    case 'shortstr':
+      assignOrDefault(a);
+      println('buffer[offset] = %s; offset++;', stringLenVar(a));
+      println('buffer.write(val, offset, "utf8"); offset += %s;',
+              stringLenVar(a));
+      break;
+    case 'longstr':
+      assignOrDefault(a);
+      println('len = val.length;');
+      println('buffer.writeUInt32BE(len, offset); offset += 4;');
+      println('val.copy(buffer, offset); offset += len;');
+      break;
+    case 'table':
+      println('offset += %s.copy(buffer, offset);', tableVar(a));
+      break;
+    default: throw new Error("Unexpected argument type: " + a.type);
+    }
+  }
+
+  // Flush any collected bits at the end
+  if (bitsInARow > 0) {
+    println('buffer[offset] = bits; offset++;');
+  }
+
+  println('buffer[offset] = %d;', constants.FRAME_END);
+  // size does not include the frame header or frame end byte
+  println('buffer.writeUInt32BE(offset - 7, 3);');
+
+  println('return buffer;');
+  println('}');
+}
+
+function fieldsDecl(args) {
+  println('var fields = {');
+  for (var i=0, num=args.length; i < num; i++) {
+    println('%s: undefined,', args[i].name);
+  }
+  println('};');
+}
+
+function decoderFn(method) {
+  var args = method.args;
+  println('function %s(buffer) {', method.decoder);
+  println('var offset = 0, val, len;');
+  fieldsDecl(args);
+
+  var bitsInARow = 0;
+
+  for (var i=0, num=args.length; i < num; i++) {
+    var a = args[i];
+    var field = "fields['" + a.name + "']";
+
+    // Flush any collected bits before doing a new field
+    if (a.type != 'bit' && bitsInARow > 0) {
+      bitsInARow = 0;
+      println('offset++;');
+    }
+
+    switch (a.type) {
+    case 'octet':
+      println('val = buffer[offset]; offset++;');
+      break;
+    case 'short':
+      println('val = buffer.readUInt16BE(offset); offset += 2;');
+      break;
+    case 'long':
+      println('val = buffer.readUInt32BE(offset); offset += 4;');
+      break;
+    case 'longlong':
+    case 'timestamp':
+      println('val = ints.readUInt64BE(buffer, offset); offset += 8;');
+      break;
+    case 'bit':
+      var bit = 1 << bitsInARow;
+      println('val = !!(buffer[offset] & %d);', bit);
+      if (bitsInARow === 7) {
+        println('offset++;');
+        bitsInARow = 0;
+      }
+      else bitsInARow++;
+      break;
+    case 'longstr':
+      println('len = buffer.readUInt32BE(offset); offset += 4;');
+      println('val = buffer.subarray(offset, offset + len);');
+      println('offset += len;');
+      break;
+    case 'shortstr':
+      println('len = buffer.readUInt8(offset); offset++;');
+      println('val = buffer.toString("utf8", offset, offset + len);');
+      println('offset += len;');
+      break;
+    case 'table':
+      println('len = buffer.readUInt32BE(offset); offset += 4;');
+      println('val = decodeFields(buffer.subarray(offset, offset + len));');
+      println('offset += len;');
+      break;
+    default:
+      throw new TypeError("Unexpected type in argument list: " + a.type);
+    }
+    println('%s = val;', field);
+  }
+  println('return fields;');
+  println('}');
+}
+
+function infoObj(thing) {
+  var info = JSON.stringify({id: thing.id,
+                             classId: thing.clazzId,
+                             methodId: thing.methodId,
+                             name: thing.name,
+                             args: thing.args});
+  println('var %s = module.exports.%s = %s;',
+          thing.info, thing.info, info);
+}
+
+// The flags are laid out in groups of fifteen in a short (high to
+// low bits), with a continuation bit (at 0) and another group
+// following if there's more than fifteen. Presence and absence
+// are conflated with true and false, for bit fields (i.e., if the
+// flag for the field is set, it's true, otherwise false).
+//
+// However, none of that is actually used in AMQP 0-9-1. The only
+// instance of properties -- basic properties -- has 14 fields, none
+// of them bits.
+
+function flagAt(index) {
+  return 1 << (15 - index);
+}
+
+function encodePropsFn(props) {
+  println('function %s(channel, size, fields) {', props.encoder);
+  println('var offset = 0, flags = 0, val, len;');
+  println('var scratchOffset = 0, varyingSize = 0;');
+
+  var fixedSize = PROPERTIES_OVERHEAD;
+
+  var args = props.args;
+
+  function incVarying(by) {
+    println("varyingSize += %d;", by);
+  }
+
+  for (var i=0, num=args.length; i < num; i++) {
+    var p = args[i];
+
+    assignArg(p);
+    println("if (val != undefined) {");
+
+    println("if (%s) {", valTypeTest(p));
+    switch (p.type) {
+    case 'shortstr':
+      assignStringLen(p);
+      incVarying(1);
+      println('varyingSize += %s;', stringLenVar(p));
+      break;
+    case 'longstr':
+      incVarying(4);
+      println('varyingSize += val.length;');
+      break;
+    case 'table':
+      assignTable(p);
+      println('varyingSize += %s.length;', tableVar(p));
+      break;
+    case 'octet': incVarying(1); break;
+    case 'short': incVarying(2); break;
+    case 'long': incVarying(4); break;
+    case 'longlong': // fall through
+    case 'timestamp':
+      incVarying(8); break;
+      // no case for bit, as they are accounted for in the flags
+    }
+    println('} else {');
+    println('throw new TypeError(');
+    println('"Field \'%s\' is the wrong type; must be %s");',
+            p.name, typeDesc(p.type));
+    println('}');
+    println('}');
+  }
+
+  println('var buffer = Buffer.alloc(%d + varyingSize);', fixedSize);
+
+  println('buffer[0] = %d', constants.FRAME_HEADER);
+  println('buffer.writeUInt16BE(channel, 1);');
+  // content class ID and 'weight' (== 0)
+  println('buffer.writeUInt32BE(%d, 7);', props.id << 16);
+  // skip frame size for now, we'll write it in when we know.
+
+  // body size
+  println('ints.writeUInt64BE(buffer, size, 11);');
+
+  println('flags = 0;');
+  // we'll write the flags later too
+  println('offset = 21;');
+
+  for (var i=0, num=args.length; i < num; i++) {
+    var p = args[i];
+    var flag = flagAt(i);
+
+    assignArg(p);
+    println("if (val != undefined) {");
+    if (p.type === 'bit') { // which none of them are ..
+      println('if (val) flags += %d;', flag);
+    }
+    else {
+      println('flags += %d;', flag);
+      // %%% FIXME only slightly different to the method args encoding
+      switch (p.type) {
+      case 'octet':
+        println('buffer.writeUInt8(val, offset); offset++;');
+        break;
+      case 'short':
+        println('buffer.writeUInt16BE(val, offset); offset += 2;');
+        break;
+      case 'long':
+        println('buffer.writeUInt32BE(val, offset); offset += 4;');
+        break;
+      case 'longlong':
+      case 'timestamp':
+        println('ints.writeUInt64BE(buffer, val, offset);');
+        println('offset += 8;');
+        break;
+      case 'shortstr':
+        var v = stringLenVar(p);
+        println('buffer[offset] = %s; offset++;', v);
+        println("buffer.write(val, offset, 'utf8');");
+        println("offset += %s;", v);
+        break;
+      case 'longstr':
+        println('buffer.writeUInt32BE(val.length, offset);');
+        println('offset += 4;');
+        println('offset += val.copy(buffer, offset);');
+        break;
+      case 'table':
+        println('offset += %s.copy(buffer, offset);', tableVar(p));
+        break;
+      default: throw new Error("Unexpected argument type: " + p.type);
+      }
+    }
+    println('}'); // != undefined
+  }
+
+  println('buffer[offset] = %d;', constants.FRAME_END);
+  // size does not include the frame header or frame end byte
+  println('buffer.writeUInt32BE(offset - 7, 3);');
+  println('buffer.writeUInt16BE(flags, 19);');
+  println('return buffer.subarray(0, offset + 1);');
+  println('}');
+}
+
+function decodePropsFn(props) {
+  var args = props.args;
+
+  println('function %s(buffer) {', props.decoder);
+  println('var flags, offset = 2, val, len;');
+
+  println('flags = buffer.readUInt16BE(0);');
+  println('if (flags === 0) return {};');
+
+  fieldsDecl(args);
+
+  for (var i=0, num=args.length; i < num; i++) {
+    var p = argument(args[i]);
+    var field = "fields['" + p.name + "']";
+
+    println('if (flags & %d) {', flagAt(i));
+    if (p.type === 'bit') {
+      println('%d = true;', field);
+    }
+    else {
+      switch (p.type) {
+      case 'octet':
+        println('val = buffer[offset]; offset++;');
+        break;
+      case 'short':
+        println('val = buffer.readUInt16BE(offset); offset += 2;');
+        break;
+      case 'long':
+        println('val = buffer.readUInt32BE(offset); offset += 4;');
+        break;
+      case 'longlong':
+      case 'timestamp':
+        println('val = ints.readUInt64BE(buffer, offset); offset += 8;');
+        break;
+      case 'longstr':
+        println('len = buffer.readUInt32BE(offset); offset += 4;');
+        println('val = buffer.subarray(offset, offset + len);');
+        println('offset += len;');
+        break;
+      case 'shortstr':
+        println('len = buffer.readUInt8(offset); offset++;');
+        println('val = buffer.toString("utf8", offset, offset + len);');
+        println('offset += len;');
+        break;
+      case 'table':
+        println('len = buffer.readUInt32BE(offset); offset += 4;');
+        println('val = decodeFields(buffer.subarray(offset, offset + len));');
+        println('offset += len;');
+        break;
+      default:
+        throw new TypeError("Unexpected type in argument list: " + p.type);
+      }
+      println('%s = val;', field);
+    }
+    println('}');
+  }
+  println('return fields;');
+  println('}');
+}

+ 22 - 0
node_modules/amqplib/callback_api.js

@@ -0,0 +1,22 @@
+var raw_connect = require('./lib/connect').connect;
+var CallbackModel = require('./lib/callback_model').CallbackModel;
+
+// Supports three shapes:
+// connect(url, options, callback)
+// connect(url, callback)
+// connect(callback)
+function connect(url, options, cb) {
+  if (typeof url === 'function')
+    cb = url, url = false, options = false;
+  else if (typeof options === 'function')
+    cb = options, options = false;
+
+  raw_connect(url, options, function(err, c) {
+    if (err === null) cb(null, new CallbackModel(c));
+    else cb(err);
+  });
+};
+
+module.exports.connect = connect;
+module.exports.credentials = require('./lib/credentials');
+module.exports.IllegalOperationError = require('./lib/error').IllegalOperationError;

+ 16 - 0
node_modules/amqplib/channel_api.js

@@ -0,0 +1,16 @@
+var raw_connect = require('./lib/connect').connect;
+var ChannelModel = require('./lib/channel_model').ChannelModel;
+var promisify = require('util').promisify;
+
+function connect(url, connOptions) {
+  return promisify(function(cb) {
+    return raw_connect(url, connOptions, cb);
+  })()
+  .then(function(conn) {
+    return new ChannelModel(conn);
+  });
+};
+
+module.exports.connect = connect;
+module.exports.credentials = require('./lib/credentials');
+module.exports.IllegalOperationError = require('./lib/error').IllegalOperationError;

+ 22 - 0
node_modules/amqplib/examples/direct_reply_to_client.js

@@ -0,0 +1,22 @@
+#!/usr/bin/env node
+
+const amqp = require('../');
+
+const queue = 'rpc_queue';
+
+(async () => {
+  const connection = await amqp.connect();
+  const channel = await connection.createChannel();
+
+  await channel.consume('amq.rabbitmq.reply-to', async (message) => {
+    console.log(message.content.toString());
+    await channel.close();
+    await connection.close();
+	}, { noAck: true });
+
+  await channel.assertQueue(queue, { durable: false });
+
+  channel.sendToQueue(queue, Buffer.from(' [X] ping'), {
+    replyTo: 'amq.rabbitmq.reply-to',
+  });
+})();

+ 25 - 0
node_modules/amqplib/examples/direct_reply_to_server.js

@@ -0,0 +1,25 @@
+#!/usr/bin/env node
+
+const amqp = require('../');
+const { v4: uuid } = require('uuid');
+
+const queue = 'rpc_queue';
+
+(async () => {
+  const connection = await amqp.connect();
+  const channel = await connection.createChannel();
+
+  process.once('SIGINT', async () => {
+    await channel.close();
+    await connection.close();
+  });
+
+  await channel.assertQueue(queue, { durable: false });
+  await channel.consume(queue, (message) => {
+  	console.log(message.content.toString());
+    channel.sendToQueue(message.properties.replyTo, Buffer.from(' [.] pong'));
+	}, { noAck: true });
+
+  console.log(' [x] To exit press CTRL+C.');
+
+})();

+ 40 - 0
node_modules/amqplib/examples/headers.js

@@ -0,0 +1,40 @@
+#!/usr/bin/env node
+
+const amqp = require('../');
+
+(async () => {
+
+  const connection = await amqp.connect();
+  const channel = await connection.createChannel();
+
+  process.once('SIGINT', async () => {
+    await channel.close();
+    await connection.close();
+  });
+
+  const { exchange } = await channel.assertExchange('matching exchange', 'headers');
+  const { queue } = await channel.assertQueue();
+
+  // When using a headers exchange, the headers to be matched go in
+  // the binding arguments. The routing key is ignore, so best left
+  // empty.
+
+  // 'x-match' is 'all' or 'any', meaning "all fields must match" or
+  // "at least one field must match", respectively. The values to be
+  // matched go in subsequent fields.
+  await channel.bindQueue(queue, exchange, '', {
+    'x-match': 'any',
+    'foo': 'bar',
+    'baz': 'boo'
+  });
+
+  await channel.consume(queue, (message) => {
+    console.log(message.content.toString());
+  }, { noAck: true });
+
+  channel.publish(exchange, '', Buffer.from('hello'), { headers: { baz: 'boo' }});
+  channel.publish(exchange, '', Buffer.from('hello'), { headers: { foo: 'bar' }});
+  channel.publish(exchange, '', Buffer.from('lost'), { headers: { meh: 'nah' }});
+
+  console.log(' [x] To exit press CTRL+C.');
+})();

+ 39 - 0
node_modules/amqplib/examples/receive_generator.js

@@ -0,0 +1,39 @@
+#!/usr/bin/env node
+
+'use strict';
+const co = require('co');
+const amqp = require('amqplib');
+const readline = require('readline');
+
+co(function* () {
+  const myConsumer = (msg) => {
+    if (msg !== null) {
+      console.log('consuming message %s in generator', JSON.stringify(msg.content.toString()));
+    }
+  };
+  const conn = yield amqp.connect('amqp://localhost');
+  try {
+    // create a message to consume
+    const q = 'hello';
+    const msg = 'Hello World!';
+    const channel = yield conn.createChannel();
+    yield channel.assertQueue(q);
+    channel.sendToQueue(q, Buffer.from(msg));
+    console.log(" [x] Sent '%s'", msg);
+    // consume the message
+    yield channel.consume(q, myConsumer, { noAck: true });
+  }
+  catch (e) {
+    throw e;
+  }
+}).catch(err => {
+  console.warn('Error:', err);
+});
+
+const rl = readline.createInterface({
+  input: process.stdin,
+  output: process.stdout
+});
+
+// pend until message is consumed
+rl.question('newline to exit', () => process.exit());

+ 42 - 0
node_modules/amqplib/examples/send_generators.js

@@ -0,0 +1,42 @@
+#!/usr/bin/env node
+
+'use strict';
+
+// NB this requires the module 'co':
+//    npm install co
+const co = require('co');
+const amqp = require('amqplib');
+
+co(function* () {
+  // connection errors are handled in the co .catch handler
+  const conn = yield amqp.connect('amqp://localhost');
+
+  // try catch will throw any errors from the yielding the following promises to the co .catch handler
+  try {
+    const q = 'hello';
+    const msg = 'Hello World!';
+
+    // use a confirm channel so we can check the message is sent OK.
+    const channel = yield conn.createConfirmChannel();
+
+    yield channel.assertQueue(q);
+
+    channel.sendToQueue(q, Buffer.from(msg));
+
+    // if message has been nacked, this will result in an error (rejected promise);
+    yield channel.waitForConfirms();
+
+    console.log(" [x] Sent '%s'", msg);
+
+    channel.close();
+  }
+  catch (e) {
+    throw e;
+  }
+  finally {
+    conn.close();
+  }
+
+}).catch(err => {
+  console.warn('Error:', err);
+});

+ 70 - 0
node_modules/amqplib/examples/ssl.js

@@ -0,0 +1,70 @@
+// Example of using a TLS/SSL connection. Note that the server must be
+// configured to accept SSL connections; see, for example,
+// http://www.rabbitmq.com/ssl.html.
+//
+// When trying this out, I followed the RabbitMQ SSL guide above,
+// almost verbatim. I set the CN of the server certificate to
+// 'localhost' rather than $(hostname) (since on my MBP hostname ends
+// up being "<blah>.local", which is just weird). My client
+// certificates etc., are in `../etc/client/`. My testca certificate
+// is in `../etc/testca` and server certs etc., in `../etc/server`,
+// and I've made a `rabbitmq.config` file, with which I start
+// RabbitMQ:
+//
+//     RABBITMQ_CONFIG_FILE=`pwd`/../etc/server/rabbitmq \
+//       /usr/local/sbin/rabbitmq-server &
+//
+// A way to check RabbitMQ's running with SSL OK is to use
+//
+//     openssl s_client -connect localhost:5671
+
+const amqp = require('../');
+const fs = require('fs');
+
+// Assemble the SSL options; for verification we need at least
+// * a certificate to present to the server ('cert', in PEM format)
+// * the private key for the certificate ('key', in PEM format)
+// * (possibly) a passphrase for the private key
+//
+// The first two may be replaced with a PKCS12 file ('pfx', in pkcs12
+// format)
+
+// We will also want to list the CA certificates that we will trust,
+// since we're using a self-signed certificate. It is NOT recommended
+// to use `rejectUnauthorized: false`.
+
+// Options for full client and server verification:
+const opts = {
+  cert: fs.readFileSync('../etc/client/cert.pem'),
+  key: fs.readFileSync('../etc/client/key.pem'),
+  // cert and key or
+  // pfx: fs.readFileSync('../etc/client/keycert.p12'),
+  passphrase: 'MySecretPassword',
+  ca: [fs.readFileSync('../etc/testca/cacert.pem')]
+};
+
+// Options for just confidentiality. This requires RabbitMQ's SSL
+// configuration to include the items
+//
+//     {verify, verify_none},
+//     {fail_if_no_peer_cert,false}
+//
+// const opts = {  ca: [fs.readFileSync('../etc/testca/cacert.pem')] };
+
+// Option to use the SSL client certificate for authentication
+// opts.credentials = amqp.credentials.external();
+
+(async () => {
+  const connection = await amqp.connect('amqp://localhost', opts);
+  const channel = await connection.createChannel();
+
+  process.on('SIGINT', async () => {
+    await channel.close();
+    await connection.close();
+  });
+
+  channel.sendToQueue('foo', Buffer.from('Hello World!'));
+
+  console.log(' [x] To exit press CTRL+C.');
+})();
+

+ 40 - 0
node_modules/amqplib/examples/stream_queues/README.md

@@ -0,0 +1,40 @@
+RabbitMQ Stream Examples 
+---
+The [stream queues](https://www.rabbitmq.com/streams.html) are available starting from RabbitMQ 3.9
+
+These examples show how to use stream queues with the lib.
+
+Send a message to a stream queue
+```
+node send_stream.js
+```
+
+Receive all the messages from stream queue:
+```
+node receive_stream.js
+```
+
+Consumers can be configured to receive messages using an offset via the `x-stream-offset` argument. e.g.
+
+```js
+channel.consume(queue, onMessage, {
+  noAck: false,
+  arguments: {
+    'x-stream-offset': 'first'
+  }
+});
+```
+
+RabbitMQ supports six different types of offset, however specifying them can be
+
+| Offset Type | Example Value                                          | Notes |
+|-----------|----------------------------------------------------------|-------|
+| First     | `{'x-stream-offset':'first'}`                            | Start from the first message in the log |
+| Last      | `{'x-stream-offset':'last'}`                             | Start from the last "chunk" of messages (could be multiple messages) |
+| Next      | `{'x-stream-offset':'next'}`                             | Start from the next message (the default) |
+| Offset    | `{'x-stream-offset':5}`                                  | a numerical value specifying an exact offset to attach to the log at |
+| Timestamp | `{'x-stream-offset':{'!':'timestamp',value:1686519750}}` | a timestamp value specifying the point in time to attach to the log at. The timestamp must be the number of seconds since 00:00:00 UTC, 1970-01-01. Consumers can receive messages published a bit before the specified timestamp. |
+| Interval  | `{'x-stream-offset':'1h'}`                               | the time interval relative to current time to attach the log at. Valid units are Y, M, D, h, m and s |
+
+
+See https://www.rabbitmq.com/streams.html#consuming for more details

+ 14 - 0
node_modules/amqplib/examples/stream_queues/package.json

@@ -0,0 +1,14 @@
+{
+  "name": "stream_queues",
+  "version": "1.0.0",
+  "description": "An example demonstrating use of stream queues",
+  "main": "n",
+  "dependencies": {
+    "amqplib": "^0.10.3"
+  },
+  "devDependencies": {},
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "license": "ISC"
+}

+ 55 - 0
node_modules/amqplib/examples/stream_queues/receive_stream.js

@@ -0,0 +1,55 @@
+const amqp = require('amqplib');
+
+(async () => {
+    try {
+        const connection = await amqp.connect('amqp://localhost');
+        process.once('SIGINT', connection.close);
+
+        const channel = await connection.createChannel();
+        const queue = 'my_first_stream';
+
+        // Define the queue stream
+        // Mandatory: exclusive: false, durable: true  autoDelete: false
+        await channel.assertQueue(queue, {
+            exclusive: false,
+            durable: true,
+            autoDelete: false,
+            arguments: {
+                'x-queue-type': 'stream',  // Mandatory to define stream queue
+                'x-max-length-bytes': 2_000_000_000  // Set the queue retention to 2GB else the stream doesn't have any limit
+            }
+        });
+
+        channel.qos(100);  // This is mandatory
+
+        channel.consume(queue, (msg) => {
+            console.log(" [x] Received '%s'", msg.content.toString());
+            channel.ack(msg);  // Mandatory
+        }, {
+            noAck: false,
+            arguments: {
+                /*
+                    Here you can specify the offset: : first, last, next, offset, timestamp and interval, i.e.
+
+                    'x-stream-offset': 'first'
+                    'x-stream-offset': 'last'
+                    'x-stream-offset': 'next'
+                    'x-stream-offset': 5
+                    'x-stream-offset': { '!': 'timestamp', value: 1686519750 }
+                    'x-stream-offset': '1h'
+
+                    The timestamp must be the desired number of seconds since 00:00:00 UTC, 1970-01-01
+                    The interval units can be Y, M, D, h, m, s
+
+                */
+                'x-stream-offset': 'first'
+            }
+        });
+
+        console.log(' [*] Waiting for messages. To exit press CTRL+C');
+    }
+    // Catch and display any errors in the console
+    catch(e) {
+        console.log(e)
+    }
+})();

+ 38 - 0
node_modules/amqplib/examples/stream_queues/send_stream.js

@@ -0,0 +1,38 @@
+const amqp = require('amqplib');
+
+
+(async () => {
+    try {
+        const connection = await amqp.connect('amqp://localhost');
+        process.once('SIGINT', connection.close);
+
+        const channel = await connection.createChannel();
+        const queue = 'my_first_stream';
+        const msg = `Hello World! ${Date.now()}`;
+
+        // Define the queue stream
+        // Mandatory: exclusive: false, durable: true  autoDelete: false
+        await channel.assertQueue(queue, {
+            exclusive: false,
+            durable: true,
+            autoDelete: false,
+            arguments: {
+                'x-queue-type': 'stream',  // Mandatory to define stream queue
+                'x-max-length-bytes': 2_000_000_000  // Set the queue retention to 2GB else the stream doesn't have any limit
+            }
+        });
+
+        // Send the message to the stream queue
+        await channel.sendToQueue(queue, Buffer.from(msg));
+        console.log(" [x] Sent '%s'", msg);
+        await channel.close();
+
+        // Close connection
+        connection.close();
+    }
+    // Catch and display any errors in the console
+    catch(e) {
+        console.log(e)
+    }
+})();
+

+ 93 - 0
node_modules/amqplib/examples/tutorials/README.md

@@ -0,0 +1,93 @@
+# RabbitMQ tutorials
+
+This directory contains the [RabbitMQ tutorials][rabbitmq-tutes],
+ported to amqplib. The sub-directory `callback_api` has translations
+of the tutorial programs to the callback-oriented API.
+
+## Preparation
+
+To run the tutorial code, you need amqplib installed. Assuming you are
+in a clone of the amqplib repository, from the tutorials directory:
+
+    npm install
+
+or to use the latest released version,
+
+    npm install amqplib
+
+Then just run each file as a script, e.g., in bash
+
+    ./send.js
+
+or
+
+    node send.js
+
+or
+
+    nave use 0.8 node send.js
+
+## [Tutorial one: Hello World!][tute-one]
+
+A "Hello World" example, with one script sending a message to a queue,
+and another receiving messages from the same queue.
+
+ * [send.js](send.js)
+ * [receive.js](receive.js)
+
+## [Tutorial two: Work queues][tute-two]
+
+Using RabbitMQ as a work queue; `new_task` creates a task, and
+`worker` processes tasks. Multiple `worker` process will share the
+tasks among them. Long-running tasks are simulated by supplying a
+string with dots, e.g., '...' to `new_task`. Each dot makes the worker
+"work" for a second.
+
+ * [new_task.js](new_task.js)
+ * [worker.js](worker.js)
+
+## [Tutorial three: Publish/Subscribe][tute-three]
+
+Using RabbitMQ as a broadcast mechanism. `emit_log` sends a "log"
+message to a fanout exchange, and all `receive_logs` processes receive
+log messages.
+
+ * [emit_log.js](emit_log.js)
+ * [receive_logs.js](receive_logs.js)
+
+## [Tutorial four: Routing][tute-four]
+
+Using RabbitMQ as a routing ('somecast') mechanism. `emit_log_direct`
+sends a log message with a severity, and all `receive_logs_direct`
+processes receive log messages for the severities on which they are
+listening.
+
+ * [emit_log_direct.js](emit_log_direct.js)
+ * [receive_logs_direct.js](receive_logs_direct.js)
+
+## [Tutorial five: Topics][tute-five]
+
+Extends the previous tutorial to routing with wildcarded patterns.
+
+ * [emit_log_topic.js](emit_log_topic.js)
+ * [receive_logs_topic.js](receive_logs_topic.js)
+
+## [Tutorial six: RPC][tute-six]
+
+Using RabbitMQ as an RPC intermediary, queueing requests for servers
+and routing replies back to clients.
+
+ * [rpc_server.js](rpc_server.js)
+ * [rpc_client.js](rpc_client.js)
+
+I depart slightly from the original tutorial code, which I think has
+some needless object-orientation (in the Python code; you don't get a
+choice about needless object-orientation in Java).
+
+[rabbitmq-tutes]: http://github.com/rabbitmq/rabbitmq-tutorials
+[tute-one]: http://www.rabbitmq.com/tutorials/tutorial-one-javascript.html
+[tute-two]: http://www.rabbitmq.com/tutorials/tutorial-two-javascript.html
+[tute-three]: http://www.rabbitmq.com/tutorials/tutorial-three-javascript.html
+[tute-four]: http://www.rabbitmq.com/tutorials/tutorial-four-javascript.html
+[tute-five]: http://www.rabbitmq.com/tutorials/tutorial-five-javascript.html
+[tute-six]: http://www.rabbitmq.com/tutorials/tutorial-six-javascript.html

+ 28 - 0
node_modules/amqplib/examples/tutorials/callback_api/emit_log.js

@@ -0,0 +1,28 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib/callback_api');
+
+const exchange = 'logs';
+const text = process.argv.slice(2).join(' ') || 'info: Hello World!';
+
+amqp.connect((err, connection) => {
+  if (err) return bail(err);
+  connection.createChannel((err, channel) => {
+    if (err) return bail(err, connection);
+    channel.assertExchange(exchange, 'fanout', { durable: false }, (err) => {
+      if (err) return bail(err, connection);
+      channel.publish(exchange, '', Buffer.from(text));
+      console.log(" [x] Sent '%s'", text);
+      channel.close(() => {
+        connection.close();
+      });
+    });
+  });
+});
+
+function bail(err, connection) {
+  console.error(err);
+  if (connection) connection.close(() => {
+    process.exit(1);
+  });
+}

+ 30 - 0
node_modules/amqplib/examples/tutorials/callback_api/emit_log_direct.js

@@ -0,0 +1,30 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib/callback_api');
+
+const exchange = 'direct_logs';
+const args = process.argv.slice(2);
+const routingKey = (args.length > 0) ? args[0] : 'info';
+const text = args.slice(1).join(' ') || 'Hello World!';
+
+amqp.connect((err, connection) => {
+  if (err) return bail(err);
+  connection.createChannel((err, channel) => {
+    if (err) return bail(err, connection);
+    channel.assertExchange(exchange, 'direct', { durable: false }, (err) => {
+      if (err) return bail(err, connection);
+      channel.publish(exchange, routingKey, Buffer.from(text));
+      console.log(" [x] Sent '%s'", text);
+      channel.close(() => {
+        connection.close();
+      });
+    });
+  });
+});
+
+function bail(err, connection) {
+  console.error(err);
+  if (connection) connection.close(() => {
+    process.exit(1);
+  });
+}

+ 30 - 0
node_modules/amqplib/examples/tutorials/callback_api/emit_log_topic.js

@@ -0,0 +1,30 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib/callback_api');
+
+const exchange = 'topic_logs';
+const args = process.argv.slice(2);
+const routingKey = (args.length > 0) ? args[0] : 'info';
+const text = args.slice(1).join(' ') || 'Hello World!';
+
+amqp.connect((err, connection) => {
+  if (err) return bail(err);
+  connection.createChannel((err, channel) => {
+    if (err) return bail(err, connection);
+    channel.assertExchange(exchange, 'topic', { durable: false }, (err) => {
+      if (err) return bail(err, connection);
+      channel.publish(exchange, routingKey, Buffer.from(text));
+      console.log(" [x] Sent '%s'", text);
+      channel.close(() => {
+        connection.close();
+      });
+    });
+  });
+});
+
+function bail(err, connection) {
+  console.error(err);
+  if (connection) connection.close(() => {
+    process.exit(1);
+  });
+}

+ 28 - 0
node_modules/amqplib/examples/tutorials/callback_api/new_task.js

@@ -0,0 +1,28 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib/callback_api');
+
+const queue = 'task_queue';
+const text = process.argv.slice(2).join(' ') || "Hello World!";
+
+amqp.connect((err, connection) => {
+  if (err) return bail(err);
+  connection.createChannel((err, channel) => {
+    if (err) return bail(err, connection);
+    channel.assertQueue(queue, { durable: true }, (err) => {
+      if (err) return bails(err, connection);
+      channel.sendToQueue(queue, Buffer.from(text), { persistent: true });
+      console.log(" [x] Sent '%s'", text);
+      channel.close(() => {
+        connection.close();
+      });
+    });
+  });
+});
+
+function bail(err, connection) {
+  console.error(err);
+  if (connection) connection.close(() => {
+    process.exit(1);
+  });
+}

+ 36 - 0
node_modules/amqplib/examples/tutorials/callback_api/receive.js

@@ -0,0 +1,36 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib/callback_api');
+
+const queue = 'hello';
+
+amqp.connect((err, connection) => {
+  if (err) return bail(err);
+  connection.createChannel((err, channel) => {
+    if (err) return bail(err, connection);
+
+    process.once('SIGINT', () => {
+      channel.close(() => {
+        connection.close();
+      });
+    });
+
+    channel.assertQueue(queue, { durable: false }, (err) => {
+      if (err) return bail(err, connection);
+      channel.consume(queue, (message) => {
+        if (message) console.log(" [x] Received '%s'", message.content.toString());
+        else console.warn(' [x] Consumer cancelled');
+      }, { noAck: true }, (err) => {
+        if (err) return bail(err, connection);
+        console.log(" [*] Waiting for logs. To exit press CTRL+C.");
+      });
+    });
+  });
+});
+
+function bail(err, connection) {
+  console.error(err);
+  if (connection) connection.close(() => {
+    process.exit(1);
+  });
+}

+ 42 - 0
node_modules/amqplib/examples/tutorials/callback_api/receive_logs.js

@@ -0,0 +1,42 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib/callback_api');
+
+const exchange = 'logs';
+
+amqp.connect((err, connection) => {
+  if (err) return bail(err);
+  connection.createChannel((err, channel) => {
+    if (err) return bail(err, connection);
+
+    process.once('SIGINT', () => {
+      channel.close(() => {
+        connection.close();
+      });
+    });
+
+    channel.assertExchange(exchange, 'fanout', { durable: false }, (err, { queue }) => {
+      if (err) return bail(err, connection);
+      channel.assertQueue('', { exclusive: true }, (err, { queue }) => {
+        if (err) return bail(err, connection);
+        channel.bindQueue(queue, exchange, '', {}, (err) => {
+          if (err) return bail(err, connection);
+          channel.consume(queue, (message) => {
+            if (message) console.log(" [x] '%s'", message.content.toString());
+            else console.warn(' [x] Consumer cancelled');
+          }, { noAck: true }, (err) => {
+            if (err) return bail(err, connection);
+            console.log(" [*] Waiting for logs. To exit press CTRL+C.");
+          });
+        });
+      });
+    });
+  });
+});
+
+function bail(err, connection) {
+  console.error(err);
+  if (connection) connection.close(() => {
+    process.exit(1);
+  });
+}

+ 57 - 0
node_modules/amqplib/examples/tutorials/callback_api/receive_logs_direct.js

@@ -0,0 +1,57 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib/callback_api');
+const { basename } = require('path');
+
+const exchange = 'direct_logs';
+const severities = process.argv.slice(2);
+if (severities.length < 1) {
+  console.log('Usage %s [info] [warning] [error]', basename(process.argv[1]));
+  process.exit(1);
+}
+
+amqp.connect((err, connection) => {
+  if (err) return bail(err);
+  connection.createChannel((err, channel) => {
+    if (err) return bail(err, connection);
+
+    process.once('SIGINT', () => {
+      channel.close(() => {
+        connection.close();
+      });
+    });
+
+    channel.assertExchange(exchange, 'direct', { durable: false }, (err) => {
+      if (err) return bail(err, connection);
+      channel.assertQueue('', { exclusive: true }, (err, { queue }) => {
+        if (err) return bail(err, connection);
+        channel.consume(queue, (message) => {
+          if (message) console.log(" [x] %s:'%s'", message.fields.routingKey, message.content.toString());
+          else console.warn(' [x] Consumer cancelled');
+        }, {noAck: true}, function(err) {
+          if (err) return bail(err, connection);
+          console.log(' [*] Waiting for logs. To exit press CTRL+C.');
+          subscribeAll(channel, queue, severities, (err) => {
+            if (err) return bail(err, connection);
+          });
+        });
+      });
+    });
+  });
+});
+
+function subscribeAll(channel, queue, bindingKeys, cb) {
+  if (bindingKeys.length === 0) return cb();
+  const bindingKey = bindingKeys.shift();
+  channel.bindQueue(queue, exchange, bindingKey, {}, (err) => {
+    if (err) return cb(err);
+    subscribeAll(channel, queue, bindingKeys, cb);
+  });
+}
+
+function bail(err, connection) {
+  console.error(err);
+  if (connection) connection.close(() => {
+    process.exit(1);
+  });
+}

+ 58 - 0
node_modules/amqplib/examples/tutorials/callback_api/receive_logs_topic.js

@@ -0,0 +1,58 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib/callback_api');
+const { basename } = require('path');
+
+const exchange = 'topic_logs';
+const severities = process.argv.slice(2);
+if (severities.length < 1) {
+  console.log('Usage %s [info] [warning] [error]', basename(process.argv[1]));
+  process.exit(1);
+}
+
+amqp.connect((err, connection) => {
+  if (err) return bail(err);
+  connection.createChannel((err, channel) => {
+    if (err) return bail(err, connection);
+
+    process.once('SIGINT', () => {
+      channel.close(() => {
+        connection.close();
+      });
+    });
+
+    channel.assertExchange(exchange, 'topic', { durable: false }, (err) => {
+      if (err) return bail(err, connection);
+      channel.assertQueue('', { exclusive: true }, (err, { queue }) => {
+        if (err) return bail(err, connection);
+        channel.consume(queue, (message) => {
+          if (message) console.log(" [x] %s:'%s'", message.fields.routingKey, message.content.toString());
+          else console.warn(' [x] Consumer cancelled');
+        }, {noAck: true}, function(err) {
+          if (err) return bail(err, connection);
+          console.log(' [*] Waiting for logs. To exit press CTRL+C.');
+          subscribeAll(channel, queue, severities, (err) => {
+            if (err) return bail(err, connection);
+          });
+        });
+      });
+    });
+  });
+});
+
+function subscribeAll(channel, queue, bindingKeys, cb) {
+  if (bindingKeys.length === 0) return cb();
+  const bindingKey = bindingKeys.shift();
+  channel.bindQueue(queue, exchange, bindingKey, {}, (err) => {
+    if (err) return cb(err);
+    subscribeAll(channel, queue, bindingKeys, cb);
+  });
+}
+
+function bail(err, connection) {
+  console.error(err);
+  if (connection) connection.close(() => {
+    process.exit(1);
+  });
+}
+

+ 51 - 0
node_modules/amqplib/examples/tutorials/callback_api/rpc_client.js

@@ -0,0 +1,51 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib/callback_api');
+const { basename } = require('path');
+const { v4: uuid } = require('uuid');
+
+const queue = 'rpc_queue';
+
+const n = parseInt(process.argv[2], 10);
+if (isNaN(n)) {
+  console.warn('Usage: %s number', basename(process.argv[1]));
+  process.exit(1);
+}
+
+amqp.connect((err, connection) => {
+  if (err) return bail(err);
+  connection.createChannel((err, channel) => {
+    if (err) return bail(err, connection);
+    channel.assertQueue('', { exclusive: true }, (err, { queue: replyTo }) => {
+      if (err) return bail(err, connection);
+
+      const correlationId = uuid();
+      channel.consume(replyTo, (message) => {
+        if (!message) console.warn(' [x] Consumer cancelled');
+        else if (message.properties.correlationId === correlationId) {
+          console.log(' [.] Got %d', message.content.toString());
+          channel.close(() => {
+            connection.close();
+          })
+        }
+      }, { noAck: true });
+
+      channel.assertQueue(queue, { durable: false }, (err) => {
+        if (err) return bail(err, connection);
+        console.log(' [x] Requesting fib(%d)', n);
+        channel.sendToQueue(queue, Buffer.from(n.toString()), {
+          correlationId,
+          replyTo
+        });
+      });
+    });
+  });
+});
+
+function bail(err, connection) {
+  console.error(err);
+  if (connection) connection.close(() => {
+    process.exit(1);
+  });
+}
+

+ 55 - 0
node_modules/amqplib/examples/tutorials/callback_api/rpc_server.js

@@ -0,0 +1,55 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib/callback_api');
+
+const queue = 'rpc_queue';
+
+amqp.connect((err, connection) => {
+  if (err) return bail(err);
+  connection.createChannel((err, channel) => {
+    if (err) return bail(err, connection);
+
+    process.once('SIGINT', () => {
+      channel.close(() => {
+        connection.close();
+      });
+    });
+
+    channel.assertQueue(queue, { durable: false }, (err) => {
+      if (err) return bail(err, connection);
+      channel.prefetch(1);
+      channel.consume(queue, (message) => {
+        const n = parseInt(message.content.toString(), 10);
+        console.log(' [.] fib(%d)', n);
+        const response = fib(n);
+        channel.sendToQueue(message.properties.replyTo, Buffer.from(response.toString()), {
+          correlationId: message.properties.correlationId
+        });
+        channel.ack(message);
+      }, { noAck: false }, function(err) {
+        if (err) return bail(err, conn);
+        console.log(' [x] Awaiting RPC requests. To exit press CTRL+C.');
+      });
+    });
+  });
+});
+
+function fib(n) {
+  // Do it the ridiculous, but not most ridiculous, way. For better,
+  // see http://nayuki.eigenstate.org/page/fast-fibonacci-algorithms
+  let a = 0, b = 1;
+  for (let i=0; i < n; i++) {
+    let c = a + b;
+    a = b; b = c;
+  }
+  return a;
+}
+
+
+function bail(err, connection) {
+  console.error(err);
+  if (connection) connection.close(() => {
+    process.exit(1);
+  });
+}
+

+ 28 - 0
node_modules/amqplib/examples/tutorials/callback_api/send.js

@@ -0,0 +1,28 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib/callback_api');
+
+const queue = 'hello';
+const text = 'Hello World!';
+
+amqp.connect((err, connection) => {
+  if (err) return bail(err);
+  connection.createChannel((err, channel) => {
+    if (err) return bail(err, connection);
+    channel.assertQueue(queue, { durable: false }, (err) => {
+      if (err) return bail(err, connection);
+      channel.sendToQueue(queue, Buffer.from(text));
+      console.log(" [x] Sent '%s'", text);
+      channel.close(() => {
+        connection.close();
+      });
+    });
+  });
+});
+
+function bail(err, connection) {
+  console.error(err);
+  if (connection) connection.close(() => {
+    process.exit(1);
+  });
+}

+ 39 - 0
node_modules/amqplib/examples/tutorials/callback_api/worker.js

@@ -0,0 +1,39 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib/callback_api');
+
+const queue = 'task_queue';
+
+amqp.connect((err, connection) => {
+  if (err) return bail(err);
+  connection.createChannel((err, channel) => {
+    if (err) return bail(err, connection);
+
+    process.once('SIGINT', () => {
+      channel.close(() => {
+        connection.close();
+      });
+    });
+
+    channel.assertQueue(queue, { durable: true }, (err, { queue }) => {
+      if (err) return bail(err, connection);
+      channel.consume(queue, (message) => {
+        const text = message.content.toString();
+        console.log(" [x] Received '%s'", text);
+        const seconds = text.split('.').length - 1;
+        setTimeout(() => {
+          console.log(" [x] Done");
+          channel.ack(message);
+        }, seconds * 1000);
+      }, { noAck: false });
+      console.log(" [*] Waiting for messages. To exit press CTRL+C");
+    });
+  });
+});
+
+function bail(err, connection) {
+  console.error(err);
+  if (connection) connection.close(() => {
+    process.exit(1);
+  });
+}

+ 24 - 0
node_modules/amqplib/examples/tutorials/emit_log.js

@@ -0,0 +1,24 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib');
+
+const exchange = 'logs';
+const text = process.argv.slice(2).join(' ') || 'info: Hello World!';
+
+(async () => {
+  let connection;
+  try {
+    connection = await amqp.connect('amqp://localhost');
+    const channel = await connection.createChannel();
+    await channel.assertExchange(exchange, 'fanout', { durable: false });
+    channel.publish(exchange, '', Buffer.from(text));
+    console.log(" [x] Sent '%s'", text);
+    await channel.close();
+  }
+  catch (err) {
+    console.warn(err);
+  }
+  finally {
+    if (connection) await connection.close();
+  };
+})();  

+ 26 - 0
node_modules/amqplib/examples/tutorials/emit_log_direct.js

@@ -0,0 +1,26 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib');
+
+const exchange = 'direct_logs';
+const args = process.argv.slice(2);
+const routingKey = (args.length > 0) ? args[0] : 'info';
+const text = args.slice(1).join(' ') || 'Hello World!';
+
+(async () => {
+  let connection;
+  try {
+    connection = await amqp.connect('amqp://localhost');
+    const channel = await connection.createChannel();
+    await channel.assertExchange(exchange, 'direct', { durable: false });
+    channel.publish(exchange, routingKey, Buffer.from(text));
+    console.log(" [x] Sent %s:'%s'", routingKey, text);
+    await channel.close();
+  }
+  catch (err) {
+    console.warn(err);
+  }
+  finally {
+    if (connection) await connection.close();
+  };
+})();  

+ 26 - 0
node_modules/amqplib/examples/tutorials/emit_log_topic.js

@@ -0,0 +1,26 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib');
+
+const exchange = 'topic_logs';
+const args = process.argv.slice(2);
+const routingKeys = (args.length > 0) ? args[0] : 'info';
+const text = args.slice(1).join(' ') || 'Hello World!';
+
+(async () => {
+  let connection;
+  try {
+    connection = await amqp.connect('amqp://localhost');
+    const channel = await connection.createChannel();
+    await channel.assertExchange(exchange, 'topic', { durable: false });
+    channel.publish(exchange, routingKeys, Buffer.from(text));
+    console.log(" [x] Sent %s:'%s'", routingKeys, text);
+    await channel.close();
+  }
+  catch (err) {
+    console.warn(err);
+  }
+  finally {
+    if (connection) await connection.close();
+  };
+})();  

+ 25 - 0
node_modules/amqplib/examples/tutorials/new_task.js

@@ -0,0 +1,25 @@
+#!/usr/bin/env node
+// Post a new task to the work queue
+
+const amqp = require('amqplib');
+
+const queue = 'task_queue';
+const text = process.argv.slice(2).join(' ') || "Hello World!";
+
+(async () => {
+  let connection;
+  try {
+    connection = await amqp.connect('amqp://localhost');
+    const channel = await connection.createChannel();
+    await channel.assertQueue(queue, { durable: true });
+    channel.sendToQueue(queue, Buffer.from(text), { persistent: true });
+    console.log(" [x] Sent '%s'", text);
+    await channel.close();
+  }
+  catch (err) {
+    console.warn(err);
+  }
+  finally { 
+    await connection.close();
+  };
+})();

+ 16 - 0
node_modules/amqplib/examples/tutorials/package.json

@@ -0,0 +1,16 @@
+{
+  "name": "amqplib-tutorials",
+  "version": "0.0.1",
+  "description": "The RabbitMQ tutorials, ported to amqplib",
+  "main": "send.js",
+  "dependencies": {
+    "amqplib": "../..",
+    "uuid": "*"
+  },
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "repository": "",
+  "author": "Michael Bridgen <mikeb@squaremobius.net>",
+  "license": "MPL 2.0"
+}

+ 26 - 0
node_modules/amqplib/examples/tutorials/receive.js

@@ -0,0 +1,26 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib');
+
+const queue = 'hello';
+
+(async () => {
+  try {
+    const connection = await amqp.connect('amqp://localhost');
+    const channel = await connection.createChannel();
+
+    process.once('SIGINT', async () => { 
+      await channel.close();
+      await connection.close();
+    });
+
+    await channel.assertQueue(queue, { durable: false });
+    await channel.consume(queue, (message) => {
+      console.log(" [x] Received '%s'", message.content.toString());
+    }, { noAck: true });
+
+    console.log(' [*] Waiting for messages. To exit press CTRL+C');
+  } catch (err) {
+    console.warn(err);
+  }
+})();

+ 30 - 0
node_modules/amqplib/examples/tutorials/receive_logs.js

@@ -0,0 +1,30 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib');
+
+const exchange = 'logs';
+
+(async () => {
+  try {
+    const connection = await amqp.connect('amqp://localhost');
+    const channel = await connection.createChannel();
+
+    process.once('SIGINT', async () => { 
+      await channel.close();
+      await connection.close();
+    });
+
+    await channel.assertExchange(exchange, 'fanout', { durable: false });
+    const { queue } = await channel.assertQueue('', { exclusive: true });
+    await channel.bindQueue(queue, exchange, '')
+
+    await channel.consume(queue, (message) => {
+      if (message) console.log(" [x] '%s'", message.content.toString());
+      else console.warn(' [x] Consumer cancelled');
+    }, { noAck: true });
+
+    console.log(' [*] Waiting for logs. To exit press CTRL+C');
+  } catch (err) {
+    console.warn(err);
+  }
+})();

+ 38 - 0
node_modules/amqplib/examples/tutorials/receive_logs_direct.js

@@ -0,0 +1,38 @@
+#!/usr/bin/env node
+
+const amqp = require('../..');
+const { basename } = require('path');
+
+const exchange = 'direct_logs';
+const bindingKeys = process.argv.slice(2);
+if (bindingKeys.length < 1) {
+  console.warn('Usage: %s [info] [warning] [error]', basename(process.argv[1]));
+  process.exit(1);
+}
+
+(async () => {
+  try {
+    const connection = await amqp.connect('amqp://localhost');
+    const channel = await connection.createChannel();
+
+    process.once('SIGINT', async () => { 
+      await channel.close();
+      await connection.close();
+    });
+
+    await channel.assertExchange(exchange, 'direct', { durable: false });
+    const { queue } = await channel.assertQueue('', { exclusive: true });
+    await Promise.all(bindingKeys.map(async (bindingKey) => {
+      await channel.bindQueue(queue, exchange, bindingKey);
+    }));
+
+    await channel.consume(queue, (message) => {
+      if (message) console.log(" [x] %s:'%s'", message.fields.routingKey, message.content.toString());
+      else console.warn(' [x] Consumer cancelled');
+    }, { noAck: true });
+
+    console.log(' [*] Waiting for logs. To exit press CTRL+C.');
+  } catch(err) {
+    console.warn(err);
+  }
+})();

+ 39 - 0
node_modules/amqplib/examples/tutorials/receive_logs_topic.js

@@ -0,0 +1,39 @@
+#!/usr/bin/env node
+
+const amqp = require('../..');
+const { basename } = require('path');
+
+const exchange = 'topic_logs';
+const bindingKeys = process.argv.slice(2);
+if (bindingKeys.length < 1) {
+  console.log('Usage: %s pattern [pattern...]', basename(process.argv[1]));
+  process.exit(1);
+}
+
+(async () => {
+  try {
+    const connection = await amqp.connect('amqp://localhost');
+    const channel = await connection.createChannel();
+
+    process.once('SIGINT', async () => { 
+      await channel.close();
+      await connection.close();
+    });
+
+    await channel.assertExchange(exchange, 'topic', { durable: false });
+    const { queue } = await channel.assertQueue('', { exclusive: true });
+    await Promise.all(bindingKeys.map(async (bindingKey) => {
+      await channel.bindQueue(queue, exchange, bindingKey);
+    }));
+
+    await channel.consume(queue, (message) => {
+      if (message) console.log(" [x] %s:'%s'", message.fields.routingKey, message.content.toString());      
+      else console.warn(' [x] Consumer cancelled');
+    }, { noAck: true });
+
+    console.log(' [*] Waiting for logs. To exit press CTRL+C.');
+  }
+  catch (err) {
+    console.warn(err);
+  }
+})();

+ 49 - 0
node_modules/amqplib/examples/tutorials/rpc_client.js

@@ -0,0 +1,49 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib');
+const { basename } = require('path');
+const { v4: uuid } = require('uuid');
+
+const queue = 'rpc_queue';
+
+const n = parseInt(process.argv[2], 10);
+if (isNaN(n)) {
+  console.warn('Usage: %s number', basename(process.argv[1]));
+  process.exit(1);
+}
+
+(async () => {
+  let connection;
+  try {
+    connection = await amqp.connect('amqp://localhost');
+    const channel = await connection.createChannel();
+    const correlationId = uuid();
+
+    const requestFib = new Promise(async (resolve) => {
+      const { queue: replyTo } = await channel.assertQueue('', { exclusive: true });
+
+      await channel.consume(replyTo, (message) => {
+        if (!message) console.warn(' [x] Consumer cancelled');
+        else if (message.properties.correlationId === correlationId) {
+          resolve(message.content.toString());
+        }
+      }, { noAck: true });
+
+      await channel.assertQueue(queue, { durable: false });
+      console.log(' [x] Requesting fib(%d)', n);
+      channel.sendToQueue(queue, Buffer.from(n.toString()), { 
+        correlationId,
+        replyTo,
+      });
+    });
+
+    const fibN = await requestFib;
+    console.log(' [.] Got %d', fibN);
+  }
+  catch (err) {
+    console.warn(err);
+  }
+  finally {
+    if (connection) await connection.close();
+  };
+})();  

+ 46 - 0
node_modules/amqplib/examples/tutorials/rpc_server.js

@@ -0,0 +1,46 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib');
+
+const queue = 'rpc_queue';
+
+(async () => {
+  try {
+    const connection = await amqp.connect('amqp://localhost');
+    const channel = await connection.createChannel();
+
+    process.once('SIGINT', async () => { 
+      await channel.close();
+      await connection.close();
+    });
+
+    await channel.assertQueue(queue, { durable: false });
+
+    channel.prefetch(1);
+    await channel.consume(queue, (message) => {
+      const n = parseInt(message.content.toString(), 10);
+      console.log(' [.] fib(%d)', n);
+      const response = fib(n);
+      channel.sendToQueue(message.properties.replyTo, Buffer.from(response.toString()), {
+        correlationId: message.properties.correlationId
+      });
+      channel.ack(message);
+    });
+
+    console.log(' [x] Awaiting RPC requests. To exit press CTRL+C.');
+  }
+  catch (err) {
+    console.warn(err);
+  }
+})();
+
+function fib(n) {
+  // Do it the ridiculous, but not most ridiculous, way. For better,
+  // see http://nayuki.eigenstate.org/page/fast-fibonacci-algorithms
+  let a = 0, b = 1;
+  for (let i=0; i < n; i++) {
+    let c = a + b;
+    a = b; b = c;
+  }
+  return a;
+}

+ 31 - 0
node_modules/amqplib/examples/tutorials/send.js

@@ -0,0 +1,31 @@
+#!/usr/bin/env node
+
+const amqp = require('amqplib');
+
+const queue = 'hello';
+const text = 'Hello World!';
+
+(async () => {
+  let connection;
+  try {
+    connection = await amqp.connect('amqp://localhost');
+    const channel = await connection.createChannel();
+
+    await channel.assertQueue(queue, { durable: false });
+
+    // NB: `sentToQueue` and `publish` both return a boolean
+    // indicating whether it's OK to send again straight away, or
+    // (when `false`) that you should wait for the event `'drain'`
+    // to fire before writing again. We're just doing the one write,
+    // so we'll ignore it.
+    channel.sendToQueue(queue, Buffer.from(text));
+    console.log(" [x] Sent '%s'", text);
+    await channel.close();
+  }
+  catch (err) {
+    console.warn(err);
+  }
+  finally {
+    if (connection) await connection.close();
+  };
+})();  

+ 34 - 0
node_modules/amqplib/examples/tutorials/worker.js

@@ -0,0 +1,34 @@
+#!/usr/bin/env node
+// Process tasks from the work queue
+
+const amqp = require('amqplib');
+
+const queue = 'task_queue';
+
+(async () => {
+  try {
+    const connection = await amqp.connect('amqp://localhost');
+    process.once('SIGINT', async () => { 
+      await connection.close();
+    });
+
+    const channel = await connection.createChannel();
+    await channel.assertQueue(queue, { durable: true });
+
+    channel.prefetch(1);
+    await channel.consume(queue, (message) => {
+      const text = message.content.toString();
+      console.log(" [x] Received '%s'", text);
+      const seconds = text.split('.').length - 1;
+      setTimeout(() => {
+        console.log(" [x] Done");
+        channel.ack(message);
+      }, seconds * 1000);      
+    }, { noAck: false });
+      
+    console.log(" [*] Waiting for messages. To exit press CTRL+C");
+  }
+  catch (err) {
+    console.warn(err);
+  }
+})();

+ 21 - 0
node_modules/amqplib/examples/waitForConfirms.js

@@ -0,0 +1,21 @@
+const amqp = require('../');
+
+(async () => {
+  let connection;
+  try {
+    connection = await amqp.connect();
+    const channel = await connection.createConfirmChannel();
+
+    for (var i=0; i < 20; i++) {
+      channel.publish('amq.topic', 'whatever', Buffer.from('blah'));
+    };
+
+    await channel.waitForConfirms();
+    console.log('All messages done');
+    await channel.close();
+  } catch (err) {
+    console.warn(err);
+  } finally {
+    if (connection) await connection.close();
+  }
+})();

+ 314 - 0
node_modules/amqplib/lib/api_args.js

@@ -0,0 +1,314 @@
+//
+//
+//
+
+'use strict';
+
+/*
+The channel (promise) and callback APIs have similar signatures, and
+in particular, both need AMQP fields prepared from the same arguments
+and options. The arguments marshalling is done here. Each of the
+procedures below takes arguments and options (the latter in an object)
+particular to the operation it represents, and returns an object with
+fields for handing to the encoder.
+*/
+
+// A number of AMQP methods have a table-typed field called
+// `arguments`, that is intended to carry extension-specific
+// values. RabbitMQ uses this in a number of places; e.g., to specify
+// an 'alternate exchange'.
+//
+// Many of the methods in this API have an `options` argument, from
+// which I take both values that have a default in AMQP (e.g.,
+// autoDelete in QueueDeclare) *and* values that are specific to
+// RabbitMQ (e.g., 'alternate-exchange'), which would normally be
+// supplied in `arguments`. So that extensions I don't support yet can
+// be used, I include `arguments` itself among the options.
+//
+// The upshot of this is that I often need to prepare an `arguments`
+// value that has any values passed in `options.arguments` as well as
+// any I've promoted to being options themselves. Since I don't want
+// to mutate anything passed in, the general pattern is to create a
+// fresh object with the `arguments` value given as its prototype; all
+// fields in the supplied value will be serialised, as well as any I
+// set on the fresh object. What I don't want to do, however, is set a
+// field to undefined by copying possibly missing field values,
+// because that will mask a value in the prototype.
+//
+// NB the `arguments` field already has a default value of `{}`, so
+// there's no need to explicitly default it unless I'm setting values.
+function setIfDefined(obj, prop, value) {
+  if (value != undefined) obj[prop] = value;
+}
+
+var EMPTY_OPTIONS = Object.freeze({});
+
+var Args = {};
+
+Args.assertQueue = function(queue, options) {
+  queue = queue || '';
+  options = options || EMPTY_OPTIONS;
+
+  var argt = Object.create(options.arguments || null);
+  setIfDefined(argt, 'x-expires', options.expires);
+  setIfDefined(argt, 'x-message-ttl', options.messageTtl);
+  setIfDefined(argt, 'x-dead-letter-exchange',
+               options.deadLetterExchange);
+  setIfDefined(argt, 'x-dead-letter-routing-key',
+               options.deadLetterRoutingKey);
+  setIfDefined(argt, 'x-max-length', options.maxLength);
+  setIfDefined(argt, 'x-max-priority', options.maxPriority);
+  setIfDefined(argt, 'x-overflow', options.overflow);
+  setIfDefined(argt, 'x-queue-mode', options.queueMode);
+
+  return {
+    queue: queue,
+    exclusive: !!options.exclusive,
+    durable: (options.durable === undefined) ? true : options.durable,
+    autoDelete: !!options.autoDelete,
+    arguments: argt,
+    passive: false,
+    // deprecated but we have to include it
+    ticket: 0,
+    nowait: false
+  };
+};
+
+Args.checkQueue = function(queue) {
+  return {
+    queue: queue,
+    passive: true, // switch to "completely different" mode
+    nowait: false,
+    durable: true, autoDelete: false, exclusive: false, // ignored
+    ticket: 0,
+  };
+};
+
+Args.deleteQueue = function(queue, options) {
+  options = options || EMPTY_OPTIONS;
+  return {
+    queue: queue,
+    ifUnused: !!options.ifUnused,
+    ifEmpty: !!options.ifEmpty,
+    ticket: 0, nowait: false
+  };
+};
+
+Args.purgeQueue = function(queue) {
+  return {
+    queue: queue,
+    ticket: 0, nowait: false
+  };
+};
+
+Args.bindQueue = function(queue, source, pattern, argt) {
+  return {
+    queue: queue,
+    exchange: source,
+    routingKey: pattern,
+    arguments: argt,
+    ticket: 0, nowait: false
+  };
+};
+
+Args.unbindQueue = function(queue, source, pattern, argt) {
+  return {
+    queue: queue,
+    exchange: source,
+    routingKey: pattern,
+    arguments: argt,
+    ticket: 0, nowait: false
+  };
+};
+
+Args.assertExchange = function(exchange, type, options) {
+  options = options || EMPTY_OPTIONS;
+  var argt = Object.create(options.arguments || null);
+  setIfDefined(argt, 'alternate-exchange', options.alternateExchange);
+  return {
+    exchange: exchange,
+    ticket: 0,
+    type: type,
+    passive: false,
+    durable: (options.durable === undefined) ? true : options.durable,
+    autoDelete: !!options.autoDelete,
+    internal: !!options.internal,
+    nowait: false,
+    arguments: argt
+  };
+};
+
+Args.checkExchange = function(exchange) {
+  return {
+    exchange: exchange,
+    passive: true, // switch to 'may as well be another method' mode
+    nowait: false,
+    // ff are ignored
+    durable: true, internal: false,  type: '',  autoDelete: false,
+    ticket: 0
+  };
+};
+
+Args.deleteExchange = function(exchange, options) {
+  options = options || EMPTY_OPTIONS;
+  return {
+    exchange: exchange,
+    ifUnused: !!options.ifUnused,
+    ticket: 0, nowait: false
+  };
+};
+
+Args.bindExchange = function(dest, source, pattern, argt) {
+  return {
+    source: source,
+    destination: dest,
+    routingKey: pattern,
+    arguments: argt,
+    ticket: 0, nowait: false
+  };
+};
+
+Args.unbindExchange = function(dest, source, pattern, argt) {
+  return {
+    source: source,
+    destination: dest,
+    routingKey: pattern,
+    arguments: argt,
+    ticket: 0, nowait: false
+  };
+};
+
+// It's convenient to construct the properties and the method fields
+// at the same time, since in the APIs, values for both can appear in
+// `options`. Since the property or mthod field names don't overlap, I
+// just return one big object that can be used for both purposes, and
+// the encoder will pick out what it wants.
+Args.publish = function(exchange, routingKey, options) {
+  options = options || EMPTY_OPTIONS;
+
+  // The CC and BCC fields expect an array of "longstr", which would
+  // normally be buffer values in JavaScript; however, since a field
+  // array (or table) cannot have shortstr values, the codec will
+  // encode all strings as longstrs anyway.
+  function convertCC(cc) {
+    if (cc === undefined) {
+      return undefined;
+    }
+    else if (Array.isArray(cc)) {
+      return cc.map(String);
+    }
+    else return [String(cc)];
+  }
+
+  var headers = Object.create(options.headers || null);
+  setIfDefined(headers, 'CC', convertCC(options.CC));
+  setIfDefined(headers, 'BCC', convertCC(options.BCC));
+
+  var deliveryMode; // undefined will default to 1 (non-persistent)
+
+  // Previously I overloaded deliveryMode be a boolean meaning
+  // 'persistent or not'; better is to name this option for what it
+  // is, but I need to have backwards compatibility for applications
+  // that either supply a numeric or boolean value.
+  if (options.persistent !== undefined)
+    deliveryMode = (options.persistent) ? 2 : 1;
+  else if (typeof options.deliveryMode === 'number')
+    deliveryMode = options.deliveryMode;
+  else if (options.deliveryMode) // is supplied and truthy
+    deliveryMode = 2;
+
+  var expiration = options.expiration;
+  if (expiration !== undefined) expiration = expiration.toString();
+
+  return {
+    // method fields
+    exchange: exchange,
+    routingKey: routingKey,
+    mandatory: !!options.mandatory,
+    immediate: false, // RabbitMQ doesn't implement this any more
+    ticket: undefined,
+    // properties
+    contentType: options.contentType,
+    contentEncoding: options.contentEncoding,
+    headers: headers,
+    deliveryMode: deliveryMode,
+    priority: options.priority,
+    correlationId: options.correlationId,
+    replyTo: options.replyTo,
+    expiration: expiration,
+    messageId: options.messageId,
+    timestamp: options.timestamp,
+    type: options.type,
+    userId: options.userId,
+    appId: options.appId,
+    clusterId: undefined
+  };
+};
+
+Args.consume = function(queue, options) {
+  options = options || EMPTY_OPTIONS;
+  var argt = Object.create(options.arguments || null);
+  setIfDefined(argt, 'x-priority', options.priority);
+  return {
+    ticket: 0,
+    queue: queue,
+    consumerTag: options.consumerTag || '',
+    noLocal: !!options.noLocal,
+    noAck: !!options.noAck,
+    exclusive: !!options.exclusive,
+    nowait: false,
+    arguments: argt
+  };
+};
+
+Args.cancel = function(consumerTag) {
+  return {
+    consumerTag: consumerTag,
+    nowait: false
+  };
+};
+
+Args.get = function(queue, options) {
+  options = options || EMPTY_OPTIONS;
+  return {
+    ticket: 0,
+    queue: queue,
+    noAck: !!options.noAck
+  };
+};
+
+Args.ack = function(tag, allUpTo) {
+  return {
+    deliveryTag: tag,
+    multiple: !!allUpTo
+  };
+};
+
+Args.nack = function(tag, allUpTo, requeue) {
+  return {
+    deliveryTag: tag,
+    multiple: !!allUpTo,
+    requeue: (requeue === undefined) ? true : requeue
+  };
+};
+
+Args.reject = function(tag, requeue) {
+  return {
+    deliveryTag: tag,
+    requeue: (requeue === undefined) ? true : requeue
+  };
+};
+
+Args.prefetch = function(count, global) {
+  return {
+    prefetchCount: count || 0,
+    prefetchSize: 0,
+    global: !!global
+  };
+};
+
+Args.recover = function() {
+  return {requeue: true};
+};
+
+module.exports = Object.freeze(Args);

+ 130 - 0
node_modules/amqplib/lib/bitset.js

@@ -0,0 +1,130 @@
+//
+//
+//
+
+'use strict';
+
+/**
+ * A bitset implementation, after that in java.util.  Yes there
+ * already exist such things, but none implement next{Clear|Set}Bit or
+ * equivalent, and none involved me tooling about for an evening.
+ */
+class BitSet {
+  /**
+   * @param {number} [size]
+   */
+  constructor(size) {
+    if (size) {
+      const numWords = Math.ceil(size / 32);
+      this.words = new Array(numWords);
+    }
+    else {
+      this.words = [];
+    }
+    this.wordsInUse = 0; // = number, not index
+  }
+
+  /**
+   * @param {number} numWords
+   */
+  ensureSize(numWords) {
+    const wordsPresent = this.words.length;
+    if (wordsPresent < numWords) {
+      this.words = this.words.concat(new Array(numWords - wordsPresent));
+    }
+  }
+
+  /**
+   * @param {number} bitIndex
+   */
+  set(bitIndex) {
+    const w = wordIndex(bitIndex);
+    if (w >= this.wordsInUse) {
+      this.ensureSize(w + 1);
+      this.wordsInUse = w + 1;
+    }
+    const bit = 1 << bitIndex;
+    this.words[w] |= bit;
+  }
+
+  /**
+   * @param {number} bitIndex
+   */
+  clear(bitIndex) {
+    const w = wordIndex(bitIndex);
+    if (w >= this.wordsInUse) return;
+    const mask = ~(1 << bitIndex);
+    this.words[w] &= mask;
+  }
+
+  /**
+   * @param {number} bitIndex
+   */
+  get(bitIndex) {
+    const w = wordIndex(bitIndex);
+    if (w >= this.wordsInUse) return false; // >= since index vs size
+    const bit = 1 << bitIndex;
+    return !!(this.words[w] & bit);
+  }
+
+  /**
+   * Give the next bit that is set on or after fromIndex, or -1 if no such bit
+   *
+   * @param {number} fromIndex
+   */
+  nextSetBit(fromIndex) {
+    let w = wordIndex(fromIndex);
+    if (w >= this.wordsInUse) return -1;
+
+    // the right-hand side is shifted to only test the bits of the first
+    // word that are > fromIndex
+    let word = this.words[w] & (0xffffffff << fromIndex);
+    while (true) {
+      if (word) return (w * 32) + trailingZeros(word);
+      w++;
+      if (w === this.wordsInUse) return -1;
+      word = this.words[w];
+    }
+  }
+
+  /**
+   * @param {number} fromIndex
+   */
+  nextClearBit(fromIndex) {
+    let w = wordIndex(fromIndex);
+    if (w >= this.wordsInUse) return fromIndex;
+
+    let word = ~(this.words[w]) & (0xffffffff << fromIndex);
+    while (true) {
+      if (word) return (w * 32) + trailingZeros(word);
+      w++;
+      if (w == this.wordsInUse) return w * 32;
+      word = ~(this.words[w]);
+    }
+  }
+}
+
+/**
+ * @param {number} bitIndex
+ */
+function wordIndex(bitIndex) {
+  return Math.floor(bitIndex / 32);
+}
+
+/**
+ * @param {number} i
+ */
+function trailingZeros(i) {
+  // From Hacker's Delight, via JDK. Probably far less effective here,
+  // since bit ops are not necessarily the quick way to do things in
+  // JS.
+  if (i === 0) return 32;
+  let y, n = 31;
+  y = i << 16; if (y != 0) { n = n -16; i = y; }
+  y = i << 8;  if (y != 0) { n = n - 8; i = y; }
+  y = i << 4;  if (y != 0) { n = n - 4; i = y; }
+  y = i << 2;  if (y != 0) { n = n - 2; i = y; }
+  return n - ((i << 1) >>> 31);
+}
+
+module.exports.BitSet = BitSet;

+ 332 - 0
node_modules/amqplib/lib/callback_model.js

@@ -0,0 +1,332 @@
+//
+//
+//
+
+'use strict';
+
+var defs = require('./defs');
+var EventEmitter = require('events');
+var BaseChannel = require('./channel').BaseChannel;
+var acceptMessage = require('./channel').acceptMessage;
+var Args = require('./api_args');
+
+class CallbackModel extends EventEmitter {
+  constructor (connection) {
+    super();
+    this.connection = connection;
+    var self = this;
+    ['error', 'close', 'blocked', 'unblocked'].forEach(function (ev) {
+      connection.on(ev, self.emit.bind(self, ev));
+    });
+  }
+
+  close (cb) {
+    this.connection.close(cb);
+  }
+
+  updateSecret(newSecret, reason, cb) {
+    this.connection._updateSecret(newSecret, reason, cb);
+  }
+
+  createChannel (cb) {
+    var ch = new Channel(this.connection);
+    ch.open(function (err, ok) {
+      if (err === null)
+        cb && cb(null, ch);
+      else
+        cb && cb(err);
+    });
+    return ch;
+  }
+
+  createConfirmChannel (cb) {
+    var ch = new ConfirmChannel(this.connection);
+    ch.open(function (err) {
+      if (err !== null)
+        return cb && cb(err);
+      else {
+        ch.rpc(defs.ConfirmSelect, { nowait: false },
+          defs.ConfirmSelectOk, function (err, _ok) {
+            if (err !== null)
+              return cb && cb(err);
+            else
+              cb && cb(null, ch);
+          });
+      }
+    });
+    return ch;
+  }
+}
+
+class Channel extends BaseChannel {
+  constructor (connection) {
+    super(connection);
+    this.on('delivery', this.handleDelivery.bind(this));
+    this.on('cancel', this.handleCancel.bind(this));
+  }
+
+  // This encodes straight-forward RPC: no side-effects and return the
+  // fields from the server response. It wraps the callback given it, so
+  // the calling method argument can be passed as-is. For anything that
+  // needs to have side-effects, or needs to change the server response,
+  // use `#_rpc(...)` and remember to dereference `.fields` of the
+  // server response.
+  rpc (method, fields, expect, cb0) {
+    var cb = callbackWrapper(this, cb0);
+    this._rpc(method, fields, expect, function (err, ok) {
+      cb(err, ok && ok.fields); // in case of an error, ok will be
+
+      // undefined
+    });
+    return this;
+  }
+
+  // === Public API ===
+  open (cb) {
+    try { this.allocate(); }
+    catch (e) { return cb(e); }
+
+    return this.rpc(defs.ChannelOpen, { outOfBand: "" },
+      defs.ChannelOpenOk, cb);
+  }
+
+  close (cb) {
+    return this.closeBecause("Goodbye", defs.constants.REPLY_SUCCESS,
+      function () { cb && cb(null); });
+  }
+
+  assertQueue (queue, options, cb) {
+    return this.rpc(defs.QueueDeclare,
+      Args.assertQueue(queue, options),
+      defs.QueueDeclareOk, cb);
+  }
+
+  checkQueue (queue, cb) {
+    return this.rpc(defs.QueueDeclare,
+      Args.checkQueue(queue),
+      defs.QueueDeclareOk, cb);
+  }
+
+  deleteQueue (queue, options, cb) {
+    return this.rpc(defs.QueueDelete,
+      Args.deleteQueue(queue, options),
+      defs.QueueDeleteOk, cb);
+  }
+
+  purgeQueue (queue, cb) {
+    return this.rpc(defs.QueuePurge,
+      Args.purgeQueue(queue),
+      defs.QueuePurgeOk, cb);
+  }
+
+  bindQueue (queue, source, pattern, argt, cb) {
+    return this.rpc(defs.QueueBind,
+      Args.bindQueue(queue, source, pattern, argt),
+      defs.QueueBindOk, cb);
+  }
+
+  unbindQueue (queue, source, pattern, argt, cb) {
+    return this.rpc(defs.QueueUnbind,
+      Args.unbindQueue(queue, source, pattern, argt),
+      defs.QueueUnbindOk, cb);
+  }
+
+  assertExchange (ex, type, options, cb0) {
+    var cb = callbackWrapper(this, cb0);
+    this._rpc(defs.ExchangeDeclare,
+      Args.assertExchange(ex, type, options),
+      defs.ExchangeDeclareOk,
+      function (e, _) { cb(e, { exchange: ex }); });
+    return this;
+  }
+
+  checkExchange (exchange, cb) {
+    return this.rpc(defs.ExchangeDeclare,
+      Args.checkExchange(exchange),
+      defs.ExchangeDeclareOk, cb);
+  }
+
+  deleteExchange (exchange, options, cb) {
+    return this.rpc(defs.ExchangeDelete,
+      Args.deleteExchange(exchange, options),
+      defs.ExchangeDeleteOk, cb);
+  }
+
+  bindExchange (dest, source, pattern, argt, cb) {
+    return this.rpc(defs.ExchangeBind,
+      Args.bindExchange(dest, source, pattern, argt),
+      defs.ExchangeBindOk, cb);
+  }
+
+  unbindExchange (dest, source, pattern, argt, cb) {
+    return this.rpc(defs.ExchangeUnbind,
+      Args.unbindExchange(dest, source, pattern, argt),
+      defs.ExchangeUnbindOk, cb);
+  }
+
+  publish (exchange, routingKey, content, options) {
+    var fieldsAndProps = Args.publish(exchange, routingKey, options);
+    return this.sendMessage(fieldsAndProps, fieldsAndProps, content);
+  }
+
+  sendToQueue (queue, content, options) {
+    return this.publish('', queue, content, options);
+  }
+
+  consume (queue, callback, options, cb0) {
+    var cb = callbackWrapper(this, cb0);
+    var fields = Args.consume(queue, options);
+    var self = this;
+    this._rpc(
+      defs.BasicConsume, fields, defs.BasicConsumeOk,
+      function (err, ok) {
+        if (err === null) {
+          self.registerConsumer(ok.fields.consumerTag, callback);
+          cb(null, ok.fields);
+        }
+        else
+          cb(err);
+      });
+    return this;
+  }
+
+  cancel (consumerTag, cb0) {
+    var cb = callbackWrapper(this, cb0);
+    var self = this;
+    this._rpc(
+      defs.BasicCancel, Args.cancel(consumerTag), defs.BasicCancelOk,
+      function (err, ok) {
+        if (err === null) {
+          self.unregisterConsumer(consumerTag);
+          cb(null, ok.fields);
+        }
+        else
+          cb(err);
+      });
+    return this;
+  }
+
+  get (queue, options, cb0) {
+    var self = this;
+    var fields = Args.get(queue, options);
+    var cb = callbackWrapper(this, cb0);
+    this.sendOrEnqueue(defs.BasicGet, fields, function (err, f) {
+      if (err === null) {
+        if (f.id === defs.BasicGetEmpty) {
+          cb(null, false);
+        }
+        else if (f.id === defs.BasicGetOk) {
+          self.handleMessage = acceptMessage(function (m) {
+            m.fields = f.fields;
+            cb(null, m);
+          });
+        }
+        else {
+          cb(new Error("Unexpected response to BasicGet: " +
+            inspect(f)));
+        }
+      }
+    });
+    return this;
+  }
+
+  ack (message, allUpTo) {
+    this.sendImmediately(
+      defs.BasicAck, Args.ack(message.fields.deliveryTag, allUpTo));
+    return this;
+  }
+
+  ackAll () {
+    this.sendImmediately(defs.BasicAck, Args.ack(0, true));
+    return this;
+  }
+
+  nack (message, allUpTo, requeue) {
+    this.sendImmediately(
+      defs.BasicNack,
+      Args.nack(message.fields.deliveryTag, allUpTo, requeue));
+    return this;
+  }
+
+  nackAll (requeue) {
+    this.sendImmediately(
+      defs.BasicNack, Args.nack(0, true, requeue));
+    return this;
+  }
+
+  reject (message, requeue) {
+    this.sendImmediately(
+      defs.BasicReject,
+      Args.reject(message.fields.deliveryTag, requeue));
+    return this;
+  }
+
+  prefetch (count, global, cb) {
+    return this.rpc(defs.BasicQos,
+      Args.prefetch(count, global),
+      defs.BasicQosOk, cb);
+  }
+
+  recover (cb) {
+    return this.rpc(defs.BasicRecover,
+      Args.recover(),
+      defs.BasicRecoverOk, cb);
+  }
+}
+
+
+// Wrap an RPC callback to make sure the callback is invoked with
+// either `(null, value)` or `(error)`, i.e., never two non-null
+// values. Also substitutes a stub if the callback is `undefined` or
+// otherwise falsey, for convenience in methods for which the callback
+// is optional (that is, most of them).
+function callbackWrapper(ch, cb) {
+  return (cb) ? function(err, ok) {
+    if (err === null) {
+      cb(null, ok);
+    }
+    else cb(err);
+  } : function() {};
+}
+
+class ConfirmChannel extends Channel {
+  publish (exchange, routingKey,
+    content, options, cb) {
+    this.pushConfirmCallback(cb);
+    return Channel.prototype.publish.call(
+      this, exchange, routingKey, content, options);
+  }
+
+  sendToQueue (queue, content,
+    options, cb) {
+    return this.publish('', queue, content, options, cb);
+  }
+
+  waitForConfirms (k) {
+    var awaiting = [];
+    var unconfirmed = this.unconfirmed;
+    unconfirmed.forEach(function (val, index) {
+      if (val === null)
+        ; // already confirmed
+      else {
+        var confirmed = new Promise(function (resolve, reject) {
+          unconfirmed[index] = function (err) {
+            if (val)
+              val(err);
+            if (err === null)
+              resolve();
+            else
+              reject(err);
+          };
+        });
+        awaiting.push(confirmed);
+      }
+    });
+    return Promise.all(awaiting).then(function () { k(); },
+      function (err) { k(err); });
+  }
+}
+
+module.exports.CallbackModel = CallbackModel;
+module.exports.Channel = Channel;
+module.exports.ConfirmChannel = ConfirmChannel;

+ 506 - 0
node_modules/amqplib/lib/channel.js

@@ -0,0 +1,506 @@
+//
+//
+//
+
+// Channel machinery.
+
+'use strict';
+
+var defs = require('./defs');
+var closeMsg = require('./format').closeMessage;
+var inspect = require('./format').inspect;
+var methodName = require('./format').methodName;
+var assert = require('assert');
+var EventEmitter = require('events');
+var fmt = require('util').format;
+var IllegalOperationError = require('./error').IllegalOperationError;
+var stackCapture = require('./error').stackCapture;
+
+class Channel extends EventEmitter {
+  constructor (connection) {
+    super();
+
+    this.connection = connection;
+    // for the presently outstanding RPC
+    this.reply = null;
+    // for the RPCs awaiting action
+    this.pending = [];
+    // for unconfirmed messages
+    this.lwm = 1; // the least, unconfirmed deliveryTag
+    this.unconfirmed = []; // rolling window of delivery callbacks
+    this.on('ack', this.handleConfirm.bind(this, function (cb) {
+      if (cb)
+        cb(null);
+    }));
+    this.on('nack', this.handleConfirm.bind(this, function (cb) {
+      if (cb)
+        cb(new Error('message nacked'));
+    }));
+    this.on('close', function () {
+      var cb;
+      while (cb = this.unconfirmed.shift()) {
+        if (cb)
+          cb(new Error('channel closed'));
+      }
+    });
+    // message frame state machine
+    this.handleMessage = acceptDeliveryOrReturn;
+  }
+
+  allocate () {
+    this.ch = this.connection.freshChannel(this);
+    return this;
+  }
+
+  // Incoming frames are either notifications of e.g., message delivery,
+  // or replies to something we've sent. In general I deal with the
+  // former by emitting an event, and with the latter by keeping a track
+  // of what's expecting a reply.
+  //
+  // The AMQP specification implies that RPCs can't be pipelined; that
+  // is, you can have only one outstanding RPC on a channel at a
+  // time. Certainly that's what RabbitMQ and its clients assume. For
+  // this reason, I buffer RPCs if the channel is already waiting for a
+  // reply.
+  // Just send the damn frame.
+  sendImmediately (method, fields) {
+    return this.connection.sendMethod(this.ch, method, fields);
+  }
+
+  // Invariant: !this.reply -> pending.length == 0. That is, whenever we
+  // clear a reply, we must send another RPC (and thereby fill
+  // this.reply) if there is one waiting. The invariant relevant here
+  // and in `accept`.
+  sendOrEnqueue (method, fields, reply) {
+    if (!this.reply) { // if no reply waiting, we can go
+      assert(this.pending.length === 0);
+      this.reply = reply;
+      this.sendImmediately(method, fields);
+    }
+    else {
+      this.pending.push({
+        method: method,
+        fields: fields,
+        reply: reply
+      });
+    }
+  }
+
+  sendMessage (fields, properties, content) {
+    return this.connection.sendMessage(
+      this.ch,
+      defs.BasicPublish, fields,
+      defs.BasicProperties, properties,
+      content);
+  }
+
+  // Internal, synchronously resolved RPC; the return value is resolved
+  // with the whole frame.
+  _rpc (method, fields, expect, cb) {
+    var self = this;
+
+    function reply (err, f) {
+      if (err === null) {
+        if (f.id === expect) {
+          return cb(null, f);
+        }
+        else {
+          // We have detected a problem, so it's up to us to close the
+          // channel
+          var expectedName = methodName(expect);
+
+          var e = new Error(fmt("Expected %s; got %s",
+            expectedName, inspect(f, false)));
+          self.closeWithError(f.id, fmt('Expected %s; got %s',
+            expectedName, methodName(f.id)),
+            defs.constants.UNEXPECTED_FRAME, e);
+          return cb(e);
+        }
+      }
+
+
+      // An error will be given if, for example, this is waiting to be
+      // sent and the connection closes
+      else if (err instanceof Error)
+        return cb(err);
+
+
+      // A close frame will be given if this is the RPC awaiting reply
+      // and the channel is closed by the server
+      else {
+        // otherwise, it's a close frame
+        var closeReason = (err.fields.classId << 16) + err.fields.methodId;
+        var e = (method === closeReason)
+          ? fmt("Operation failed: %s; %s",
+            methodName(method), closeMsg(err))
+          : fmt("Channel closed by server: %s", closeMsg(err));
+        var closeFrameError = new Error(e);
+        closeFrameError.code = err.fields.replyCode;
+        closeFrameError.classId = err.fields.classId;
+        closeFrameError.methodId = err.fields.methodId;
+        return cb(closeFrameError);
+      }
+    }
+
+    this.sendOrEnqueue(method, fields, reply);
+  }
+
+  // Move to entirely closed state.
+  toClosed (capturedStack) {
+    this._rejectPending();
+    invalidateSend(this, 'Channel closed', capturedStack);
+    this.accept = invalidOp('Channel closed', capturedStack);
+    this.connection.releaseChannel(this.ch);
+    this.emit('close');
+  }
+
+  // Stop being able to send and receive methods and content. Used when
+  // we close the channel. Invokes the continuation once the server has
+  // acknowledged the close, but before the channel is moved to the
+  // closed state.
+  toClosing (capturedStack, k) {
+    var send = this.sendImmediately.bind(this);
+    invalidateSend(this, 'Channel closing', capturedStack);
+
+    this.accept = function (f) {
+      if (f.id === defs.ChannelCloseOk) {
+        if (k)
+          k();
+        var s = stackCapture('ChannelCloseOk frame received');
+        this.toClosed(s);
+      }
+      else if (f.id === defs.ChannelClose) {
+        send(defs.ChannelCloseOk, {});
+      }
+      // else ignore frame
+    };
+  }
+
+  _rejectPending () {
+    function rej (r) {
+      r(new Error("Channel ended, no reply will be forthcoming"));
+    }
+    if (this.reply !== null)
+      rej(this.reply);
+    this.reply = null;
+
+    var discard;
+    while (discard = this.pending.shift())
+      rej(discard.reply);
+    this.pending = null; // so pushes will break
+  }
+
+  closeBecause (reason, code, k) {
+    this.sendImmediately(defs.ChannelClose, {
+      replyText: reason,
+      replyCode: code,
+      methodId: 0, classId: 0
+    });
+    var s = stackCapture('closeBecause called: ' + reason);
+    this.toClosing(s, k);
+  }
+
+  // If we close because there's been an error, we need to distinguish
+  // between what we tell the server (`reason`) and what we report as
+  // the cause in the client (`error`).
+  closeWithError (id, reason, code, error) {
+    var self = this;
+    this.closeBecause(reason, code, function () {
+      error.code = code;
+      // content frames and consumer errors do not provide a method a class/method ID
+      if (id) {
+        error.classId = defs.info(id).classId;
+        error.methodId = defs.info(id).methodId;
+      }
+      self.emit('error', error);
+    });
+  }
+
+  // A trampolining state machine for message frames on a channel. A
+  // message arrives in at least two frames: first, a method announcing
+  // the message (either a BasicDeliver or BasicGetOk); then, a message
+  // header with the message properties; then, zero or more content
+  // frames.
+  // Keep the try/catch localised, in an attempt to avoid disabling
+  // optimisation
+  acceptMessageFrame (f) {
+    try {
+      this.handleMessage = this.handleMessage(f);
+    }
+    catch (msg) {
+      if (typeof msg === 'string') {
+        this.closeWithError(f.id, msg, defs.constants.UNEXPECTED_FRAME,
+          new Error(msg));
+      }
+      else if (msg instanceof Error) {
+        this.closeWithError(f.id, 'Error while processing message',
+          defs.constants.INTERNAL_ERROR, msg);
+      }
+      else {
+        this.closeWithError(f.id, 'Internal error while processing message',
+          defs.constants.INTERNAL_ERROR,
+          new Error(msg.toString()));
+      }
+    }
+  }
+
+  handleConfirm (handle, f) {
+    var tag = f.deliveryTag;
+    var multi = f.multiple;
+
+    if (multi) {
+      var confirmed = this.unconfirmed.splice(0, tag - this.lwm + 1);
+      this.lwm = tag + 1;
+      confirmed.forEach(handle);
+    }
+    else {
+      var c;
+      if (tag === this.lwm) {
+        c = this.unconfirmed.shift();
+        this.lwm++;
+        // Advance the LWM and the window to the next non-gap, or
+        // possibly to the end
+        while (this.unconfirmed[0] === null) {
+          this.unconfirmed.shift();
+          this.lwm++;
+        }
+      }
+      else {
+        c = this.unconfirmed[tag - this.lwm];
+        this.unconfirmed[tag - this.lwm] = null;
+      }
+      // Technically, in the single-deliveryTag case, I should report a
+      // protocol breach if it's already been confirmed.
+      handle(c);
+    }
+  }
+
+  pushConfirmCallback (cb) {
+    // `null` is used specifically for marking already confirmed slots,
+    // so I coerce `undefined` and `null` to false; functions are never
+    // falsey.
+    this.unconfirmed.push(cb || false);
+  }
+
+  onBufferDrain () {
+    this.emit('drain');
+  }
+
+  accept(f) {
+
+    switch (f.id) {
+
+      // Message frames
+    case undefined: // content frame!
+    case defs.BasicDeliver:
+    case defs.BasicReturn:
+    case defs.BasicProperties:
+      return this.acceptMessageFrame(f);
+
+      // confirmations, need to do confirm.select first
+    case defs.BasicAck:
+      return this.emit('ack', f.fields);
+    case defs.BasicNack:
+      return this.emit('nack', f.fields);
+    case defs.BasicCancel:
+      // The broker can send this if e.g., the queue is deleted.
+      return this.emit('cancel', f.fields);
+
+    case defs.ChannelClose:
+      // Any remote closure is an error to us. Reject the pending reply
+      // with the close frame, so it can see whether it was that
+      // operation that caused it to close.
+      if (this.reply) {
+        var reply = this.reply; this.reply = null;
+        reply(f);
+      }
+      var emsg = "Channel closed by server: " + closeMsg(f);
+      this.sendImmediately(defs.ChannelCloseOk, {});
+
+      var error = new Error(emsg);
+      error.code = f.fields.replyCode;
+      error.classId = f.fields.classId;
+      error.methodId = f.fields.methodId;
+      this.emit('error', error);
+
+      var s = stackCapture(emsg);
+      this.toClosed(s);
+      return;
+
+    case defs.BasicFlow:
+      // RabbitMQ doesn't send this, it just blocks the TCP socket
+      return this.closeWithError(f.id, "Flow not implemented",
+                                 defs.constants.NOT_IMPLEMENTED,
+                                 new Error('Flow not implemented'));
+
+    default: // assume all other things are replies
+      // Resolving the reply may lead to another RPC; to make sure we
+      // don't hold that up, clear this.reply
+      var reply = this.reply; this.reply = null;
+      // however, maybe there's an RPC waiting to go? If so, that'll
+      // fill this.reply again, restoring the invariant. This does rely
+      // on any response being recv'ed after resolving the promise,
+      // below; hence, I use synchronous defer.
+      if (this.pending.length > 0) {
+        var send = this.pending.shift();
+        this.reply = send.reply;
+        this.sendImmediately(send.method, send.fields);
+      }
+      return reply(null, f);
+    }
+  }
+}
+
+// Shutdown protocol. There's three scenarios:
+//
+// 1. The application decides to shut the channel
+// 2. The server decides to shut the channel, possibly because of
+// something the application did
+// 3. The connection is closing, so there won't be any more frames
+// going back and forth.
+//
+// 1 and 2 involve an exchange of method frames (Close and CloseOk),
+// while 3 doesn't; the connection simply says "shutdown" to the
+// channel, which then acts as if it's closing, without going through
+// the exchange.
+
+function invalidOp(msg, stack) {
+  return function() {
+    throw new IllegalOperationError(msg, stack);
+  };
+}
+
+function invalidateSend(ch, msg, stack) {
+  ch.sendImmediately = ch.sendOrEnqueue = ch.sendMessage =
+    invalidOp(msg, stack);
+}
+
+// Kick off a message delivery given a BasicDeliver or BasicReturn
+// frame (BasicGet uses the RPC mechanism)
+function acceptDeliveryOrReturn(f) {
+  var event;
+  if (f.id === defs.BasicDeliver) event = 'delivery';
+  else if (f.id === defs.BasicReturn) event = 'return';
+  else throw fmt("Expected BasicDeliver or BasicReturn; got %s",
+                 inspect(f));
+
+  var self = this;
+  var fields = f.fields;
+  return acceptMessage(function(message) {
+    message.fields = fields;
+    self.emit(event, message);
+  });
+}
+
+// Move to the state of waiting for message frames (headers, then
+// one or more content frames)
+function acceptMessage(continuation) {
+  var totalSize = 0, remaining = 0;
+  var buffers = null;
+
+  var message = {
+    fields: null,
+    properties: null,
+    content: null
+  };
+
+  return headers;
+
+  // expect a headers frame
+  function headers(f) {
+    if (f.id === defs.BasicProperties) {
+      message.properties = f.fields;
+      totalSize = remaining = f.size;
+
+      // for zero-length messages, content frames aren't required.
+      if (totalSize === 0) {
+        message.content = Buffer.alloc(0);
+        continuation(message);
+        return acceptDeliveryOrReturn;
+      }
+      else {
+        return content;
+      }
+    }
+    else {
+      throw "Expected headers frame after delivery";
+    }
+  }
+
+  // expect a content frame
+  // %%% TODO cancelled messages (sent as zero-length content frame)
+  function content(f) {
+    if (f.content) {
+      var size = f.content.length;
+      remaining -= size;
+      if (remaining === 0) {
+        if (buffers !== null) {
+          buffers.push(f.content);
+          message.content = Buffer.concat(buffers);
+        }
+        else {
+          message.content = f.content;
+        }
+        continuation(message);
+        return acceptDeliveryOrReturn;
+      }
+      else if (remaining < 0) {
+        throw fmt("Too much content sent! Expected %d bytes",
+                  totalSize);
+      }
+      else {
+        if (buffers !== null)
+          buffers.push(f.content);
+        else
+          buffers = [f.content];
+        return content;
+      }
+    }
+    else throw "Expected content frame after headers"
+  }
+}
+
+// This adds just a bit more stuff useful for the APIs, but not
+// low-level machinery.
+class BaseChannel extends Channel {
+  constructor (connection) {
+    super(connection);
+    this.consumers = new Map();
+  }
+
+  // Not sure I like the ff, it's going to be changing hidden classes
+  // all over the place. On the other hand, whaddya do.
+  registerConsumer (tag, callback) {
+    this.consumers.set(tag, callback);
+  }
+
+  unregisterConsumer (tag) {
+    this.consumers.delete(tag);
+  }
+
+  dispatchMessage (fields, message) {
+    var consumerTag = fields.consumerTag;
+    var consumer = this.consumers.get(consumerTag);
+    if (consumer) {
+      return consumer(message);
+    }
+    else {
+      // %%% Surely a race here
+      throw new Error("Unknown consumer: " + consumerTag);
+    }
+  }
+
+  handleDelivery (message) {
+    return this.dispatchMessage(message.fields, message);
+  }
+
+  handleCancel (fields) {
+    var result = this.dispatchMessage(fields, null);
+    this.unregisterConsumer(fields.consumerTag);
+    return result;
+  }
+}
+
+module.exports.acceptMessage = acceptMessage;
+module.exports.BaseChannel = BaseChannel;
+module.exports.Channel = Channel;

+ 306 - 0
node_modules/amqplib/lib/channel_model.js

@@ -0,0 +1,306 @@
+//
+//
+//
+
+'use strict';
+
+const EventEmitter = require('events');
+const promisify = require('util').promisify;
+const defs = require('./defs');
+const {BaseChannel} = require('./channel');
+const {acceptMessage} = require('./channel');
+const Args = require('./api_args');
+const {inspect} = require('./format');
+
+class ChannelModel extends EventEmitter {
+  constructor(connection) {
+    super();
+    this.connection = connection;
+
+    ['error', 'close', 'blocked', 'unblocked'].forEach(ev => {
+      connection.on(ev, this.emit.bind(this, ev));
+    });
+  }
+
+  close() {
+    return promisify(this.connection.close.bind(this.connection))();
+  }
+
+  updateSecret(newSecret, reason) {
+    return promisify(this.connection._updateSecret.bind(this.connection))(newSecret, reason);
+  }
+
+  async createChannel() {
+    const channel = new Channel(this.connection);
+    await channel.open();
+    return channel;
+  }
+
+  async createConfirmChannel() {
+    const channel = new ConfirmChannel(this.connection);
+    await channel.open();
+    await channel.rpc(defs.ConfirmSelect, {nowait: false}, defs.ConfirmSelectOk);
+    return channel;
+  }
+}
+
+// Channels
+
+class Channel extends BaseChannel {
+  constructor(connection) {
+    super(connection);
+    this.on('delivery', this.handleDelivery.bind(this));
+    this.on('cancel', this.handleCancel.bind(this));
+  }
+
+  // An RPC that returns a 'proper' promise, which resolves to just the
+  // response's fields; this is intended to be suitable for implementing
+  // API procedures.
+  async rpc(method, fields, expect) {
+    const f = await promisify(cb => {
+      return this._rpc(method, fields, expect, cb);
+    })();
+
+    return f.fields;
+  }
+
+  // Do the remarkably simple channel open handshake
+  async open() {
+    const ch = await this.allocate.bind(this)();
+    return ch.rpc(defs.ChannelOpen, {outOfBand: ""},
+                  defs.ChannelOpenOk);
+  }
+
+  close() {
+    return promisify(cb => {
+      return this.closeBecause("Goodbye", defs.constants.REPLY_SUCCESS,
+                      cb);
+    })();
+  }
+
+  // === Public API, declaring queues and stuff ===
+
+  assertQueue(queue, options) {
+    return this.rpc(defs.QueueDeclare,
+                    Args.assertQueue(queue, options),
+                    defs.QueueDeclareOk);
+  }
+
+  checkQueue(queue) {
+    return this.rpc(defs.QueueDeclare,
+                    Args.checkQueue(queue),
+                    defs.QueueDeclareOk);
+  }
+
+  deleteQueue(queue, options) {
+    return this.rpc(defs.QueueDelete,
+                    Args.deleteQueue(queue, options),
+                    defs.QueueDeleteOk);
+  }
+
+  purgeQueue(queue) {
+    return this.rpc(defs.QueuePurge,
+                    Args.purgeQueue(queue),
+                    defs.QueuePurgeOk);
+  }
+
+  bindQueue(queue, source, pattern, argt) {
+    return this.rpc(defs.QueueBind,
+                    Args.bindQueue(queue, source, pattern, argt),
+                    defs.QueueBindOk);
+  }
+
+  unbindQueue(queue, source, pattern, argt) {
+    return this.rpc(defs.QueueUnbind,
+                    Args.unbindQueue(queue, source, pattern, argt),
+                    defs.QueueUnbindOk);
+  }
+
+  assertExchange(exchange, type, options) {
+    // The server reply is an empty set of fields, but it's convenient
+    // to have the exchange name handed to the continuation.
+    return this.rpc(defs.ExchangeDeclare,
+                    Args.assertExchange(exchange, type, options),
+                    defs.ExchangeDeclareOk)
+      .then(_ok => { return { exchange }; });
+  }
+
+  checkExchange(exchange) {
+    return this.rpc(defs.ExchangeDeclare,
+                    Args.checkExchange(exchange),
+                    defs.ExchangeDeclareOk);
+  }
+
+  deleteExchange(name, options) {
+    return this.rpc(defs.ExchangeDelete,
+                    Args.deleteExchange(name, options),
+                    defs.ExchangeDeleteOk);
+  }
+
+  bindExchange(dest, source, pattern, argt) {
+    return this.rpc(defs.ExchangeBind,
+                    Args.bindExchange(dest, source, pattern, argt),
+                    defs.ExchangeBindOk);
+  }
+
+  unbindExchange(dest, source, pattern, argt) {
+    return this.rpc(defs.ExchangeUnbind,
+                    Args.unbindExchange(dest, source, pattern, argt),
+                    defs.ExchangeUnbindOk);
+  }
+
+  // Working with messages
+
+  publish(exchange, routingKey, content, options) {
+    const fieldsAndProps = Args.publish(exchange, routingKey, options);
+    return this.sendMessage(fieldsAndProps, fieldsAndProps, content);
+  }
+
+  sendToQueue(queue, content, options) {
+    return this.publish('', queue, content, options);
+  }
+
+  consume(queue, callback, options) {
+    // NB we want the callback to be run synchronously, so that we've
+    // registered the consumerTag before any messages can arrive.
+    const fields = Args.consume(queue, options);
+    return new Promise((resolve, reject) => {
+      this._rpc(defs.BasicConsume, fields, defs.BasicConsumeOk, (err, ok) => {
+        if (err) return reject(err);
+        this.registerConsumer(ok.fields.consumerTag, callback);
+        resolve(ok.fields);
+      });
+    });
+  }
+
+  async cancel(consumerTag) {
+    const ok = await promisify(cb => {
+      this._rpc(defs.BasicCancel, Args.cancel(consumerTag),
+            defs.BasicCancelOk,
+            cb);
+    })()
+    .then(ok => {
+      this.unregisterConsumer(consumerTag);
+      return ok.fields;
+    });
+  }
+
+  get(queue, options) {
+    const fields = Args.get(queue, options);
+    return new Promise((resolve, reject) => {
+      this.sendOrEnqueue(defs.BasicGet, fields, (err, f) => {
+        if (err) return reject(err);
+        if (f.id === defs.BasicGetEmpty) {
+          return resolve(false);
+        }
+        else if (f.id === defs.BasicGetOk) {
+          const fields = f.fields;
+          this.handleMessage = acceptMessage(m => {
+            m.fields = fields;
+            resolve(m);
+          });
+        }
+        else {
+          reject(new Error(`Unexpected response to BasicGet: ${inspect(f)}`));
+        }
+      });
+    });
+  }
+
+  ack(message, allUpTo) {
+    this.sendImmediately(
+      defs.BasicAck,
+      Args.ack(message.fields.deliveryTag, allUpTo));
+  }
+
+  ackAll() {
+    this.sendImmediately(defs.BasicAck, Args.ack(0, true));
+  }
+
+  nack(message, allUpTo, requeue) {
+    this.sendImmediately(
+      defs.BasicNack,
+      Args.nack(message.fields.deliveryTag, allUpTo, requeue));
+  }
+
+  nackAll(requeue) {
+    this.sendImmediately(defs.BasicNack,
+                         Args.nack(0, true, requeue));
+  }
+
+  // `Basic.Nack` is not available in older RabbitMQ versions (or in the
+  // AMQP specification), so you have to use the one-at-a-time
+  // `Basic.Reject`. This is otherwise synonymous with
+  // `#nack(message, false, requeue)`.
+  reject(message, requeue) {
+    this.sendImmediately(
+      defs.BasicReject,
+      Args.reject(message.fields.deliveryTag, requeue));
+  }
+
+  recover() {
+    return this.rpc(defs.BasicRecover,
+                    Args.recover(),
+                    defs.BasicRecoverOk);
+  }
+
+  qos(count, global) {
+    return this.rpc(defs.BasicQos,
+                    Args.prefetch(count, global),
+                    defs.BasicQosOk);
+  }
+}
+
+// There are more options in AMQP than exposed here; RabbitMQ only
+// implements prefetch based on message count, and only for individual
+// channels or consumers. RabbitMQ v3.3.0 and after treat prefetch
+// (without `global` set) as per-consumer (for consumers following),
+// and prefetch with `global` set as per-channel.
+Channel.prototype.prefetch = Channel.prototype.qos
+
+// Confirm channel. This is a channel with confirms 'switched on',
+// meaning sent messages will provoke a responding 'ack' or 'nack'
+// from the server. The upshot of this is that `publish` and
+// `sendToQueue` both take a callback, which will be called either
+// with `null` as its argument to signify 'ack', or an exception as
+// its argument to signify 'nack'.
+
+class ConfirmChannel extends Channel {
+  publish(exchange, routingKey, content, options, cb) {
+    this.pushConfirmCallback(cb);
+    return super.publish(exchange, routingKey, content, options);
+  }
+
+  sendToQueue(queue, content, options, cb) {
+    return this.publish('', queue, content, options, cb);
+  }
+
+  waitForConfirms() {
+    const awaiting = [];
+    const unconfirmed = this.unconfirmed;
+    unconfirmed.forEach((val, index) => {
+      if (val !== null) {
+        const confirmed = new Promise((resolve, reject) => {
+          unconfirmed[index] = err => {
+            if (val) val(err);
+            if (err === null) resolve();
+            else reject(err);
+          };
+        });
+        awaiting.push(confirmed);
+      }
+    });
+    // Channel closed
+    if (!this.pending) {
+      var cb;
+      while (cb = this.unconfirmed.shift()) {
+        if (cb) cb(new Error('channel closed'));
+      }
+    }
+    return Promise.all(awaiting);
+  }
+}
+
+module.exports.ConfirmChannel = ConfirmChannel;
+module.exports.Channel = Channel;
+module.exports.ChannelModel = ChannelModel;

+ 345 - 0
node_modules/amqplib/lib/codec.js

@@ -0,0 +1,345 @@
+//
+//
+//
+
+/*
+
+The AMQP 0-9-1 is a mess when it comes to the types that can be
+encoded on the wire.
+
+There are four encoding schemes, and three overlapping sets of types:
+frames, methods, (field-)tables, and properties.
+
+Each *frame type* has a set layout in which values of given types are
+concatenated along with sections of "raw binary" data.
+
+In frames there are `shortstr`s, that is length-prefixed strings of
+UTF8 chars, 8 bit unsigned integers (called `octet`), unsigned 16 bit
+integers (called `short` or `short-uint`), unsigned 32 bit integers
+(called `long` or `long-uint`), unsigned 64 bit integers (called
+`longlong` or `longlong-uint`), and flags (called `bit`).
+
+Methods are encoded as a frame giving a method ID and a sequence of
+arguments of known types. The encoded method argument values are
+concatenated (with some fun complications around "packing" consecutive
+bit values into bytes).
+
+Along with the types given in frames, method arguments may be long
+byte strings (`longstr`, not required to be UTF8) or 64 bit unsigned
+integers to be interpreted as timestamps (yeah I don't know why
+either), or arbitrary sets of key-value pairs (called `field-table`).
+
+Inside a field table the keys are `shortstr` and the values are
+prefixed with a byte tag giving the type. The types are any of the
+above except for bits (which are replaced by byte-wide `bool`), along
+with a NULL value `void`, a special fixed-precision number encoding
+(`decimal`), IEEE754 `float`s and `double`s, signed integers,
+`field-array` (a sequence of tagged values), and nested field-tables.
+
+RabbitMQ and QPid use a subset of the field-table types, and different
+value tags, established before the AMQP 0-9-1 specification was
+published. So far as I know, no-one uses the types and tags as
+published. http://www.rabbitmq.com/amqp-0-9-1-errata.html gives the
+list of field-table types.
+
+Lastly, there are (sets of) properties, only one of which is given in
+AMQP 0-9-1: `BasicProperties`. These are almost the same as methods,
+except that they appear in content header frames, which include a
+content size, and they carry a set of flags indicating which
+properties are present. This scheme can save ones of bytes per message
+(messages which take a minimum of three frames each to send).
+
+*/
+
+'use strict';
+
+var ints = require('buffer-more-ints');
+
+// JavaScript uses only doubles so what I'm testing for is whether
+// it's *better* to encode a number as a float or double. This really
+// just amounts to testing whether there's a fractional part to the
+// number, except that see below. NB I don't use bitwise operations to
+// do this 'efficiently' -- it would mask the number to 32 bits.
+//
+// At 2^50, doubles don't have sufficient precision to distinguish
+// between floating point and integer numbers (`Math.pow(2, 50) + 0.1
+// === Math.pow(2, 50)` (and, above 2^53, doubles cannot represent all
+// integers (`Math.pow(2, 53) + 1 === Math.pow(2, 53)`)). Hence
+// anything with a magnitude at or above 2^50 may as well be encoded
+// as a 64-bit integer. Except that only signed integers are supported
+// by RabbitMQ, so anything above 2^63 - 1 must be a double.
+function isFloatingPoint(n) {
+    return n >= 0x8000000000000000 ||
+        (Math.abs(n) < 0x4000000000000
+         && Math.floor(n) !== n);
+}
+
+function encodeTable(buffer, val, offset) {
+    var start = offset;
+    offset += 4; // leave room for the table length
+    for (var key in val) {
+        if (val[key] !== undefined) {
+          var len = Buffer.byteLength(key);
+          buffer.writeUInt8(len, offset); offset++;
+          buffer.write(key, offset, 'utf8'); offset += len;
+          offset += encodeFieldValue(buffer, val[key], offset);
+        }
+    }
+    var size = offset - start;
+    buffer.writeUInt32BE(size - 4, start);
+    return size;
+}
+
+function encodeArray(buffer, val, offset) {
+    var start = offset;
+    offset += 4;
+    for (var i=0, num=val.length; i < num; i++) {
+        offset += encodeFieldValue(buffer, val[i], offset);
+    }
+    var size = offset - start;
+    buffer.writeUInt32BE(size - 4, start);
+    return size;
+}
+
+function encodeFieldValue(buffer, value, offset) {
+    var start = offset;
+    var type = typeof value, val = value;
+    // A trapdoor for specifying a type, e.g., timestamp
+    if (value && type === 'object' && value.hasOwnProperty('!')) {
+        val = value.value;
+        type = value['!'];
+    }
+
+    // If it's a JS number, we'll have to guess what type to encode it
+    // as.
+    if (type == 'number') {
+        // Making assumptions about the kind of number (floating point
+        // v integer, signed, unsigned, size) desired is dangerous in
+        // general; however, in practice RabbitMQ uses only
+        // longstrings and unsigned integers in its arguments, and
+        // other clients generally conflate number types anyway. So
+        // the only distinction we care about is floating point vs
+        // integers, preferring integers since those can be promoted
+        // if necessary. If floating point is required, we may as well
+        // use double precision.
+        if (isFloatingPoint(val)) {
+            type = 'double';
+        }
+        else { // only signed values are used in tables by
+               // RabbitMQ. It *used* to (< v3.3.0) treat the byte 'b'
+               // type as unsigned, but most clients (and the spec)
+               // think it's signed, and now RabbitMQ does too.
+            if (val < 128 && val >= -128) {
+                type = 'byte';
+            }
+            else if (val >= -0x8000 && val < 0x8000) {
+                type = 'short'
+            }
+            else if (val >= -0x80000000 && val < 0x80000000) {
+                type = 'int';
+            }
+            else {
+                type = 'long';
+            }
+        }
+    }
+
+    function tag(t) { buffer.write(t, offset); offset++; }
+
+    switch (type) {
+    case 'string': // no shortstr in field tables
+        var len = Buffer.byteLength(val, 'utf8');
+        tag('S');
+        buffer.writeUInt32BE(len, offset); offset += 4;
+        buffer.write(val, offset, 'utf8'); offset += len;
+        break;
+    case 'object':
+        if (val === null) {
+            tag('V');
+        }
+        else if (Array.isArray(val)) {
+            tag('A');
+            offset += encodeArray(buffer, val, offset);
+        }
+        else if (Buffer.isBuffer(val)) {
+            tag('x');
+            buffer.writeUInt32BE(val.length, offset); offset += 4;
+            val.copy(buffer, offset); offset += val.length;
+        }
+        else {
+            tag('F');
+            offset += encodeTable(buffer, val, offset);
+        }
+        break;
+    case 'boolean':
+        tag('t');
+        buffer.writeUInt8((val) ? 1 : 0, offset); offset++;
+        break;
+    // These are the types that are either guessed above, or
+    // explicitly given using the {'!': type} notation.
+    case 'double':
+    case 'float64':
+        tag('d');
+        buffer.writeDoubleBE(val, offset);
+        offset += 8;
+        break;
+    case 'byte':
+    case 'int8':
+        tag('b');
+        buffer.writeInt8(val, offset); offset++;
+        break;
+    case 'unsignedbyte':
+    case 'uint8':
+        tag('B');
+        buffer.writeUInt8(val, offset); offset++;
+        break;
+    case 'short':
+    case 'int16':
+        tag('s');
+        buffer.writeInt16BE(val, offset); offset += 2;
+        break;
+    case 'unsignedshort':
+    case 'uint16':
+        tag('u');
+        buffer.writeUInt16BE(val, offset); offset += 2;
+        break;
+    case 'int':
+    case 'int32':
+        tag('I');
+        buffer.writeInt32BE(val, offset); offset += 4;
+        break;
+    case 'unsignedint':
+    case 'uint32':
+        tag('i');
+        buffer.writeUInt32BE(val, offset); offset += 4;
+        break;
+    case 'long':
+    case 'int64':
+        tag('l');
+        ints.writeInt64BE(buffer, val, offset); offset += 8;
+        break;
+
+    // Now for exotic types, those can _only_ be denoted by using
+    // `{'!': type, value: val}
+    case 'timestamp':
+        tag('T');
+        ints.writeUInt64BE(buffer, val, offset); offset += 8;
+        break;
+    case 'float':
+        tag('f');
+        buffer.writeFloatBE(val, offset); offset += 4;
+        break;
+    case 'decimal':
+        tag('D');
+        if (val.hasOwnProperty('places') && val.hasOwnProperty('digits')
+            && val.places >= 0 && val.places < 256) {
+            buffer[offset] = val.places; offset++;
+            buffer.writeUInt32BE(val.digits, offset); offset += 4;
+        }
+        else throw new TypeError(
+            "Decimal value must be {'places': 0..255, 'digits': uint32}, " +
+                "got " + JSON.stringify(val));
+        break;
+    default:
+        throw new TypeError('Unknown type to encode: ' + type);
+    }
+    return offset - start;
+}
+
+// Assume we're given a slice of the buffer that contains just the
+// fields.
+function decodeFields(slice) {
+    var fields = {}, offset = 0, size = slice.length;
+    var len, key, val;
+
+    function decodeFieldValue() {
+        var tag = String.fromCharCode(slice[offset]); offset++;
+        switch (tag) {
+        case 'b':
+            val = slice.readInt8(offset); offset++;
+            break;
+        case 'B':
+            val = slice.readUInt8(offset); offset++;
+            break;
+        case 'S':
+            len = slice.readUInt32BE(offset); offset += 4;
+            val = slice.toString('utf8', offset, offset + len);
+            offset += len;
+            break;
+        case 'I':
+            val = slice.readInt32BE(offset); offset += 4;
+            break;
+        case 'i':
+            val = slice.readUInt32BE(offset); offset += 4;
+            break;
+        case 'D': // only positive decimals, apparently.
+            var places = slice[offset]; offset++;
+            var digits = slice.readUInt32BE(offset); offset += 4;
+            val = {'!': 'decimal', value: {places: places, digits: digits}};
+            break;
+        case 'T':
+            val = ints.readUInt64BE(slice, offset); offset += 8;
+            val = {'!': 'timestamp', value: val};
+            break;
+        case 'F':
+            len = slice.readUInt32BE(offset); offset += 4;
+            val = decodeFields(slice.subarray(offset, offset + len));
+            offset += len;
+            break;
+        case 'A':
+            len = slice.readUInt32BE(offset); offset += 4;
+            decodeArray(offset + len);
+            // NB decodeArray will itself update offset and val
+            break;
+        case 'd':
+            val = slice.readDoubleBE(offset); offset += 8;
+            break;
+        case 'f':
+            val = slice.readFloatBE(offset); offset += 4;
+            break;
+        case 'l':
+            val = ints.readInt64BE(slice, offset); offset += 8;
+            break;
+        case 's':
+            val = slice.readInt16BE(offset); offset += 2;
+            break;
+        case 'u':
+            val = slice.readUInt16BE(offset); offset += 2;
+            break;
+        case 't':
+            val = slice[offset] != 0; offset++;
+            break;
+        case 'V':
+            val = null;
+            break;
+        case 'x':
+            len = slice.readUInt32BE(offset); offset += 4;
+            val = slice.subarray(offset, offset + len);
+            offset += len;
+            break;
+        default:
+            throw new TypeError('Unexpected type tag "' + tag +'"');
+        }
+    }
+
+    function decodeArray(until) {
+        var vals = [];
+        while (offset < until) {
+            decodeFieldValue();
+            vals.push(val);
+        }
+        val = vals;
+    }
+
+    while (offset < size) {
+        len = slice.readUInt8(offset); offset++;
+        key = slice.toString('utf8', offset, offset + len);
+        offset += len;
+        decodeFieldValue();
+        fields[key] = val;
+    }
+    return fields;
+}
+
+module.exports.encodeTable = encodeTable;
+module.exports.decodeFields = decodeFields;

+ 189 - 0
node_modules/amqplib/lib/connect.js

@@ -0,0 +1,189 @@
+//
+//
+//
+
+// General-purpose API for glueing everything together.
+
+'use strict';
+
+var URL = require('url-parse');
+var QS = require('querystring');
+var Connection = require('./connection').Connection;
+var fmt = require('util').format;
+var credentials = require('./credentials');
+
+function copyInto(obj, target) {
+  var keys = Object.keys(obj);
+  var i = keys.length;
+  while (i--) {
+    var k = keys[i];
+    target[k] = obj[k];
+  }
+  return target;
+}
+
+// Adapted from util._extend, which is too fringe to use.
+function clone(obj) {
+  return copyInto(obj, {});
+}
+
+var CLIENT_PROPERTIES = {
+  "product": "amqplib",
+  "version": require('../package.json').version,
+  "platform": fmt('Node.JS %s', process.version),
+  "information": "http://squaremo.github.io/amqp.node",
+  "capabilities": {
+    "publisher_confirms": true,
+    "exchange_exchange_bindings": true,
+    "basic.nack": true,
+    "consumer_cancel_notify": true,
+    "connection.blocked": true,
+    "authentication_failure_close": true
+  }
+};
+
+// Construct the main frames used in the opening handshake
+function openFrames(vhost, query, credentials, extraClientProperties) {
+  if (!vhost)
+    vhost = '/';
+  else
+    vhost = QS.unescape(vhost);
+
+  var query = query || {};
+
+  function intOrDefault(val, def) {
+    return (val === undefined) ? def : parseInt(val);
+  }
+
+  var clientProperties = Object.create(CLIENT_PROPERTIES);
+
+  return {
+    // start-ok
+    'clientProperties': copyInto(extraClientProperties, clientProperties),
+    'mechanism': credentials.mechanism,
+    'response': credentials.response(),
+    'locale': query.locale || 'en_US',
+
+    // tune-ok
+    'channelMax': intOrDefault(query.channelMax, 0),
+    'frameMax': intOrDefault(query.frameMax, 0x1000),
+    'heartbeat': intOrDefault(query.heartbeat, 0),
+
+    // open
+    'virtualHost': vhost,
+    'capabilities': '',
+    'insist': 0
+  };
+}
+
+// Decide on credentials based on what we're supplied.
+function credentialsFromUrl(parts) {
+  var user = 'guest', passwd = 'guest';
+  if (parts.username != '' || parts.password != '') {
+    user = (parts.username) ? unescape(parts.username) : '';
+    passwd = (parts.password) ? unescape(parts.password) : '';
+  }
+  return credentials.plain(user, passwd);
+}
+
+function connect(url, socketOptions, openCallback) {
+  // tls.connect uses `util._extend()` on the options given it, which
+  // copies only properties mentioned in `Object.keys()`, when
+  // processing the options. So I have to make copies too, rather
+  // than using `Object.create()`.
+  var sockopts = clone(socketOptions || {});
+  url = url || 'amqp://localhost';
+
+  var noDelay = !!sockopts.noDelay;
+  var timeout = sockopts.timeout;
+  var keepAlive = !!sockopts.keepAlive;
+  // 0 is default for node
+  var keepAliveDelay = sockopts.keepAliveDelay || 0;
+
+  var extraClientProperties = sockopts.clientProperties || {};
+
+  var protocol, fields;
+  if (typeof url === 'object') {
+    protocol = (url.protocol || 'amqp') + ':';
+    sockopts.host = url.hostname;
+    sockopts.servername = sockopts.servername || url.hostname;
+    sockopts.port = url.port || ((protocol === 'amqp:') ? 5672 : 5671);
+
+    var user, pass;
+    // Only default if both are missing, to have the same behaviour as
+    // the stringly URL.
+    if (url.username == undefined && url.password == undefined) {
+      user = 'guest'; pass = 'guest';
+    } else {
+      user = url.username || '';
+      pass = url.password || '';
+    }
+
+    var config = {
+      locale: url.locale,
+      channelMax: url.channelMax,
+      frameMax: url.frameMax,
+      heartbeat: url.heartbeat,
+    };
+
+    fields = openFrames(url.vhost, config, sockopts.credentials || credentials.plain(user, pass), extraClientProperties);
+  } else {
+    var parts = URL(url, true); // yes, parse the query string
+    protocol = parts.protocol;
+    sockopts.host = parts.hostname;
+    sockopts.servername = sockopts.servername || parts.hostname;
+    sockopts.port = parseInt(parts.port) || ((protocol === 'amqp:') ? 5672 : 5671);
+    var vhost = parts.pathname ? parts.pathname.substr(1) : null;
+    fields = openFrames(vhost, parts.query, sockopts.credentials || credentialsFromUrl(parts), extraClientProperties);
+  }
+
+  var sockok = false;
+  var sock;
+
+  function onConnect() {
+    sockok = true;
+    sock.setNoDelay(noDelay);
+    if (keepAlive) sock.setKeepAlive(keepAlive, keepAliveDelay);
+
+    var c = new Connection(sock);
+    c.open(fields, function(err, ok) {
+      // disable timeout once the connection is open, we don't want
+      // it fouling things
+      if (timeout) sock.setTimeout(0);
+      if (err === null) {
+        openCallback(null, c);
+      } else {
+        // The connection isn't closed by the server on e.g. wrong password
+        sock.end();
+        sock.destroy();
+        openCallback(err);
+      }
+    });
+  }
+
+  if (protocol === 'amqp:') {
+    sock = require('net').connect(sockopts, onConnect);
+  }
+  else if (protocol === 'amqps:') {
+    sock = require('tls').connect(sockopts, onConnect);
+  }
+  else {
+    throw new Error("Expected amqp: or amqps: as the protocol; got " + protocol);
+  }
+
+  if (timeout) {
+    sock.setTimeout(timeout, function() {
+      sock.end();
+      sock.destroy();
+      openCallback(new Error('connect ETIMEDOUT'));
+    });
+  }
+
+  sock.once('error', function(err) {
+    if (!sockok) openCallback(err);
+  });
+
+}
+
+module.exports.connect = connect;
+module.exports.credentialsFromUrl = credentialsFromUrl;

+ 675 - 0
node_modules/amqplib/lib/connection.js

@@ -0,0 +1,675 @@
+//
+//
+//
+
+'use strict';
+
+var defs = require('./defs');
+var constants = defs.constants;
+var frame = require('./frame');
+var HEARTBEAT = frame.HEARTBEAT;
+var Mux = require('./mux').Mux;
+
+var Duplex = require('stream').Duplex;
+var EventEmitter = require('events');
+var Heart = require('./heartbeat').Heart;
+
+var methodName = require('./format').methodName;
+var closeMsg = require('./format').closeMessage;
+var inspect = require('./format').inspect;
+
+var BitSet = require('./bitset').BitSet;
+var fmt = require('util').format;
+var PassThrough = require('stream').PassThrough;
+var IllegalOperationError = require('./error').IllegalOperationError;
+var stackCapture = require('./error').stackCapture;
+
+// High-water mark for channel write buffers, in 'objects' (which are
+// encoded frames as buffers).
+var DEFAULT_WRITE_HWM = 1024;
+// If all the frames of a message (method, properties, content) total
+// to less than this, copy them into a single buffer and write it all
+// at once. Note that this is less than the minimum frame size: if it
+// was greater, we might have to fragment the content.
+var SINGLE_CHUNK_THRESHOLD = 2048;
+
+class Connection extends EventEmitter {
+  constructor (underlying) {
+    super();
+
+    var stream = this.stream = wrapStream(underlying);
+    this.muxer = new Mux(stream);
+
+    // frames
+    this.rest = Buffer.alloc(0);
+    this.frameMax = constants.FRAME_MIN_SIZE;
+    this.sentSinceLastCheck = false;
+    this.recvSinceLastCheck = false;
+
+    this.expectSocketClose = false;
+    this.freeChannels = new BitSet();
+    this.channels = [{
+      channel: { accept: channel0(this) },
+      buffer: underlying
+    }];
+  }
+
+  // This changed between versions, as did the codec, methods, etc. AMQP
+  // 0-9-1 is fairly similar to 0.8, but better, and nothing implements
+  // 0.8 that doesn't implement 0-9-1. In other words, it doesn't make
+  // much sense to generalise here.
+  sendProtocolHeader () {
+    this.sendBytes(frame.PROTOCOL_HEADER);
+  }
+
+  /*
+    The frighteningly complicated opening protocol (spec section 2.2.4):
+
+       Client -> Server
+
+         protocol header ->
+           <- start
+         start-ok ->
+       .. next two zero or more times ..
+           <- secure
+         secure-ok ->
+           <- tune
+         tune-ok ->
+         open ->
+           <- open-ok
+
+  If I'm only supporting SASL's PLAIN mechanism (which I am for the time
+  being), it gets a bit easier since the server won't in general send
+  back a `secure`, it'll just send `tune` after the `start-ok`.
+  (SASL PLAIN: http://tools.ietf.org/html/rfc4616)
+
+  */
+  open (allFields, openCallback0) {
+    var self = this;
+    var openCallback = openCallback0 || function () { };
+
+    // This is where we'll put our negotiated values
+    var tunedOptions = Object.create(allFields);
+
+    function wait (k) {
+      self.step(function (err, frame) {
+        if (err !== null)
+          bail(err);
+        else if (frame.channel !== 0) {
+          bail(new Error(
+            fmt("Frame on channel != 0 during handshake: %s",
+              inspect(frame, false))));
+        }
+        else
+          k(frame);
+      });
+    }
+
+    function expect (Method, k) {
+      wait(function (frame) {
+        if (frame.id === Method)
+          k(frame);
+        else {
+          bail(new Error(
+            fmt("Expected %s; got %s",
+              methodName(Method), inspect(frame, false))));
+        }
+      });
+    }
+
+    function bail (err) {
+      openCallback(err);
+    }
+
+    function send (Method) {
+      // This can throw an exception if there's some problem with the
+      // options; e.g., something is a string instead of a number.
+      self.sendMethod(0, Method, tunedOptions);
+    }
+
+    function negotiate (server, desired) {
+      // We get sent values for channelMax, frameMax and heartbeat,
+      // which we may accept or lower (subject to a minimum for
+      // frameMax, but we'll leave that to the server to enforce). In
+      // all cases, `0` really means "no limit", or rather the highest
+      // value in the encoding, e.g., unsigned short for channelMax.
+      if (server === 0 || desired === 0) {
+        // i.e., whichever places a limit, if either
+        return Math.max(server, desired);
+      }
+      else {
+        return Math.min(server, desired);
+      }
+    }
+
+    function onStart (start) {
+      var mechanisms = start.fields.mechanisms.toString().split(' ');
+      if (mechanisms.indexOf(allFields.mechanism) < 0) {
+        bail(new Error(fmt('SASL mechanism %s is not provided by the server',
+          allFields.mechanism)));
+        return;
+      }
+      self.serverProperties = start.fields.serverProperties;
+      try {
+        send(defs.ConnectionStartOk);
+      } catch (err) {
+        bail(err);
+        return;
+      }
+      wait(afterStartOk);
+    }
+
+    function afterStartOk (reply) {
+      switch (reply.id) {
+        case defs.ConnectionSecure:
+          bail(new Error(
+            "Wasn't expecting to have to go through secure"));
+          break;
+        case defs.ConnectionClose:
+          bail(new Error(fmt("Handshake terminated by server: %s",
+            closeMsg(reply))));
+          break;
+        case defs.ConnectionTune:
+          var fields = reply.fields;
+          tunedOptions.frameMax =
+            negotiate(fields.frameMax, allFields.frameMax);
+          tunedOptions.channelMax =
+            negotiate(fields.channelMax, allFields.channelMax);
+          tunedOptions.heartbeat =
+            negotiate(fields.heartbeat, allFields.heartbeat);
+          try {
+            send(defs.ConnectionTuneOk);
+            send(defs.ConnectionOpen);
+          } catch (err) {
+            bail(err);
+            return;
+          }
+          expect(defs.ConnectionOpenOk, onOpenOk);
+          break;
+        default:
+          bail(new Error(
+            fmt("Expected connection.secure, connection.close, " +
+              "or connection.tune during handshake; got %s",
+              inspect(reply, false))));
+          break;
+      }
+    }
+
+    function onOpenOk (openOk) {
+      // Impose the maximum of the encoded value, if the negotiated
+      // value is zero, meaning "no, no limits"
+      self.channelMax = tunedOptions.channelMax || 0xffff;
+      self.frameMax = tunedOptions.frameMax || 0xffffffff;
+      // 0 means "no heartbeat", rather than "maximum period of
+      // heartbeating"
+      self.heartbeat = tunedOptions.heartbeat;
+      self.heartbeater = self.startHeartbeater();
+      self.accept = mainAccept;
+      succeed(openOk);
+    }
+
+    // If the server closes the connection, it's probably because of
+    // something we did
+    function endWhileOpening (err) {
+      bail(err || new Error('Socket closed abruptly ' +
+        'during opening handshake'));
+    }
+
+    this.stream.on('end', endWhileOpening);
+    this.stream.on('error', endWhileOpening);
+
+    function succeed (ok) {
+      self.stream.removeListener('end', endWhileOpening);
+      self.stream.removeListener('error', endWhileOpening);
+      self.stream.on('error', self.onSocketError.bind(self));
+      self.stream.on('end', self.onSocketError.bind(
+        self, new Error('Unexpected close')));
+      self.on('frameError', self.onSocketError.bind(self));
+      self.acceptLoop();
+      openCallback(null, ok);
+    }
+
+    // Now kick off the handshake by prompting the server
+    this.sendProtocolHeader();
+    expect(defs.ConnectionStart, onStart);
+  }
+
+  // Closing things: AMQP has a closing handshake that applies to
+  // closing both connects and channels. As the initiating party, I send
+  // Close, then ignore all frames until I see either CloseOK --
+  // which signifies that the other party has seen the Close and shut
+  // the connection or channel down, so it's fine to free resources; or
+  // Close, which means the other party also wanted to close the
+  // whatever, and I should send CloseOk so it can free resources,
+  // then go back to waiting for the CloseOk. If I receive a Close
+  // out of the blue, I should throw away any unsent frames (they will
+  // be ignored anyway) and send CloseOk, then clean up resources. In
+  // general, Close out of the blue signals an error (or a forced
+  // closure, which may as well be an error).
+  //
+  //  RUNNING [1] --- send Close ---> Closing [2] ---> recv Close --+
+  //     |                               |                         [3]
+  //     |                               +------ send CloseOk ------+
+  //  recv Close                   recv CloseOk
+  //     |                               |
+  //     V                               V
+  //  Ended [4] ---- send CloseOk ---> Closed [5]
+  //
+  // [1] All frames accepted; getting a Close frame from the server
+  // moves to Ended; client may initiate a close by sending Close
+  // itself.
+  // [2] Client has initiated a close; only CloseOk or (simulataneously
+  // sent) Close is accepted.
+  // [3] Simultaneous close
+  // [4] Server won't send any more frames; accept no more frames, send
+  // CloseOk.
+  // [5] Fully closed, client will send no more, server will send no
+  // more. Signal 'close' or 'error'.
+  //
+  // There are two signalling mechanisms used in the API. The first is
+  // that calling `close` will return a promise, that will either
+  // resolve once the connection or channel is cleanly shut down, or
+  // will reject if the shutdown times out.
+  //
+  // The second is the 'close' and 'error' events. These are
+  // emitted as above. The events will fire *before* promises are
+  // resolved.
+  // Close the connection without even giving a reason. Typical.
+  close (closeCallback) {
+    var k = closeCallback && function () { closeCallback(null); };
+    this.closeBecause("Cheers, thanks", constants.REPLY_SUCCESS, k);
+  }
+
+  // Close with a reason and a 'code'. I'm pretty sure RabbitMQ totally
+  // ignores these; maybe it logs them. The continuation will be invoked
+  // when the CloseOk has been received, and before the 'close' event.
+  closeBecause (reason, code, k) {
+    this.sendMethod(0, defs.ConnectionClose, {
+      replyText: reason,
+      replyCode: code,
+      methodId: 0, classId: 0
+    });
+    var s = stackCapture('closeBecause called: ' + reason);
+    this.toClosing(s, k);
+  }
+
+  closeWithError (reason, code, error) {
+    this.emit('error', error);
+    this.closeBecause(reason, code);
+  }
+
+  onSocketError (err) {
+    if (!this.expectSocketClose) {
+      // forestall any more calls to onSocketError, since we're signed
+      // up for `'error'` *and* `'end'`
+      this.expectSocketClose = true;
+      this.emit('error', err);
+      var s = stackCapture('Socket error');
+      this.toClosed(s, err);
+    }
+  }
+
+  // A close has been initiated. Repeat: a close has been initiated.
+  // This means we should not send more frames, anyway they will be
+  // ignored. We also have to shut down all the channels.
+  toClosing (capturedStack, k) {
+    var send = this.sendMethod.bind(this);
+
+    this.accept = function (f) {
+      if (f.id === defs.ConnectionCloseOk) {
+        if (k)
+          k();
+        var s = stackCapture('ConnectionCloseOk received');
+        this.toClosed(s, undefined);
+      }
+      else if (f.id === defs.ConnectionClose) {
+        send(0, defs.ConnectionCloseOk, {});
+      }
+      // else ignore frame
+    };
+    invalidateSend(this, 'Connection closing', capturedStack);
+  }
+
+  _closeChannels (capturedStack) {
+    for (var i = 1; i < this.channels.length; i++) {
+      var ch = this.channels[i];
+      if (ch !== null) {
+        ch.channel.toClosed(capturedStack); // %%% or with an error? not clear
+      }
+    }
+  }
+
+  // A close has been confirmed. Cease all communication.
+  toClosed (capturedStack, maybeErr) {
+    this._closeChannels(capturedStack);
+    var info = fmt('Connection closed (%s)',
+      (maybeErr) ? maybeErr.toString() : 'by client');
+    // Tidy up, invalidate enverything, dynamite the bridges.
+    invalidateSend(this, info, capturedStack);
+    this.accept = invalidOp(info, capturedStack);
+    this.close = function (cb) {
+      cb && cb(new IllegalOperationError(info, capturedStack));
+    };
+    if (this.heartbeater)
+      this.heartbeater.clear();
+    // This is certainly true now, if it wasn't before
+    this.expectSocketClose = true;
+    this.stream.end();
+    this.emit('close', maybeErr);
+  }
+
+  _updateSecret(newSecret, reason, cb) {
+    this.sendMethod(0, defs.ConnectionUpdateSecret, {
+      newSecret,
+      reason
+    });
+    this.once('update-secret-ok', cb);
+  }
+
+  // ===
+  startHeartbeater () {
+    if (this.heartbeat === 0)
+      return null;
+    else {
+      var self = this;
+      var hb = new Heart(this.heartbeat,
+        this.checkSend.bind(this),
+        this.checkRecv.bind(this));
+      hb.on('timeout', function () {
+        var hberr = new Error("Heartbeat timeout");
+        self.emit('error', hberr);
+        var s = stackCapture('Heartbeat timeout');
+        self.toClosed(s, hberr);
+      });
+      hb.on('beat', function () {
+        self.sendHeartbeat();
+      });
+      return hb;
+    }
+  }
+
+  // I use an array to keep track of the channels, rather than an
+  // object. The channel identifiers are numbers, and allocated by the
+  // connection. If I try to allocate low numbers when they are
+  // available (which I do, by looking from the start of the bitset),
+  // this ought to keep the array small, and out of 'sparse array
+  // storage'. I also set entries to null, rather than deleting them, in
+  // the expectation that the next channel allocation will fill the slot
+  // again rather than growing the array. See
+  // http://www.html5rocks.com/en/tutorials/speed/v8/
+  freshChannel (channel, options) {
+    var next = this.freeChannels.nextClearBit(1);
+    if (next < 0 || next > this.channelMax)
+      throw new Error("No channels left to allocate");
+    this.freeChannels.set(next);
+
+    var hwm = (options && options.highWaterMark) || DEFAULT_WRITE_HWM;
+    var writeBuffer = new PassThrough({
+      objectMode: true, highWaterMark: hwm
+    });
+    this.channels[next] = { channel: channel, buffer: writeBuffer };
+    writeBuffer.on('drain', function () {
+      channel.onBufferDrain();
+    });
+    this.muxer.pipeFrom(writeBuffer);
+    return next;
+  }
+
+  releaseChannel (channel) {
+    this.freeChannels.clear(channel);
+    var buffer = this.channels[channel].buffer;
+    buffer.end(); // will also cause it to be unpiped
+    this.channels[channel] = null;
+  }
+
+  acceptLoop () {
+    var self = this;
+
+    function go () {
+      try {
+        var f; while (f = self.recvFrame())
+          self.accept(f);
+      }
+      catch (e) {
+        self.emit('frameError', e);
+      }
+    }
+    self.stream.on('readable', go);
+    go();
+  }
+
+  step (cb) {
+    var self = this;
+    function recv () {
+      var f;
+      try {
+        f = self.recvFrame();
+      }
+      catch (e) {
+        cb(e, null);
+        return;
+      }
+      if (f)
+        cb(null, f);
+      else
+        self.stream.once('readable', recv);
+    }
+    recv();
+  }
+
+  checkSend () {
+    var check = this.sentSinceLastCheck;
+    this.sentSinceLastCheck = false;
+    return check;
+  }
+
+  checkRecv () {
+    var check = this.recvSinceLastCheck;
+    this.recvSinceLastCheck = false;
+    return check;
+  }
+
+  sendBytes (bytes) {
+    this.sentSinceLastCheck = true;
+    this.stream.write(bytes);
+  }
+
+  sendHeartbeat () {
+    return this.sendBytes(frame.HEARTBEAT_BUF);
+  }
+
+  sendMethod (channel, Method, fields) {
+    var frame = encodeMethod(Method, channel, fields);
+    this.sentSinceLastCheck = true;
+    var buffer = this.channels[channel].buffer;
+    return buffer.write(frame);
+  }
+
+  sendMessage (channel, Method, fields, Properties, props, content) {
+    if (!Buffer.isBuffer(content))
+      throw new TypeError('content is not a buffer');
+
+    var mframe = encodeMethod(Method, channel, fields);
+    var pframe = encodeProperties(Properties, channel,
+      content.length, props);
+    var buffer = this.channels[channel].buffer;
+    this.sentSinceLastCheck = true;
+
+    var methodHeaderLen = mframe.length + pframe.length;
+    var bodyLen = (content.length > 0) ?
+      content.length + FRAME_OVERHEAD : 0;
+    var allLen = methodHeaderLen + bodyLen;
+
+    if (allLen < SINGLE_CHUNK_THRESHOLD) {
+      // Use `allocUnsafe` to avoid excessive allocations and CPU usage
+      // from zeroing. The returned Buffer is not zeroed and so must be
+      // completely filled to be used safely.
+      // See https://github.com/amqp-node/amqplib/pull/695
+      var all = Buffer.allocUnsafe(allLen);
+      var offset = mframe.copy(all, 0);
+      offset += pframe.copy(all, offset);
+
+      if (bodyLen > 0)
+        makeBodyFrame(channel, content).copy(all, offset);
+      return buffer.write(all);
+    }
+    else {
+      if (methodHeaderLen < SINGLE_CHUNK_THRESHOLD) {
+        // Use `allocUnsafe` to avoid excessive allocations and CPU usage
+        // from zeroing. The returned Buffer is not zeroed and so must be
+        // completely filled to be used safely.
+        // See https://github.com/amqp-node/amqplib/pull/695
+        var both = Buffer.allocUnsafe(methodHeaderLen);
+        var offset = mframe.copy(both, 0);
+        pframe.copy(both, offset);
+        buffer.write(both);
+      }
+      else {
+        buffer.write(mframe);
+        buffer.write(pframe);
+      }
+      return this.sendContent(channel, content);
+    }
+  }
+
+  sendContent (channel, body) {
+    if (!Buffer.isBuffer(body)) {
+      throw new TypeError(fmt("Expected buffer; got %s", body));
+    }
+    var writeResult = true;
+    var buffer = this.channels[channel].buffer;
+
+    var maxBody = this.frameMax - FRAME_OVERHEAD;
+
+    for (var offset = 0; offset < body.length; offset += maxBody) {
+      var end = offset + maxBody;
+      var slice = (end > body.length) ? body.subarray(offset) : body.subarray(offset, end);
+      var bodyFrame = makeBodyFrame(channel, slice);
+      writeResult = buffer.write(bodyFrame);
+    }
+    this.sentSinceLastCheck = true;
+    return writeResult;
+  }
+
+  recvFrame () {
+    // %%% identifying invariants might help here?
+    var frame = parseFrame(this.rest, this.frameMax);
+
+    if (!frame) {
+      var incoming = this.stream.read();
+      if (incoming === null) {
+        return false;
+      }
+      else {
+        this.recvSinceLastCheck = true;
+        this.rest = Buffer.concat([this.rest, incoming]);
+        return this.recvFrame();
+      }
+    }
+    else {
+      this.rest = frame.rest;
+      return decodeFrame(frame);
+    }
+  }
+}
+
+// Usual frame accept mode
+function mainAccept(frame) {
+  var rec = this.channels[frame.channel];
+  if (rec) { return rec.channel.accept(frame); }
+  // NB CHANNEL_ERROR may not be right, but I don't know what is ..
+  else
+    this.closeWithError(
+      fmt('Frame on unknown channel %d', frame.channel),
+      constants.CHANNEL_ERROR,
+      new Error(fmt("Frame on unknown channel: %s",
+                    inspect(frame, false))));
+}
+
+// Handle anything that comes through on channel 0, that's the
+// connection control channel. This is only used once mainAccept is
+// installed as the frame handler, after the opening handshake.
+function channel0(connection) {
+  return function(f) {
+    // Once we get a 'close', we know 1. we'll get no more frames, and
+    // 2. anything we send except close, or close-ok, will be
+    // ignored. If we already sent 'close', this won't be invoked since
+    // we're already in closing mode; if we didn't well we're not going
+    // to send it now are we.
+    if (f === HEARTBEAT); // ignore; it's already counted as activity
+                          // on the socket, which is its purpose
+    else if (f.id === defs.ConnectionClose) {
+      // Oh. OK. I guess we're done here then.
+      connection.sendMethod(0, defs.ConnectionCloseOk, {});
+      var emsg = fmt('Connection closed: %s', closeMsg(f));
+      var s = stackCapture(emsg);
+      var e = new Error(emsg);
+      e.code = f.fields.replyCode;
+      if (isFatalError(e)) {
+        connection.emit('error', e);
+      }
+      connection.toClosed(s, e);
+    }
+    else if (f.id === defs.ConnectionBlocked) {
+      connection.emit('blocked', f.fields.reason);
+    }
+    else if (f.id === defs.ConnectionUnblocked) {
+      connection.emit('unblocked');
+    }
+    else if (f.id === defs.ConnectionUpdateSecretOk) {
+      connection.emit('update-secret-ok');
+    }
+    else {
+      connection.closeWithError(
+        fmt("Unexpected frame on channel 0"),
+        constants.UNEXPECTED_FRAME,
+        new Error(fmt("Unexpected frame on channel 0: %s",
+                      inspect(f, false))));
+    }
+  };
+}
+
+function invalidOp(msg, stack) {
+  return function() {
+    throw new IllegalOperationError(msg, stack);
+  };
+}
+
+function invalidateSend(conn, msg, stack) {
+  conn.sendMethod = conn.sendContent = conn.sendMessage =
+    invalidOp(msg, stack);
+}
+
+var encodeMethod = defs.encodeMethod;
+var encodeProperties = defs.encodeProperties;
+
+var FRAME_OVERHEAD = defs.FRAME_OVERHEAD;
+var makeBodyFrame = frame.makeBodyFrame;
+
+var parseFrame = frame.parseFrame;
+var decodeFrame = frame.decodeFrame;
+
+function wrapStream(s) {
+  if (s instanceof Duplex) return s;
+  else {
+    var ws = new Duplex();
+    ws.wrap(s); //wraps the readable side of things
+    ws._write = function(chunk, encoding, callback) {
+      return s.write(chunk, encoding, callback);
+    };
+    return ws;
+  }
+}
+
+function isFatalError(error) {
+  switch (error && error.code) {
+  case defs.constants.CONNECTION_FORCED:
+  case defs.constants.REPLY_SUCCESS:
+    return false;
+  default:
+    return true;
+  }
+}
+
+module.exports.Connection = Connection;
+module.exports.isFatalError = isFatalError;

+ 42 - 0
node_modules/amqplib/lib/credentials.js

@@ -0,0 +1,42 @@
+//
+//
+//
+
+// Different kind of credentials that can be supplied when opening a
+// connection, corresponding to SASL mechanisms There's only two
+// useful mechanisms that RabbitMQ implements:
+//  * PLAIN (send username and password in the plain)
+//  * EXTERNAL (assume the server will figure out who you are from
+//    context, i.e., your SSL certificate)
+var codec = require('./codec')
+
+module.exports.plain = function(user, passwd) {
+  return {
+    mechanism: 'PLAIN',
+    response: function() {
+      return Buffer.from(['', user, passwd].join(String.fromCharCode(0)))
+    },
+    username: user,
+    password: passwd
+  }
+}
+
+module.exports.amqplain = function(user, passwd) {
+  return {
+    mechanism: 'AMQPLAIN',
+    response: function() {
+      const buffer = Buffer.alloc(16384);
+      const size = codec.encodeTable(buffer, { LOGIN: user, PASSWORD: passwd}, 0);
+      return buffer.subarray(4, size);
+    },
+    username: user,
+    password: passwd
+  }
+}
+
+module.exports.external = function() {
+  return {
+    mechanism: 'EXTERNAL',
+    response: function() { return Buffer.from(''); }
+  }
+}

+ 5077 - 0
node_modules/amqplib/lib/defs.js

@@ -0,0 +1,5077 @@
+/** @preserve This file is generated by the script
+ * ../bin/generate-defs.js, which is not in general included in a
+ * distribution, but is available in the source repository e.g. at
+ * https://github.com/squaremo/amqp.node/
+ */
+"use strict";
+
+function decodeBasicQos(buffer) {
+  var val, offset = 0, fields = {
+    prefetchSize: void 0,
+    prefetchCount: void 0,
+    global: void 0
+  };
+  val = buffer.readUInt32BE(offset);
+  offset += 4;
+  fields.prefetchSize = val;
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.prefetchCount = val;
+  val = !!(1 & buffer[offset]);
+  fields.global = val;
+  return fields;
+}
+
+function encodeBasicQos(channel, fields) {
+  var offset = 0, val = null, bits = 0, buffer = Buffer.alloc(19);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3932170, 7);
+  offset = 11;
+  val = fields.prefetchSize;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'prefetchSize' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt32BE(val, offset);
+  offset += 4;
+  val = fields.prefetchCount;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'prefetchCount' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.global;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  buffer[offset] = bits;
+  offset++;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeBasicQosOk(buffer) {
+  return {};
+}
+
+function encodeBasicQosOk(channel, fields) {
+  var offset = 0, buffer = Buffer.alloc(12);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3932171, 7);
+  offset = 11;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeBasicConsume(buffer) {
+  var val, len, offset = 0, fields = {
+    ticket: void 0,
+    queue: void 0,
+    consumerTag: void 0,
+    noLocal: void 0,
+    noAck: void 0,
+    exclusive: void 0,
+    nowait: void 0,
+    arguments: void 0
+  };
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.ticket = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.queue = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.consumerTag = val;
+  val = !!(1 & buffer[offset]);
+  fields.noLocal = val;
+  val = !!(2 & buffer[offset]);
+  fields.noAck = val;
+  val = !!(4 & buffer[offset]);
+  fields.exclusive = val;
+  val = !!(8 & buffer[offset]);
+  fields.nowait = val;
+  offset++;
+  len = buffer.readUInt32BE(offset);
+  offset += 4;
+  val = decodeFields(buffer.subarray(offset, offset + len));
+  offset += len;
+  fields.arguments = val;
+  return fields;
+}
+
+function encodeBasicConsume(channel, fields) {
+  var len, offset = 0, val = null, bits = 0, varyingSize = 0, scratchOffset = 0;
+  val = fields.queue;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'queue' is the wrong type; must be a string (up to 255 chars)");
+  var queue_len = Buffer.byteLength(val, "utf8");
+  varyingSize += queue_len;
+  val = fields.consumerTag;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'consumerTag' is the wrong type; must be a string (up to 255 chars)");
+  var consumerTag_len = Buffer.byteLength(val, "utf8");
+  varyingSize += consumerTag_len;
+  val = fields.arguments;
+  if (void 0 === val) val = {}; else if ("object" != typeof val) throw new TypeError("Field 'arguments' is the wrong type; must be an object");
+  len = encodeTable(SCRATCH, val, scratchOffset);
+  var arguments_encoded = SCRATCH.slice(scratchOffset, scratchOffset + len);
+  scratchOffset += len;
+  varyingSize += arguments_encoded.length;
+  var buffer = Buffer.alloc(17 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3932180, 7);
+  offset = 11;
+  val = fields.ticket;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'ticket' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.queue;
+  void 0 === val && (val = "");
+  buffer[offset] = queue_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += queue_len;
+  val = fields.consumerTag;
+  void 0 === val && (val = "");
+  buffer[offset] = consumerTag_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += consumerTag_len;
+  val = fields.noLocal;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  val = fields.noAck;
+  void 0 === val && (val = !1);
+  val && (bits += 2);
+  val = fields.exclusive;
+  void 0 === val && (val = !1);
+  val && (bits += 4);
+  val = fields.nowait;
+  void 0 === val && (val = !1);
+  val && (bits += 8);
+  buffer[offset] = bits;
+  offset++;
+  bits = 0;
+  offset += arguments_encoded.copy(buffer, offset);
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeBasicConsumeOk(buffer) {
+  var val, len, offset = 0, fields = {
+    consumerTag: void 0
+  };
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.consumerTag = val;
+  return fields;
+}
+
+function encodeBasicConsumeOk(channel, fields) {
+  var offset = 0, val = null, varyingSize = 0;
+  val = fields.consumerTag;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'consumerTag'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'consumerTag' is the wrong type; must be a string (up to 255 chars)");
+  var consumerTag_len = Buffer.byteLength(val, "utf8");
+  varyingSize += consumerTag_len;
+  var buffer = Buffer.alloc(13 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3932181, 7);
+  offset = 11;
+  val = fields.consumerTag;
+  void 0 === val && (val = void 0);
+  buffer[offset] = consumerTag_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += consumerTag_len;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeBasicCancel(buffer) {
+  var val, len, offset = 0, fields = {
+    consumerTag: void 0,
+    nowait: void 0
+  };
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.consumerTag = val;
+  val = !!(1 & buffer[offset]);
+  fields.nowait = val;
+  return fields;
+}
+
+function encodeBasicCancel(channel, fields) {
+  var offset = 0, val = null, bits = 0, varyingSize = 0;
+  val = fields.consumerTag;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'consumerTag'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'consumerTag' is the wrong type; must be a string (up to 255 chars)");
+  var consumerTag_len = Buffer.byteLength(val, "utf8");
+  varyingSize += consumerTag_len;
+  var buffer = Buffer.alloc(14 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3932190, 7);
+  offset = 11;
+  val = fields.consumerTag;
+  void 0 === val && (val = void 0);
+  buffer[offset] = consumerTag_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += consumerTag_len;
+  val = fields.nowait;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  buffer[offset] = bits;
+  offset++;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeBasicCancelOk(buffer) {
+  var val, len, offset = 0, fields = {
+    consumerTag: void 0
+  };
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.consumerTag = val;
+  return fields;
+}
+
+function encodeBasicCancelOk(channel, fields) {
+  var offset = 0, val = null, varyingSize = 0;
+  val = fields.consumerTag;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'consumerTag'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'consumerTag' is the wrong type; must be a string (up to 255 chars)");
+  var consumerTag_len = Buffer.byteLength(val, "utf8");
+  varyingSize += consumerTag_len;
+  var buffer = Buffer.alloc(13 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3932191, 7);
+  offset = 11;
+  val = fields.consumerTag;
+  void 0 === val && (val = void 0);
+  buffer[offset] = consumerTag_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += consumerTag_len;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeBasicPublish(buffer) {
+  var val, len, offset = 0, fields = {
+    ticket: void 0,
+    exchange: void 0,
+    routingKey: void 0,
+    mandatory: void 0,
+    immediate: void 0
+  };
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.ticket = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.exchange = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.routingKey = val;
+  val = !!(1 & buffer[offset]);
+  fields.mandatory = val;
+  val = !!(2 & buffer[offset]);
+  fields.immediate = val;
+  return fields;
+}
+
+function encodeBasicPublish(channel, fields) {
+  var offset = 0, val = null, bits = 0, varyingSize = 0;
+  val = fields.exchange;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'exchange' is the wrong type; must be a string (up to 255 chars)");
+  var exchange_len = Buffer.byteLength(val, "utf8");
+  varyingSize += exchange_len;
+  val = fields.routingKey;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'routingKey' is the wrong type; must be a string (up to 255 chars)");
+  var routingKey_len = Buffer.byteLength(val, "utf8");
+  varyingSize += routingKey_len;
+  var buffer = Buffer.alloc(17 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3932200, 7);
+  offset = 11;
+  val = fields.ticket;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'ticket' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.exchange;
+  void 0 === val && (val = "");
+  buffer[offset] = exchange_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += exchange_len;
+  val = fields.routingKey;
+  void 0 === val && (val = "");
+  buffer[offset] = routingKey_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += routingKey_len;
+  val = fields.mandatory;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  val = fields.immediate;
+  void 0 === val && (val = !1);
+  val && (bits += 2);
+  buffer[offset] = bits;
+  offset++;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeBasicReturn(buffer) {
+  var val, len, offset = 0, fields = {
+    replyCode: void 0,
+    replyText: void 0,
+    exchange: void 0,
+    routingKey: void 0
+  };
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.replyCode = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.replyText = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.exchange = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.routingKey = val;
+  return fields;
+}
+
+function encodeBasicReturn(channel, fields) {
+  var offset = 0, val = null, varyingSize = 0;
+  val = fields.replyText;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'replyText' is the wrong type; must be a string (up to 255 chars)");
+  var replyText_len = Buffer.byteLength(val, "utf8");
+  varyingSize += replyText_len;
+  val = fields.exchange;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'exchange'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'exchange' is the wrong type; must be a string (up to 255 chars)");
+  var exchange_len = Buffer.byteLength(val, "utf8");
+  varyingSize += exchange_len;
+  val = fields.routingKey;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'routingKey'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'routingKey' is the wrong type; must be a string (up to 255 chars)");
+  var routingKey_len = Buffer.byteLength(val, "utf8");
+  varyingSize += routingKey_len;
+  var buffer = Buffer.alloc(17 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3932210, 7);
+  offset = 11;
+  val = fields.replyCode;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'replyCode'");
+  if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'replyCode' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.replyText;
+  void 0 === val && (val = "");
+  buffer[offset] = replyText_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += replyText_len;
+  val = fields.exchange;
+  void 0 === val && (val = void 0);
+  buffer[offset] = exchange_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += exchange_len;
+  val = fields.routingKey;
+  void 0 === val && (val = void 0);
+  buffer[offset] = routingKey_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += routingKey_len;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeBasicDeliver(buffer) {
+  var val, len, offset = 0, fields = {
+    consumerTag: void 0,
+    deliveryTag: void 0,
+    redelivered: void 0,
+    exchange: void 0,
+    routingKey: void 0
+  };
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.consumerTag = val;
+  val = ints.readUInt64BE(buffer, offset);
+  offset += 8;
+  fields.deliveryTag = val;
+  val = !!(1 & buffer[offset]);
+  fields.redelivered = val;
+  offset++;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.exchange = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.routingKey = val;
+  return fields;
+}
+
+function encodeBasicDeliver(channel, fields) {
+  var offset = 0, val = null, bits = 0, varyingSize = 0;
+  val = fields.consumerTag;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'consumerTag'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'consumerTag' is the wrong type; must be a string (up to 255 chars)");
+  var consumerTag_len = Buffer.byteLength(val, "utf8");
+  varyingSize += consumerTag_len;
+  val = fields.exchange;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'exchange'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'exchange' is the wrong type; must be a string (up to 255 chars)");
+  var exchange_len = Buffer.byteLength(val, "utf8");
+  varyingSize += exchange_len;
+  val = fields.routingKey;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'routingKey'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'routingKey' is the wrong type; must be a string (up to 255 chars)");
+  var routingKey_len = Buffer.byteLength(val, "utf8");
+  varyingSize += routingKey_len;
+  var buffer = Buffer.alloc(24 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3932220, 7);
+  offset = 11;
+  val = fields.consumerTag;
+  void 0 === val && (val = void 0);
+  buffer[offset] = consumerTag_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += consumerTag_len;
+  val = fields.deliveryTag;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'deliveryTag'");
+  if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'deliveryTag' is the wrong type; must be a number (but not NaN)");
+  ints.writeUInt64BE(buffer, val, offset);
+  offset += 8;
+  val = fields.redelivered;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  buffer[offset] = bits;
+  offset++;
+  bits = 0;
+  val = fields.exchange;
+  void 0 === val && (val = void 0);
+  buffer[offset] = exchange_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += exchange_len;
+  val = fields.routingKey;
+  void 0 === val && (val = void 0);
+  buffer[offset] = routingKey_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += routingKey_len;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeBasicGet(buffer) {
+  var val, len, offset = 0, fields = {
+    ticket: void 0,
+    queue: void 0,
+    noAck: void 0
+  };
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.ticket = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.queue = val;
+  val = !!(1 & buffer[offset]);
+  fields.noAck = val;
+  return fields;
+}
+
+function encodeBasicGet(channel, fields) {
+  var offset = 0, val = null, bits = 0, varyingSize = 0;
+  val = fields.queue;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'queue' is the wrong type; must be a string (up to 255 chars)");
+  var queue_len = Buffer.byteLength(val, "utf8");
+  varyingSize += queue_len;
+  var buffer = Buffer.alloc(16 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3932230, 7);
+  offset = 11;
+  val = fields.ticket;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'ticket' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.queue;
+  void 0 === val && (val = "");
+  buffer[offset] = queue_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += queue_len;
+  val = fields.noAck;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  buffer[offset] = bits;
+  offset++;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeBasicGetOk(buffer) {
+  var val, len, offset = 0, fields = {
+    deliveryTag: void 0,
+    redelivered: void 0,
+    exchange: void 0,
+    routingKey: void 0,
+    messageCount: void 0
+  };
+  val = ints.readUInt64BE(buffer, offset);
+  offset += 8;
+  fields.deliveryTag = val;
+  val = !!(1 & buffer[offset]);
+  fields.redelivered = val;
+  offset++;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.exchange = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.routingKey = val;
+  val = buffer.readUInt32BE(offset);
+  offset += 4;
+  fields.messageCount = val;
+  return fields;
+}
+
+function encodeBasicGetOk(channel, fields) {
+  var offset = 0, val = null, bits = 0, varyingSize = 0;
+  val = fields.exchange;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'exchange'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'exchange' is the wrong type; must be a string (up to 255 chars)");
+  var exchange_len = Buffer.byteLength(val, "utf8");
+  varyingSize += exchange_len;
+  val = fields.routingKey;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'routingKey'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'routingKey' is the wrong type; must be a string (up to 255 chars)");
+  var routingKey_len = Buffer.byteLength(val, "utf8");
+  varyingSize += routingKey_len;
+  var buffer = Buffer.alloc(27 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3932231, 7);
+  offset = 11;
+  val = fields.deliveryTag;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'deliveryTag'");
+  if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'deliveryTag' is the wrong type; must be a number (but not NaN)");
+  ints.writeUInt64BE(buffer, val, offset);
+  offset += 8;
+  val = fields.redelivered;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  buffer[offset] = bits;
+  offset++;
+  bits = 0;
+  val = fields.exchange;
+  void 0 === val && (val = void 0);
+  buffer[offset] = exchange_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += exchange_len;
+  val = fields.routingKey;
+  void 0 === val && (val = void 0);
+  buffer[offset] = routingKey_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += routingKey_len;
+  val = fields.messageCount;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'messageCount'");
+  if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'messageCount' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt32BE(val, offset);
+  offset += 4;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeBasicGetEmpty(buffer) {
+  var val, len, offset = 0, fields = {
+    clusterId: void 0
+  };
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.clusterId = val;
+  return fields;
+}
+
+function encodeBasicGetEmpty(channel, fields) {
+  var offset = 0, val = null, varyingSize = 0;
+  val = fields.clusterId;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'clusterId' is the wrong type; must be a string (up to 255 chars)");
+  var clusterId_len = Buffer.byteLength(val, "utf8");
+  varyingSize += clusterId_len;
+  var buffer = Buffer.alloc(13 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3932232, 7);
+  offset = 11;
+  val = fields.clusterId;
+  void 0 === val && (val = "");
+  buffer[offset] = clusterId_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += clusterId_len;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeBasicAck(buffer) {
+  var val, offset = 0, fields = {
+    deliveryTag: void 0,
+    multiple: void 0
+  };
+  val = ints.readUInt64BE(buffer, offset);
+  offset += 8;
+  fields.deliveryTag = val;
+  val = !!(1 & buffer[offset]);
+  fields.multiple = val;
+  return fields;
+}
+
+function encodeBasicAck(channel, fields) {
+  var offset = 0, val = null, bits = 0, buffer = Buffer.alloc(21);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3932240, 7);
+  offset = 11;
+  val = fields.deliveryTag;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'deliveryTag' is the wrong type; must be a number (but not NaN)");
+  ints.writeUInt64BE(buffer, val, offset);
+  offset += 8;
+  val = fields.multiple;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  buffer[offset] = bits;
+  offset++;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeBasicReject(buffer) {
+  var val, offset = 0, fields = {
+    deliveryTag: void 0,
+    requeue: void 0
+  };
+  val = ints.readUInt64BE(buffer, offset);
+  offset += 8;
+  fields.deliveryTag = val;
+  val = !!(1 & buffer[offset]);
+  fields.requeue = val;
+  return fields;
+}
+
+function encodeBasicReject(channel, fields) {
+  var offset = 0, val = null, bits = 0, buffer = Buffer.alloc(21);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3932250, 7);
+  offset = 11;
+  val = fields.deliveryTag;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'deliveryTag'");
+  if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'deliveryTag' is the wrong type; must be a number (but not NaN)");
+  ints.writeUInt64BE(buffer, val, offset);
+  offset += 8;
+  val = fields.requeue;
+  void 0 === val && (val = !0);
+  val && (bits += 1);
+  buffer[offset] = bits;
+  offset++;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeBasicRecoverAsync(buffer) {
+  var val, fields = {
+    requeue: void 0
+  };
+  val = !!(1 & buffer[0]);
+  fields.requeue = val;
+  return fields;
+}
+
+function encodeBasicRecoverAsync(channel, fields) {
+  var offset = 0, val = null, bits = 0, buffer = Buffer.alloc(13);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3932260, 7);
+  offset = 11;
+  val = fields.requeue;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  buffer[offset] = bits;
+  offset++;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeBasicRecover(buffer) {
+  var val, fields = {
+    requeue: void 0
+  };
+  val = !!(1 & buffer[0]);
+  fields.requeue = val;
+  return fields;
+}
+
+function encodeBasicRecover(channel, fields) {
+  var offset = 0, val = null, bits = 0, buffer = Buffer.alloc(13);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3932270, 7);
+  offset = 11;
+  val = fields.requeue;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  buffer[offset] = bits;
+  offset++;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeBasicRecoverOk(buffer) {
+  return {};
+}
+
+function encodeBasicRecoverOk(channel, fields) {
+  var offset = 0, buffer = Buffer.alloc(12);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3932271, 7);
+  offset = 11;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeBasicNack(buffer) {
+  var val, offset = 0, fields = {
+    deliveryTag: void 0,
+    multiple: void 0,
+    requeue: void 0
+  };
+  val = ints.readUInt64BE(buffer, offset);
+  offset += 8;
+  fields.deliveryTag = val;
+  val = !!(1 & buffer[offset]);
+  fields.multiple = val;
+  val = !!(2 & buffer[offset]);
+  fields.requeue = val;
+  return fields;
+}
+
+function encodeBasicNack(channel, fields) {
+  var offset = 0, val = null, bits = 0, buffer = Buffer.alloc(21);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3932280, 7);
+  offset = 11;
+  val = fields.deliveryTag;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'deliveryTag' is the wrong type; must be a number (but not NaN)");
+  ints.writeUInt64BE(buffer, val, offset);
+  offset += 8;
+  val = fields.multiple;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  val = fields.requeue;
+  void 0 === val && (val = !0);
+  val && (bits += 2);
+  buffer[offset] = bits;
+  offset++;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeConnectionStart(buffer) {
+  var val, len, offset = 0, fields = {
+    versionMajor: void 0,
+    versionMinor: void 0,
+    serverProperties: void 0,
+    mechanisms: void 0,
+    locales: void 0
+  };
+  val = buffer[offset];
+  offset++;
+  fields.versionMajor = val;
+  val = buffer[offset];
+  offset++;
+  fields.versionMinor = val;
+  len = buffer.readUInt32BE(offset);
+  offset += 4;
+  val = decodeFields(buffer.subarray(offset, offset + len));
+  offset += len;
+  fields.serverProperties = val;
+  len = buffer.readUInt32BE(offset);
+  offset += 4;
+  val = buffer.subarray(offset, offset + len);
+  offset += len;
+  fields.mechanisms = val;
+  len = buffer.readUInt32BE(offset);
+  offset += 4;
+  val = buffer.subarray(offset, offset + len);
+  offset += len;
+  fields.locales = val;
+  return fields;
+}
+
+function encodeConnectionStart(channel, fields) {
+  var len, offset = 0, val = null, varyingSize = 0, scratchOffset = 0;
+  val = fields.serverProperties;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'serverProperties'");
+  if ("object" != typeof val) throw new TypeError("Field 'serverProperties' is the wrong type; must be an object");
+  len = encodeTable(SCRATCH, val, scratchOffset);
+  var serverProperties_encoded = SCRATCH.slice(scratchOffset, scratchOffset + len);
+  scratchOffset += len;
+  varyingSize += serverProperties_encoded.length;
+  val = fields.mechanisms;
+  if (void 0 === val) val = Buffer.from("PLAIN"); else if (!Buffer.isBuffer(val)) throw new TypeError("Field 'mechanisms' is the wrong type; must be a Buffer");
+  varyingSize += val.length;
+  val = fields.locales;
+  if (void 0 === val) val = Buffer.from("en_US"); else if (!Buffer.isBuffer(val)) throw new TypeError("Field 'locales' is the wrong type; must be a Buffer");
+  varyingSize += val.length;
+  var buffer = Buffer.alloc(22 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(655370, 7);
+  offset = 11;
+  val = fields.versionMajor;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'versionMajor' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt8(val, offset);
+  offset++;
+  val = fields.versionMinor;
+  if (void 0 === val) val = 9; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'versionMinor' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt8(val, offset);
+  offset++;
+  offset += serverProperties_encoded.copy(buffer, offset);
+  val = fields.mechanisms;
+  void 0 === val && (val = Buffer.from("PLAIN"));
+  len = val.length;
+  buffer.writeUInt32BE(len, offset);
+  offset += 4;
+  val.copy(buffer, offset);
+  offset += len;
+  val = fields.locales;
+  void 0 === val && (val = Buffer.from("en_US"));
+  len = val.length;
+  buffer.writeUInt32BE(len, offset);
+  offset += 4;
+  val.copy(buffer, offset);
+  offset += len;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeConnectionStartOk(buffer) {
+  var val, len, offset = 0, fields = {
+    clientProperties: void 0,
+    mechanism: void 0,
+    response: void 0,
+    locale: void 0
+  };
+  len = buffer.readUInt32BE(offset);
+  offset += 4;
+  val = decodeFields(buffer.subarray(offset, offset + len));
+  offset += len;
+  fields.clientProperties = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.mechanism = val;
+  len = buffer.readUInt32BE(offset);
+  offset += 4;
+  val = buffer.subarray(offset, offset + len);
+  offset += len;
+  fields.response = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.locale = val;
+  return fields;
+}
+
+function encodeConnectionStartOk(channel, fields) {
+  var len, offset = 0, val = null, varyingSize = 0, scratchOffset = 0;
+  val = fields.clientProperties;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'clientProperties'");
+  if ("object" != typeof val) throw new TypeError("Field 'clientProperties' is the wrong type; must be an object");
+  len = encodeTable(SCRATCH, val, scratchOffset);
+  var clientProperties_encoded = SCRATCH.slice(scratchOffset, scratchOffset + len);
+  scratchOffset += len;
+  varyingSize += clientProperties_encoded.length;
+  val = fields.mechanism;
+  if (void 0 === val) val = "PLAIN"; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'mechanism' is the wrong type; must be a string (up to 255 chars)");
+  var mechanism_len = Buffer.byteLength(val, "utf8");
+  varyingSize += mechanism_len;
+  val = fields.response;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'response'");
+  if (!Buffer.isBuffer(val)) throw new TypeError("Field 'response' is the wrong type; must be a Buffer");
+  varyingSize += val.length;
+  val = fields.locale;
+  if (void 0 === val) val = "en_US"; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'locale' is the wrong type; must be a string (up to 255 chars)");
+  var locale_len = Buffer.byteLength(val, "utf8");
+  varyingSize += locale_len;
+  var buffer = Buffer.alloc(18 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(655371, 7);
+  offset = 11;
+  offset += clientProperties_encoded.copy(buffer, offset);
+  val = fields.mechanism;
+  void 0 === val && (val = "PLAIN");
+  buffer[offset] = mechanism_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += mechanism_len;
+  val = fields.response;
+  void 0 === val && (val = Buffer.from(void 0));
+  len = val.length;
+  buffer.writeUInt32BE(len, offset);
+  offset += 4;
+  val.copy(buffer, offset);
+  offset += len;
+  val = fields.locale;
+  void 0 === val && (val = "en_US");
+  buffer[offset] = locale_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += locale_len;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeConnectionSecure(buffer) {
+  var val, len, offset = 0, fields = {
+    challenge: void 0
+  };
+  len = buffer.readUInt32BE(offset);
+  offset += 4;
+  val = buffer.subarray(offset, offset + len);
+  offset += len;
+  fields.challenge = val;
+  return fields;
+}
+
+function encodeConnectionSecure(channel, fields) {
+  var len, offset = 0, val = null, varyingSize = 0;
+  val = fields.challenge;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'challenge'");
+  if (!Buffer.isBuffer(val)) throw new TypeError("Field 'challenge' is the wrong type; must be a Buffer");
+  varyingSize += val.length;
+  var buffer = Buffer.alloc(16 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(655380, 7);
+  offset = 11;
+  val = fields.challenge;
+  void 0 === val && (val = Buffer.from(void 0));
+  len = val.length;
+  buffer.writeUInt32BE(len, offset);
+  offset += 4;
+  val.copy(buffer, offset);
+  offset += len;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeConnectionSecureOk(buffer) {
+  var val, len, offset = 0, fields = {
+    response: void 0
+  };
+  len = buffer.readUInt32BE(offset);
+  offset += 4;
+  val = buffer.subarray(offset, offset + len);
+  offset += len;
+  fields.response = val;
+  return fields;
+}
+
+function encodeConnectionSecureOk(channel, fields) {
+  var len, offset = 0, val = null, varyingSize = 0;
+  val = fields.response;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'response'");
+  if (!Buffer.isBuffer(val)) throw new TypeError("Field 'response' is the wrong type; must be a Buffer");
+  varyingSize += val.length;
+  var buffer = Buffer.alloc(16 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(655381, 7);
+  offset = 11;
+  val = fields.response;
+  void 0 === val && (val = Buffer.from(void 0));
+  len = val.length;
+  buffer.writeUInt32BE(len, offset);
+  offset += 4;
+  val.copy(buffer, offset);
+  offset += len;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeConnectionTune(buffer) {
+  var val, offset = 0, fields = {
+    channelMax: void 0,
+    frameMax: void 0,
+    heartbeat: void 0
+  };
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.channelMax = val;
+  val = buffer.readUInt32BE(offset);
+  offset += 4;
+  fields.frameMax = val;
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.heartbeat = val;
+  return fields;
+}
+
+function encodeConnectionTune(channel, fields) {
+  var offset = 0, val = null, buffer = Buffer.alloc(20);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(655390, 7);
+  offset = 11;
+  val = fields.channelMax;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'channelMax' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.frameMax;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'frameMax' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt32BE(val, offset);
+  offset += 4;
+  val = fields.heartbeat;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'heartbeat' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeConnectionTuneOk(buffer) {
+  var val, offset = 0, fields = {
+    channelMax: void 0,
+    frameMax: void 0,
+    heartbeat: void 0
+  };
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.channelMax = val;
+  val = buffer.readUInt32BE(offset);
+  offset += 4;
+  fields.frameMax = val;
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.heartbeat = val;
+  return fields;
+}
+
+function encodeConnectionTuneOk(channel, fields) {
+  var offset = 0, val = null, buffer = Buffer.alloc(20);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(655391, 7);
+  offset = 11;
+  val = fields.channelMax;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'channelMax' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.frameMax;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'frameMax' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt32BE(val, offset);
+  offset += 4;
+  val = fields.heartbeat;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'heartbeat' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeConnectionOpen(buffer) {
+  var val, len, offset = 0, fields = {
+    virtualHost: void 0,
+    capabilities: void 0,
+    insist: void 0
+  };
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.virtualHost = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.capabilities = val;
+  val = !!(1 & buffer[offset]);
+  fields.insist = val;
+  return fields;
+}
+
+function encodeConnectionOpen(channel, fields) {
+  var offset = 0, val = null, bits = 0, varyingSize = 0;
+  val = fields.virtualHost;
+  if (void 0 === val) val = "/"; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'virtualHost' is the wrong type; must be a string (up to 255 chars)");
+  var virtualHost_len = Buffer.byteLength(val, "utf8");
+  varyingSize += virtualHost_len;
+  val = fields.capabilities;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'capabilities' is the wrong type; must be a string (up to 255 chars)");
+  var capabilities_len = Buffer.byteLength(val, "utf8");
+  varyingSize += capabilities_len;
+  var buffer = Buffer.alloc(15 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(655400, 7);
+  offset = 11;
+  val = fields.virtualHost;
+  void 0 === val && (val = "/");
+  buffer[offset] = virtualHost_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += virtualHost_len;
+  val = fields.capabilities;
+  void 0 === val && (val = "");
+  buffer[offset] = capabilities_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += capabilities_len;
+  val = fields.insist;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  buffer[offset] = bits;
+  offset++;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeConnectionOpenOk(buffer) {
+  var val, len, offset = 0, fields = {
+    knownHosts: void 0
+  };
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.knownHosts = val;
+  return fields;
+}
+
+function encodeConnectionOpenOk(channel, fields) {
+  var offset = 0, val = null, varyingSize = 0;
+  val = fields.knownHosts;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'knownHosts' is the wrong type; must be a string (up to 255 chars)");
+  var knownHosts_len = Buffer.byteLength(val, "utf8");
+  varyingSize += knownHosts_len;
+  var buffer = Buffer.alloc(13 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(655401, 7);
+  offset = 11;
+  val = fields.knownHosts;
+  void 0 === val && (val = "");
+  buffer[offset] = knownHosts_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += knownHosts_len;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeConnectionClose(buffer) {
+  var val, len, offset = 0, fields = {
+    replyCode: void 0,
+    replyText: void 0,
+    classId: void 0,
+    methodId: void 0
+  };
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.replyCode = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.replyText = val;
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.classId = val;
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.methodId = val;
+  return fields;
+}
+
+function encodeConnectionClose(channel, fields) {
+  var offset = 0, val = null, varyingSize = 0;
+  val = fields.replyText;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'replyText' is the wrong type; must be a string (up to 255 chars)");
+  var replyText_len = Buffer.byteLength(val, "utf8");
+  varyingSize += replyText_len;
+  var buffer = Buffer.alloc(19 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(655410, 7);
+  offset = 11;
+  val = fields.replyCode;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'replyCode'");
+  if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'replyCode' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.replyText;
+  void 0 === val && (val = "");
+  buffer[offset] = replyText_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += replyText_len;
+  val = fields.classId;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'classId'");
+  if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'classId' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.methodId;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'methodId'");
+  if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'methodId' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeConnectionCloseOk(buffer) {
+  return {};
+}
+
+function encodeConnectionCloseOk(channel, fields) {
+  var offset = 0, buffer = Buffer.alloc(12);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(655411, 7);
+  offset = 11;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeConnectionBlocked(buffer) {
+  var val, len, offset = 0, fields = {
+    reason: void 0
+  };
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.reason = val;
+  return fields;
+}
+
+function encodeConnectionBlocked(channel, fields) {
+  var offset = 0, val = null, varyingSize = 0;
+  val = fields.reason;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'reason' is the wrong type; must be a string (up to 255 chars)");
+  var reason_len = Buffer.byteLength(val, "utf8");
+  varyingSize += reason_len;
+  var buffer = Buffer.alloc(13 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(655420, 7);
+  offset = 11;
+  val = fields.reason;
+  void 0 === val && (val = "");
+  buffer[offset] = reason_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += reason_len;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeConnectionUnblocked(buffer) {
+  return {};
+}
+
+function encodeConnectionUnblocked(channel, fields) {
+  var offset = 0, buffer = Buffer.alloc(12);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(655421, 7);
+  offset = 11;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeConnectionUpdateSecret(buffer) {
+  var val, len, offset = 0, fields = {
+    newSecret: void 0,
+    reason: void 0
+  };
+  len = buffer.readUInt32BE(offset);
+  offset += 4;
+  val = buffer.subarray(offset, offset + len);
+  offset += len;
+  fields.newSecret = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.reason = val;
+  return fields;
+}
+
+function encodeConnectionUpdateSecret(channel, fields) {
+  var len, offset = 0, val = null, varyingSize = 0;
+  val = fields.newSecret;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'newSecret'");
+  if (!Buffer.isBuffer(val)) throw new TypeError("Field 'newSecret' is the wrong type; must be a Buffer");
+  varyingSize += val.length;
+  val = fields.reason;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'reason'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'reason' is the wrong type; must be a string (up to 255 chars)");
+  var reason_len = Buffer.byteLength(val, "utf8");
+  varyingSize += reason_len;
+  var buffer = Buffer.alloc(17 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(655430, 7);
+  offset = 11;
+  val = fields.newSecret;
+  void 0 === val && (val = Buffer.from(void 0));
+  len = val.length;
+  buffer.writeUInt32BE(len, offset);
+  offset += 4;
+  val.copy(buffer, offset);
+  offset += len;
+  val = fields.reason;
+  void 0 === val && (val = void 0);
+  buffer[offset] = reason_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += reason_len;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeConnectionUpdateSecretOk(buffer) {
+  return {};
+}
+
+function encodeConnectionUpdateSecretOk(channel, fields) {
+  var offset = 0, buffer = Buffer.alloc(12);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(655431, 7);
+  offset = 11;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeChannelOpen(buffer) {
+  var val, len, offset = 0, fields = {
+    outOfBand: void 0
+  };
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.outOfBand = val;
+  return fields;
+}
+
+function encodeChannelOpen(channel, fields) {
+  var offset = 0, val = null, varyingSize = 0;
+  val = fields.outOfBand;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'outOfBand' is the wrong type; must be a string (up to 255 chars)");
+  var outOfBand_len = Buffer.byteLength(val, "utf8");
+  varyingSize += outOfBand_len;
+  var buffer = Buffer.alloc(13 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(1310730, 7);
+  offset = 11;
+  val = fields.outOfBand;
+  void 0 === val && (val = "");
+  buffer[offset] = outOfBand_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += outOfBand_len;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeChannelOpenOk(buffer) {
+  var val, len, offset = 0, fields = {
+    channelId: void 0
+  };
+  len = buffer.readUInt32BE(offset);
+  offset += 4;
+  val = buffer.subarray(offset, offset + len);
+  offset += len;
+  fields.channelId = val;
+  return fields;
+}
+
+function encodeChannelOpenOk(channel, fields) {
+  var len, offset = 0, val = null, varyingSize = 0;
+  val = fields.channelId;
+  if (void 0 === val) val = Buffer.from(""); else if (!Buffer.isBuffer(val)) throw new TypeError("Field 'channelId' is the wrong type; must be a Buffer");
+  varyingSize += val.length;
+  var buffer = Buffer.alloc(16 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(1310731, 7);
+  offset = 11;
+  val = fields.channelId;
+  void 0 === val && (val = Buffer.from(""));
+  len = val.length;
+  buffer.writeUInt32BE(len, offset);
+  offset += 4;
+  val.copy(buffer, offset);
+  offset += len;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeChannelFlow(buffer) {
+  var val, fields = {
+    active: void 0
+  };
+  val = !!(1 & buffer[0]);
+  fields.active = val;
+  return fields;
+}
+
+function encodeChannelFlow(channel, fields) {
+  var offset = 0, val = null, bits = 0, buffer = Buffer.alloc(13);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(1310740, 7);
+  offset = 11;
+  val = fields.active;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'active'");
+  val && (bits += 1);
+  buffer[offset] = bits;
+  offset++;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeChannelFlowOk(buffer) {
+  var val, fields = {
+    active: void 0
+  };
+  val = !!(1 & buffer[0]);
+  fields.active = val;
+  return fields;
+}
+
+function encodeChannelFlowOk(channel, fields) {
+  var offset = 0, val = null, bits = 0, buffer = Buffer.alloc(13);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(1310741, 7);
+  offset = 11;
+  val = fields.active;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'active'");
+  val && (bits += 1);
+  buffer[offset] = bits;
+  offset++;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeChannelClose(buffer) {
+  var val, len, offset = 0, fields = {
+    replyCode: void 0,
+    replyText: void 0,
+    classId: void 0,
+    methodId: void 0
+  };
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.replyCode = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.replyText = val;
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.classId = val;
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.methodId = val;
+  return fields;
+}
+
+function encodeChannelClose(channel, fields) {
+  var offset = 0, val = null, varyingSize = 0;
+  val = fields.replyText;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'replyText' is the wrong type; must be a string (up to 255 chars)");
+  var replyText_len = Buffer.byteLength(val, "utf8");
+  varyingSize += replyText_len;
+  var buffer = Buffer.alloc(19 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(1310760, 7);
+  offset = 11;
+  val = fields.replyCode;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'replyCode'");
+  if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'replyCode' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.replyText;
+  void 0 === val && (val = "");
+  buffer[offset] = replyText_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += replyText_len;
+  val = fields.classId;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'classId'");
+  if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'classId' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.methodId;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'methodId'");
+  if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'methodId' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeChannelCloseOk(buffer) {
+  return {};
+}
+
+function encodeChannelCloseOk(channel, fields) {
+  var offset = 0, buffer = Buffer.alloc(12);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(1310761, 7);
+  offset = 11;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeAccessRequest(buffer) {
+  var val, len, offset = 0, fields = {
+    realm: void 0,
+    exclusive: void 0,
+    passive: void 0,
+    active: void 0,
+    write: void 0,
+    read: void 0
+  };
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.realm = val;
+  val = !!(1 & buffer[offset]);
+  fields.exclusive = val;
+  val = !!(2 & buffer[offset]);
+  fields.passive = val;
+  val = !!(4 & buffer[offset]);
+  fields.active = val;
+  val = !!(8 & buffer[offset]);
+  fields.write = val;
+  val = !!(16 & buffer[offset]);
+  fields.read = val;
+  return fields;
+}
+
+function encodeAccessRequest(channel, fields) {
+  var offset = 0, val = null, bits = 0, varyingSize = 0;
+  val = fields.realm;
+  if (void 0 === val) val = "/data"; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'realm' is the wrong type; must be a string (up to 255 chars)");
+  var realm_len = Buffer.byteLength(val, "utf8");
+  varyingSize += realm_len;
+  var buffer = Buffer.alloc(14 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(1966090, 7);
+  offset = 11;
+  val = fields.realm;
+  void 0 === val && (val = "/data");
+  buffer[offset] = realm_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += realm_len;
+  val = fields.exclusive;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  val = fields.passive;
+  void 0 === val && (val = !0);
+  val && (bits += 2);
+  val = fields.active;
+  void 0 === val && (val = !0);
+  val && (bits += 4);
+  val = fields.write;
+  void 0 === val && (val = !0);
+  val && (bits += 8);
+  val = fields.read;
+  void 0 === val && (val = !0);
+  val && (bits += 16);
+  buffer[offset] = bits;
+  offset++;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeAccessRequestOk(buffer) {
+  var val, offset = 0, fields = {
+    ticket: void 0
+  };
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.ticket = val;
+  return fields;
+}
+
+function encodeAccessRequestOk(channel, fields) {
+  var offset = 0, val = null, buffer = Buffer.alloc(14);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(1966091, 7);
+  offset = 11;
+  val = fields.ticket;
+  if (void 0 === val) val = 1; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'ticket' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeExchangeDeclare(buffer) {
+  var val, len, offset = 0, fields = {
+    ticket: void 0,
+    exchange: void 0,
+    type: void 0,
+    passive: void 0,
+    durable: void 0,
+    autoDelete: void 0,
+    internal: void 0,
+    nowait: void 0,
+    arguments: void 0
+  };
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.ticket = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.exchange = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.type = val;
+  val = !!(1 & buffer[offset]);
+  fields.passive = val;
+  val = !!(2 & buffer[offset]);
+  fields.durable = val;
+  val = !!(4 & buffer[offset]);
+  fields.autoDelete = val;
+  val = !!(8 & buffer[offset]);
+  fields.internal = val;
+  val = !!(16 & buffer[offset]);
+  fields.nowait = val;
+  offset++;
+  len = buffer.readUInt32BE(offset);
+  offset += 4;
+  val = decodeFields(buffer.subarray(offset, offset + len));
+  offset += len;
+  fields.arguments = val;
+  return fields;
+}
+
+function encodeExchangeDeclare(channel, fields) {
+  var len, offset = 0, val = null, bits = 0, varyingSize = 0, scratchOffset = 0;
+  val = fields.exchange;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'exchange'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'exchange' is the wrong type; must be a string (up to 255 chars)");
+  var exchange_len = Buffer.byteLength(val, "utf8");
+  varyingSize += exchange_len;
+  val = fields.type;
+  if (void 0 === val) val = "direct"; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'type' is the wrong type; must be a string (up to 255 chars)");
+  var type_len = Buffer.byteLength(val, "utf8");
+  varyingSize += type_len;
+  val = fields.arguments;
+  if (void 0 === val) val = {}; else if ("object" != typeof val) throw new TypeError("Field 'arguments' is the wrong type; must be an object");
+  len = encodeTable(SCRATCH, val, scratchOffset);
+  var arguments_encoded = SCRATCH.slice(scratchOffset, scratchOffset + len);
+  scratchOffset += len;
+  varyingSize += arguments_encoded.length;
+  var buffer = Buffer.alloc(17 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(2621450, 7);
+  offset = 11;
+  val = fields.ticket;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'ticket' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.exchange;
+  void 0 === val && (val = void 0);
+  buffer[offset] = exchange_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += exchange_len;
+  val = fields.type;
+  void 0 === val && (val = "direct");
+  buffer[offset] = type_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += type_len;
+  val = fields.passive;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  val = fields.durable;
+  void 0 === val && (val = !1);
+  val && (bits += 2);
+  val = fields.autoDelete;
+  void 0 === val && (val = !1);
+  val && (bits += 4);
+  val = fields.internal;
+  void 0 === val && (val = !1);
+  val && (bits += 8);
+  val = fields.nowait;
+  void 0 === val && (val = !1);
+  val && (bits += 16);
+  buffer[offset] = bits;
+  offset++;
+  bits = 0;
+  offset += arguments_encoded.copy(buffer, offset);
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeExchangeDeclareOk(buffer) {
+  return {};
+}
+
+function encodeExchangeDeclareOk(channel, fields) {
+  var offset = 0, buffer = Buffer.alloc(12);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(2621451, 7);
+  offset = 11;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeExchangeDelete(buffer) {
+  var val, len, offset = 0, fields = {
+    ticket: void 0,
+    exchange: void 0,
+    ifUnused: void 0,
+    nowait: void 0
+  };
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.ticket = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.exchange = val;
+  val = !!(1 & buffer[offset]);
+  fields.ifUnused = val;
+  val = !!(2 & buffer[offset]);
+  fields.nowait = val;
+  return fields;
+}
+
+function encodeExchangeDelete(channel, fields) {
+  var offset = 0, val = null, bits = 0, varyingSize = 0;
+  val = fields.exchange;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'exchange'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'exchange' is the wrong type; must be a string (up to 255 chars)");
+  var exchange_len = Buffer.byteLength(val, "utf8");
+  varyingSize += exchange_len;
+  var buffer = Buffer.alloc(16 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(2621460, 7);
+  offset = 11;
+  val = fields.ticket;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'ticket' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.exchange;
+  void 0 === val && (val = void 0);
+  buffer[offset] = exchange_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += exchange_len;
+  val = fields.ifUnused;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  val = fields.nowait;
+  void 0 === val && (val = !1);
+  val && (bits += 2);
+  buffer[offset] = bits;
+  offset++;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeExchangeDeleteOk(buffer) {
+  return {};
+}
+
+function encodeExchangeDeleteOk(channel, fields) {
+  var offset = 0, buffer = Buffer.alloc(12);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(2621461, 7);
+  offset = 11;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeExchangeBind(buffer) {
+  var val, len, offset = 0, fields = {
+    ticket: void 0,
+    destination: void 0,
+    source: void 0,
+    routingKey: void 0,
+    nowait: void 0,
+    arguments: void 0
+  };
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.ticket = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.destination = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.source = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.routingKey = val;
+  val = !!(1 & buffer[offset]);
+  fields.nowait = val;
+  offset++;
+  len = buffer.readUInt32BE(offset);
+  offset += 4;
+  val = decodeFields(buffer.subarray(offset, offset + len));
+  offset += len;
+  fields.arguments = val;
+  return fields;
+}
+
+function encodeExchangeBind(channel, fields) {
+  var len, offset = 0, val = null, bits = 0, varyingSize = 0, scratchOffset = 0;
+  val = fields.destination;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'destination'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'destination' is the wrong type; must be a string (up to 255 chars)");
+  var destination_len = Buffer.byteLength(val, "utf8");
+  varyingSize += destination_len;
+  val = fields.source;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'source'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'source' is the wrong type; must be a string (up to 255 chars)");
+  var source_len = Buffer.byteLength(val, "utf8");
+  varyingSize += source_len;
+  val = fields.routingKey;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'routingKey' is the wrong type; must be a string (up to 255 chars)");
+  var routingKey_len = Buffer.byteLength(val, "utf8");
+  varyingSize += routingKey_len;
+  val = fields.arguments;
+  if (void 0 === val) val = {}; else if ("object" != typeof val) throw new TypeError("Field 'arguments' is the wrong type; must be an object");
+  len = encodeTable(SCRATCH, val, scratchOffset);
+  var arguments_encoded = SCRATCH.slice(scratchOffset, scratchOffset + len);
+  scratchOffset += len;
+  varyingSize += arguments_encoded.length;
+  var buffer = Buffer.alloc(18 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(2621470, 7);
+  offset = 11;
+  val = fields.ticket;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'ticket' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.destination;
+  void 0 === val && (val = void 0);
+  buffer[offset] = destination_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += destination_len;
+  val = fields.source;
+  void 0 === val && (val = void 0);
+  buffer[offset] = source_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += source_len;
+  val = fields.routingKey;
+  void 0 === val && (val = "");
+  buffer[offset] = routingKey_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += routingKey_len;
+  val = fields.nowait;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  buffer[offset] = bits;
+  offset++;
+  bits = 0;
+  offset += arguments_encoded.copy(buffer, offset);
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeExchangeBindOk(buffer) {
+  return {};
+}
+
+function encodeExchangeBindOk(channel, fields) {
+  var offset = 0, buffer = Buffer.alloc(12);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(2621471, 7);
+  offset = 11;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeExchangeUnbind(buffer) {
+  var val, len, offset = 0, fields = {
+    ticket: void 0,
+    destination: void 0,
+    source: void 0,
+    routingKey: void 0,
+    nowait: void 0,
+    arguments: void 0
+  };
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.ticket = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.destination = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.source = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.routingKey = val;
+  val = !!(1 & buffer[offset]);
+  fields.nowait = val;
+  offset++;
+  len = buffer.readUInt32BE(offset);
+  offset += 4;
+  val = decodeFields(buffer.subarray(offset, offset + len));
+  offset += len;
+  fields.arguments = val;
+  return fields;
+}
+
+function encodeExchangeUnbind(channel, fields) {
+  var len, offset = 0, val = null, bits = 0, varyingSize = 0, scratchOffset = 0;
+  val = fields.destination;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'destination'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'destination' is the wrong type; must be a string (up to 255 chars)");
+  var destination_len = Buffer.byteLength(val, "utf8");
+  varyingSize += destination_len;
+  val = fields.source;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'source'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'source' is the wrong type; must be a string (up to 255 chars)");
+  var source_len = Buffer.byteLength(val, "utf8");
+  varyingSize += source_len;
+  val = fields.routingKey;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'routingKey' is the wrong type; must be a string (up to 255 chars)");
+  var routingKey_len = Buffer.byteLength(val, "utf8");
+  varyingSize += routingKey_len;
+  val = fields.arguments;
+  if (void 0 === val) val = {}; else if ("object" != typeof val) throw new TypeError("Field 'arguments' is the wrong type; must be an object");
+  len = encodeTable(SCRATCH, val, scratchOffset);
+  var arguments_encoded = SCRATCH.slice(scratchOffset, scratchOffset + len);
+  scratchOffset += len;
+  varyingSize += arguments_encoded.length;
+  var buffer = Buffer.alloc(18 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(2621480, 7);
+  offset = 11;
+  val = fields.ticket;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'ticket' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.destination;
+  void 0 === val && (val = void 0);
+  buffer[offset] = destination_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += destination_len;
+  val = fields.source;
+  void 0 === val && (val = void 0);
+  buffer[offset] = source_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += source_len;
+  val = fields.routingKey;
+  void 0 === val && (val = "");
+  buffer[offset] = routingKey_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += routingKey_len;
+  val = fields.nowait;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  buffer[offset] = bits;
+  offset++;
+  bits = 0;
+  offset += arguments_encoded.copy(buffer, offset);
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeExchangeUnbindOk(buffer) {
+  return {};
+}
+
+function encodeExchangeUnbindOk(channel, fields) {
+  var offset = 0, buffer = Buffer.alloc(12);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(2621491, 7);
+  offset = 11;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeQueueDeclare(buffer) {
+  var val, len, offset = 0, fields = {
+    ticket: void 0,
+    queue: void 0,
+    passive: void 0,
+    durable: void 0,
+    exclusive: void 0,
+    autoDelete: void 0,
+    nowait: void 0,
+    arguments: void 0
+  };
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.ticket = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.queue = val;
+  val = !!(1 & buffer[offset]);
+  fields.passive = val;
+  val = !!(2 & buffer[offset]);
+  fields.durable = val;
+  val = !!(4 & buffer[offset]);
+  fields.exclusive = val;
+  val = !!(8 & buffer[offset]);
+  fields.autoDelete = val;
+  val = !!(16 & buffer[offset]);
+  fields.nowait = val;
+  offset++;
+  len = buffer.readUInt32BE(offset);
+  offset += 4;
+  val = decodeFields(buffer.subarray(offset, offset + len));
+  offset += len;
+  fields.arguments = val;
+  return fields;
+}
+
+function encodeQueueDeclare(channel, fields) {
+  var len, offset = 0, val = null, bits = 0, varyingSize = 0, scratchOffset = 0;
+  val = fields.queue;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'queue' is the wrong type; must be a string (up to 255 chars)");
+  var queue_len = Buffer.byteLength(val, "utf8");
+  varyingSize += queue_len;
+  val = fields.arguments;
+  if (void 0 === val) val = {}; else if ("object" != typeof val) throw new TypeError("Field 'arguments' is the wrong type; must be an object");
+  len = encodeTable(SCRATCH, val, scratchOffset);
+  var arguments_encoded = SCRATCH.slice(scratchOffset, scratchOffset + len);
+  scratchOffset += len;
+  varyingSize += arguments_encoded.length;
+  var buffer = Buffer.alloc(16 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3276810, 7);
+  offset = 11;
+  val = fields.ticket;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'ticket' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.queue;
+  void 0 === val && (val = "");
+  buffer[offset] = queue_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += queue_len;
+  val = fields.passive;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  val = fields.durable;
+  void 0 === val && (val = !1);
+  val && (bits += 2);
+  val = fields.exclusive;
+  void 0 === val && (val = !1);
+  val && (bits += 4);
+  val = fields.autoDelete;
+  void 0 === val && (val = !1);
+  val && (bits += 8);
+  val = fields.nowait;
+  void 0 === val && (val = !1);
+  val && (bits += 16);
+  buffer[offset] = bits;
+  offset++;
+  bits = 0;
+  offset += arguments_encoded.copy(buffer, offset);
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeQueueDeclareOk(buffer) {
+  var val, len, offset = 0, fields = {
+    queue: void 0,
+    messageCount: void 0,
+    consumerCount: void 0
+  };
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.queue = val;
+  val = buffer.readUInt32BE(offset);
+  offset += 4;
+  fields.messageCount = val;
+  val = buffer.readUInt32BE(offset);
+  offset += 4;
+  fields.consumerCount = val;
+  return fields;
+}
+
+function encodeQueueDeclareOk(channel, fields) {
+  var offset = 0, val = null, varyingSize = 0;
+  val = fields.queue;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'queue'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'queue' is the wrong type; must be a string (up to 255 chars)");
+  var queue_len = Buffer.byteLength(val, "utf8");
+  varyingSize += queue_len;
+  var buffer = Buffer.alloc(21 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3276811, 7);
+  offset = 11;
+  val = fields.queue;
+  void 0 === val && (val = void 0);
+  buffer[offset] = queue_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += queue_len;
+  val = fields.messageCount;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'messageCount'");
+  if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'messageCount' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt32BE(val, offset);
+  offset += 4;
+  val = fields.consumerCount;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'consumerCount'");
+  if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'consumerCount' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt32BE(val, offset);
+  offset += 4;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeQueueBind(buffer) {
+  var val, len, offset = 0, fields = {
+    ticket: void 0,
+    queue: void 0,
+    exchange: void 0,
+    routingKey: void 0,
+    nowait: void 0,
+    arguments: void 0
+  };
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.ticket = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.queue = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.exchange = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.routingKey = val;
+  val = !!(1 & buffer[offset]);
+  fields.nowait = val;
+  offset++;
+  len = buffer.readUInt32BE(offset);
+  offset += 4;
+  val = decodeFields(buffer.subarray(offset, offset + len));
+  offset += len;
+  fields.arguments = val;
+  return fields;
+}
+
+function encodeQueueBind(channel, fields) {
+  var len, offset = 0, val = null, bits = 0, varyingSize = 0, scratchOffset = 0;
+  val = fields.queue;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'queue' is the wrong type; must be a string (up to 255 chars)");
+  var queue_len = Buffer.byteLength(val, "utf8");
+  varyingSize += queue_len;
+  val = fields.exchange;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'exchange'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'exchange' is the wrong type; must be a string (up to 255 chars)");
+  var exchange_len = Buffer.byteLength(val, "utf8");
+  varyingSize += exchange_len;
+  val = fields.routingKey;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'routingKey' is the wrong type; must be a string (up to 255 chars)");
+  var routingKey_len = Buffer.byteLength(val, "utf8");
+  varyingSize += routingKey_len;
+  val = fields.arguments;
+  if (void 0 === val) val = {}; else if ("object" != typeof val) throw new TypeError("Field 'arguments' is the wrong type; must be an object");
+  len = encodeTable(SCRATCH, val, scratchOffset);
+  var arguments_encoded = SCRATCH.slice(scratchOffset, scratchOffset + len);
+  scratchOffset += len;
+  varyingSize += arguments_encoded.length;
+  var buffer = Buffer.alloc(18 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3276820, 7);
+  offset = 11;
+  val = fields.ticket;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'ticket' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.queue;
+  void 0 === val && (val = "");
+  buffer[offset] = queue_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += queue_len;
+  val = fields.exchange;
+  void 0 === val && (val = void 0);
+  buffer[offset] = exchange_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += exchange_len;
+  val = fields.routingKey;
+  void 0 === val && (val = "");
+  buffer[offset] = routingKey_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += routingKey_len;
+  val = fields.nowait;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  buffer[offset] = bits;
+  offset++;
+  bits = 0;
+  offset += arguments_encoded.copy(buffer, offset);
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeQueueBindOk(buffer) {
+  return {};
+}
+
+function encodeQueueBindOk(channel, fields) {
+  var offset = 0, buffer = Buffer.alloc(12);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3276821, 7);
+  offset = 11;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeQueuePurge(buffer) {
+  var val, len, offset = 0, fields = {
+    ticket: void 0,
+    queue: void 0,
+    nowait: void 0
+  };
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.ticket = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.queue = val;
+  val = !!(1 & buffer[offset]);
+  fields.nowait = val;
+  return fields;
+}
+
+function encodeQueuePurge(channel, fields) {
+  var offset = 0, val = null, bits = 0, varyingSize = 0;
+  val = fields.queue;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'queue' is the wrong type; must be a string (up to 255 chars)");
+  var queue_len = Buffer.byteLength(val, "utf8");
+  varyingSize += queue_len;
+  var buffer = Buffer.alloc(16 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3276830, 7);
+  offset = 11;
+  val = fields.ticket;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'ticket' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.queue;
+  void 0 === val && (val = "");
+  buffer[offset] = queue_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += queue_len;
+  val = fields.nowait;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  buffer[offset] = bits;
+  offset++;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeQueuePurgeOk(buffer) {
+  var val, offset = 0, fields = {
+    messageCount: void 0
+  };
+  val = buffer.readUInt32BE(offset);
+  offset += 4;
+  fields.messageCount = val;
+  return fields;
+}
+
+function encodeQueuePurgeOk(channel, fields) {
+  var offset = 0, val = null, buffer = Buffer.alloc(16);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3276831, 7);
+  offset = 11;
+  val = fields.messageCount;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'messageCount'");
+  if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'messageCount' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt32BE(val, offset);
+  offset += 4;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeQueueDelete(buffer) {
+  var val, len, offset = 0, fields = {
+    ticket: void 0,
+    queue: void 0,
+    ifUnused: void 0,
+    ifEmpty: void 0,
+    nowait: void 0
+  };
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.ticket = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.queue = val;
+  val = !!(1 & buffer[offset]);
+  fields.ifUnused = val;
+  val = !!(2 & buffer[offset]);
+  fields.ifEmpty = val;
+  val = !!(4 & buffer[offset]);
+  fields.nowait = val;
+  return fields;
+}
+
+function encodeQueueDelete(channel, fields) {
+  var offset = 0, val = null, bits = 0, varyingSize = 0;
+  val = fields.queue;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'queue' is the wrong type; must be a string (up to 255 chars)");
+  var queue_len = Buffer.byteLength(val, "utf8");
+  varyingSize += queue_len;
+  var buffer = Buffer.alloc(16 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3276840, 7);
+  offset = 11;
+  val = fields.ticket;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'ticket' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.queue;
+  void 0 === val && (val = "");
+  buffer[offset] = queue_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += queue_len;
+  val = fields.ifUnused;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  val = fields.ifEmpty;
+  void 0 === val && (val = !1);
+  val && (bits += 2);
+  val = fields.nowait;
+  void 0 === val && (val = !1);
+  val && (bits += 4);
+  buffer[offset] = bits;
+  offset++;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeQueueDeleteOk(buffer) {
+  var val, offset = 0, fields = {
+    messageCount: void 0
+  };
+  val = buffer.readUInt32BE(offset);
+  offset += 4;
+  fields.messageCount = val;
+  return fields;
+}
+
+function encodeQueueDeleteOk(channel, fields) {
+  var offset = 0, val = null, buffer = Buffer.alloc(16);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3276841, 7);
+  offset = 11;
+  val = fields.messageCount;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'messageCount'");
+  if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'messageCount' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt32BE(val, offset);
+  offset += 4;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeQueueUnbind(buffer) {
+  var val, len, offset = 0, fields = {
+    ticket: void 0,
+    queue: void 0,
+    exchange: void 0,
+    routingKey: void 0,
+    arguments: void 0
+  };
+  val = buffer.readUInt16BE(offset);
+  offset += 2;
+  fields.ticket = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.queue = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.exchange = val;
+  len = buffer.readUInt8(offset);
+  offset++;
+  val = buffer.toString("utf8", offset, offset + len);
+  offset += len;
+  fields.routingKey = val;
+  len = buffer.readUInt32BE(offset);
+  offset += 4;
+  val = decodeFields(buffer.subarray(offset, offset + len));
+  offset += len;
+  fields.arguments = val;
+  return fields;
+}
+
+function encodeQueueUnbind(channel, fields) {
+  var len, offset = 0, val = null, varyingSize = 0, scratchOffset = 0;
+  val = fields.queue;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'queue' is the wrong type; must be a string (up to 255 chars)");
+  var queue_len = Buffer.byteLength(val, "utf8");
+  varyingSize += queue_len;
+  val = fields.exchange;
+  if (void 0 === val) throw new Error("Missing value for mandatory field 'exchange'");
+  if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'exchange' is the wrong type; must be a string (up to 255 chars)");
+  var exchange_len = Buffer.byteLength(val, "utf8");
+  varyingSize += exchange_len;
+  val = fields.routingKey;
+  if (void 0 === val) val = ""; else if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'routingKey' is the wrong type; must be a string (up to 255 chars)");
+  var routingKey_len = Buffer.byteLength(val, "utf8");
+  varyingSize += routingKey_len;
+  val = fields.arguments;
+  if (void 0 === val) val = {}; else if ("object" != typeof val) throw new TypeError("Field 'arguments' is the wrong type; must be an object");
+  len = encodeTable(SCRATCH, val, scratchOffset);
+  var arguments_encoded = SCRATCH.slice(scratchOffset, scratchOffset + len);
+  scratchOffset += len;
+  varyingSize += arguments_encoded.length;
+  var buffer = Buffer.alloc(17 + varyingSize);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3276850, 7);
+  offset = 11;
+  val = fields.ticket;
+  if (void 0 === val) val = 0; else if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'ticket' is the wrong type; must be a number (but not NaN)");
+  buffer.writeUInt16BE(val, offset);
+  offset += 2;
+  val = fields.queue;
+  void 0 === val && (val = "");
+  buffer[offset] = queue_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += queue_len;
+  val = fields.exchange;
+  void 0 === val && (val = void 0);
+  buffer[offset] = exchange_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += exchange_len;
+  val = fields.routingKey;
+  void 0 === val && (val = "");
+  buffer[offset] = routingKey_len;
+  offset++;
+  buffer.write(val, offset, "utf8");
+  offset += routingKey_len;
+  offset += arguments_encoded.copy(buffer, offset);
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeQueueUnbindOk(buffer) {
+  return {};
+}
+
+function encodeQueueUnbindOk(channel, fields) {
+  var offset = 0, buffer = Buffer.alloc(12);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3276851, 7);
+  offset = 11;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeTxSelect(buffer) {
+  return {};
+}
+
+function encodeTxSelect(channel, fields) {
+  var offset = 0, buffer = Buffer.alloc(12);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(5898250, 7);
+  offset = 11;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeTxSelectOk(buffer) {
+  return {};
+}
+
+function encodeTxSelectOk(channel, fields) {
+  var offset = 0, buffer = Buffer.alloc(12);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(5898251, 7);
+  offset = 11;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeTxCommit(buffer) {
+  return {};
+}
+
+function encodeTxCommit(channel, fields) {
+  var offset = 0, buffer = Buffer.alloc(12);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(5898260, 7);
+  offset = 11;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeTxCommitOk(buffer) {
+  return {};
+}
+
+function encodeTxCommitOk(channel, fields) {
+  var offset = 0, buffer = Buffer.alloc(12);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(5898261, 7);
+  offset = 11;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeTxRollback(buffer) {
+  return {};
+}
+
+function encodeTxRollback(channel, fields) {
+  var offset = 0, buffer = Buffer.alloc(12);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(5898270, 7);
+  offset = 11;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeTxRollbackOk(buffer) {
+  return {};
+}
+
+function encodeTxRollbackOk(channel, fields) {
+  var offset = 0, buffer = Buffer.alloc(12);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(5898271, 7);
+  offset = 11;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeConfirmSelect(buffer) {
+  var val, fields = {
+    nowait: void 0
+  };
+  val = !!(1 & buffer[0]);
+  fields.nowait = val;
+  return fields;
+}
+
+function encodeConfirmSelect(channel, fields) {
+  var offset = 0, val = null, bits = 0, buffer = Buffer.alloc(13);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(5570570, 7);
+  offset = 11;
+  val = fields.nowait;
+  void 0 === val && (val = !1);
+  val && (bits += 1);
+  buffer[offset] = bits;
+  offset++;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function decodeConfirmSelectOk(buffer) {
+  return {};
+}
+
+function encodeConfirmSelectOk(channel, fields) {
+  var offset = 0, buffer = Buffer.alloc(12);
+  buffer[0] = 1;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(5570571, 7);
+  offset = 11;
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  return buffer;
+}
+
+function encodeBasicProperties(channel, size, fields) {
+  var val, len, offset = 0, flags = 0, scratchOffset = 0, varyingSize = 0;
+  val = fields.contentType;
+  if (void 0 != val) {
+    if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'contentType' is the wrong type; must be a string (up to 255 chars)");
+    var contentType_len = Buffer.byteLength(val, "utf8");
+    varyingSize += 1;
+    varyingSize += contentType_len;
+  }
+  val = fields.contentEncoding;
+  if (void 0 != val) {
+    if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'contentEncoding' is the wrong type; must be a string (up to 255 chars)");
+    var contentEncoding_len = Buffer.byteLength(val, "utf8");
+    varyingSize += 1;
+    varyingSize += contentEncoding_len;
+  }
+  val = fields.headers;
+  if (void 0 != val) {
+    if ("object" != typeof val) throw new TypeError("Field 'headers' is the wrong type; must be an object");
+    len = encodeTable(SCRATCH, val, scratchOffset);
+    var headers_encoded = SCRATCH.slice(scratchOffset, scratchOffset + len);
+    scratchOffset += len;
+    varyingSize += headers_encoded.length;
+  }
+  val = fields.deliveryMode;
+  if (void 0 != val) {
+    if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'deliveryMode' is the wrong type; must be a number (but not NaN)");
+    varyingSize += 1;
+  }
+  val = fields.priority;
+  if (void 0 != val) {
+    if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'priority' is the wrong type; must be a number (but not NaN)");
+    varyingSize += 1;
+  }
+  val = fields.correlationId;
+  if (void 0 != val) {
+    if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'correlationId' is the wrong type; must be a string (up to 255 chars)");
+    var correlationId_len = Buffer.byteLength(val, "utf8");
+    varyingSize += 1;
+    varyingSize += correlationId_len;
+  }
+  val = fields.replyTo;
+  if (void 0 != val) {
+    if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'replyTo' is the wrong type; must be a string (up to 255 chars)");
+    var replyTo_len = Buffer.byteLength(val, "utf8");
+    varyingSize += 1;
+    varyingSize += replyTo_len;
+  }
+  val = fields.expiration;
+  if (void 0 != val) {
+    if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'expiration' is the wrong type; must be a string (up to 255 chars)");
+    var expiration_len = Buffer.byteLength(val, "utf8");
+    varyingSize += 1;
+    varyingSize += expiration_len;
+  }
+  val = fields.messageId;
+  if (void 0 != val) {
+    if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'messageId' is the wrong type; must be a string (up to 255 chars)");
+    var messageId_len = Buffer.byteLength(val, "utf8");
+    varyingSize += 1;
+    varyingSize += messageId_len;
+  }
+  val = fields.timestamp;
+  if (void 0 != val) {
+    if ("number" != typeof val || isNaN(val)) throw new TypeError("Field 'timestamp' is the wrong type; must be a number (but not NaN)");
+    varyingSize += 8;
+  }
+  val = fields.type;
+  if (void 0 != val) {
+    if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'type' is the wrong type; must be a string (up to 255 chars)");
+    var type_len = Buffer.byteLength(val, "utf8");
+    varyingSize += 1;
+    varyingSize += type_len;
+  }
+  val = fields.userId;
+  if (void 0 != val) {
+    if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'userId' is the wrong type; must be a string (up to 255 chars)");
+    var userId_len = Buffer.byteLength(val, "utf8");
+    varyingSize += 1;
+    varyingSize += userId_len;
+  }
+  val = fields.appId;
+  if (void 0 != val) {
+    if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'appId' is the wrong type; must be a string (up to 255 chars)");
+    var appId_len = Buffer.byteLength(val, "utf8");
+    varyingSize += 1;
+    varyingSize += appId_len;
+  }
+  val = fields.clusterId;
+  if (void 0 != val) {
+    if (!("string" == typeof val && Buffer.byteLength(val) < 256)) throw new TypeError("Field 'clusterId' is the wrong type; must be a string (up to 255 chars)");
+    var clusterId_len = Buffer.byteLength(val, "utf8");
+    varyingSize += 1;
+    varyingSize += clusterId_len;
+  }
+  var buffer = Buffer.alloc(22 + varyingSize);
+  buffer[0] = 2;
+  buffer.writeUInt16BE(channel, 1);
+  buffer.writeUInt32BE(3932160, 7);
+  ints.writeUInt64BE(buffer, size, 11);
+  flags = 0;
+  offset = 21;
+  val = fields.contentType;
+  if (void 0 != val) {
+    flags += 32768;
+    buffer[offset] = contentType_len;
+    offset++;
+    buffer.write(val, offset, "utf8");
+    offset += contentType_len;
+  }
+  val = fields.contentEncoding;
+  if (void 0 != val) {
+    flags += 16384;
+    buffer[offset] = contentEncoding_len;
+    offset++;
+    buffer.write(val, offset, "utf8");
+    offset += contentEncoding_len;
+  }
+  val = fields.headers;
+  if (void 0 != val) {
+    flags += 8192;
+    offset += headers_encoded.copy(buffer, offset);
+  }
+  val = fields.deliveryMode;
+  if (void 0 != val) {
+    flags += 4096;
+    buffer.writeUInt8(val, offset);
+    offset++;
+  }
+  val = fields.priority;
+  if (void 0 != val) {
+    flags += 2048;
+    buffer.writeUInt8(val, offset);
+    offset++;
+  }
+  val = fields.correlationId;
+  if (void 0 != val) {
+    flags += 1024;
+    buffer[offset] = correlationId_len;
+    offset++;
+    buffer.write(val, offset, "utf8");
+    offset += correlationId_len;
+  }
+  val = fields.replyTo;
+  if (void 0 != val) {
+    flags += 512;
+    buffer[offset] = replyTo_len;
+    offset++;
+    buffer.write(val, offset, "utf8");
+    offset += replyTo_len;
+  }
+  val = fields.expiration;
+  if (void 0 != val) {
+    flags += 256;
+    buffer[offset] = expiration_len;
+    offset++;
+    buffer.write(val, offset, "utf8");
+    offset += expiration_len;
+  }
+  val = fields.messageId;
+  if (void 0 != val) {
+    flags += 128;
+    buffer[offset] = messageId_len;
+    offset++;
+    buffer.write(val, offset, "utf8");
+    offset += messageId_len;
+  }
+  val = fields.timestamp;
+  if (void 0 != val) {
+    flags += 64;
+    ints.writeUInt64BE(buffer, val, offset);
+    offset += 8;
+  }
+  val = fields.type;
+  if (void 0 != val) {
+    flags += 32;
+    buffer[offset] = type_len;
+    offset++;
+    buffer.write(val, offset, "utf8");
+    offset += type_len;
+  }
+  val = fields.userId;
+  if (void 0 != val) {
+    flags += 16;
+    buffer[offset] = userId_len;
+    offset++;
+    buffer.write(val, offset, "utf8");
+    offset += userId_len;
+  }
+  val = fields.appId;
+  if (void 0 != val) {
+    flags += 8;
+    buffer[offset] = appId_len;
+    offset++;
+    buffer.write(val, offset, "utf8");
+    offset += appId_len;
+  }
+  val = fields.clusterId;
+  if (void 0 != val) {
+    flags += 4;
+    buffer[offset] = clusterId_len;
+    offset++;
+    buffer.write(val, offset, "utf8");
+    offset += clusterId_len;
+  }
+  buffer[offset] = 206;
+  buffer.writeUInt32BE(offset - 7, 3);
+  buffer.writeUInt16BE(flags, 19);
+  return buffer.subarray(0, offset + 1);
+}
+
+function decodeBasicProperties(buffer) {
+  var flags, val, len, offset = 2;
+  flags = buffer.readUInt16BE(0);
+  if (0 === flags) return {};
+  var fields = {
+    contentType: void 0,
+    contentEncoding: void 0,
+    headers: void 0,
+    deliveryMode: void 0,
+    priority: void 0,
+    correlationId: void 0,
+    replyTo: void 0,
+    expiration: void 0,
+    messageId: void 0,
+    timestamp: void 0,
+    type: void 0,
+    userId: void 0,
+    appId: void 0,
+    clusterId: void 0
+  };
+  if (32768 & flags) {
+    len = buffer.readUInt8(offset);
+    offset++;
+    val = buffer.toString("utf8", offset, offset + len);
+    offset += len;
+    fields.contentType = val;
+  }
+  if (16384 & flags) {
+    len = buffer.readUInt8(offset);
+    offset++;
+    val = buffer.toString("utf8", offset, offset + len);
+    offset += len;
+    fields.contentEncoding = val;
+  }
+  if (8192 & flags) {
+    len = buffer.readUInt32BE(offset);
+    offset += 4;
+    val = decodeFields(buffer.subarray(offset, offset + len));
+    offset += len;
+    fields.headers = val;
+  }
+  if (4096 & flags) {
+    val = buffer[offset];
+    offset++;
+    fields.deliveryMode = val;
+  }
+  if (2048 & flags) {
+    val = buffer[offset];
+    offset++;
+    fields.priority = val;
+  }
+  if (1024 & flags) {
+    len = buffer.readUInt8(offset);
+    offset++;
+    val = buffer.toString("utf8", offset, offset + len);
+    offset += len;
+    fields.correlationId = val;
+  }
+  if (512 & flags) {
+    len = buffer.readUInt8(offset);
+    offset++;
+    val = buffer.toString("utf8", offset, offset + len);
+    offset += len;
+    fields.replyTo = val;
+  }
+  if (256 & flags) {
+    len = buffer.readUInt8(offset);
+    offset++;
+    val = buffer.toString("utf8", offset, offset + len);
+    offset += len;
+    fields.expiration = val;
+  }
+  if (128 & flags) {
+    len = buffer.readUInt8(offset);
+    offset++;
+    val = buffer.toString("utf8", offset, offset + len);
+    offset += len;
+    fields.messageId = val;
+  }
+  if (64 & flags) {
+    val = ints.readUInt64BE(buffer, offset);
+    offset += 8;
+    fields.timestamp = val;
+  }
+  if (32 & flags) {
+    len = buffer.readUInt8(offset);
+    offset++;
+    val = buffer.toString("utf8", offset, offset + len);
+    offset += len;
+    fields.type = val;
+  }
+  if (16 & flags) {
+    len = buffer.readUInt8(offset);
+    offset++;
+    val = buffer.toString("utf8", offset, offset + len);
+    offset += len;
+    fields.userId = val;
+  }
+  if (8 & flags) {
+    len = buffer.readUInt8(offset);
+    offset++;
+    val = buffer.toString("utf8", offset, offset + len);
+    offset += len;
+    fields.appId = val;
+  }
+  if (4 & flags) {
+    len = buffer.readUInt8(offset);
+    offset++;
+    val = buffer.toString("utf8", offset, offset + len);
+    offset += len;
+    fields.clusterId = val;
+  }
+  return fields;
+}
+
+var codec = require("./codec"), ints = require("buffer-more-ints"), encodeTable = codec.encodeTable, decodeFields = codec.decodeFields, SCRATCH = Buffer.alloc(65536), EMPTY_OBJECT = Object.freeze({});
+
+module.exports.constants = {
+  FRAME_METHOD: 1,
+  FRAME_HEADER: 2,
+  FRAME_BODY: 3,
+  FRAME_HEARTBEAT: 8,
+  FRAME_MIN_SIZE: 4096,
+  FRAME_END: 206,
+  REPLY_SUCCESS: 200,
+  CONTENT_TOO_LARGE: 311,
+  NO_ROUTE: 312,
+  NO_CONSUMERS: 313,
+  ACCESS_REFUSED: 403,
+  NOT_FOUND: 404,
+  RESOURCE_LOCKED: 405,
+  PRECONDITION_FAILED: 406,
+  CONNECTION_FORCED: 320,
+  INVALID_PATH: 402,
+  FRAME_ERROR: 501,
+  SYNTAX_ERROR: 502,
+  COMMAND_INVALID: 503,
+  CHANNEL_ERROR: 504,
+  UNEXPECTED_FRAME: 505,
+  RESOURCE_ERROR: 506,
+  NOT_ALLOWED: 530,
+  NOT_IMPLEMENTED: 540,
+  INTERNAL_ERROR: 541
+};
+
+module.exports.constant_strs = {
+  "1": "FRAME-METHOD",
+  "2": "FRAME-HEADER",
+  "3": "FRAME-BODY",
+  "8": "FRAME-HEARTBEAT",
+  "200": "REPLY-SUCCESS",
+  "206": "FRAME-END",
+  "311": "CONTENT-TOO-LARGE",
+  "312": "NO-ROUTE",
+  "313": "NO-CONSUMERS",
+  "320": "CONNECTION-FORCED",
+  "402": "INVALID-PATH",
+  "403": "ACCESS-REFUSED",
+  "404": "NOT-FOUND",
+  "405": "RESOURCE-LOCKED",
+  "406": "PRECONDITION-FAILED",
+  "501": "FRAME-ERROR",
+  "502": "SYNTAX-ERROR",
+  "503": "COMMAND-INVALID",
+  "504": "CHANNEL-ERROR",
+  "505": "UNEXPECTED-FRAME",
+  "506": "RESOURCE-ERROR",
+  "530": "NOT-ALLOWED",
+  "540": "NOT-IMPLEMENTED",
+  "541": "INTERNAL-ERROR",
+  "4096": "FRAME-MIN-SIZE"
+};
+
+module.exports.FRAME_OVERHEAD = 8;
+
+module.exports.decode = function(id, buf) {
+  switch (id) {
+   case 3932170:
+    return decodeBasicQos(buf);
+
+   case 3932171:
+    return decodeBasicQosOk(buf);
+
+   case 3932180:
+    return decodeBasicConsume(buf);
+
+   case 3932181:
+    return decodeBasicConsumeOk(buf);
+
+   case 3932190:
+    return decodeBasicCancel(buf);
+
+   case 3932191:
+    return decodeBasicCancelOk(buf);
+
+   case 3932200:
+    return decodeBasicPublish(buf);
+
+   case 3932210:
+    return decodeBasicReturn(buf);
+
+   case 3932220:
+    return decodeBasicDeliver(buf);
+
+   case 3932230:
+    return decodeBasicGet(buf);
+
+   case 3932231:
+    return decodeBasicGetOk(buf);
+
+   case 3932232:
+    return decodeBasicGetEmpty(buf);
+
+   case 3932240:
+    return decodeBasicAck(buf);
+
+   case 3932250:
+    return decodeBasicReject(buf);
+
+   case 3932260:
+    return decodeBasicRecoverAsync(buf);
+
+   case 3932270:
+    return decodeBasicRecover(buf);
+
+   case 3932271:
+    return decodeBasicRecoverOk(buf);
+
+   case 3932280:
+    return decodeBasicNack(buf);
+
+   case 655370:
+    return decodeConnectionStart(buf);
+
+   case 655371:
+    return decodeConnectionStartOk(buf);
+
+   case 655380:
+    return decodeConnectionSecure(buf);
+
+   case 655381:
+    return decodeConnectionSecureOk(buf);
+
+   case 655390:
+    return decodeConnectionTune(buf);
+
+   case 655391:
+    return decodeConnectionTuneOk(buf);
+
+   case 655400:
+    return decodeConnectionOpen(buf);
+
+   case 655401:
+    return decodeConnectionOpenOk(buf);
+
+   case 655410:
+    return decodeConnectionClose(buf);
+
+   case 655411:
+    return decodeConnectionCloseOk(buf);
+
+   case 655420:
+    return decodeConnectionBlocked(buf);
+
+   case 655421:
+    return decodeConnectionUnblocked(buf);
+
+   case 655430:
+    return decodeConnectionUpdateSecret(buf);
+
+   case 655431:
+    return decodeConnectionUpdateSecretOk(buf);
+
+   case 1310730:
+    return decodeChannelOpen(buf);
+
+   case 1310731:
+    return decodeChannelOpenOk(buf);
+
+   case 1310740:
+    return decodeChannelFlow(buf);
+
+   case 1310741:
+    return decodeChannelFlowOk(buf);
+
+   case 1310760:
+    return decodeChannelClose(buf);
+
+   case 1310761:
+    return decodeChannelCloseOk(buf);
+
+   case 1966090:
+    return decodeAccessRequest(buf);
+
+   case 1966091:
+    return decodeAccessRequestOk(buf);
+
+   case 2621450:
+    return decodeExchangeDeclare(buf);
+
+   case 2621451:
+    return decodeExchangeDeclareOk(buf);
+
+   case 2621460:
+    return decodeExchangeDelete(buf);
+
+   case 2621461:
+    return decodeExchangeDeleteOk(buf);
+
+   case 2621470:
+    return decodeExchangeBind(buf);
+
+   case 2621471:
+    return decodeExchangeBindOk(buf);
+
+   case 2621480:
+    return decodeExchangeUnbind(buf);
+
+   case 2621491:
+    return decodeExchangeUnbindOk(buf);
+
+   case 3276810:
+    return decodeQueueDeclare(buf);
+
+   case 3276811:
+    return decodeQueueDeclareOk(buf);
+
+   case 3276820:
+    return decodeQueueBind(buf);
+
+   case 3276821:
+    return decodeQueueBindOk(buf);
+
+   case 3276830:
+    return decodeQueuePurge(buf);
+
+   case 3276831:
+    return decodeQueuePurgeOk(buf);
+
+   case 3276840:
+    return decodeQueueDelete(buf);
+
+   case 3276841:
+    return decodeQueueDeleteOk(buf);
+
+   case 3276850:
+    return decodeQueueUnbind(buf);
+
+   case 3276851:
+    return decodeQueueUnbindOk(buf);
+
+   case 5898250:
+    return decodeTxSelect(buf);
+
+   case 5898251:
+    return decodeTxSelectOk(buf);
+
+   case 5898260:
+    return decodeTxCommit(buf);
+
+   case 5898261:
+    return decodeTxCommitOk(buf);
+
+   case 5898270:
+    return decodeTxRollback(buf);
+
+   case 5898271:
+    return decodeTxRollbackOk(buf);
+
+   case 5570570:
+    return decodeConfirmSelect(buf);
+
+   case 5570571:
+    return decodeConfirmSelectOk(buf);
+
+   case 60:
+    return decodeBasicProperties(buf);
+
+   default:
+    throw new Error("Unknown class/method ID");
+  }
+};
+
+module.exports.encodeMethod = function(id, channel, fields) {
+  switch (id) {
+   case 3932170:
+    return encodeBasicQos(channel, fields);
+
+   case 3932171:
+    return encodeBasicQosOk(channel, fields);
+
+   case 3932180:
+    return encodeBasicConsume(channel, fields);
+
+   case 3932181:
+    return encodeBasicConsumeOk(channel, fields);
+
+   case 3932190:
+    return encodeBasicCancel(channel, fields);
+
+   case 3932191:
+    return encodeBasicCancelOk(channel, fields);
+
+   case 3932200:
+    return encodeBasicPublish(channel, fields);
+
+   case 3932210:
+    return encodeBasicReturn(channel, fields);
+
+   case 3932220:
+    return encodeBasicDeliver(channel, fields);
+
+   case 3932230:
+    return encodeBasicGet(channel, fields);
+
+   case 3932231:
+    return encodeBasicGetOk(channel, fields);
+
+   case 3932232:
+    return encodeBasicGetEmpty(channel, fields);
+
+   case 3932240:
+    return encodeBasicAck(channel, fields);
+
+   case 3932250:
+    return encodeBasicReject(channel, fields);
+
+   case 3932260:
+    return encodeBasicRecoverAsync(channel, fields);
+
+   case 3932270:
+    return encodeBasicRecover(channel, fields);
+
+   case 3932271:
+    return encodeBasicRecoverOk(channel, fields);
+
+   case 3932280:
+    return encodeBasicNack(channel, fields);
+
+   case 655370:
+    return encodeConnectionStart(channel, fields);
+
+   case 655371:
+    return encodeConnectionStartOk(channel, fields);
+
+   case 655380:
+    return encodeConnectionSecure(channel, fields);
+
+   case 655381:
+    return encodeConnectionSecureOk(channel, fields);
+
+   case 655390:
+    return encodeConnectionTune(channel, fields);
+
+   case 655391:
+    return encodeConnectionTuneOk(channel, fields);
+
+   case 655400:
+    return encodeConnectionOpen(channel, fields);
+
+   case 655401:
+    return encodeConnectionOpenOk(channel, fields);
+
+   case 655410:
+    return encodeConnectionClose(channel, fields);
+
+   case 655411:
+    return encodeConnectionCloseOk(channel, fields);
+
+   case 655420:
+    return encodeConnectionBlocked(channel, fields);
+
+   case 655421:
+    return encodeConnectionUnblocked(channel, fields);
+
+   case 655430:
+    return encodeConnectionUpdateSecret(channel, fields);
+
+   case 655431:
+    return encodeConnectionUpdateSecretOk(channel, fields);
+
+   case 1310730:
+    return encodeChannelOpen(channel, fields);
+
+   case 1310731:
+    return encodeChannelOpenOk(channel, fields);
+
+   case 1310740:
+    return encodeChannelFlow(channel, fields);
+
+   case 1310741:
+    return encodeChannelFlowOk(channel, fields);
+
+   case 1310760:
+    return encodeChannelClose(channel, fields);
+
+   case 1310761:
+    return encodeChannelCloseOk(channel, fields);
+
+   case 1966090:
+    return encodeAccessRequest(channel, fields);
+
+   case 1966091:
+    return encodeAccessRequestOk(channel, fields);
+
+   case 2621450:
+    return encodeExchangeDeclare(channel, fields);
+
+   case 2621451:
+    return encodeExchangeDeclareOk(channel, fields);
+
+   case 2621460:
+    return encodeExchangeDelete(channel, fields);
+
+   case 2621461:
+    return encodeExchangeDeleteOk(channel, fields);
+
+   case 2621470:
+    return encodeExchangeBind(channel, fields);
+
+   case 2621471:
+    return encodeExchangeBindOk(channel, fields);
+
+   case 2621480:
+    return encodeExchangeUnbind(channel, fields);
+
+   case 2621491:
+    return encodeExchangeUnbindOk(channel, fields);
+
+   case 3276810:
+    return encodeQueueDeclare(channel, fields);
+
+   case 3276811:
+    return encodeQueueDeclareOk(channel, fields);
+
+   case 3276820:
+    return encodeQueueBind(channel, fields);
+
+   case 3276821:
+    return encodeQueueBindOk(channel, fields);
+
+   case 3276830:
+    return encodeQueuePurge(channel, fields);
+
+   case 3276831:
+    return encodeQueuePurgeOk(channel, fields);
+
+   case 3276840:
+    return encodeQueueDelete(channel, fields);
+
+   case 3276841:
+    return encodeQueueDeleteOk(channel, fields);
+
+   case 3276850:
+    return encodeQueueUnbind(channel, fields);
+
+   case 3276851:
+    return encodeQueueUnbindOk(channel, fields);
+
+   case 5898250:
+    return encodeTxSelect(channel, fields);
+
+   case 5898251:
+    return encodeTxSelectOk(channel, fields);
+
+   case 5898260:
+    return encodeTxCommit(channel, fields);
+
+   case 5898261:
+    return encodeTxCommitOk(channel, fields);
+
+   case 5898270:
+    return encodeTxRollback(channel, fields);
+
+   case 5898271:
+    return encodeTxRollbackOk(channel, fields);
+
+   case 5570570:
+    return encodeConfirmSelect(channel, fields);
+
+   case 5570571:
+    return encodeConfirmSelectOk(channel, fields);
+
+   default:
+    throw new Error("Unknown class/method ID");
+  }
+};
+
+module.exports.encodeProperties = function(id, channel, size, fields) {
+  switch (id) {
+   case 60:
+    return encodeBasicProperties(channel, size, fields);
+
+   default:
+    throw new Error("Unknown class/properties ID");
+  }
+};
+
+module.exports.info = function(id) {
+  switch (id) {
+   case 3932170:
+    return methodInfoBasicQos;
+
+   case 3932171:
+    return methodInfoBasicQosOk;
+
+   case 3932180:
+    return methodInfoBasicConsume;
+
+   case 3932181:
+    return methodInfoBasicConsumeOk;
+
+   case 3932190:
+    return methodInfoBasicCancel;
+
+   case 3932191:
+    return methodInfoBasicCancelOk;
+
+   case 3932200:
+    return methodInfoBasicPublish;
+
+   case 3932210:
+    return methodInfoBasicReturn;
+
+   case 3932220:
+    return methodInfoBasicDeliver;
+
+   case 3932230:
+    return methodInfoBasicGet;
+
+   case 3932231:
+    return methodInfoBasicGetOk;
+
+   case 3932232:
+    return methodInfoBasicGetEmpty;
+
+   case 3932240:
+    return methodInfoBasicAck;
+
+   case 3932250:
+    return methodInfoBasicReject;
+
+   case 3932260:
+    return methodInfoBasicRecoverAsync;
+
+   case 3932270:
+    return methodInfoBasicRecover;
+
+   case 3932271:
+    return methodInfoBasicRecoverOk;
+
+   case 3932280:
+    return methodInfoBasicNack;
+
+   case 655370:
+    return methodInfoConnectionStart;
+
+   case 655371:
+    return methodInfoConnectionStartOk;
+
+   case 655380:
+    return methodInfoConnectionSecure;
+
+   case 655381:
+    return methodInfoConnectionSecureOk;
+
+   case 655390:
+    return methodInfoConnectionTune;
+
+   case 655391:
+    return methodInfoConnectionTuneOk;
+
+   case 655400:
+    return methodInfoConnectionOpen;
+
+   case 655401:
+    return methodInfoConnectionOpenOk;
+
+   case 655410:
+    return methodInfoConnectionClose;
+
+   case 655411:
+    return methodInfoConnectionCloseOk;
+
+   case 655420:
+    return methodInfoConnectionBlocked;
+
+   case 655421:
+    return methodInfoConnectionUnblocked;
+
+   case 655430:
+    return methodInfoConnectionUpdateSecret;
+
+   case 655431:
+    return methodInfoConnectionUpdateSecretOk;
+
+   case 1310730:
+    return methodInfoChannelOpen;
+
+   case 1310731:
+    return methodInfoChannelOpenOk;
+
+   case 1310740:
+    return methodInfoChannelFlow;
+
+   case 1310741:
+    return methodInfoChannelFlowOk;
+
+   case 1310760:
+    return methodInfoChannelClose;
+
+   case 1310761:
+    return methodInfoChannelCloseOk;
+
+   case 1966090:
+    return methodInfoAccessRequest;
+
+   case 1966091:
+    return methodInfoAccessRequestOk;
+
+   case 2621450:
+    return methodInfoExchangeDeclare;
+
+   case 2621451:
+    return methodInfoExchangeDeclareOk;
+
+   case 2621460:
+    return methodInfoExchangeDelete;
+
+   case 2621461:
+    return methodInfoExchangeDeleteOk;
+
+   case 2621470:
+    return methodInfoExchangeBind;
+
+   case 2621471:
+    return methodInfoExchangeBindOk;
+
+   case 2621480:
+    return methodInfoExchangeUnbind;
+
+   case 2621491:
+    return methodInfoExchangeUnbindOk;
+
+   case 3276810:
+    return methodInfoQueueDeclare;
+
+   case 3276811:
+    return methodInfoQueueDeclareOk;
+
+   case 3276820:
+    return methodInfoQueueBind;
+
+   case 3276821:
+    return methodInfoQueueBindOk;
+
+   case 3276830:
+    return methodInfoQueuePurge;
+
+   case 3276831:
+    return methodInfoQueuePurgeOk;
+
+   case 3276840:
+    return methodInfoQueueDelete;
+
+   case 3276841:
+    return methodInfoQueueDeleteOk;
+
+   case 3276850:
+    return methodInfoQueueUnbind;
+
+   case 3276851:
+    return methodInfoQueueUnbindOk;
+
+   case 5898250:
+    return methodInfoTxSelect;
+
+   case 5898251:
+    return methodInfoTxSelectOk;
+
+   case 5898260:
+    return methodInfoTxCommit;
+
+   case 5898261:
+    return methodInfoTxCommitOk;
+
+   case 5898270:
+    return methodInfoTxRollback;
+
+   case 5898271:
+    return methodInfoTxRollbackOk;
+
+   case 5570570:
+    return methodInfoConfirmSelect;
+
+   case 5570571:
+    return methodInfoConfirmSelectOk;
+
+   case 60:
+    return propertiesInfoBasicProperties;
+
+   default:
+    throw new Error("Unknown class/method ID");
+  }
+};
+
+module.exports.BasicQos = 3932170;
+
+var methodInfoBasicQos = module.exports.methodInfoBasicQos = {
+  id: 3932170,
+  classId: 60,
+  methodId: 10,
+  name: "BasicQos",
+  args: [ {
+    type: "long",
+    name: "prefetchSize",
+    default: 0
+  }, {
+    type: "short",
+    name: "prefetchCount",
+    default: 0
+  }, {
+    type: "bit",
+    name: "global",
+    default: !1
+  } ]
+};
+
+module.exports.BasicQosOk = 3932171;
+
+var methodInfoBasicQosOk = module.exports.methodInfoBasicQosOk = {
+  id: 3932171,
+  classId: 60,
+  methodId: 11,
+  name: "BasicQosOk",
+  args: []
+};
+
+module.exports.BasicConsume = 3932180;
+
+var methodInfoBasicConsume = module.exports.methodInfoBasicConsume = {
+  id: 3932180,
+  classId: 60,
+  methodId: 20,
+  name: "BasicConsume",
+  args: [ {
+    type: "short",
+    name: "ticket",
+    default: 0
+  }, {
+    type: "shortstr",
+    name: "queue",
+    default: ""
+  }, {
+    type: "shortstr",
+    name: "consumerTag",
+    default: ""
+  }, {
+    type: "bit",
+    name: "noLocal",
+    default: !1
+  }, {
+    type: "bit",
+    name: "noAck",
+    default: !1
+  }, {
+    type: "bit",
+    name: "exclusive",
+    default: !1
+  }, {
+    type: "bit",
+    name: "nowait",
+    default: !1
+  }, {
+    type: "table",
+    name: "arguments",
+    default: {}
+  } ]
+};
+
+module.exports.BasicConsumeOk = 3932181;
+
+var methodInfoBasicConsumeOk = module.exports.methodInfoBasicConsumeOk = {
+  id: 3932181,
+  classId: 60,
+  methodId: 21,
+  name: "BasicConsumeOk",
+  args: [ {
+    type: "shortstr",
+    name: "consumerTag"
+  } ]
+};
+
+module.exports.BasicCancel = 3932190;
+
+var methodInfoBasicCancel = module.exports.methodInfoBasicCancel = {
+  id: 3932190,
+  classId: 60,
+  methodId: 30,
+  name: "BasicCancel",
+  args: [ {
+    type: "shortstr",
+    name: "consumerTag"
+  }, {
+    type: "bit",
+    name: "nowait",
+    default: !1
+  } ]
+};
+
+module.exports.BasicCancelOk = 3932191;
+
+var methodInfoBasicCancelOk = module.exports.methodInfoBasicCancelOk = {
+  id: 3932191,
+  classId: 60,
+  methodId: 31,
+  name: "BasicCancelOk",
+  args: [ {
+    type: "shortstr",
+    name: "consumerTag"
+  } ]
+};
+
+module.exports.BasicPublish = 3932200;
+
+var methodInfoBasicPublish = module.exports.methodInfoBasicPublish = {
+  id: 3932200,
+  classId: 60,
+  methodId: 40,
+  name: "BasicPublish",
+  args: [ {
+    type: "short",
+    name: "ticket",
+    default: 0
+  }, {
+    type: "shortstr",
+    name: "exchange",
+    default: ""
+  }, {
+    type: "shortstr",
+    name: "routingKey",
+    default: ""
+  }, {
+    type: "bit",
+    name: "mandatory",
+    default: !1
+  }, {
+    type: "bit",
+    name: "immediate",
+    default: !1
+  } ]
+};
+
+module.exports.BasicReturn = 3932210;
+
+var methodInfoBasicReturn = module.exports.methodInfoBasicReturn = {
+  id: 3932210,
+  classId: 60,
+  methodId: 50,
+  name: "BasicReturn",
+  args: [ {
+    type: "short",
+    name: "replyCode"
+  }, {
+    type: "shortstr",
+    name: "replyText",
+    default: ""
+  }, {
+    type: "shortstr",
+    name: "exchange"
+  }, {
+    type: "shortstr",
+    name: "routingKey"
+  } ]
+};
+
+module.exports.BasicDeliver = 3932220;
+
+var methodInfoBasicDeliver = module.exports.methodInfoBasicDeliver = {
+  id: 3932220,
+  classId: 60,
+  methodId: 60,
+  name: "BasicDeliver",
+  args: [ {
+    type: "shortstr",
+    name: "consumerTag"
+  }, {
+    type: "longlong",
+    name: "deliveryTag"
+  }, {
+    type: "bit",
+    name: "redelivered",
+    default: !1
+  }, {
+    type: "shortstr",
+    name: "exchange"
+  }, {
+    type: "shortstr",
+    name: "routingKey"
+  } ]
+};
+
+module.exports.BasicGet = 3932230;
+
+var methodInfoBasicGet = module.exports.methodInfoBasicGet = {
+  id: 3932230,
+  classId: 60,
+  methodId: 70,
+  name: "BasicGet",
+  args: [ {
+    type: "short",
+    name: "ticket",
+    default: 0
+  }, {
+    type: "shortstr",
+    name: "queue",
+    default: ""
+  }, {
+    type: "bit",
+    name: "noAck",
+    default: !1
+  } ]
+};
+
+module.exports.BasicGetOk = 3932231;
+
+var methodInfoBasicGetOk = module.exports.methodInfoBasicGetOk = {
+  id: 3932231,
+  classId: 60,
+  methodId: 71,
+  name: "BasicGetOk",
+  args: [ {
+    type: "longlong",
+    name: "deliveryTag"
+  }, {
+    type: "bit",
+    name: "redelivered",
+    default: !1
+  }, {
+    type: "shortstr",
+    name: "exchange"
+  }, {
+    type: "shortstr",
+    name: "routingKey"
+  }, {
+    type: "long",
+    name: "messageCount"
+  } ]
+};
+
+module.exports.BasicGetEmpty = 3932232;
+
+var methodInfoBasicGetEmpty = module.exports.methodInfoBasicGetEmpty = {
+  id: 3932232,
+  classId: 60,
+  methodId: 72,
+  name: "BasicGetEmpty",
+  args: [ {
+    type: "shortstr",
+    name: "clusterId",
+    default: ""
+  } ]
+};
+
+module.exports.BasicAck = 3932240;
+
+var methodInfoBasicAck = module.exports.methodInfoBasicAck = {
+  id: 3932240,
+  classId: 60,
+  methodId: 80,
+  name: "BasicAck",
+  args: [ {
+    type: "longlong",
+    name: "deliveryTag",
+    default: 0
+  }, {
+    type: "bit",
+    name: "multiple",
+    default: !1
+  } ]
+};
+
+module.exports.BasicReject = 3932250;
+
+var methodInfoBasicReject = module.exports.methodInfoBasicReject = {
+  id: 3932250,
+  classId: 60,
+  methodId: 90,
+  name: "BasicReject",
+  args: [ {
+    type: "longlong",
+    name: "deliveryTag"
+  }, {
+    type: "bit",
+    name: "requeue",
+    default: !0
+  } ]
+};
+
+module.exports.BasicRecoverAsync = 3932260;
+
+var methodInfoBasicRecoverAsync = module.exports.methodInfoBasicRecoverAsync = {
+  id: 3932260,
+  classId: 60,
+  methodId: 100,
+  name: "BasicRecoverAsync",
+  args: [ {
+    type: "bit",
+    name: "requeue",
+    default: !1
+  } ]
+};
+
+module.exports.BasicRecover = 3932270;
+
+var methodInfoBasicRecover = module.exports.methodInfoBasicRecover = {
+  id: 3932270,
+  classId: 60,
+  methodId: 110,
+  name: "BasicRecover",
+  args: [ {
+    type: "bit",
+    name: "requeue",
+    default: !1
+  } ]
+};
+
+module.exports.BasicRecoverOk = 3932271;
+
+var methodInfoBasicRecoverOk = module.exports.methodInfoBasicRecoverOk = {
+  id: 3932271,
+  classId: 60,
+  methodId: 111,
+  name: "BasicRecoverOk",
+  args: []
+};
+
+module.exports.BasicNack = 3932280;
+
+var methodInfoBasicNack = module.exports.methodInfoBasicNack = {
+  id: 3932280,
+  classId: 60,
+  methodId: 120,
+  name: "BasicNack",
+  args: [ {
+    type: "longlong",
+    name: "deliveryTag",
+    default: 0
+  }, {
+    type: "bit",
+    name: "multiple",
+    default: !1
+  }, {
+    type: "bit",
+    name: "requeue",
+    default: !0
+  } ]
+};
+
+module.exports.ConnectionStart = 655370;
+
+var methodInfoConnectionStart = module.exports.methodInfoConnectionStart = {
+  id: 655370,
+  classId: 10,
+  methodId: 10,
+  name: "ConnectionStart",
+  args: [ {
+    type: "octet",
+    name: "versionMajor",
+    default: 0
+  }, {
+    type: "octet",
+    name: "versionMinor",
+    default: 9
+  }, {
+    type: "table",
+    name: "serverProperties"
+  }, {
+    type: "longstr",
+    name: "mechanisms",
+    default: "PLAIN"
+  }, {
+    type: "longstr",
+    name: "locales",
+    default: "en_US"
+  } ]
+};
+
+module.exports.ConnectionStartOk = 655371;
+
+var methodInfoConnectionStartOk = module.exports.methodInfoConnectionStartOk = {
+  id: 655371,
+  classId: 10,
+  methodId: 11,
+  name: "ConnectionStartOk",
+  args: [ {
+    type: "table",
+    name: "clientProperties"
+  }, {
+    type: "shortstr",
+    name: "mechanism",
+    default: "PLAIN"
+  }, {
+    type: "longstr",
+    name: "response"
+  }, {
+    type: "shortstr",
+    name: "locale",
+    default: "en_US"
+  } ]
+};
+
+module.exports.ConnectionSecure = 655380;
+
+var methodInfoConnectionSecure = module.exports.methodInfoConnectionSecure = {
+  id: 655380,
+  classId: 10,
+  methodId: 20,
+  name: "ConnectionSecure",
+  args: [ {
+    type: "longstr",
+    name: "challenge"
+  } ]
+};
+
+module.exports.ConnectionSecureOk = 655381;
+
+var methodInfoConnectionSecureOk = module.exports.methodInfoConnectionSecureOk = {
+  id: 655381,
+  classId: 10,
+  methodId: 21,
+  name: "ConnectionSecureOk",
+  args: [ {
+    type: "longstr",
+    name: "response"
+  } ]
+};
+
+module.exports.ConnectionTune = 655390;
+
+var methodInfoConnectionTune = module.exports.methodInfoConnectionTune = {
+  id: 655390,
+  classId: 10,
+  methodId: 30,
+  name: "ConnectionTune",
+  args: [ {
+    type: "short",
+    name: "channelMax",
+    default: 0
+  }, {
+    type: "long",
+    name: "frameMax",
+    default: 0
+  }, {
+    type: "short",
+    name: "heartbeat",
+    default: 0
+  } ]
+};
+
+module.exports.ConnectionTuneOk = 655391;
+
+var methodInfoConnectionTuneOk = module.exports.methodInfoConnectionTuneOk = {
+  id: 655391,
+  classId: 10,
+  methodId: 31,
+  name: "ConnectionTuneOk",
+  args: [ {
+    type: "short",
+    name: "channelMax",
+    default: 0
+  }, {
+    type: "long",
+    name: "frameMax",
+    default: 0
+  }, {
+    type: "short",
+    name: "heartbeat",
+    default: 0
+  } ]
+};
+
+module.exports.ConnectionOpen = 655400;
+
+var methodInfoConnectionOpen = module.exports.methodInfoConnectionOpen = {
+  id: 655400,
+  classId: 10,
+  methodId: 40,
+  name: "ConnectionOpen",
+  args: [ {
+    type: "shortstr",
+    name: "virtualHost",
+    default: "/"
+  }, {
+    type: "shortstr",
+    name: "capabilities",
+    default: ""
+  }, {
+    type: "bit",
+    name: "insist",
+    default: !1
+  } ]
+};
+
+module.exports.ConnectionOpenOk = 655401;
+
+var methodInfoConnectionOpenOk = module.exports.methodInfoConnectionOpenOk = {
+  id: 655401,
+  classId: 10,
+  methodId: 41,
+  name: "ConnectionOpenOk",
+  args: [ {
+    type: "shortstr",
+    name: "knownHosts",
+    default: ""
+  } ]
+};
+
+module.exports.ConnectionClose = 655410;
+
+var methodInfoConnectionClose = module.exports.methodInfoConnectionClose = {
+  id: 655410,
+  classId: 10,
+  methodId: 50,
+  name: "ConnectionClose",
+  args: [ {
+    type: "short",
+    name: "replyCode"
+  }, {
+    type: "shortstr",
+    name: "replyText",
+    default: ""
+  }, {
+    type: "short",
+    name: "classId"
+  }, {
+    type: "short",
+    name: "methodId"
+  } ]
+};
+
+module.exports.ConnectionCloseOk = 655411;
+
+var methodInfoConnectionCloseOk = module.exports.methodInfoConnectionCloseOk = {
+  id: 655411,
+  classId: 10,
+  methodId: 51,
+  name: "ConnectionCloseOk",
+  args: []
+};
+
+module.exports.ConnectionBlocked = 655420;
+
+var methodInfoConnectionBlocked = module.exports.methodInfoConnectionBlocked = {
+  id: 655420,
+  classId: 10,
+  methodId: 60,
+  name: "ConnectionBlocked",
+  args: [ {
+    type: "shortstr",
+    name: "reason",
+    default: ""
+  } ]
+};
+
+module.exports.ConnectionUnblocked = 655421;
+
+var methodInfoConnectionUnblocked = module.exports.methodInfoConnectionUnblocked = {
+  id: 655421,
+  classId: 10,
+  methodId: 61,
+  name: "ConnectionUnblocked",
+  args: []
+};
+
+module.exports.ConnectionUpdateSecret = 655430;
+
+var methodInfoConnectionUpdateSecret = module.exports.methodInfoConnectionUpdateSecret = {
+  id: 655430,
+  classId: 10,
+  methodId: 70,
+  name: "ConnectionUpdateSecret",
+  args: [ {
+    type: "longstr",
+    name: "newSecret"
+  }, {
+    type: "shortstr",
+    name: "reason"
+  } ]
+};
+
+module.exports.ConnectionUpdateSecretOk = 655431;
+
+var methodInfoConnectionUpdateSecretOk = module.exports.methodInfoConnectionUpdateSecretOk = {
+  id: 655431,
+  classId: 10,
+  methodId: 71,
+  name: "ConnectionUpdateSecretOk",
+  args: []
+};
+
+module.exports.ChannelOpen = 1310730;
+
+var methodInfoChannelOpen = module.exports.methodInfoChannelOpen = {
+  id: 1310730,
+  classId: 20,
+  methodId: 10,
+  name: "ChannelOpen",
+  args: [ {
+    type: "shortstr",
+    name: "outOfBand",
+    default: ""
+  } ]
+};
+
+module.exports.ChannelOpenOk = 1310731;
+
+var methodInfoChannelOpenOk = module.exports.methodInfoChannelOpenOk = {
+  id: 1310731,
+  classId: 20,
+  methodId: 11,
+  name: "ChannelOpenOk",
+  args: [ {
+    type: "longstr",
+    name: "channelId",
+    default: ""
+  } ]
+};
+
+module.exports.ChannelFlow = 1310740;
+
+var methodInfoChannelFlow = module.exports.methodInfoChannelFlow = {
+  id: 1310740,
+  classId: 20,
+  methodId: 20,
+  name: "ChannelFlow",
+  args: [ {
+    type: "bit",
+    name: "active"
+  } ]
+};
+
+module.exports.ChannelFlowOk = 1310741;
+
+var methodInfoChannelFlowOk = module.exports.methodInfoChannelFlowOk = {
+  id: 1310741,
+  classId: 20,
+  methodId: 21,
+  name: "ChannelFlowOk",
+  args: [ {
+    type: "bit",
+    name: "active"
+  } ]
+};
+
+module.exports.ChannelClose = 1310760;
+
+var methodInfoChannelClose = module.exports.methodInfoChannelClose = {
+  id: 1310760,
+  classId: 20,
+  methodId: 40,
+  name: "ChannelClose",
+  args: [ {
+    type: "short",
+    name: "replyCode"
+  }, {
+    type: "shortstr",
+    name: "replyText",
+    default: ""
+  }, {
+    type: "short",
+    name: "classId"
+  }, {
+    type: "short",
+    name: "methodId"
+  } ]
+};
+
+module.exports.ChannelCloseOk = 1310761;
+
+var methodInfoChannelCloseOk = module.exports.methodInfoChannelCloseOk = {
+  id: 1310761,
+  classId: 20,
+  methodId: 41,
+  name: "ChannelCloseOk",
+  args: []
+};
+
+module.exports.AccessRequest = 1966090;
+
+var methodInfoAccessRequest = module.exports.methodInfoAccessRequest = {
+  id: 1966090,
+  classId: 30,
+  methodId: 10,
+  name: "AccessRequest",
+  args: [ {
+    type: "shortstr",
+    name: "realm",
+    default: "/data"
+  }, {
+    type: "bit",
+    name: "exclusive",
+    default: !1
+  }, {
+    type: "bit",
+    name: "passive",
+    default: !0
+  }, {
+    type: "bit",
+    name: "active",
+    default: !0
+  }, {
+    type: "bit",
+    name: "write",
+    default: !0
+  }, {
+    type: "bit",
+    name: "read",
+    default: !0
+  } ]
+};
+
+module.exports.AccessRequestOk = 1966091;
+
+var methodInfoAccessRequestOk = module.exports.methodInfoAccessRequestOk = {
+  id: 1966091,
+  classId: 30,
+  methodId: 11,
+  name: "AccessRequestOk",
+  args: [ {
+    type: "short",
+    name: "ticket",
+    default: 1
+  } ]
+};
+
+module.exports.ExchangeDeclare = 2621450;
+
+var methodInfoExchangeDeclare = module.exports.methodInfoExchangeDeclare = {
+  id: 2621450,
+  classId: 40,
+  methodId: 10,
+  name: "ExchangeDeclare",
+  args: [ {
+    type: "short",
+    name: "ticket",
+    default: 0
+  }, {
+    type: "shortstr",
+    name: "exchange"
+  }, {
+    type: "shortstr",
+    name: "type",
+    default: "direct"
+  }, {
+    type: "bit",
+    name: "passive",
+    default: !1
+  }, {
+    type: "bit",
+    name: "durable",
+    default: !1
+  }, {
+    type: "bit",
+    name: "autoDelete",
+    default: !1
+  }, {
+    type: "bit",
+    name: "internal",
+    default: !1
+  }, {
+    type: "bit",
+    name: "nowait",
+    default: !1
+  }, {
+    type: "table",
+    name: "arguments",
+    default: {}
+  } ]
+};
+
+module.exports.ExchangeDeclareOk = 2621451;
+
+var methodInfoExchangeDeclareOk = module.exports.methodInfoExchangeDeclareOk = {
+  id: 2621451,
+  classId: 40,
+  methodId: 11,
+  name: "ExchangeDeclareOk",
+  args: []
+};
+
+module.exports.ExchangeDelete = 2621460;
+
+var methodInfoExchangeDelete = module.exports.methodInfoExchangeDelete = {
+  id: 2621460,
+  classId: 40,
+  methodId: 20,
+  name: "ExchangeDelete",
+  args: [ {
+    type: "short",
+    name: "ticket",
+    default: 0
+  }, {
+    type: "shortstr",
+    name: "exchange"
+  }, {
+    type: "bit",
+    name: "ifUnused",
+    default: !1
+  }, {
+    type: "bit",
+    name: "nowait",
+    default: !1
+  } ]
+};
+
+module.exports.ExchangeDeleteOk = 2621461;
+
+var methodInfoExchangeDeleteOk = module.exports.methodInfoExchangeDeleteOk = {
+  id: 2621461,
+  classId: 40,
+  methodId: 21,
+  name: "ExchangeDeleteOk",
+  args: []
+};
+
+module.exports.ExchangeBind = 2621470;
+
+var methodInfoExchangeBind = module.exports.methodInfoExchangeBind = {
+  id: 2621470,
+  classId: 40,
+  methodId: 30,
+  name: "ExchangeBind",
+  args: [ {
+    type: "short",
+    name: "ticket",
+    default: 0
+  }, {
+    type: "shortstr",
+    name: "destination"
+  }, {
+    type: "shortstr",
+    name: "source"
+  }, {
+    type: "shortstr",
+    name: "routingKey",
+    default: ""
+  }, {
+    type: "bit",
+    name: "nowait",
+    default: !1
+  }, {
+    type: "table",
+    name: "arguments",
+    default: {}
+  } ]
+};
+
+module.exports.ExchangeBindOk = 2621471;
+
+var methodInfoExchangeBindOk = module.exports.methodInfoExchangeBindOk = {
+  id: 2621471,
+  classId: 40,
+  methodId: 31,
+  name: "ExchangeBindOk",
+  args: []
+};
+
+module.exports.ExchangeUnbind = 2621480;
+
+var methodInfoExchangeUnbind = module.exports.methodInfoExchangeUnbind = {
+  id: 2621480,
+  classId: 40,
+  methodId: 40,
+  name: "ExchangeUnbind",
+  args: [ {
+    type: "short",
+    name: "ticket",
+    default: 0
+  }, {
+    type: "shortstr",
+    name: "destination"
+  }, {
+    type: "shortstr",
+    name: "source"
+  }, {
+    type: "shortstr",
+    name: "routingKey",
+    default: ""
+  }, {
+    type: "bit",
+    name: "nowait",
+    default: !1
+  }, {
+    type: "table",
+    name: "arguments",
+    default: {}
+  } ]
+};
+
+module.exports.ExchangeUnbindOk = 2621491;
+
+var methodInfoExchangeUnbindOk = module.exports.methodInfoExchangeUnbindOk = {
+  id: 2621491,
+  classId: 40,
+  methodId: 51,
+  name: "ExchangeUnbindOk",
+  args: []
+};
+
+module.exports.QueueDeclare = 3276810;
+
+var methodInfoQueueDeclare = module.exports.methodInfoQueueDeclare = {
+  id: 3276810,
+  classId: 50,
+  methodId: 10,
+  name: "QueueDeclare",
+  args: [ {
+    type: "short",
+    name: "ticket",
+    default: 0
+  }, {
+    type: "shortstr",
+    name: "queue",
+    default: ""
+  }, {
+    type: "bit",
+    name: "passive",
+    default: !1
+  }, {
+    type: "bit",
+    name: "durable",
+    default: !1
+  }, {
+    type: "bit",
+    name: "exclusive",
+    default: !1
+  }, {
+    type: "bit",
+    name: "autoDelete",
+    default: !1
+  }, {
+    type: "bit",
+    name: "nowait",
+    default: !1
+  }, {
+    type: "table",
+    name: "arguments",
+    default: {}
+  } ]
+};
+
+module.exports.QueueDeclareOk = 3276811;
+
+var methodInfoQueueDeclareOk = module.exports.methodInfoQueueDeclareOk = {
+  id: 3276811,
+  classId: 50,
+  methodId: 11,
+  name: "QueueDeclareOk",
+  args: [ {
+    type: "shortstr",
+    name: "queue"
+  }, {
+    type: "long",
+    name: "messageCount"
+  }, {
+    type: "long",
+    name: "consumerCount"
+  } ]
+};
+
+module.exports.QueueBind = 3276820;
+
+var methodInfoQueueBind = module.exports.methodInfoQueueBind = {
+  id: 3276820,
+  classId: 50,
+  methodId: 20,
+  name: "QueueBind",
+  args: [ {
+    type: "short",
+    name: "ticket",
+    default: 0
+  }, {
+    type: "shortstr",
+    name: "queue",
+    default: ""
+  }, {
+    type: "shortstr",
+    name: "exchange"
+  }, {
+    type: "shortstr",
+    name: "routingKey",
+    default: ""
+  }, {
+    type: "bit",
+    name: "nowait",
+    default: !1
+  }, {
+    type: "table",
+    name: "arguments",
+    default: {}
+  } ]
+};
+
+module.exports.QueueBindOk = 3276821;
+
+var methodInfoQueueBindOk = module.exports.methodInfoQueueBindOk = {
+  id: 3276821,
+  classId: 50,
+  methodId: 21,
+  name: "QueueBindOk",
+  args: []
+};
+
+module.exports.QueuePurge = 3276830;
+
+var methodInfoQueuePurge = module.exports.methodInfoQueuePurge = {
+  id: 3276830,
+  classId: 50,
+  methodId: 30,
+  name: "QueuePurge",
+  args: [ {
+    type: "short",
+    name: "ticket",
+    default: 0
+  }, {
+    type: "shortstr",
+    name: "queue",
+    default: ""
+  }, {
+    type: "bit",
+    name: "nowait",
+    default: !1
+  } ]
+};
+
+module.exports.QueuePurgeOk = 3276831;
+
+var methodInfoQueuePurgeOk = module.exports.methodInfoQueuePurgeOk = {
+  id: 3276831,
+  classId: 50,
+  methodId: 31,
+  name: "QueuePurgeOk",
+  args: [ {
+    type: "long",
+    name: "messageCount"
+  } ]
+};
+
+module.exports.QueueDelete = 3276840;
+
+var methodInfoQueueDelete = module.exports.methodInfoQueueDelete = {
+  id: 3276840,
+  classId: 50,
+  methodId: 40,
+  name: "QueueDelete",
+  args: [ {
+    type: "short",
+    name: "ticket",
+    default: 0
+  }, {
+    type: "shortstr",
+    name: "queue",
+    default: ""
+  }, {
+    type: "bit",
+    name: "ifUnused",
+    default: !1
+  }, {
+    type: "bit",
+    name: "ifEmpty",
+    default: !1
+  }, {
+    type: "bit",
+    name: "nowait",
+    default: !1
+  } ]
+};
+
+module.exports.QueueDeleteOk = 3276841;
+
+var methodInfoQueueDeleteOk = module.exports.methodInfoQueueDeleteOk = {
+  id: 3276841,
+  classId: 50,
+  methodId: 41,
+  name: "QueueDeleteOk",
+  args: [ {
+    type: "long",
+    name: "messageCount"
+  } ]
+};
+
+module.exports.QueueUnbind = 3276850;
+
+var methodInfoQueueUnbind = module.exports.methodInfoQueueUnbind = {
+  id: 3276850,
+  classId: 50,
+  methodId: 50,
+  name: "QueueUnbind",
+  args: [ {
+    type: "short",
+    name: "ticket",
+    default: 0
+  }, {
+    type: "shortstr",
+    name: "queue",
+    default: ""
+  }, {
+    type: "shortstr",
+    name: "exchange"
+  }, {
+    type: "shortstr",
+    name: "routingKey",
+    default: ""
+  }, {
+    type: "table",
+    name: "arguments",
+    default: {}
+  } ]
+};
+
+module.exports.QueueUnbindOk = 3276851;
+
+var methodInfoQueueUnbindOk = module.exports.methodInfoQueueUnbindOk = {
+  id: 3276851,
+  classId: 50,
+  methodId: 51,
+  name: "QueueUnbindOk",
+  args: []
+};
+
+module.exports.TxSelect = 5898250;
+
+var methodInfoTxSelect = module.exports.methodInfoTxSelect = {
+  id: 5898250,
+  classId: 90,
+  methodId: 10,
+  name: "TxSelect",
+  args: []
+};
+
+module.exports.TxSelectOk = 5898251;
+
+var methodInfoTxSelectOk = module.exports.methodInfoTxSelectOk = {
+  id: 5898251,
+  classId: 90,
+  methodId: 11,
+  name: "TxSelectOk",
+  args: []
+};
+
+module.exports.TxCommit = 5898260;
+
+var methodInfoTxCommit = module.exports.methodInfoTxCommit = {
+  id: 5898260,
+  classId: 90,
+  methodId: 20,
+  name: "TxCommit",
+  args: []
+};
+
+module.exports.TxCommitOk = 5898261;
+
+var methodInfoTxCommitOk = module.exports.methodInfoTxCommitOk = {
+  id: 5898261,
+  classId: 90,
+  methodId: 21,
+  name: "TxCommitOk",
+  args: []
+};
+
+module.exports.TxRollback = 5898270;
+
+var methodInfoTxRollback = module.exports.methodInfoTxRollback = {
+  id: 5898270,
+  classId: 90,
+  methodId: 30,
+  name: "TxRollback",
+  args: []
+};
+
+module.exports.TxRollbackOk = 5898271;
+
+var methodInfoTxRollbackOk = module.exports.methodInfoTxRollbackOk = {
+  id: 5898271,
+  classId: 90,
+  methodId: 31,
+  name: "TxRollbackOk",
+  args: []
+};
+
+module.exports.ConfirmSelect = 5570570;
+
+var methodInfoConfirmSelect = module.exports.methodInfoConfirmSelect = {
+  id: 5570570,
+  classId: 85,
+  methodId: 10,
+  name: "ConfirmSelect",
+  args: [ {
+    type: "bit",
+    name: "nowait",
+    default: !1
+  } ]
+};
+
+module.exports.ConfirmSelectOk = 5570571;
+
+var methodInfoConfirmSelectOk = module.exports.methodInfoConfirmSelectOk = {
+  id: 5570571,
+  classId: 85,
+  methodId: 11,
+  name: "ConfirmSelectOk",
+  args: []
+};
+
+module.exports.BasicProperties = 60;
+
+var propertiesInfoBasicProperties = module.exports.propertiesInfoBasicProperties = {
+  id: 60,
+  name: "BasicProperties",
+  args: [ {
+    type: "shortstr",
+    name: "contentType"
+  }, {
+    type: "shortstr",
+    name: "contentEncoding"
+  }, {
+    type: "table",
+    name: "headers"
+  }, {
+    type: "octet",
+    name: "deliveryMode"
+  }, {
+    type: "octet",
+    name: "priority"
+  }, {
+    type: "shortstr",
+    name: "correlationId"
+  }, {
+    type: "shortstr",
+    name: "replyTo"
+  }, {
+    type: "shortstr",
+    name: "expiration"
+  }, {
+    type: "shortstr",
+    name: "messageId"
+  }, {
+    type: "timestamp",
+    name: "timestamp"
+  }, {
+    type: "shortstr",
+    name: "type"
+  }, {
+    type: "shortstr",
+    name: "userId"
+  }, {
+    type: "shortstr",
+    name: "appId"
+  }, {
+    type: "shortstr",
+    name: "clusterId"
+  } ]
+};

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно