@bigtyphoon/melo 1.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +55 -0
  3. package/bin/commadtest.ts +10 -0
  4. package/bin/commands/add.ts +43 -0
  5. package/bin/commands/init.ts +292 -0
  6. package/bin/commands/kill.ts +21 -0
  7. package/bin/commands/list.ts +60 -0
  8. package/bin/commands/masterha.ts +40 -0
  9. package/bin/commands/restart.ts +48 -0
  10. package/bin/commands/start.ts +65 -0
  11. package/bin/commands/stop.ts +26 -0
  12. package/bin/melo.ts +30 -0
  13. package/bin/utils/constants.ts +27 -0
  14. package/bin/utils/utils.ts +130 -0
  15. package/dist/bin/commadtest.js +9 -0
  16. package/dist/bin/commands/add.js +40 -0
  17. package/dist/bin/commands/init.js +279 -0
  18. package/dist/bin/commands/kill.js +21 -0
  19. package/dist/bin/commands/list.js +65 -0
  20. package/dist/bin/commands/masterha.js +36 -0
  21. package/dist/bin/commands/restart.js +45 -0
  22. package/dist/bin/commands/start.js +58 -0
  23. package/dist/bin/commands/stop.js +20 -0
  24. package/dist/bin/melo.js +26 -0
  25. package/dist/bin/utils/constants.js +28 -0
  26. package/dist/bin/utils/utils.js +134 -0
  27. package/dist/lib/application.js +888 -0
  28. package/dist/lib/common/manager/appManager.js +112 -0
  29. package/dist/lib/common/manager/taskManager.js +39 -0
  30. package/dist/lib/common/remote/backend/msgRemote.js +63 -0
  31. package/dist/lib/common/remote/frontend/channelRemote.js +78 -0
  32. package/dist/lib/common/remote/frontend/sessionRemote.js +76 -0
  33. package/dist/lib/common/service/backendSessionService.js +337 -0
  34. package/dist/lib/common/service/channelService.js +514 -0
  35. package/dist/lib/common/service/connectionService.js +95 -0
  36. package/dist/lib/common/service/filterService.js +112 -0
  37. package/dist/lib/common/service/handlerService.js +187 -0
  38. package/dist/lib/common/service/sessionService.js +610 -0
  39. package/dist/lib/components/backendSession.js +14 -0
  40. package/dist/lib/components/channel.js +13 -0
  41. package/dist/lib/components/connection.js +12 -0
  42. package/dist/lib/components/connector.js +437 -0
  43. package/dist/lib/components/dictionary.js +93 -0
  44. package/dist/lib/components/master.js +39 -0
  45. package/dist/lib/components/monitor.js +25 -0
  46. package/dist/lib/components/protobuf.js +156 -0
  47. package/dist/lib/components/proxy.js +236 -0
  48. package/dist/lib/components/pushScheduler.js +62 -0
  49. package/dist/lib/components/remote.js +127 -0
  50. package/dist/lib/components/server.js +63 -0
  51. package/dist/lib/components/session.js +20 -0
  52. package/dist/lib/connectors/commands/handshake.js +119 -0
  53. package/dist/lib/connectors/commands/heartbeat.js +67 -0
  54. package/dist/lib/connectors/commands/kick.js +15 -0
  55. package/dist/lib/connectors/common/coder.js +90 -0
  56. package/dist/lib/connectors/common/handler.js +57 -0
  57. package/dist/lib/connectors/hybrid/IHybridSocket.js +3 -0
  58. package/dist/lib/connectors/hybrid/switcher.js +100 -0
  59. package/dist/lib/connectors/hybrid/tcpprocessor.js +40 -0
  60. package/dist/lib/connectors/hybrid/tcpsocket.js +171 -0
  61. package/dist/lib/connectors/hybrid/wsprocessor.js +49 -0
  62. package/dist/lib/connectors/hybridconnector.js +89 -0
  63. package/dist/lib/connectors/hybridsocket.js +139 -0
  64. package/dist/lib/connectors/mqtt/generate.js +113 -0
  65. package/dist/lib/connectors/mqtt/mqttadaptor.js +81 -0
  66. package/dist/lib/connectors/mqtt/protocol.js +48 -0
  67. package/dist/lib/connectors/mqttconnector.js +107 -0
  68. package/dist/lib/connectors/mqttsocket.js +59 -0
  69. package/dist/lib/connectors/sioconnector.js +135 -0
  70. package/dist/lib/connectors/siosocket.js +69 -0
  71. package/dist/lib/connectors/udpconnector.js +76 -0
  72. package/dist/lib/connectors/udpsocket.js +93 -0
  73. package/dist/lib/filters/handler/serial.js +44 -0
  74. package/dist/lib/filters/handler/time.js +32 -0
  75. package/dist/lib/filters/handler/timeout.js +45 -0
  76. package/dist/lib/filters/handler/toobusy.js +36 -0
  77. package/dist/lib/filters/rpc/rpcLog.js +43 -0
  78. package/dist/lib/filters/rpc/toobusy.js +41 -0
  79. package/dist/lib/index.js +81 -0
  80. package/dist/lib/interfaces/IComponent.js +3 -0
  81. package/dist/lib/interfaces/IConnector.js +3 -0
  82. package/dist/lib/interfaces/IHandlerFilter.js +3 -0
  83. package/dist/lib/interfaces/ILifeCycle.js +3 -0
  84. package/dist/lib/interfaces/IPlugin.js +3 -0
  85. package/dist/lib/interfaces/IPushScheduler.js +3 -0
  86. package/dist/lib/interfaces/ISocket.js +3 -0
  87. package/dist/lib/interfaces/IStore.js +3 -0
  88. package/dist/lib/interfaces/define.js +3 -0
  89. package/dist/lib/master/master.js +129 -0
  90. package/dist/lib/master/starter.js +236 -0
  91. package/dist/lib/master/watchdog.js +120 -0
  92. package/dist/lib/melo.js +125 -0
  93. package/dist/lib/modules/console.js +436 -0
  94. package/dist/lib/modules/masterwatcher.js +98 -0
  95. package/dist/lib/modules/monitorwatcher.js +124 -0
  96. package/dist/lib/modules/onlineUser.js +69 -0
  97. package/dist/lib/modules/restartNotifyModule.js +107 -0
  98. package/dist/lib/modules/watchServer.js +737 -0
  99. package/dist/lib/monitor/monitor.js +80 -0
  100. package/dist/lib/pushSchedulers/buffer.js +96 -0
  101. package/dist/lib/pushSchedulers/direct.js +58 -0
  102. package/dist/lib/pushSchedulers/multi.js +80 -0
  103. package/dist/lib/server/server.js +500 -0
  104. package/dist/lib/util/appUtil.js +306 -0
  105. package/dist/lib/util/constants.js +117 -0
  106. package/dist/lib/util/countDownLatch.js +51 -0
  107. package/dist/lib/util/events.js +20 -0
  108. package/dist/lib/util/handlerHelper.js +8 -0
  109. package/dist/lib/util/log.js +14 -0
  110. package/dist/lib/util/moduleUtil.js +101 -0
  111. package/dist/lib/util/pathUtil.js +134 -0
  112. package/dist/lib/util/remoterHelper.js +8 -0
  113. package/dist/lib/util/utils.js +358 -0
  114. package/dist/test/application.js +522 -0
  115. package/dist/test/config/log4js.json +28 -0
  116. package/dist/test/config/master.json +9 -0
  117. package/dist/test/config/servers.json +6 -0
  118. package/dist/test/filters/handler/serial.js +41 -0
  119. package/dist/test/filters/handler/time.js +41 -0
  120. package/dist/test/filters/handler/timeout.js +41 -0
  121. package/dist/test/filters/handler/toobusy.js +57 -0
  122. package/dist/test/filters/rpc/rpcLog.js +22 -0
  123. package/dist/test/filters/rpc/toobusy.js +39 -0
  124. package/dist/test/manager/mockChannelManager.js +77 -0
  125. package/dist/test/manager/taskManager.js +68 -0
  126. package/dist/test/mock-base/app/servers/other-file +0 -0
  127. package/dist/test/mock-plugin/components/mockPlugin.js +10 -0
  128. package/dist/test/mock-plugin/events/mockEvent.js +12 -0
  129. package/dist/test/modules/console.js +242 -0
  130. package/dist/test/pomelo.js +19 -0
  131. package/dist/test/remote/channelRemote.js +159 -0
  132. package/dist/test/service/channel.js +134 -0
  133. package/dist/test/service/channelService.js +216 -0
  134. package/dist/test/service/connectionService.js +114 -0
  135. package/dist/test/service/filterService.js +144 -0
  136. package/dist/test/service/handlerService.js +65 -0
  137. package/dist/test/service/sessionService.js +387 -0
  138. package/dist/test/util/countDownLatch.js +70 -0
  139. package/dist/test/util/pathUtil.js +108 -0
  140. package/dist/test/util/utils.js +140 -0
  141. package/lib/application.ts +1240 -0
  142. package/lib/common/manager/appManager.ts +118 -0
  143. package/lib/common/manager/taskManager.ts +50 -0
  144. package/lib/common/remote/backend/msgRemote.ts +134 -0
  145. package/lib/common/remote/frontend/channelRemote.ts +91 -0
  146. package/lib/common/remote/frontend/sessionRemote.ts +91 -0
  147. package/lib/common/service/backendSessionService.ts +388 -0
  148. package/lib/common/service/channelService.ts +609 -0
  149. package/lib/common/service/connectionService.ts +112 -0
  150. package/lib/common/service/filterService.ts +118 -0
  151. package/lib/common/service/handlerService.ts +224 -0
  152. package/lib/common/service/sessionService.ts +731 -0
  153. package/lib/components/backendSession.ts +14 -0
  154. package/lib/components/channel.ts +11 -0
  155. package/lib/components/connection.ts +13 -0
  156. package/lib/components/connector.ts +533 -0
  157. package/lib/components/dictionary.ts +121 -0
  158. package/lib/components/master.ts +41 -0
  159. package/lib/components/monitor.ts +30 -0
  160. package/lib/components/protobuf.ts +208 -0
  161. package/lib/components/proxy.ts +282 -0
  162. package/lib/components/pushScheduler.ts +70 -0
  163. package/lib/components/remote.ts +166 -0
  164. package/lib/components/server.ts +71 -0
  165. package/lib/components/session.ts +22 -0
  166. package/lib/connectors/commands/handshake.ts +155 -0
  167. package/lib/connectors/commands/heartbeat.ts +83 -0
  168. package/lib/connectors/commands/kick.ts +11 -0
  169. package/lib/connectors/common/coder.ts +93 -0
  170. package/lib/connectors/common/handler.ts +62 -0
  171. package/lib/connectors/hybrid/IHybridSocket.ts +9 -0
  172. package/lib/connectors/hybrid/switcher.ts +142 -0
  173. package/lib/connectors/hybrid/tcpprocessor.ts +43 -0
  174. package/lib/connectors/hybrid/tcpsocket.ts +223 -0
  175. package/lib/connectors/hybrid/wsprocessor.ts +57 -0
  176. package/lib/connectors/hybridconnector.ts +134 -0
  177. package/lib/connectors/hybridsocket.ts +168 -0
  178. package/lib/connectors/mqtt/generate.ts +103 -0
  179. package/lib/connectors/mqtt/mqttadaptor.ts +114 -0
  180. package/lib/connectors/mqtt/protocol.ts +49 -0
  181. package/lib/connectors/mqttconnector.ts +134 -0
  182. package/lib/connectors/mqttsocket.ts +79 -0
  183. package/lib/connectors/sioconnector.ts +161 -0
  184. package/lib/connectors/siosocket.ts +85 -0
  185. package/lib/connectors/udpconnector.ts +113 -0
  186. package/lib/connectors/udpsocket.ts +110 -0
  187. package/lib/filters/handler/serial.ts +46 -0
  188. package/lib/filters/handler/time.ts +35 -0
  189. package/lib/filters/handler/timeout.ts +50 -0
  190. package/lib/filters/handler/toobusy.ts +37 -0
  191. package/lib/filters/rpc/rpcLog.ts +42 -0
  192. package/lib/filters/rpc/toobusy.ts +41 -0
  193. package/lib/index.ts +74 -0
  194. package/lib/interfaces/IComponent.ts +47 -0
  195. package/lib/interfaces/IConnector.ts +20 -0
  196. package/lib/interfaces/IHandlerFilter.ts +15 -0
  197. package/lib/interfaces/ILifeCycle.ts +16 -0
  198. package/lib/interfaces/IPlugin.ts +65 -0
  199. package/lib/interfaces/IPushScheduler.ts +52 -0
  200. package/lib/interfaces/ISocket.ts +26 -0
  201. package/lib/interfaces/IStore.ts +10 -0
  202. package/lib/interfaces/define.ts +15 -0
  203. package/lib/master/master.ts +148 -0
  204. package/lib/master/starter.ts +234 -0
  205. package/lib/master/watchdog.ts +135 -0
  206. package/lib/melo.ts +152 -0
  207. package/lib/modules/console.ts +465 -0
  208. package/lib/modules/masterwatcher.ts +120 -0
  209. package/lib/modules/monitorwatcher.ts +151 -0
  210. package/lib/modules/onlineUser.ts +78 -0
  211. package/lib/modules/restartNotifyModule.ts +128 -0
  212. package/lib/modules/watchServer.ts +766 -0
  213. package/lib/monitor/monitor.ts +99 -0
  214. package/lib/pushSchedulers/buffer.ts +117 -0
  215. package/lib/pushSchedulers/direct.ts +65 -0
  216. package/lib/pushSchedulers/multi.ts +94 -0
  217. package/lib/server/server.ts +554 -0
  218. package/lib/util/appUtil.ts +313 -0
  219. package/lib/util/constants.ts +154 -0
  220. package/lib/util/countDownLatch.ts +72 -0
  221. package/lib/util/events.ts +15 -0
  222. package/lib/util/handlerHelper.ts +5 -0
  223. package/lib/util/log.ts +11 -0
  224. package/lib/util/moduleUtil.ts +110 -0
  225. package/lib/util/pathUtil.ts +132 -0
  226. package/lib/util/remoterHelper.ts +68 -0
  227. package/lib/util/utils.ts +365 -0
  228. package/package.json +93 -0
  229. package/template/game-server/.vscode/launch.json +27 -0
  230. package/template/game-server/app/servers/connector/handler/entryHandler.ts +50 -0
  231. package/template/game-server/app/servers/connector/remote/authRemoter.ts +36 -0
  232. package/template/game-server/app.ts +30 -0
  233. package/template/game-server/app.ts.mqtt +32 -0
  234. package/template/game-server/app.ts.sio +36 -0
  235. package/template/game-server/app.ts.sio.wss +34 -0
  236. package/template/game-server/app.ts.udp +31 -0
  237. package/template/game-server/app.ts.wss +40 -0
  238. package/template/game-server/config/adminServer.json +5 -0
  239. package/template/game-server/config/adminUser.json +22 -0
  240. package/template/game-server/config/clientProtos.json +1 -0
  241. package/template/game-server/config/dictionary.json +1 -0
  242. package/template/game-server/config/log4js.json +150 -0
  243. package/template/game-server/config/master.json +8 -0
  244. package/template/game-server/config/serverProtos.json +1 -0
  245. package/template/game-server/config/servers.json +12 -0
  246. package/template/game-server/copy.js +5 -0
  247. package/template/game-server/package.json +28 -0
  248. package/template/game-server/preload.ts +40 -0
  249. package/template/game-server/tsconfig.json +36 -0
  250. package/template/npm-install.bat +4 -0
  251. package/template/npm-install.sh +5 -0
  252. package/template/readme.md +31 -0
  253. package/template/shared/server.crt +15 -0
  254. package/template/shared/server.key +15 -0
  255. package/template/web-server/app.js +25 -0
  256. package/template/web-server/app.js.https +36 -0
  257. package/template/web-server/bin/component.bat +1 -0
  258. package/template/web-server/bin/component.sh +1 -0
  259. package/template/web-server/package.json +10 -0
  260. package/template/web-server/public/css/base.css +76 -0
  261. package/template/web-server/public/image/logo.png +0 -0
  262. package/template/web-server/public/image/sp.png +0 -0
  263. package/template/web-server/public/index.html +57 -0
  264. package/template/web-server/public/index.html.sio +58 -0
  265. package/template/web-server/public/js/lib/build/build.js +1730 -0
  266. package/template/web-server/public/js/lib/build/build.js.wss +1721 -0
  267. package/template/web-server/public/js/lib/component.json +6 -0
  268. package/template/web-server/public/js/lib/local/boot/component.json +11 -0
  269. package/template/web-server/public/js/lib/local/boot/index.js +11 -0
  270. package/template/web-server/public/js/lib/meloclient.js +456 -0
  271. package/template/web-server/public/js/lib/meloclient.js.wss +456 -0
  272. package/template/web-server/public/js/lib/socket.io.js +3 -0
  273. package/test/application.ts +607 -0
  274. package/test/filters/handler/serial.ts +47 -0
  275. package/test/filters/handler/time.ts +47 -0
  276. package/test/filters/handler/timeout.ts +46 -0
  277. package/test/filters/handler/toobusy.ts +59 -0
  278. package/test/filters/rpc/rpcLog.ts +20 -0
  279. package/test/filters/rpc/toobusy.ts +40 -0
  280. package/test/manager/mockChannelManager.ts +92 -0
  281. package/test/manager/taskManager.ts +78 -0
  282. package/test/mock-base/app/servers/other-file +0 -0
  283. package/test/mock-plugin/components/mockPlugin.ts +8 -0
  284. package/test/mock-plugin/events/mockEvent.ts +12 -0
  285. package/test/modules/console.ts +264 -0
  286. package/test/pomelo.ts +18 -0
  287. package/test/remote/channelRemote.ts +176 -0
  288. package/test/service/channel.ts +161 -0
  289. package/test/service/channelService.ts +243 -0
  290. package/test/service/connectionService.ts +142 -0
  291. package/test/service/filterService.ts +165 -0
  292. package/test/service/handlerService.ts +77 -0
  293. package/test/service/sessionService.ts +464 -0
  294. package/test/util/countDownLatch.ts +81 -0
  295. package/test/util/pathUtil.ts +122 -0
  296. package/test/util/utils.ts +165 -0
@@ -0,0 +1,888 @@
1
+ "use strict";
2
+ /*!
3
+ * Melo -- proto
4
+ * Copyright(c) 2012 xiechengchao <xiecc@163.com>
5
+ * MIT Licensed
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.Application = void 0;
9
+ /**
10
+ * Module dependencies.
11
+ */
12
+ const utils = require("./util/utils");
13
+ const melo_logger_1 = require("@bigtyphoon/melo-logger");
14
+ const events_1 = require("events");
15
+ const events_2 = require("./util/events");
16
+ const appUtil = require("./util/appUtil");
17
+ const Constants = require("./util/constants");
18
+ const appManager = require("./common/manager/appManager");
19
+ const fs = require("fs");
20
+ const path = require("path");
21
+ let logger = (0, melo_logger_1.getLogger)('melo', path.basename(__filename));
22
+ /**
23
+ * Application states
24
+ */
25
+ let STATE_INITED = 1; // app has inited
26
+ let STATE_BEFORE_START = 2; // app before start
27
+ let STATE_START = 3; // app start
28
+ let STATE_STARTED = 4; // app has started
29
+ let STATE_STOPED = 5; // app has stoped
30
+ class Application {
31
+ constructor() {
32
+ this.loaded = []; // loaded component list
33
+ this.components = {}; // name -> component map
34
+ this.settings = {}; // collection keep set/get
35
+ this.event = new events_1.EventEmitter(); // event object to sub/pub events
36
+ // global server infos
37
+ this.master = null; // master server info
38
+ this.servers = {}; // current global server info maps, id -> info
39
+ this.serverTypeMaps = {}; // current global type maps, type -> [info]
40
+ this.serverTypes = []; // current global server type list
41
+ this.usedPlugins = []; // current server custom lifecycle callbacks
42
+ this.clusterSeq = {}; // cluster id seqence
43
+ this.astart = utils.promisify(this.start);
44
+ this.aconfigure = utils.promisify(this.configure);
45
+ }
46
+ /**
47
+ * Initialize the server.
48
+ *
49
+ * - setup default configuration
50
+ */
51
+ init(opts) {
52
+ opts = opts || {};
53
+ let base = opts.base || path.dirname(require.main.filename);
54
+ this.set(Constants.RESERVED.BASE, base);
55
+ this.base = base;
56
+ appUtil.defaultConfiguration(this);
57
+ this.state = STATE_INITED;
58
+ logger.info('application inited: %j', this.getServerId());
59
+ }
60
+ /**
61
+ * Get application base path
62
+ *
63
+ * // cwd: /home/game/
64
+ * melo start
65
+ * // app.getBase() -> /home/game
66
+ *
67
+ * @return {String} application base path
68
+ *
69
+ * @memberOf Application
70
+ */
71
+ getBase() {
72
+ return this.get(Constants.RESERVED.BASE);
73
+ }
74
+ /**
75
+ * Override require method in application
76
+ *
77
+ * @param {String} relative path of file
78
+ *
79
+ * @memberOf Application
80
+ */
81
+ require(ph) {
82
+ return require(path.join(this.getBase(), ph));
83
+ }
84
+ /**
85
+ * Configure logger with {$base}/config/log4js.json
86
+ *
87
+ * @param {Object} logger melo-logger instance without configuration
88
+ *
89
+ * @memberOf Application
90
+ */
91
+ configureLogger(logger) {
92
+ if (process.env.POMELO_LOGGER !== 'off') {
93
+ let serverId = this.getServerId();
94
+ let base = this.getBase();
95
+ let env = this.get(Constants.RESERVED.ENV);
96
+ let originPath = path.join(base, Constants.FILEPATH.LOG);
97
+ let presentPath = path.join(base, Constants.FILEPATH.CONFIG_DIR, env, path.basename(Constants.FILEPATH.LOG));
98
+ if (this._checkCanRequire(originPath)) {
99
+ logger.configure(originPath, { serverId: serverId, base: base });
100
+ }
101
+ else if (this._checkCanRequire(presentPath)) {
102
+ logger.configure(presentPath, { serverId: serverId, base: base });
103
+ }
104
+ else {
105
+ console.error('logger file path configuration is error.');
106
+ }
107
+ }
108
+ }
109
+ /**
110
+ * add a filter to before and after filter
111
+ *
112
+ * @param {Object} filter provide before and after filter method.
113
+ * A filter should have two methods: before and after.
114
+ * @memberOf Application
115
+ */
116
+ filter(filter) {
117
+ this.before(filter);
118
+ this.after(filter);
119
+ }
120
+ /**
121
+ * Add before filter.
122
+ *
123
+ * @param {Object|Function} bf before fileter, bf(msg, session, next)
124
+ * @memberOf Application
125
+ */
126
+ before(bf) {
127
+ addFilter(this, Constants.KEYWORDS.BEFORE_FILTER, bf);
128
+ }
129
+ /**
130
+ * Add after filter.
131
+ *
132
+ * @param {Object|Function} af after filter, `af(err, msg, session, resp, next)`
133
+ * @memberOf Application
134
+ */
135
+ after(af) {
136
+ addFilter(this, Constants.KEYWORDS.AFTER_FILTER, af);
137
+ }
138
+ /**
139
+ * add a global filter to before and after global filter
140
+ *
141
+ * @param {Object} filter provide before and after filter method.
142
+ * A filter should have two methods: before and after.
143
+ * @memberOf Application
144
+ */
145
+ globalFilter(filter) {
146
+ this.globalBefore(filter);
147
+ this.globalAfter(filter);
148
+ }
149
+ /**
150
+ * Add global before filter.
151
+ *
152
+ * @param {Object|Function} bf before fileter, bf(msg, session, next)
153
+ * @memberOf Application
154
+ */
155
+ globalBefore(bf) {
156
+ addFilter(this, Constants.KEYWORDS.GLOBAL_BEFORE_FILTER, bf);
157
+ }
158
+ /**
159
+ * Add global after filter.
160
+ *
161
+ * @param {Object|Function} af after filter, `af(err, msg, session, resp, next)`
162
+ * @memberOf Application
163
+ */
164
+ globalAfter(af) {
165
+ addFilter(this, Constants.KEYWORDS.GLOBAL_AFTER_FILTER, af);
166
+ }
167
+ /**
168
+ * Add rpc before filter.
169
+ *
170
+ * @param {Object|Function} bf before fileter, bf(serverId, msg, opts, next)
171
+ * @memberOf Application
172
+ */
173
+ rpcBefore(bf) {
174
+ addFilter(this, Constants.KEYWORDS.RPC_BEFORE_FILTER, bf);
175
+ }
176
+ /**
177
+ * Add rpc after filter.
178
+ *
179
+ * @param {Object|Function} af after filter, `af(serverId, msg, opts, next)`
180
+ * @memberOf Application
181
+ */
182
+ rpcAfter(af) {
183
+ addFilter(this, Constants.KEYWORDS.RPC_AFTER_FILTER, af);
184
+ }
185
+ /**
186
+ * add a rpc filter to before and after rpc filter
187
+ *
188
+ * @param {Object} filter provide before and after filter method.
189
+ * A filter should have two methods: before and after.
190
+ * @memberOf Application
191
+ */
192
+ rpcFilter(filter) {
193
+ this.rpcBefore(filter);
194
+ this.rpcAfter(filter);
195
+ }
196
+ load(name, component, opts) {
197
+ if (typeof name !== 'string') {
198
+ opts = component;
199
+ component = name;
200
+ name = null;
201
+ }
202
+ if (typeof component === 'function') {
203
+ component = new component(this, opts);
204
+ }
205
+ if (!name && typeof component.name === 'string') {
206
+ name = component.name;
207
+ }
208
+ if (name && this.components[name]) {
209
+ // ignore duplicat component
210
+ logger.warn('ignore duplicate component: %j', name);
211
+ return;
212
+ }
213
+ this.loaded.push(component);
214
+ if (name) {
215
+ // components with a name would get by name throught app.components later.
216
+ this.components[name] = component;
217
+ }
218
+ return component;
219
+ }
220
+ _checkCanRequire(path) {
221
+ try {
222
+ path = require.resolve(path);
223
+ }
224
+ catch (err) {
225
+ return null;
226
+ }
227
+ return path;
228
+ }
229
+ /**
230
+ * Load Configure json file to settings.(support different enviroment directory & compatible for old path)
231
+ *
232
+ * @param {String} key environment key
233
+ * @param {String} val environment value
234
+ * @param {Boolean} reload whether reload after change default false
235
+ * @return {Server|Mixed} for chaining, or the setting value
236
+ * @memberOf Application
237
+ */
238
+ loadConfigBaseApp(key, val, reload = false) {
239
+ let self = this;
240
+ let env = this.get(Constants.RESERVED.ENV);
241
+ let originPath = path.join(this.getBase(), val);
242
+ let presentPath = path.join(this.getBase(), Constants.FILEPATH.CONFIG_DIR, env, path.basename(val));
243
+ let realPath;
244
+ let tmp;
245
+ if (self._checkCanRequire(originPath)) {
246
+ realPath = require.resolve(originPath);
247
+ let file = require(originPath);
248
+ if (file[env]) {
249
+ file = file[env];
250
+ }
251
+ this.set(key, file);
252
+ }
253
+ else if (self._checkCanRequire(presentPath)) {
254
+ realPath = require.resolve(presentPath);
255
+ let pfile = require(presentPath);
256
+ this.set(key, pfile);
257
+ }
258
+ else {
259
+ logger.error('invalid configuration with file path: %s', key);
260
+ }
261
+ if (!!realPath && !!reload) {
262
+ const watcher = fs.watch(realPath, function (event, filename) {
263
+ if (event === 'change') {
264
+ self.clearRequireCache(require.resolve(realPath));
265
+ watcher.close();
266
+ self.loadConfigBaseApp(key, val, reload);
267
+ }
268
+ });
269
+ }
270
+ }
271
+ clearRequireCache(path) {
272
+ const moduleObj = require.cache[path];
273
+ if (!moduleObj) {
274
+ logger.warn('can not find module of truepath', path);
275
+ return;
276
+ }
277
+ if (moduleObj.parent) {
278
+ // console.log('has parent ',moduleObj.parent);
279
+ moduleObj.parent.children.splice(moduleObj.parent.children.indexOf(moduleObj), 1);
280
+ }
281
+ delete require.cache[path];
282
+ }
283
+ /**
284
+ * Load Configure json file to settings.
285
+ *
286
+ * @param {String} key environment key
287
+ * @param {String} val environment value
288
+ * @return {Server|Mixed} for chaining, or the setting value
289
+ * @memberOf Application
290
+ */
291
+ loadConfig(key, val) {
292
+ let env = this.get(Constants.RESERVED.ENV);
293
+ let cfg = require(val);
294
+ if (cfg[env]) {
295
+ cfg = cfg[env];
296
+ }
297
+ this.set(key, cfg);
298
+ }
299
+ /**
300
+ * Set the route function for the specified server type.
301
+ *
302
+ * Examples:
303
+ *
304
+ * app.route('area', routeFunc);
305
+ *
306
+ * let routeFunc = function(session, msg, app, cb) {
307
+ * // all request to area would be route to the first area server
308
+ * let areas = app.getServersByType('area');
309
+ * cb(null, areas[0].id);
310
+ * };
311
+ *
312
+ * @param {String} serverType server type string
313
+ * @param {Function} routeFunc route function. routeFunc(session, msg, app, cb)
314
+ * @return {Object} current application instance for chain invoking
315
+ * @memberOf Application
316
+ */
317
+ route(serverType, routeFunc) {
318
+ let routes = this.get(Constants.KEYWORDS.ROUTE);
319
+ if (!routes) {
320
+ routes = {};
321
+ this.set(Constants.KEYWORDS.ROUTE, routes);
322
+ }
323
+ routes[serverType] = routeFunc;
324
+ return this;
325
+ }
326
+ /**
327
+ * Set before stop function. It would perform before servers stop.
328
+ *
329
+ * @param {Function} fun before close function
330
+ * @return {Void}
331
+ * @memberOf Application
332
+ */
333
+ beforeStopHook(fun) {
334
+ logger.warn('this method was deprecated in melo 0.8');
335
+ if (!!fun && typeof fun === 'function') {
336
+ this.set(Constants.KEYWORDS.BEFORE_STOP_HOOK, fun);
337
+ }
338
+ }
339
+ /**
340
+ * Start application. It would load the default components and start all the loaded components.
341
+ *
342
+ * @param {Function} cb callback function
343
+ * @memberOf Application
344
+ */
345
+ start(cb) {
346
+ this.startTime = Date.now();
347
+ if (this.state > STATE_INITED) {
348
+ utils.invokeCallback(cb, new Error('application has already start.'));
349
+ return;
350
+ }
351
+ let self = this;
352
+ appUtil.startByType(self, function () {
353
+ appUtil.loadDefaultComponents(self);
354
+ let startUp = function () {
355
+ self.state = STATE_BEFORE_START;
356
+ logger.info('%j enter before start...', self.getServerId());
357
+ appUtil.optComponents(self.loaded, Constants.RESERVED.BEFORE_START, function (err) {
358
+ if (err) {
359
+ utils.invokeCallback(cb, err);
360
+ }
361
+ else {
362
+ logger.info('%j enter start...', self.getServerId());
363
+ appUtil.optComponents(self.loaded, Constants.RESERVED.START, function (err) {
364
+ self.state = STATE_START;
365
+ if (err) {
366
+ utils.invokeCallback(cb, err);
367
+ }
368
+ else {
369
+ logger.info('%j enter after start...', self.getServerId());
370
+ self.afterStart(cb);
371
+ }
372
+ });
373
+ }
374
+ });
375
+ };
376
+ appUtil.optLifecycles(self.usedPlugins, Constants.LIFECYCLE.BEFORE_STARTUP, self, function (err) {
377
+ if (err) {
378
+ utils.invokeCallback(cb, err);
379
+ }
380
+ else {
381
+ startUp();
382
+ }
383
+ });
384
+ });
385
+ }
386
+ /**
387
+ * Lifecycle callback for after start.
388
+ *
389
+ * @param {Function} cb callback function
390
+ * @return {Void}
391
+ */
392
+ afterStart(cb) {
393
+ if (this.state !== STATE_START) {
394
+ utils.invokeCallback(cb, new Error('application is not running now.'));
395
+ return;
396
+ }
397
+ let self = this;
398
+ appUtil.optComponents(this.loaded, Constants.RESERVED.AFTER_START, function (err) {
399
+ self.state = STATE_STARTED;
400
+ let id = self.getServerId();
401
+ if (!err) {
402
+ logger.info('%j finish start', id);
403
+ }
404
+ appUtil.optLifecycles(self.usedPlugins, Constants.LIFECYCLE.AFTER_STARTUP, self, function (err) {
405
+ let usedTime = Date.now() - self.startTime;
406
+ logger.info('%j startup in %s ms', id, usedTime);
407
+ self.event.emit(events_2.default.START_SERVER, id);
408
+ cb && cb(err);
409
+ });
410
+ });
411
+ }
412
+ /**
413
+ * Stop components.
414
+ *
415
+ * @param {Boolean} force whether stop the app immediately
416
+ */
417
+ stop(force) {
418
+ if (this.state > STATE_STARTED) {
419
+ logger.warn('[melo application] application is not running now.');
420
+ return;
421
+ }
422
+ this.state = STATE_STOPED;
423
+ let self = this;
424
+ this.stopTimer = setTimeout(function () {
425
+ process.exit(0);
426
+ }, Constants.TIME.TIME_WAIT_STOP);
427
+ let cancelShutDownTimer = function () {
428
+ if (!!self.stopTimer) {
429
+ clearTimeout(self.stopTimer);
430
+ }
431
+ };
432
+ let shutDown = function () {
433
+ appUtil.stopComps(self.loaded, 0, force, function () {
434
+ cancelShutDownTimer();
435
+ if (force) {
436
+ process.exit(0);
437
+ }
438
+ });
439
+ };
440
+ let fun = this.get(Constants.KEYWORDS.BEFORE_STOP_HOOK);
441
+ appUtil.optLifecycles(self.usedPlugins, Constants.LIFECYCLE.BEFORE_SHUTDOWN, self, function (err) {
442
+ if (err) {
443
+ console.error(`throw err when beforeShutdown `, err.stack);
444
+ }
445
+ else {
446
+ if (!!fun) {
447
+ utils.invokeCallback(fun, self, shutDown, cancelShutDownTimer);
448
+ }
449
+ else {
450
+ shutDown();
451
+ }
452
+ }
453
+ }, cancelShutDownTimer);
454
+ }
455
+ set(setting, val, attach) {
456
+ this.settings[setting] = val;
457
+ if (attach) {
458
+ this[setting] = val;
459
+ }
460
+ return this;
461
+ }
462
+ get(setting) {
463
+ return this.settings[setting];
464
+ }
465
+ /**
466
+ * Check if `setting` is enabled.
467
+ *
468
+ * @param {String} setting application setting
469
+ * @return {Boolean}
470
+ * @memberOf Application
471
+ */
472
+ enabled(setting) {
473
+ return !!this.get(setting);
474
+ }
475
+ /**
476
+ * Check if `setting` is disabled.
477
+ *
478
+ * @param {String} setting application setting
479
+ * @return {Boolean}
480
+ * @memberOf Application
481
+ */
482
+ disabled(setting) {
483
+ return !this.get(setting);
484
+ }
485
+ /**
486
+ * Enable `setting`.
487
+ *
488
+ * @param {String} setting application setting
489
+ * @return {app} for chaining
490
+ * @memberOf Application
491
+ */
492
+ enable(setting) {
493
+ return this.set(setting, true);
494
+ }
495
+ /**
496
+ * Disable `setting`.
497
+ *
498
+ * @param {String} setting application setting
499
+ * @return {app} for chaining
500
+ * @memberOf Application
501
+ */
502
+ disable(setting) {
503
+ return this.set(setting, false);
504
+ }
505
+ configure(env, type, fn) {
506
+ let args = [].slice.call(arguments);
507
+ fn = args.pop();
508
+ env = type = Constants.RESERVED.ALL;
509
+ if (args.length > 0) {
510
+ env = args[0];
511
+ }
512
+ if (args.length > 1) {
513
+ type = args[1];
514
+ }
515
+ if (env === Constants.RESERVED.ALL || contains(this.settings.env, env)) {
516
+ if (type === Constants.RESERVED.ALL || contains(this.settings.serverType, type)) {
517
+ fn.call(this);
518
+ }
519
+ }
520
+ return this;
521
+ }
522
+ registerAdmin(moduleId, module, opts) {
523
+ let modules = this.get(Constants.KEYWORDS.MODULE);
524
+ if (!modules) {
525
+ modules = {};
526
+ this.set(Constants.KEYWORDS.MODULE, modules);
527
+ }
528
+ if (typeof moduleId !== 'string') {
529
+ opts = module;
530
+ module = moduleId;
531
+ if (module) {
532
+ moduleId = (module.moduleId);
533
+ if (!moduleId)
534
+ moduleId = module.constructor.name;
535
+ }
536
+ }
537
+ if (!moduleId) {
538
+ return;
539
+ }
540
+ modules[moduleId] = {
541
+ moduleId: moduleId,
542
+ module: module,
543
+ opts: opts
544
+ };
545
+ }
546
+ /**
547
+ * Use plugin.
548
+ *
549
+ * @param {Object} plugin plugin instance
550
+ * @param {[type]} opts (optional) construct parameters for the factory function
551
+ * @memberOf Application
552
+ */
553
+ use(plugin, opts) {
554
+ opts = opts || {};
555
+ if (!plugin) {
556
+ throw new Error(`pluin is null!]`);
557
+ }
558
+ if (this.usedPlugins.indexOf(plugin) >= 0) {
559
+ throw new Error(`pluin[${plugin.name} was used already!]`);
560
+ }
561
+ if (plugin.components) {
562
+ for (let componentCtor of plugin.components) {
563
+ this.load(componentCtor, opts);
564
+ }
565
+ }
566
+ if (plugin.events) {
567
+ for (let eventCtor of plugin.events) {
568
+ this.loadEvent(eventCtor, opts);
569
+ }
570
+ }
571
+ this.usedPlugins.push(plugin);
572
+ console.warn(`used Plugin : ${plugin.name}`);
573
+ }
574
+ /**
575
+ * Application transaction. Transcation includes conditions and handlers, if conditions are satisfied, handlers would be executed.
576
+ * And you can set retry times to execute handlers. The transaction log is in file logs/transaction.log.
577
+ *
578
+ * @param {String} name transaction name
579
+ * @param {Object} conditions functions which are called before transaction
580
+ * @param {Object} handlers functions which are called during transaction
581
+ * @param {Number} retry retry times to execute handlers if conditions are successfully executed
582
+ * @memberOf Application
583
+ */
584
+ transaction(name, conditions, handlers, retry) {
585
+ appManager.transaction(name, conditions, handlers, retry);
586
+ }
587
+ /**
588
+ * Get master server info.
589
+ *
590
+ * @return {Object} master server info, {id, host, port}
591
+ * @memberOf Application
592
+ */
593
+ getMaster() {
594
+ return this.master;
595
+ }
596
+ /**
597
+ * Get current server info.
598
+ *
599
+ * @return {Object} current server info, {id, serverType, host, port}
600
+ * @memberOf Application
601
+ */
602
+ getCurServer() {
603
+ return this.curServer;
604
+ }
605
+ /**
606
+ * Get current server id.
607
+ *
608
+ * @return {String|Number} current server id from servers.json
609
+ * @memberOf Application
610
+ */
611
+ getServerId() {
612
+ return this.serverId;
613
+ }
614
+ /**
615
+ * Get current server
616
+ * @returns ServerInfo
617
+ */
618
+ getCurrentServer() {
619
+ return this.curServer;
620
+ }
621
+ /**
622
+ * Get current server type.
623
+ *
624
+ * @return {String|Number} current server type from servers.json
625
+ * @memberOf Application
626
+ */
627
+ getServerType() {
628
+ return this.serverType;
629
+ }
630
+ /**
631
+ * Get all the current server infos.
632
+ *
633
+ * @return {Object} server info map, key: server id, value: server info
634
+ * @memberOf Application
635
+ */
636
+ getServers() {
637
+ return this.servers;
638
+ }
639
+ /**
640
+ * Get all server infos from servers.json.
641
+ *
642
+ * @return {Object} server info map, key: server id, value: server info
643
+ * @memberOf Application
644
+ */
645
+ getServersFromConfig() {
646
+ return this.get(Constants.KEYWORDS.SERVER_MAP);
647
+ }
648
+ /**
649
+ * Get all the server type.
650
+ *
651
+ * @return {Array} server type list
652
+ * @memberOf Application
653
+ */
654
+ getServerTypes() {
655
+ return this.serverTypes;
656
+ }
657
+ /**
658
+ * Get server info by server id from current server cluster.
659
+ *
660
+ * @param {String} serverId server id
661
+ * @return {Object} server info or undefined
662
+ * @memberOf Application
663
+ */
664
+ getServerById(serverId) {
665
+ return this.servers[serverId];
666
+ }
667
+ /**
668
+ * Get server info by server id from servers.json.
669
+ *
670
+ * @param {String} serverId server id
671
+ * @return {Object} server info or undefined
672
+ * @memberOf Application
673
+ */
674
+ getServerFromConfig(serverId) {
675
+ return this.get(Constants.KEYWORDS.SERVER_MAP)[serverId];
676
+ }
677
+ /**
678
+ * Get server infos by server type.
679
+ *
680
+ * @param {String} serverType server type
681
+ * @return {Array} server info list
682
+ * @memberOf Application
683
+ */
684
+ getServersByType(serverType) {
685
+ return this.serverTypeMaps[serverType];
686
+ }
687
+ /**
688
+ * Check the server whether is a frontend server
689
+ *
690
+ * @param {server} server server info. it would check current server
691
+ * if server not specified
692
+ * @return {Boolean}
693
+ *
694
+ * @memberOf Application
695
+ */
696
+ isFrontend(server) {
697
+ server = server || this.getCurServer();
698
+ return !!server && server.frontend === 'true';
699
+ }
700
+ /**
701
+ * Check the server whether is a backend server
702
+ *
703
+ * @param {server} server server info. it would check current server
704
+ * if server not specified
705
+ * @return {Boolean}
706
+ * @memberOf Application
707
+ */
708
+ isBackend(server) {
709
+ server = server || this.getCurServer();
710
+ return !!server && !server.frontend;
711
+ }
712
+ /**
713
+ * Check whether current server is a master server
714
+ *
715
+ * @return {Boolean}
716
+ * @memberOf Application
717
+ */
718
+ isMaster() {
719
+ return this.serverType === Constants.RESERVED.MASTER;
720
+ }
721
+ /**
722
+ * Add new server info to current application in runtime.
723
+ *
724
+ * @param {Array} servers new server info list
725
+ * @memberOf Application
726
+ */
727
+ addServers(servers) {
728
+ if (!servers || !servers.length) {
729
+ return;
730
+ }
731
+ let item, slist;
732
+ for (let i = 0, l = servers.length; i < l; i++) {
733
+ item = servers[i];
734
+ // update global server map
735
+ this.servers[item.id] = item;
736
+ // update global server type map
737
+ slist = this.serverTypeMaps[item.serverType];
738
+ if (!slist) {
739
+ this.serverTypeMaps[item.serverType] = slist = [];
740
+ }
741
+ replaceServer(slist, item);
742
+ // update global server type list
743
+ if (this.serverTypes.indexOf(item.serverType) < 0) {
744
+ this.serverTypes.push(item.serverType);
745
+ }
746
+ }
747
+ this.event.emit(events_2.default.ADD_SERVERS, servers);
748
+ }
749
+ /**
750
+ * Remove server info from current application at runtime.
751
+ *
752
+ * @param {Array} ids server id list
753
+ * @memberOf Application
754
+ */
755
+ removeServers(ids) {
756
+ if (!ids || !ids.length) {
757
+ return;
758
+ }
759
+ let id, item, slist;
760
+ for (let i = 0, l = ids.length; i < l; i++) {
761
+ id = ids[i];
762
+ item = this.servers[id];
763
+ if (!item) {
764
+ continue;
765
+ }
766
+ // clean global server map
767
+ delete this.servers[id];
768
+ // clean global server type map
769
+ slist = this.serverTypeMaps[item.serverType];
770
+ removeServer(slist, id);
771
+ // TODO: should remove the server type if the slist is empty?
772
+ }
773
+ this.event.emit(events_2.default.REMOVE_SERVERS, ids);
774
+ }
775
+ /**
776
+ * Replace server info from current application at runtime.
777
+ *
778
+ * @param {Object} server id map
779
+ * @memberOf Application
780
+ */
781
+ replaceServers(servers) {
782
+ if (!servers) {
783
+ return;
784
+ }
785
+ this.servers = servers;
786
+ this.serverTypeMaps = {};
787
+ this.serverTypes = [];
788
+ let serverArray = [];
789
+ for (let id in servers) {
790
+ let server = servers[id];
791
+ let serverType = server[Constants.RESERVED.SERVER_TYPE];
792
+ let slist = this.serverTypeMaps[serverType];
793
+ if (!slist) {
794
+ this.serverTypeMaps[serverType] = slist = [];
795
+ }
796
+ this.serverTypeMaps[serverType].push(server);
797
+ // update global server type list
798
+ if (this.serverTypes.indexOf(serverType) < 0) {
799
+ this.serverTypes.push(serverType);
800
+ }
801
+ serverArray.push(server);
802
+ }
803
+ this.event.emit(events_2.default.REPLACE_SERVERS, serverArray);
804
+ }
805
+ /**
806
+ * Add crons from current application at runtime.
807
+ *
808
+ * @param {Array} crons new crons would be added in application
809
+ * @memberOf Application
810
+ */
811
+ addCrons(crons) {
812
+ if (!crons || !crons.length) {
813
+ logger.warn('crons is not defined.');
814
+ return;
815
+ }
816
+ this.event.emit(events_2.default.ADD_CRONS, crons);
817
+ }
818
+ /**
819
+ * Remove crons from current application at runtime.
820
+ *
821
+ * @param {Array} crons old crons would be removed in application
822
+ * @memberOf Application
823
+ */
824
+ removeCrons(crons) {
825
+ if (!crons || !crons.length) {
826
+ logger.warn('ids is not defined.');
827
+ return;
828
+ }
829
+ this.event.emit(events_2.default.REMOVE_CRONS, crons);
830
+ }
831
+ /**
832
+ * 加载一个事件侦听
833
+ * @param Event
834
+ * @param opts
835
+ */
836
+ loadEvent(Event, opts) {
837
+ let eventInstance = new Event(opts);
838
+ for (let evt in events_2.AppEvents) {
839
+ let name = events_2.AppEvents[evt];
840
+ let method = eventInstance[name];
841
+ if (method) {
842
+ this.event.on(name, method.bind(eventInstance));
843
+ }
844
+ }
845
+ }
846
+ }
847
+ exports.Application = Application;
848
+ let replaceServer = function (slist, serverInfo) {
849
+ for (let i = 0, l = slist.length; i < l; i++) {
850
+ if (slist[i].id === serverInfo.id) {
851
+ slist[i] = serverInfo;
852
+ return;
853
+ }
854
+ }
855
+ slist.push(serverInfo);
856
+ };
857
+ let removeServer = function (slist, id) {
858
+ if (!slist || !slist.length) {
859
+ return;
860
+ }
861
+ for (let i = 0, l = slist.length; i < l; i++) {
862
+ if (slist[i].id === id) {
863
+ slist.splice(i, 1);
864
+ return;
865
+ }
866
+ }
867
+ };
868
+ let contains = function (str, settings) {
869
+ if (!settings) {
870
+ return false;
871
+ }
872
+ let ts = settings.split('|');
873
+ for (let i = 0, l = ts.length; i < l; i++) {
874
+ if (str === ts[i]) {
875
+ return true;
876
+ }
877
+ }
878
+ return false;
879
+ };
880
+ let addFilter = function (app, type, filter) {
881
+ let filters = app.get(type);
882
+ if (!filters) {
883
+ filters = [];
884
+ app.set(type, filters);
885
+ }
886
+ filters.push(filter);
887
+ };
888
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwbGljYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9saWIvYXBwbGljYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7O0dBSUc7OztBQUVIOztHQUVHO0FBQ0gsc0NBQXNDO0FBQ3RDLHlEQUE2RDtBQUM3RCxtQ0FBc0M7QUFDdEMsMENBQTZEO0FBQzdELDBDQUEwQztBQUUxQyw4Q0FBOEM7QUFFOUMsMERBQTBEO0FBRTFELHlCQUF5QjtBQUN6Qiw2QkFBNkI7QUE0QjdCLElBQUksTUFBTSxHQUFHLElBQUEsdUJBQVMsRUFBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO0FBa0UxRDs7R0FFRztBQUNILElBQUksWUFBWSxHQUFHLENBQUMsQ0FBQyxDQUFFLGlCQUFpQjtBQUN4QyxJQUFJLGtCQUFrQixHQUFHLENBQUMsQ0FBQyxDQUFFLG1CQUFtQjtBQUNoRCxJQUFJLFdBQVcsR0FBRyxDQUFDLENBQUMsQ0FBRSxZQUFZO0FBQ2xDLElBQUksYUFBYSxHQUFHLENBQUMsQ0FBQyxDQUFFLGtCQUFrQjtBQUMxQyxJQUFJLFlBQVksR0FBRyxDQUFDLENBQUMsQ0FBRSxpQkFBaUI7QUFFeEMsTUFBYSxXQUFXO0lBQXhCO1FBRUksV0FBTSxHQUFpQixFQUFFLENBQUMsQ0FBTyx3QkFBd0I7UUFDekQsZUFBVSxHQWVOLEVBQUUsQ0FBQyxDQUFHLHdCQUF3QjtRQU1sQyxhQUFRLEdBQTJCLEVBQUUsQ0FBQyxDQUFLLDBCQUEwQjtRQUNyRSxVQUFLLEdBQUcsSUFBSSxxQkFBWSxFQUFFLENBQUMsQ0FBRSxpQ0FBaUM7UUFROUQsc0JBQXNCO1FBQ3RCLFdBQU0sR0FBb0IsSUFBSSxDQUFDLENBQVMscUJBQXFCO1FBQzdELFlBQU8sR0FBaUMsRUFBRSxDQUFDLENBQVUsOENBQThDO1FBQ25HLG1CQUFjLEdBQXFDLEVBQUUsQ0FBQyxDQUFHLDJDQUEyQztRQUNwRyxnQkFB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