werift 0.16.0 → 0.16.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.
Files changed (80) hide show
  1. package/lib/rtp/src/codec/index.d.ts +0 -4
  2. package/lib/rtp/src/codec/index.js +2 -6
  3. package/lib/rtp/src/codec/index.js.map +1 -1
  4. package/lib/rtp/src/index.d.ts +1 -6
  5. package/lib/rtp/src/index.js +1 -6
  6. package/lib/rtp/src/index.js.map +1 -1
  7. package/lib/rtp/src/processor/depacketizer.d.ts +26 -0
  8. package/lib/rtp/src/processor/depacketizer.js +114 -0
  9. package/lib/rtp/src/processor/depacketizer.js.map +1 -0
  10. package/lib/rtp/src/processor/depacketizerCallback.d.ts +13 -0
  11. package/lib/rtp/src/processor/depacketizerCallback.js +20 -0
  12. package/lib/rtp/src/processor/depacketizerCallback.js.map +1 -0
  13. package/lib/rtp/src/processor/depacketizerTransformer.d.ts +8 -0
  14. package/lib/rtp/src/processor/depacketizerTransformer.js +20 -0
  15. package/lib/rtp/src/processor/depacketizerTransformer.js.map +1 -0
  16. package/lib/rtp/src/processor/index.d.ts +9 -0
  17. package/lib/rtp/src/{processor_v2 → processor}/index.js +6 -1
  18. package/lib/rtp/src/processor/index.js.map +1 -0
  19. package/lib/rtp/src/processor/jitterBuffer.d.ts +26 -11
  20. package/lib/rtp/src/processor/jitterBuffer.js +150 -42
  21. package/lib/rtp/src/processor/jitterBuffer.js.map +1 -1
  22. package/lib/rtp/src/processor/jitterBufferCallback.d.ts +10 -0
  23. package/lib/rtp/src/processor/jitterBufferCallback.js +21 -0
  24. package/lib/rtp/src/processor/jitterBufferCallback.js.map +1 -0
  25. package/lib/rtp/src/processor/jitterBufferTransformer.d.ts +9 -0
  26. package/lib/rtp/src/processor/jitterBufferTransformer.js +22 -0
  27. package/lib/rtp/src/processor/jitterBufferTransformer.js.map +1 -0
  28. package/lib/rtp/src/{processor_v2 → processor}/source/index.d.ts +0 -0
  29. package/lib/rtp/src/{processor_v2 → processor}/source/index.js +0 -0
  30. package/lib/rtp/src/processor/source/index.js.map +1 -0
  31. package/lib/rtp/src/processor/source/rtp.d.ts +20 -0
  32. package/lib/rtp/src/processor/source/rtp.js +32 -0
  33. package/lib/rtp/src/processor/source/rtp.js.map +1 -0
  34. package/lib/rtp/src/processor/webm.d.ts +24 -24
  35. package/lib/rtp/src/processor/webm.js +78 -89
  36. package/lib/rtp/src/processor/webm.js.map +1 -1
  37. package/lib/rtp/src/processor/webmStream.d.ts +31 -0
  38. package/lib/rtp/src/processor/webmStream.js +36 -0
  39. package/lib/rtp/src/processor/webmStream.js.map +1 -0
  40. package/lib/rtp/src/rtp/rtp.d.ts +1 -0
  41. package/lib/rtp/src/rtp/rtp.js +3 -0
  42. package/lib/rtp/src/rtp/rtp.js.map +1 -1
  43. package/lib/webrtc/src/media/rtpReceiver.d.ts +3 -2
  44. package/lib/webrtc/src/media/rtpReceiver.js +14 -6
  45. package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
  46. package/lib/webrtc/src/nonstandard/recorder/writer/webm.js +8 -6
  47. package/lib/webrtc/src/nonstandard/recorder/writer/webm.js.map +1 -1
  48. package/lib/webrtc/src/peerConnection.js +3 -1
  49. package/lib/webrtc/src/peerConnection.js.map +1 -1
  50. package/package.json +1 -1
  51. package/src/media/rtpReceiver.ts +23 -11
  52. package/src/nonstandard/recorder/writer/webm.ts +9 -7
  53. package/src/peerConnection.ts +3 -1
  54. package/lib/rtp/src/processor/base.d.ts +0 -18
  55. package/lib/rtp/src/processor/base.js +0 -39
  56. package/lib/rtp/src/processor/base.js.map +0 -1
  57. package/lib/rtp/src/processor/lipsync.d.ts +0 -30
  58. package/lib/rtp/src/processor/lipsync.js +0 -92
  59. package/lib/rtp/src/processor/lipsync.js.map +0 -1
  60. package/lib/rtp/src/processor/sampleBuilder.d.ts +0 -13
  61. package/lib/rtp/src/processor/sampleBuilder.js +0 -33
  62. package/lib/rtp/src/processor/sampleBuilder.js.map +0 -1
  63. package/lib/rtp/src/processor_v2/depacketizer.d.ts +0 -17
  64. package/lib/rtp/src/processor_v2/depacketizer.js +0 -84
  65. package/lib/rtp/src/processor_v2/depacketizer.js.map +0 -1
  66. package/lib/rtp/src/processor_v2/index.d.ts +0 -4
  67. package/lib/rtp/src/processor_v2/index.js.map +0 -1
  68. package/lib/rtp/src/processor_v2/jitterBuffer.d.ts +0 -33
  69. package/lib/rtp/src/processor_v2/jitterBuffer.js +0 -154
  70. package/lib/rtp/src/processor_v2/jitterBuffer.js.map +0 -1
  71. package/lib/rtp/src/processor_v2/source/base.d.ts +0 -8
  72. package/lib/rtp/src/processor_v2/source/base.js +0 -16
  73. package/lib/rtp/src/processor_v2/source/base.js.map +0 -1
  74. package/lib/rtp/src/processor_v2/source/index.js.map +0 -1
  75. package/lib/rtp/src/processor_v2/source/rtp.d.ts +0 -14
  76. package/lib/rtp/src/processor_v2/source/rtp.js +0 -24
  77. package/lib/rtp/src/processor_v2/source/rtp.js.map +0 -1
  78. package/lib/rtp/src/processor_v2/webmLive.d.ts +0 -51
  79. package/lib/rtp/src/processor_v2/webmLive.js +0 -154
  80. package/lib/rtp/src/processor_v2/webmLive.js.map +0 -1
@@ -1,24 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RtpSourceStream = void 0;
4
- const rx_mini_1 = require("rx.mini");
5
- const base_1 = require("./base");
6
- class RtpSourceStream extends base_1.SourceStream {
7
- constructor(ev, options = {}) {
8
- super();
9
- this.disposer = new rx_mini_1.EventDisposer();
10
- ev.subscribe((rtp) => {
11
- if (options.payloadType != undefined &&
12
- options.payloadType !== rtp.header.payloadType) {
13
- return;
14
- }
15
- this.write({ rtp });
16
- }).disposer(this.disposer);
17
- }
18
- async stop() {
19
- this.controller.enqueue({ eol: true });
20
- this.disposer.dispose();
21
- }
22
- }
23
- exports.RtpSourceStream = RtpSourceStream;
24
- //# sourceMappingURL=rtp.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rtp.js","sourceRoot":"","sources":["../../../../../../rtp/src/processor_v2/source/rtp.ts"],"names":[],"mappings":";;;AAAA,qCAA+C;AAG/C,iCAAsC;AAOtC,MAAa,eAAgB,SAAQ,mBAAuB;IAG1D,YAAY,EAAsB,EAAE,UAAoC,EAAE;QACxE,KAAK,EAAE,CAAC;QAHO,aAAQ,GAAG,IAAI,uBAAa,EAAE,CAAC;QAK9C,EAAE,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE;YACnB,IACE,OAAO,CAAC,WAAW,IAAI,SAAS;gBAChC,OAAO,CAAC,WAAW,KAAK,GAAG,CAAC,MAAM,CAAC,WAAW,EAC9C;gBACA,OAAO;aACR;YAED,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QACtB,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC;CACF;AAtBD,0CAsBC","sourcesContent":["import Event, { EventDisposer } from \"rx.mini\";\n\nimport { RtpPacket } from \"../../rtp/rtp\";\nimport { SourceStream } from \"./base\";\n\nexport interface RtpOutput {\n rtp?: RtpPacket;\n eol?: boolean;\n}\n\nexport class RtpSourceStream extends SourceStream<RtpOutput> {\n private readonly disposer = new EventDisposer();\n\n constructor(ev: Event<[RtpPacket]>, options: { payloadType?: number } = {}) {\n super();\n\n ev.subscribe((rtp) => {\n if (\n options.payloadType != undefined &&\n options.payloadType !== rtp.header.payloadType\n ) {\n return;\n }\n\n this.write({ rtp });\n }).disposer(this.disposer);\n }\n\n async stop() {\n this.controller.enqueue({ eol: true });\n this.disposer.dispose();\n }\n}\n"]}
@@ -1,51 +0,0 @@
1
- /// <reference types="node" />
2
- /// <reference types="node" />
3
- import { ReadableStream, WritableStream } from "stream/web";
4
- import { SupportedCodec } from "../container/webm";
5
- import { DepacketizerOutput } from "./depacketizer";
6
- export declare type WebmLiveInput = DepacketizerOutput;
7
- export declare type WebmLiveOutput = {
8
- packet?: Buffer;
9
- eol?: {
10
- /**ms */
11
- duration: number;
12
- durationElement: Uint8Array;
13
- };
14
- };
15
- export interface WebmLiveOption {
16
- /**ms */
17
- duration?: number;
18
- }
19
- export declare class WebmLiveSink {
20
- tracks: {
21
- width?: number;
22
- height?: number;
23
- kind: "audio" | "video";
24
- codec: SupportedCodec;
25
- clockRate: number;
26
- trackNumber: number;
27
- }[];
28
- private options;
29
- private builder;
30
- private queue;
31
- private relativeTimestamp;
32
- private timestamps;
33
- private cuePoints;
34
- private position;
35
- stopped: boolean;
36
- audioStream: WritableStream<WebmLiveInput>;
37
- videoStream: WritableStream<WebmLiveInput>;
38
- webmStream: ReadableStream<WebmLiveOutput>;
39
- private controller;
40
- constructor(tracks: {
41
- width?: number;
42
- height?: number;
43
- kind: "audio" | "video";
44
- codec: SupportedCodec;
45
- clockRate: number;
46
- trackNumber: number;
47
- }[], options?: WebmLiveOption);
48
- private init;
49
- private onFrameReceived;
50
- private stop;
51
- }
@@ -1,154 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.WebmLiveSink = void 0;
7
- const debug_1 = __importDefault(require("debug"));
8
- const web_1 = require("stream/web");
9
- const __1 = require("..");
10
- const webm_1 = require("../container/webm");
11
- const sourcePath = `werift-rtp : packages/rtp/src/processor_v2/webmLive.ts`;
12
- const log = (0, debug_1.default)(sourcePath);
13
- class WebmLiveSink {
14
- constructor(tracks, options = {}) {
15
- this.tracks = tracks;
16
- this.options = options;
17
- this.queue = new __1.PromiseQueue();
18
- this.relativeTimestamp = 0;
19
- this.timestamps = {};
20
- this.cuePoints = [];
21
- this.position = 0;
22
- this.stopped = false;
23
- this.builder = new webm_1.WEBMBuilder(tracks);
24
- tracks.forEach((t) => {
25
- this.timestamps[t.trackNumber] = new ClusterTimestamp(t.clockRate);
26
- });
27
- const createStream = (trackNumber) => new web_1.WritableStream({
28
- write: ({ frame, eol }) => {
29
- if (this.stopped)
30
- return;
31
- if (!frame) {
32
- if (eol) {
33
- this.stop();
34
- }
35
- return;
36
- }
37
- this.queue.push(() => this.onFrameReceived({ ...frame, trackNumber }));
38
- },
39
- });
40
- const audioTrack = tracks.find((t) => t.kind === "audio");
41
- if (audioTrack) {
42
- this.audioStream = createStream(audioTrack.trackNumber);
43
- }
44
- const videoTrack = tracks.find((t) => t.kind === "video");
45
- if (videoTrack) {
46
- this.videoStream = createStream(videoTrack.trackNumber);
47
- }
48
- this.webmStream = new web_1.ReadableStream({
49
- start: (controller) => {
50
- this.controller = controller;
51
- },
52
- });
53
- this.queue.push(() => this.init());
54
- }
55
- async init() {
56
- const staticPart = Buffer.concat([
57
- this.builder.ebmlHeader,
58
- this.builder.createSegment(this.options.duration),
59
- ]);
60
- this.controller.enqueue({ packet: staticPart });
61
- this.position += staticPart.length;
62
- const video = this.tracks.find((t) => t.kind === "video");
63
- if (video) {
64
- this.cuePoints.push(new CuePoint(this.builder, video.trackNumber, 0.0, this.position));
65
- }
66
- }
67
- async onFrameReceived(frame) {
68
- const track = this.tracks.find((t) => t.trackNumber === frame.trackNumber);
69
- if (!track) {
70
- return;
71
- }
72
- const timestampManager = this.timestamps[track.trackNumber];
73
- let elapsed = timestampManager.update(frame.timestamp);
74
- if ((track.kind === "video" && frame.isKeyframe) ||
75
- elapsed > MaxSinged16Int) {
76
- this.relativeTimestamp += elapsed;
77
- const cluster = this.builder.createCluster(this.relativeTimestamp);
78
- this.controller.enqueue({ packet: Buffer.from(cluster) });
79
- if (elapsed !== 0) {
80
- this.cuePoints.push(new CuePoint(this.builder, track.trackNumber, this.relativeTimestamp, this.position));
81
- }
82
- this.position += cluster.length;
83
- Object.values(this.timestamps).forEach((t) => t.reset());
84
- elapsed = timestampManager.update(frame.timestamp);
85
- }
86
- const block = this.builder.createSimpleBlock(frame.data, frame.isKeyframe, track.trackNumber, elapsed);
87
- this.controller.enqueue({ packet: block });
88
- this.position += block.length;
89
- const [cuePoint] = this.cuePoints.slice(-1);
90
- if (cuePoint) {
91
- cuePoint.blockNumber++;
92
- }
93
- }
94
- async stop() {
95
- if (this.stopped) {
96
- return;
97
- }
98
- this.stopped = true;
99
- log("stop");
100
- const cues = this.builder.createCues(this.cuePoints.map((c) => c.build()));
101
- this.controller.enqueue({ packet: Buffer.from(cues) });
102
- const latestTimestamp = Object.values(this.timestamps).sort((a, b) => a.elapsed - b.elapsed)[0].elapsed;
103
- const duration = this.relativeTimestamp + latestTimestamp;
104
- const durationElement = this.builder.createDuration(duration);
105
- this.controller.enqueue({ eol: { duration, durationElement } });
106
- this.controller.close();
107
- }
108
- }
109
- exports.WebmLiveSink = WebmLiveSink;
110
- class ClusterTimestamp {
111
- constructor(clockRate) {
112
- this.clockRate = clockRate;
113
- this.elapsed = 0;
114
- }
115
- reset() {
116
- this.baseTimestamp = undefined;
117
- }
118
- update(timestamp) {
119
- if (this.baseTimestamp == undefined) {
120
- this.baseTimestamp = timestamp;
121
- }
122
- const rotate = Math.abs(timestamp - this.baseTimestamp) > (Max32Uint / 4) * 3;
123
- if (rotate) {
124
- log("rotate", { baseTimestamp: this.baseTimestamp, timestamp });
125
- }
126
- const elapsed = rotate
127
- ? timestamp + Max32Uint - this.baseTimestamp
128
- : timestamp - this.baseTimestamp;
129
- this.elapsed = (0, __1.int)((elapsed / this.clockRate) * 1000);
130
- return this.elapsed;
131
- }
132
- }
133
- class CuePoint {
134
- constructor(builder, trackNumber, relativeTimestamp, position) {
135
- this.builder = builder;
136
- this.trackNumber = trackNumber;
137
- this.relativeTimestamp = relativeTimestamp;
138
- this.position = position;
139
- /**
140
- * cuesの後のclusterのあるべき位置
141
- * cuesはclusterの前に挿入される
142
- */
143
- this.cuesLength = 0;
144
- this.blockNumber = 0;
145
- }
146
- build() {
147
- return this.builder.createCuePoint(this.relativeTimestamp, this.trackNumber, this.position - 48 + this.cuesLength, this.blockNumber);
148
- }
149
- }
150
- /**4294967295 */
151
- const Max32Uint = Number(0x01n << 32n) - 1;
152
- /**32767 */
153
- const MaxSinged16Int = (0x01 << 16) / 2 - 1;
154
- //# sourceMappingURL=webmLive.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"webmLive.js","sourceRoot":"","sources":["../../../../../rtp/src/processor_v2/webmLive.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\nimport {\n ReadableStream,\n ReadableStreamController,\n WritableStream,\n} from \"stream/web\";\n\nimport { int, PromiseQueue } from \"..\";\nimport { SupportedCodec, WEBMBuilder } from \"../container/webm\";\nimport { DepacketizerOutput } from \"./depacketizer\";\n\nconst sourcePath = `werift-rtp : packages/rtp/src/processor_v2/webmLive.ts`;\nconst log = debug(sourcePath);\n\nexport type WebmLiveInput = DepacketizerOutput;\n\nexport type WebmLiveOutput = {\n packet?: Buffer;\n eol?: {\n /**ms */\n duration: number;\n durationElement: Uint8Array;\n };\n};\n\nexport interface WebmLiveOption {\n /**ms */\n duration?: number;\n}\n\nexport class WebmLiveSink {\n private builder: WEBMBuilder;\n private queue = new PromiseQueue();\n private relativeTimestamp = 0;\n private timestamps: { [pt: number]: ClusterTimestamp } = {};\n private cuePoints: CuePoint[] = [];\n private position = 0;\n stopped = false;\n audioStream!: WritableStream<WebmLiveInput>;\n videoStream!: WritableStream<WebmLiveInput>;\n webmStream: ReadableStream<WebmLiveOutput>;\n private controller!: ReadableStreamController<WebmLiveOutput>;\n\n constructor(\n public tracks: {\n width?: number;\n height?: number;\n kind: \"audio\" | \"video\";\n codec: SupportedCodec;\n clockRate: number;\n trackNumber: number;\n }[],\n private options: WebmLiveOption = {}\n ) {\n this.builder = new WEBMBuilder(tracks);\n\n tracks.forEach((t) => {\n this.timestamps[t.trackNumber] = new ClusterTimestamp(t.clockRate);\n });\n\n const createStream = (trackNumber: number) =>\n new WritableStream({\n write: ({ frame, eol }: WebmLiveInput) => {\n if (this.stopped) return;\n if (!frame) {\n if (eol) {\n this.stop();\n }\n return;\n }\n\n this.queue.push(() =>\n this.onFrameReceived({ ...frame, trackNumber })\n );\n },\n });\n\n const audioTrack = tracks.find((t) => t.kind === \"audio\");\n if (audioTrack) {\n this.audioStream = createStream(audioTrack.trackNumber);\n }\n\n const videoTrack = tracks.find((t) => t.kind === \"video\");\n if (videoTrack) {\n this.videoStream = createStream(videoTrack.trackNumber);\n }\n\n this.webmStream = new ReadableStream<WebmLiveOutput>({\n start: (controller) => {\n this.controller = controller;\n },\n });\n\n this.queue.push(() => this.init());\n }\n\n private async init() {\n const staticPart = Buffer.concat([\n this.builder.ebmlHeader,\n this.builder.createSegment(this.options.duration),\n ]);\n this.controller.enqueue({ packet: staticPart });\n this.position += staticPart.length;\n\n const video = this.tracks.find((t) => t.kind === \"video\");\n if (video) {\n this.cuePoints.push(\n new CuePoint(this.builder, video.trackNumber, 0.0, this.position)\n );\n }\n }\n\n private async onFrameReceived(\n frame: WebmLiveInput[\"frame\"] & { trackNumber: number }\n ) {\n const track = this.tracks.find((t) => t.trackNumber === frame.trackNumber);\n if (!track) {\n return;\n }\n\n const timestampManager = this.timestamps[track.trackNumber];\n let elapsed = timestampManager.update(frame.timestamp);\n\n if (\n (track.kind === \"video\" && frame.isKeyframe) ||\n elapsed > MaxSinged16Int\n ) {\n this.relativeTimestamp += elapsed;\n\n const cluster = this.builder.createCluster(this.relativeTimestamp);\n this.controller.enqueue({ packet: Buffer.from(cluster) });\n\n if (elapsed !== 0) {\n this.cuePoints.push(\n new CuePoint(\n this.builder,\n track.trackNumber,\n this.relativeTimestamp,\n this.position\n )\n );\n }\n this.position += cluster.length;\n Object.values(this.timestamps).forEach((t) => t.reset());\n elapsed = timestampManager.update(frame.timestamp);\n }\n\n const block = this.builder.createSimpleBlock(\n frame.data,\n frame.isKeyframe,\n track.trackNumber,\n elapsed\n );\n this.controller.enqueue({ packet: block });\n this.position += block.length;\n const [cuePoint] = this.cuePoints.slice(-1);\n if (cuePoint) {\n cuePoint.blockNumber++;\n }\n }\n\n private async stop() {\n if (this.stopped) {\n return;\n }\n this.stopped = true;\n\n log(\"stop\");\n\n const cues = this.builder.createCues(this.cuePoints.map((c) => c.build()));\n this.controller.enqueue({ packet: Buffer.from(cues) });\n\n const latestTimestamp = Object.values(this.timestamps).sort(\n (a, b) => a.elapsed - b.elapsed\n )[0].elapsed;\n const duration = this.relativeTimestamp + latestTimestamp;\n const durationElement = this.builder.createDuration(duration);\n this.controller.enqueue({ eol: { duration, durationElement } });\n\n this.controller.close();\n }\n}\n\nclass ClusterTimestamp {\n baseTimestamp?: number;\n elapsed = 0;\n\n constructor(public clockRate: number) {}\n\n reset() {\n this.baseTimestamp = undefined;\n }\n\n update(timestamp: number) {\n if (this.baseTimestamp == undefined) {\n this.baseTimestamp = timestamp;\n }\n const rotate =\n Math.abs(timestamp - this.baseTimestamp) > (Max32Uint / 4) * 3;\n\n if (rotate) {\n log(\"rotate\", { baseTimestamp: this.baseTimestamp, timestamp });\n }\n\n const elapsed = rotate\n ? timestamp + Max32Uint - this.baseTimestamp\n : timestamp - this.baseTimestamp;\n\n this.elapsed = int((elapsed / this.clockRate) * 1000);\n return this.elapsed;\n }\n}\n\nclass CuePoint {\n /**\n * cuesの後のclusterのあるべき位置\n * cuesはclusterの前に挿入される\n */\n cuesLength = 0;\n blockNumber = 0;\n\n constructor(\n private readonly builder: WEBMBuilder,\n private readonly trackNumber: number,\n private readonly relativeTimestamp: number,\n public position: number\n ) {}\n\n build() {\n return this.builder.createCuePoint(\n this.relativeTimestamp,\n this.trackNumber,\n this.position - 48 + this.cuesLength,\n this.blockNumber\n );\n }\n}\n\n/**4294967295 */\nconst Max32Uint = Number(0x01n << 32n) - 1;\n/**32767 */\nconst MaxSinged16Int = (0x01 << 16) / 2 - 1;\n"]}