soajs.controller 4.2.43 → 4.3.1

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.
@@ -3,7 +3,7 @@
3
3
  const helper = require("../../../helper.js");
4
4
  const mw = helper.requireModule('./mw/lastSeen/index');
5
5
  const assert = require('assert');
6
- const nock = require('nock')
6
+ const nock = require('nock');
7
7
 
8
8
  describe("Unit test for: mw - lastSeen", () => {
9
9
 
@@ -11,7 +11,7 @@ describe("Unit test for: mw - lastSeen", () => {
11
11
  let res = {};
12
12
  let req = {
13
13
  getClientIP: () => {
14
- return "127.0.0.1"
14
+ return "127.0.0.1";
15
15
  },
16
16
  soajs: {
17
17
  log: {
@@ -65,4 +65,948 @@ describe("Unit test for: mw - lastSeen", () => {
65
65
  });
66
66
  });
67
67
 
68
+ describe("include filter tests", () => {
69
+
70
+ it("no include filter - backward compatibility - should trigger", (done) => {
71
+ let res = {};
72
+ let req = {
73
+ method: "GET",
74
+ getClientIP: () => {
75
+ return "127.0.0.1";
76
+ },
77
+ soajs: {
78
+ log: {
79
+ debug: (a) => {
80
+ console.log(a);
81
+ },
82
+ error: (a) => {
83
+ console.log(a);
84
+ }
85
+ },
86
+ controller: {
87
+ serviceParams: {
88
+ name: "dashboard",
89
+ parsedUrl: {
90
+ pathname: "/some/api"
91
+ }
92
+ }
93
+ },
94
+ uracDriver: {
95
+ getProfile: () => {
96
+ return { _id: "1111111111" };
97
+ }
98
+ },
99
+ awareness: {
100
+ getHost: (name, version, cb) => {
101
+ return cb("urac.fake");
102
+ }
103
+ },
104
+ registry: {
105
+ services: {
106
+ urac: {
107
+ port: 4001
108
+ }
109
+ },
110
+ custom: {
111
+ gateway: {
112
+ value: {
113
+ lastSeen: {
114
+ active: true,
115
+ network: "YAYA"
116
+ // No include filter
117
+ }
118
+ }
119
+ }
120
+ }
121
+ }
122
+ }
123
+ };
124
+ const scope = nock('http://urac.fake:4001')
125
+ .post('/user/last/seen', "{\"network\":\"YAYA\"}")
126
+ .reply(200, {
127
+ result: true,
128
+ data: true
129
+ });
130
+ let functionMw = mw({});
131
+ functionMw(req, res, (error) => {
132
+ assert.ifError(error);
133
+ done();
134
+ });
135
+ });
136
+
137
+ it("include filter with service true - should trigger for any API/method", (done) => {
138
+ let res = {};
139
+ let req = {
140
+ method: "POST",
141
+ getClientIP: () => {
142
+ return "127.0.0.1";
143
+ },
144
+ soajs: {
145
+ log: {
146
+ debug: (a) => {
147
+ console.log(a);
148
+ },
149
+ error: (a) => {
150
+ console.log(a);
151
+ }
152
+ },
153
+ controller: {
154
+ serviceParams: {
155
+ name: "dashboard",
156
+ parsedUrl: {
157
+ pathname: "/any/api/path"
158
+ }
159
+ }
160
+ },
161
+ uracDriver: {
162
+ getProfile: () => {
163
+ return { _id: "1111111111" };
164
+ }
165
+ },
166
+ awareness: {
167
+ getHost: (name, version, cb) => {
168
+ return cb("urac.fake");
169
+ }
170
+ },
171
+ registry: {
172
+ services: {
173
+ urac: {
174
+ port: 4001
175
+ }
176
+ },
177
+ custom: {
178
+ gateway: {
179
+ value: {
180
+ lastSeen: {
181
+ active: true,
182
+ network: "YAYA",
183
+ include: {
184
+ "dashboard": true
185
+ }
186
+ }
187
+ }
188
+ }
189
+ }
190
+ }
191
+ }
192
+ };
193
+ const scope = nock('http://urac.fake:4001')
194
+ .post('/user/last/seen', "{\"network\":\"YAYA\"}")
195
+ .reply(200, {
196
+ result: true,
197
+ data: true
198
+ });
199
+ let functionMw = mw({});
200
+ functionMw(req, res, (error) => {
201
+ assert.ifError(error);
202
+ done();
203
+ });
204
+ });
205
+
206
+ it("include filter with service NOT in whitelist - should NOT trigger", (done) => {
207
+ let lastSeenSkipped = false;
208
+ let res = {};
209
+ let req = {
210
+ method: "GET",
211
+ getClientIP: () => {
212
+ return "127.0.0.1";
213
+ },
214
+ soajs: {
215
+ log: {
216
+ debug: (a) => {
217
+ console.log(a);
218
+ if (a && a.includes && a.includes("lastSeen skipped")) {
219
+ lastSeenSkipped = true;
220
+ }
221
+ },
222
+ error: (a) => {
223
+ console.log(a);
224
+ }
225
+ },
226
+ controller: {
227
+ serviceParams: {
228
+ name: "other-service",
229
+ parsedUrl: {
230
+ pathname: "/some/api"
231
+ }
232
+ }
233
+ },
234
+ uracDriver: {
235
+ getProfile: () => {
236
+ return { _id: "1111111111" };
237
+ }
238
+ },
239
+ awareness: {
240
+ getHost: (name, version, cb) => {
241
+ return cb("urac.fake");
242
+ }
243
+ },
244
+ registry: {
245
+ services: {
246
+ urac: {
247
+ port: 4001
248
+ }
249
+ },
250
+ custom: {
251
+ gateway: {
252
+ value: {
253
+ lastSeen: {
254
+ active: true,
255
+ network: "YAYA",
256
+ include: {
257
+ "dashboard": true
258
+ }
259
+ }
260
+ }
261
+ }
262
+ }
263
+ }
264
+ }
265
+ };
266
+ let functionMw = mw({});
267
+ functionMw(req, res, (error) => {
268
+ assert.ifError(error);
269
+ setTimeout(() => {
270
+ assert.ok(lastSeenSkipped, "lastSeen should have been skipped");
271
+ done();
272
+ }, 50);
273
+ });
274
+ });
275
+
276
+ it("include filter with specific API and method match - should trigger", (done) => {
277
+ let res = {};
278
+ let req = {
279
+ method: "POST",
280
+ getClientIP: () => {
281
+ return "127.0.0.1";
282
+ },
283
+ soajs: {
284
+ log: {
285
+ debug: (a) => {
286
+ console.log(a);
287
+ },
288
+ error: (a) => {
289
+ console.log(a);
290
+ }
291
+ },
292
+ controller: {
293
+ serviceParams: {
294
+ name: "urac",
295
+ parsedUrl: {
296
+ pathname: "/user/profile"
297
+ }
298
+ }
299
+ },
300
+ uracDriver: {
301
+ getProfile: () => {
302
+ return { _id: "1111111111" };
303
+ }
304
+ },
305
+ awareness: {
306
+ getHost: (name, version, cb) => {
307
+ return cb("urac.fake");
308
+ }
309
+ },
310
+ registry: {
311
+ services: {
312
+ urac: {
313
+ port: 4001
314
+ }
315
+ },
316
+ custom: {
317
+ gateway: {
318
+ value: {
319
+ lastSeen: {
320
+ active: true,
321
+ network: "YAYA",
322
+ include: {
323
+ "urac": {
324
+ "apis": {
325
+ "/user/profile": ["get", "post"]
326
+ }
327
+ }
328
+ }
329
+ }
330
+ }
331
+ }
332
+ }
333
+ }
334
+ }
335
+ };
336
+ const scope = nock('http://urac.fake:4001')
337
+ .post('/user/last/seen', "{\"network\":\"YAYA\"}")
338
+ .reply(200, {
339
+ result: true,
340
+ data: true
341
+ });
342
+ let functionMw = mw({});
343
+ functionMw(req, res, (error) => {
344
+ assert.ifError(error);
345
+ done();
346
+ });
347
+ });
348
+
349
+ it("include filter with specific API but method NOT match - should NOT trigger", (done) => {
350
+ let lastSeenSkipped = false;
351
+ let res = {};
352
+ let req = {
353
+ method: "DELETE",
354
+ getClientIP: () => {
355
+ return "127.0.0.1";
356
+ },
357
+ soajs: {
358
+ log: {
359
+ debug: (a) => {
360
+ console.log(a);
361
+ if (a && a.includes && a.includes("lastSeen skipped")) {
362
+ lastSeenSkipped = true;
363
+ }
364
+ },
365
+ error: (a) => {
366
+ console.log(a);
367
+ }
368
+ },
369
+ controller: {
370
+ serviceParams: {
371
+ name: "urac",
372
+ parsedUrl: {
373
+ pathname: "/user/profile"
374
+ }
375
+ }
376
+ },
377
+ uracDriver: {
378
+ getProfile: () => {
379
+ return { _id: "1111111111" };
380
+ }
381
+ },
382
+ awareness: {
383
+ getHost: (name, version, cb) => {
384
+ return cb("urac.fake");
385
+ }
386
+ },
387
+ registry: {
388
+ services: {
389
+ urac: {
390
+ port: 4001
391
+ }
392
+ },
393
+ custom: {
394
+ gateway: {
395
+ value: {
396
+ lastSeen: {
397
+ active: true,
398
+ network: "YAYA",
399
+ include: {
400
+ "urac": {
401
+ "apis": {
402
+ "/user/profile": ["get", "post"]
403
+ }
404
+ }
405
+ }
406
+ }
407
+ }
408
+ }
409
+ }
410
+ }
411
+ }
412
+ };
413
+ let functionMw = mw({});
414
+ functionMw(req, res, (error) => {
415
+ assert.ifError(error);
416
+ setTimeout(() => {
417
+ assert.ok(lastSeenSkipped, "lastSeen should have been skipped");
418
+ done();
419
+ }, 50);
420
+ });
421
+ });
422
+
423
+ it("include filter with API true - all methods - should trigger", (done) => {
424
+ let res = {};
425
+ let req = {
426
+ method: "PUT",
427
+ getClientIP: () => {
428
+ return "127.0.0.1";
429
+ },
430
+ soajs: {
431
+ log: {
432
+ debug: (a) => {
433
+ console.log(a);
434
+ },
435
+ error: (a) => {
436
+ console.log(a);
437
+ }
438
+ },
439
+ controller: {
440
+ serviceParams: {
441
+ name: "urac",
442
+ parsedUrl: {
443
+ pathname: "/user/login"
444
+ }
445
+ }
446
+ },
447
+ uracDriver: {
448
+ getProfile: () => {
449
+ return { _id: "1111111111" };
450
+ }
451
+ },
452
+ awareness: {
453
+ getHost: (name, version, cb) => {
454
+ return cb("urac.fake");
455
+ }
456
+ },
457
+ registry: {
458
+ services: {
459
+ urac: {
460
+ port: 4001
461
+ }
462
+ },
463
+ custom: {
464
+ gateway: {
465
+ value: {
466
+ lastSeen: {
467
+ active: true,
468
+ network: "YAYA",
469
+ include: {
470
+ "urac": {
471
+ "apis": {
472
+ "/user/login": true
473
+ }
474
+ }
475
+ }
476
+ }
477
+ }
478
+ }
479
+ }
480
+ }
481
+ }
482
+ };
483
+ const scope = nock('http://urac.fake:4001')
484
+ .post('/user/last/seen', "{\"network\":\"YAYA\"}")
485
+ .reply(200, {
486
+ result: true,
487
+ data: true
488
+ });
489
+ let functionMw = mw({});
490
+ functionMw(req, res, (error) => {
491
+ assert.ifError(error);
492
+ done();
493
+ });
494
+ });
495
+
496
+ it("include filter with wildcard '*': true - should trigger for all APIs", (done) => {
497
+ let res = {};
498
+ let req = {
499
+ method: "GET",
500
+ getClientIP: () => {
501
+ return "127.0.0.1";
502
+ },
503
+ soajs: {
504
+ log: {
505
+ debug: (a) => {
506
+ console.log(a);
507
+ },
508
+ error: (a) => {
509
+ console.log(a);
510
+ }
511
+ },
512
+ controller: {
513
+ serviceParams: {
514
+ name: "multitenant",
515
+ parsedUrl: {
516
+ pathname: "/any/random/api"
517
+ }
518
+ }
519
+ },
520
+ uracDriver: {
521
+ getProfile: () => {
522
+ return { _id: "1111111111" };
523
+ }
524
+ },
525
+ awareness: {
526
+ getHost: (name, version, cb) => {
527
+ return cb("urac.fake");
528
+ }
529
+ },
530
+ registry: {
531
+ services: {
532
+ urac: {
533
+ port: 4001
534
+ }
535
+ },
536
+ custom: {
537
+ gateway: {
538
+ value: {
539
+ lastSeen: {
540
+ active: true,
541
+ network: "YAYA",
542
+ include: {
543
+ "multitenant": {
544
+ "apis": {
545
+ "*": true
546
+ }
547
+ }
548
+ }
549
+ }
550
+ }
551
+ }
552
+ }
553
+ }
554
+ }
555
+ };
556
+ const scope = nock('http://urac.fake:4001')
557
+ .post('/user/last/seen', "{\"network\":\"YAYA\"}")
558
+ .reply(200, {
559
+ result: true,
560
+ data: true
561
+ });
562
+ let functionMw = mw({});
563
+ functionMw(req, res, (error) => {
564
+ assert.ifError(error);
565
+ done();
566
+ });
567
+ });
568
+
569
+ it("include filter with wildcard '*' and method array - should trigger for matching method", (done) => {
570
+ let res = {};
571
+ let req = {
572
+ method: "POST",
573
+ getClientIP: () => {
574
+ return "127.0.0.1";
575
+ },
576
+ soajs: {
577
+ log: {
578
+ debug: (a) => {
579
+ console.log(a);
580
+ },
581
+ error: (a) => {
582
+ console.log(a);
583
+ }
584
+ },
585
+ controller: {
586
+ serviceParams: {
587
+ name: "multitenant",
588
+ parsedUrl: {
589
+ pathname: "/any/random/api"
590
+ }
591
+ }
592
+ },
593
+ uracDriver: {
594
+ getProfile: () => {
595
+ return { _id: "1111111111" };
596
+ }
597
+ },
598
+ awareness: {
599
+ getHost: (name, version, cb) => {
600
+ return cb("urac.fake");
601
+ }
602
+ },
603
+ registry: {
604
+ services: {
605
+ urac: {
606
+ port: 4001
607
+ }
608
+ },
609
+ custom: {
610
+ gateway: {
611
+ value: {
612
+ lastSeen: {
613
+ active: true,
614
+ network: "YAYA",
615
+ include: {
616
+ "multitenant": {
617
+ "apis": {
618
+ "*": ["post", "put"]
619
+ }
620
+ }
621
+ }
622
+ }
623
+ }
624
+ }
625
+ }
626
+ }
627
+ }
628
+ };
629
+ const scope = nock('http://urac.fake:4001')
630
+ .post('/user/last/seen', "{\"network\":\"YAYA\"}")
631
+ .reply(200, {
632
+ result: true,
633
+ data: true
634
+ });
635
+ let functionMw = mw({});
636
+ functionMw(req, res, (error) => {
637
+ assert.ifError(error);
638
+ done();
639
+ });
640
+ });
641
+
642
+ it("include filter with wildcard '*' and method array - should NOT trigger for non-matching method", (done) => {
643
+ let lastSeenSkipped = false;
644
+ let res = {};
645
+ let req = {
646
+ method: "GET",
647
+ getClientIP: () => {
648
+ return "127.0.0.1";
649
+ },
650
+ soajs: {
651
+ log: {
652
+ debug: (a) => {
653
+ console.log(a);
654
+ if (a && a.includes && a.includes("lastSeen skipped")) {
655
+ lastSeenSkipped = true;
656
+ }
657
+ },
658
+ error: (a) => {
659
+ console.log(a);
660
+ }
661
+ },
662
+ controller: {
663
+ serviceParams: {
664
+ name: "multitenant",
665
+ parsedUrl: {
666
+ pathname: "/any/random/api"
667
+ }
668
+ }
669
+ },
670
+ uracDriver: {
671
+ getProfile: () => {
672
+ return { _id: "1111111111" };
673
+ }
674
+ },
675
+ awareness: {
676
+ getHost: (name, version, cb) => {
677
+ return cb("urac.fake");
678
+ }
679
+ },
680
+ registry: {
681
+ services: {
682
+ urac: {
683
+ port: 4001
684
+ }
685
+ },
686
+ custom: {
687
+ gateway: {
688
+ value: {
689
+ lastSeen: {
690
+ active: true,
691
+ network: "YAYA",
692
+ include: {
693
+ "multitenant": {
694
+ "apis": {
695
+ "*": ["post", "put"]
696
+ }
697
+ }
698
+ }
699
+ }
700
+ }
701
+ }
702
+ }
703
+ }
704
+ }
705
+ };
706
+ let functionMw = mw({});
707
+ functionMw(req, res, (error) => {
708
+ assert.ifError(error);
709
+ setTimeout(() => {
710
+ assert.ok(lastSeenSkipped, "lastSeen should have been skipped");
711
+ done();
712
+ }, 50);
713
+ });
714
+ });
715
+
716
+ it("include filter with API not in whitelist - should NOT trigger", (done) => {
717
+ let lastSeenSkipped = false;
718
+ let res = {};
719
+ let req = {
720
+ method: "GET",
721
+ getClientIP: () => {
722
+ return "127.0.0.1";
723
+ },
724
+ soajs: {
725
+ log: {
726
+ debug: (a) => {
727
+ console.log(a);
728
+ if (a && a.includes && a.includes("lastSeen skipped")) {
729
+ lastSeenSkipped = true;
730
+ }
731
+ },
732
+ error: (a) => {
733
+ console.log(a);
734
+ }
735
+ },
736
+ controller: {
737
+ serviceParams: {
738
+ name: "urac",
739
+ parsedUrl: {
740
+ pathname: "/user/other-api"
741
+ }
742
+ }
743
+ },
744
+ uracDriver: {
745
+ getProfile: () => {
746
+ return { _id: "1111111111" };
747
+ }
748
+ },
749
+ awareness: {
750
+ getHost: (name, version, cb) => {
751
+ return cb("urac.fake");
752
+ }
753
+ },
754
+ registry: {
755
+ services: {
756
+ urac: {
757
+ port: 4001
758
+ }
759
+ },
760
+ custom: {
761
+ gateway: {
762
+ value: {
763
+ lastSeen: {
764
+ active: true,
765
+ network: "YAYA",
766
+ include: {
767
+ "urac": {
768
+ "apis": {
769
+ "/user/profile": ["get", "post"]
770
+ }
771
+ }
772
+ }
773
+ }
774
+ }
775
+ }
776
+ }
777
+ }
778
+ }
779
+ };
780
+ let functionMw = mw({});
781
+ functionMw(req, res, (error) => {
782
+ assert.ifError(error);
783
+ setTimeout(() => {
784
+ assert.ok(lastSeenSkipped, "lastSeen should have been skipped");
785
+ done();
786
+ }, 50);
787
+ });
788
+ });
789
+
790
+ it("include filter with path params - should trigger for matching URL", (done) => {
791
+ let res = {};
792
+ let req = {
793
+ method: "POST",
794
+ getClientIP: () => {
795
+ return "127.0.0.1";
796
+ },
797
+ soajs: {
798
+ log: {
799
+ debug: (a) => {
800
+ console.log(a);
801
+ },
802
+ error: (a) => {
803
+ console.log(a);
804
+ }
805
+ },
806
+ controller: {
807
+ serviceParams: {
808
+ name: "av",
809
+ parsedUrl: {
810
+ pathname: "/get/calls/room/abc123"
811
+ }
812
+ }
813
+ },
814
+ uracDriver: {
815
+ getProfile: () => {
816
+ return { _id: "1111111111" };
817
+ }
818
+ },
819
+ awareness: {
820
+ getHost: (name, version, cb) => {
821
+ return cb("urac.fake");
822
+ }
823
+ },
824
+ registry: {
825
+ services: {
826
+ urac: {
827
+ port: 4001
828
+ }
829
+ },
830
+ custom: {
831
+ gateway: {
832
+ value: {
833
+ lastSeen: {
834
+ active: true,
835
+ network: "YAYA",
836
+ include: {
837
+ "av": {
838
+ "apis": {
839
+ "/get/calls/room/:roomId": ["post"]
840
+ }
841
+ }
842
+ }
843
+ }
844
+ }
845
+ }
846
+ }
847
+ }
848
+ }
849
+ };
850
+ const scope = nock('http://urac.fake:4001')
851
+ .post('/user/last/seen', "{\"network\":\"YAYA\"}")
852
+ .reply(200, {
853
+ result: true,
854
+ data: true
855
+ });
856
+ let functionMw = mw({});
857
+ functionMw(req, res, (error) => {
858
+ assert.ifError(error);
859
+ done();
860
+ });
861
+ });
862
+
863
+ it("include filter with path params - should NOT trigger for non-matching URL", (done) => {
864
+ let lastSeenSkipped = false;
865
+ let res = {};
866
+ let req = {
867
+ method: "POST",
868
+ getClientIP: () => {
869
+ return "127.0.0.1";
870
+ },
871
+ soajs: {
872
+ log: {
873
+ debug: (a) => {
874
+ console.log(a);
875
+ if (a && a.includes && a.includes("lastSeen skipped")) {
876
+ lastSeenSkipped = true;
877
+ }
878
+ },
879
+ error: (a) => {
880
+ console.log(a);
881
+ }
882
+ },
883
+ controller: {
884
+ serviceParams: {
885
+ name: "av",
886
+ parsedUrl: {
887
+ pathname: "/get/calls/other/abc123"
888
+ }
889
+ }
890
+ },
891
+ uracDriver: {
892
+ getProfile: () => {
893
+ return { _id: "1111111111" };
894
+ }
895
+ },
896
+ awareness: {
897
+ getHost: (name, version, cb) => {
898
+ return cb("urac.fake");
899
+ }
900
+ },
901
+ registry: {
902
+ services: {
903
+ urac: {
904
+ port: 4001
905
+ }
906
+ },
907
+ custom: {
908
+ gateway: {
909
+ value: {
910
+ lastSeen: {
911
+ active: true,
912
+ network: "YAYA",
913
+ include: {
914
+ "av": {
915
+ "apis": {
916
+ "/get/calls/room/:roomId": ["post"]
917
+ }
918
+ }
919
+ }
920
+ }
921
+ }
922
+ }
923
+ }
924
+ }
925
+ }
926
+ };
927
+ let functionMw = mw({});
928
+ functionMw(req, res, (error) => {
929
+ assert.ifError(error);
930
+ setTimeout(() => {
931
+ assert.ok(lastSeenSkipped, "lastSeen should have been skipped");
932
+ done();
933
+ }, 50);
934
+ });
935
+ });
936
+
937
+ it("include filter with multiple path params - should trigger", (done) => {
938
+ let res = {};
939
+ let req = {
940
+ method: "GET",
941
+ getClientIP: () => {
942
+ return "127.0.0.1";
943
+ },
944
+ soajs: {
945
+ log: {
946
+ debug: (a) => {
947
+ console.log(a);
948
+ },
949
+ error: (a) => {
950
+ console.log(a);
951
+ }
952
+ },
953
+ controller: {
954
+ serviceParams: {
955
+ name: "api",
956
+ parsedUrl: {
957
+ pathname: "/users/user123/posts/post456"
958
+ }
959
+ }
960
+ },
961
+ uracDriver: {
962
+ getProfile: () => {
963
+ return { _id: "1111111111" };
964
+ }
965
+ },
966
+ awareness: {
967
+ getHost: (name, version, cb) => {
968
+ return cb("urac.fake");
969
+ }
970
+ },
971
+ registry: {
972
+ services: {
973
+ urac: {
974
+ port: 4001
975
+ }
976
+ },
977
+ custom: {
978
+ gateway: {
979
+ value: {
980
+ lastSeen: {
981
+ active: true,
982
+ network: "YAYA",
983
+ include: {
984
+ "api": {
985
+ "apis": {
986
+ "/users/:userId/posts/:postId": true
987
+ }
988
+ }
989
+ }
990
+ }
991
+ }
992
+ }
993
+ }
994
+ }
995
+ }
996
+ };
997
+ const scope = nock('http://urac.fake:4001')
998
+ .post('/user/last/seen', "{\"network\":\"YAYA\"}")
999
+ .reply(200, {
1000
+ result: true,
1001
+ data: true
1002
+ });
1003
+ let functionMw = mw({});
1004
+ functionMw(req, res, (error) => {
1005
+ assert.ifError(error);
1006
+ done();
1007
+ });
1008
+ });
1009
+
1010
+ });
1011
+
68
1012
  });