563 lines
16 KiB
JavaScript
563 lines
16 KiB
JavaScript
/*
|
|
Copyright (c) 2019 The Khronos Group Inc.
|
|
Use of this source code is governed by an MIT-style license that can be
|
|
found in the LICENSE.txt file.
|
|
*/
|
|
|
|
// This test relies on the surrounding web page defining a variable
|
|
// "contextVersion" which indicates what version of WebGL it's running
|
|
// on -- 1 for WebGL 1.0, 2 for WebGL 2.0, etc.
|
|
|
|
"use strict";
|
|
description("Validate tex functions input parameters");
|
|
|
|
var wtu = WebGLTestUtils;
|
|
var gl = null;
|
|
var tex = null;
|
|
var error = 0;
|
|
|
|
shouldBeNonNull("gl = wtu.create3DContext(undefined, undefined, contextVersion)");
|
|
shouldBeNonNull("tex = gl.createTexture()");
|
|
gl.bindTexture(gl.TEXTURE_2D, tex);
|
|
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
|
|
|
function enumToString(value) {
|
|
return wtu.glEnumToString(gl, value);
|
|
}
|
|
|
|
function testTexParameter(testCase) {
|
|
var msg = "paramName: " + enumToString(testCase.pname);
|
|
error = testCase.expectedError;
|
|
gl.texParameteri(testCase.target, testCase.pname, testCase.param);
|
|
wtu.glErrorShouldBe(gl, error, msg);
|
|
gl.texParameterf(testCase.target, testCase.pname, testCase.param);
|
|
wtu.glErrorShouldBe(gl, error, msg);
|
|
}
|
|
|
|
function testGetTexParameter(testCase) {
|
|
var msg = "paramName: " + enumToString(testCase.pname);
|
|
error = testCase.expectedError;
|
|
gl.getTexParameter(testCase.target, testCase.pname);
|
|
wtu.glErrorShouldBe(gl, error, msg);
|
|
}
|
|
|
|
function testTexImage2D(testCase) {
|
|
var level = 0;
|
|
var width = 16;
|
|
var height = 16;
|
|
var msg = " internalFormat: " + enumToString(testCase.internalFormat) +
|
|
" target: " + enumToString(testCase.target) +
|
|
" format: " + enumToString(testCase.format) +
|
|
" type: " + enumToString(testCase.type) +
|
|
" border: " + testCase.border;
|
|
|
|
gl.texImage2D(testCase.target, level, testCase.internalFormat, width, height, testCase.border, testCase.format, testCase.type, null);
|
|
error = testCase.expectedError;
|
|
wtu.glErrorShouldBe(gl, error, msg);
|
|
}
|
|
|
|
function testTexSubImage2D(testCase) {
|
|
var level = 0;
|
|
var xoffset = 0;
|
|
var yoffset = 0;
|
|
var width = 16;
|
|
var height = 16;
|
|
var msg = " format: " + enumToString(testCase.format) +
|
|
" type: " + enumToString(testCase.type);
|
|
var array = new Uint8Array(width * height * 4);
|
|
|
|
gl.texSubImage2D(testCase.target, level, xoffset, yoffset, width, height, testCase.format, testCase.type, array);
|
|
error = testCase.expectedError;
|
|
wtu.glErrorShouldBe(gl, error, msg);
|
|
}
|
|
|
|
function testCopyTexImage2D(testCase) {
|
|
var level = 0;
|
|
var x = 0;
|
|
var y = 0;
|
|
var width = 16;
|
|
var height = 16;
|
|
var msg = " colorBufferFormat: " + enumToString(testCase.colorBufferFormat) +
|
|
" internalFormat: " + enumToString(testCase.internalFormat) +
|
|
" target: " + enumToString(testCase.target) +
|
|
" border: " + testCase.border;
|
|
|
|
gl.renderbufferStorage(gl.RENDERBUFFER, testCase.colorBufferFormat, width, height);
|
|
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
|
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
|
|
|
|
gl.copyTexImage2D(testCase.target, level, testCase.internalFormat, x, y, width, height, testCase.border);
|
|
error = testCase.expectedError;
|
|
wtu.glErrorShouldBe(gl, error, msg);
|
|
}
|
|
|
|
function testCopyTexSubImage2D(testCase) {
|
|
var level = 0;
|
|
var x = 0;
|
|
var y = 0;
|
|
var width = 16;
|
|
var height = 16;
|
|
var xoffset = 0;
|
|
var yoffset = 0;
|
|
var border = 0;
|
|
var type = gl.UNSIGNED_BYTE;
|
|
var msg = " colorBufferFormat: " + enumToString(testCase.colorBufferFormat) +
|
|
" internalFormat: " + enumToString(testCase.internalFormat) +
|
|
" target: " + enumToString(testCase.target);
|
|
|
|
gl.renderbufferStorage(gl.RENDERBUFFER, testCase.colorBufferFormat, width, height);
|
|
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
|
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
|
|
|
|
gl.texImage2D(testCase.target, level, testCase.internalFormat, xoffset + width, yoffset + height, border, testCase.internalFormat, type, null);
|
|
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
|
|
|
gl.copyTexSubImage2D(testCase.target, level, xoffset, yoffset, x, y, width, height);
|
|
error = testCase.expectedError;
|
|
wtu.glErrorShouldBe(gl, error, msg);
|
|
}
|
|
|
|
function testCopyFromInternalFBO(testCase) {
|
|
var target = gl.TEXTURE_2D;
|
|
var level = 0;
|
|
var x = 0;
|
|
var y = 0;
|
|
var width = 16;
|
|
var height = 16;
|
|
var xoffset = 0;
|
|
var yoffset = 0;
|
|
var border = 0;
|
|
var type = gl.UNSIGNED_BYTE;
|
|
var msg = " colorBufferFormat: " + enumToString(testCase.contextAlpha ? gl.RGBA : gl.RGB) +
|
|
" internalFormat: " + enumToString(testCase.internalFormat);
|
|
|
|
if (testCase.contextAlpha) {
|
|
gl = wtu.create3DContext(null, { alpha: true }, contextVersion);
|
|
} else {
|
|
gl = wtu.create3DContext(null, { alpha: false }, contextVersion);
|
|
}
|
|
shouldBeNonNull("gl");
|
|
shouldBeNonNull("tex = gl.createTexture()");
|
|
gl.bindTexture(target, tex);
|
|
if (testCase.subImage) {
|
|
gl.texImage2D(target, level, testCase.internalFormat, xoffset + width, yoffset + height, border, testCase.internalFormat, type, null);
|
|
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
|
gl.copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
|
|
} else {
|
|
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
|
gl.copyTexImage2D(target, level, testCase.internalFormat, x, y, width, height, border);
|
|
}
|
|
error = testCase.expectedError;
|
|
wtu.glErrorShouldBe(gl, error, msg);
|
|
}
|
|
|
|
// Only for WebGL2.0.
|
|
function testTexImage3D(testCase) {
|
|
var level = 0;
|
|
var width = 16;
|
|
var height = 16;
|
|
var depth = 16;
|
|
var msg = " internalFormat: " + enumToString(testCase.internalFormat) +
|
|
" target: " + enumToString(testCase.target) +
|
|
" format: " + enumToString(testCase.format) +
|
|
" type: " + enumToString(testCase.type) +
|
|
" border: " + testCase.border;
|
|
|
|
gl.texImage3D(testCase.target, level, testCase.internalFormat, width, height, depth, testCase.border, testCase.format, testCase.type, null);
|
|
error = testCase.expectedError;
|
|
wtu.glErrorShouldBe(gl, error, msg);
|
|
}
|
|
|
|
function testTexSubImage3D(testCase) {
|
|
var level = 0;
|
|
var xoffset = 0;
|
|
var yoffset = 0;
|
|
var zoffset = 0;
|
|
var width = 16;
|
|
var height = 16;
|
|
var depth = 16;
|
|
var msg = " format: " + enumToString(testCase.format) +
|
|
" type: " + enumToString(testCase.type);
|
|
var array = new Uint8Array(width * height * depth * 4);
|
|
|
|
gl.texSubImage3D(testCase.target, level, xoffset, yoffset, zoffset, width, height, depth, testCase.format, testCase.type, array);
|
|
error = testCase.expectedError;
|
|
wtu.glErrorShouldBe(gl, error, msg);
|
|
}
|
|
|
|
|
|
// Start checking.
|
|
|
|
debug("");
|
|
debug("Checking TexParameter: a set of inputs that are valid in GL but invalid in WebGL");
|
|
|
|
testCases = [
|
|
{ target: 0x0DE0, // GL_TEXTURE_1D
|
|
pname: gl.TEXTURE_WRAP_T,
|
|
param: gl.REPEAT,
|
|
expectedError: gl.INVALID_ENUM },
|
|
{ target: gl.TEXTURE_2D,
|
|
pname: gl.TEXTURE_WRAP_T,
|
|
param: 0x2900, // GL_CLAMP
|
|
expectedError: gl.INVALID_ENUM },
|
|
{ target: gl.TEXTURE_2D,
|
|
pname: gl.TEXTURE_WRAP_T,
|
|
param: gl.REPEAT,
|
|
expectedError: gl.NO_ERROR }
|
|
];
|
|
|
|
if (contextVersion < 2) {
|
|
testCases = testCases.concat([
|
|
{ target: gl.TEXTURE_2D,
|
|
pname: 0x813A, // GL_TEXTURE_MIN_LOD
|
|
param: 0,
|
|
expectedError: gl.INVALID_ENUM }
|
|
]);
|
|
} else {
|
|
testCases = testCases.concat([
|
|
{ target: gl.TEXTURE_2D,
|
|
pname: 0x8E42, // GL_TEXTURE_SWIZZLE_R
|
|
param: 0x1903, // GL_RED
|
|
expectedError: gl.INVALID_ENUM },
|
|
{ target: gl.TEXTURE_2D,
|
|
pname: 0x8072, // GL_TEXTURE_WRAP_R
|
|
param: 0x2900, // GL_CLAMP
|
|
expectedError: gl.INVALID_ENUM }
|
|
]);
|
|
}
|
|
|
|
for (var ii = 0; ii < testCases.length; ++ii) {
|
|
testTexParameter(testCases[ii]);
|
|
}
|
|
|
|
debug("");
|
|
debug("Checking GetTexParameter: a set of inputs that are valid in GL but invalid in WebGL");
|
|
|
|
testCases = [
|
|
{ target: 0x0DE0, // GL_TEXTURE_1D
|
|
pname: gl.TEXTURE_WRAP_T,
|
|
expectedError: gl.INVALID_ENUM },
|
|
{ target: gl.TEXTURE_2D,
|
|
pname: gl.TEXTURE_WRAP_T,
|
|
expectedError: gl.NO_ERROR }
|
|
];
|
|
|
|
if (contextVersion < 2) {
|
|
testCases = testCases.concat([
|
|
{ target: gl.TEXTURE_2D,
|
|
pname: 0x813A, // GL_TEXTURE_MIN_LOD
|
|
expectedError: gl.INVALID_ENUM }
|
|
]);
|
|
} else {
|
|
testCases = testCases.concat([
|
|
{ target: gl.TEXTURE_2D,
|
|
pname: 0x8E42, // GL_TEXTURE_SWIZZLE_R
|
|
expectedError: gl.INVALID_ENUM }
|
|
]);
|
|
}
|
|
|
|
for (var ii = 0; ii < testCases.length; ++ii) {
|
|
testGetTexParameter(testCases[ii]);
|
|
}
|
|
|
|
debug("");
|
|
debug("Checking TexImage2D: a set of inputs that are valid in GL but invalid in WebGL");
|
|
|
|
var testCases = [
|
|
{ target: 0x8064, // GL_PROXY_TEXTURE_2D
|
|
internalFormat: gl.RGBA,
|
|
border: 0,
|
|
format: gl.RGBA,
|
|
type: gl.UNSIGNED_BYTE,
|
|
expectedError: gl.INVALID_ENUM },
|
|
{ target: gl.TEXTURE_2D,
|
|
internalFormat: 0x1903, // GL_RED
|
|
border: 0,
|
|
format: 0x1903, // GL_RED
|
|
type: gl.UNSIGNED_BYTE,
|
|
expectedError: [gl.INVALID_ENUM, gl.INVALID_VALUE, gl.INVALID_OPERATION] },
|
|
{ target: gl.TEXTURE_2D,
|
|
internalFormat: gl.RGBA,
|
|
border: 1,
|
|
format: gl.RGBA,
|
|
type: gl.UNSIGNED_BYTE,
|
|
expectedError: gl.INVALID_VALUE },
|
|
{ target: gl.TEXTURE_2D,
|
|
internalFormat: gl.RGBA,
|
|
border: 0,
|
|
format: gl.RGB,
|
|
type: gl.UNSIGNED_BYTE,
|
|
expectedError: gl.INVALID_OPERATION },
|
|
{ target: gl.TEXTURE_2D,
|
|
internalFormat: gl.RGBA,
|
|
border: 0,
|
|
format: gl.RGBA,
|
|
type: gl.UNSIGNED_BYTE,
|
|
expectedError: gl.NO_ERROR }
|
|
];
|
|
|
|
if (contextVersion < 2) {
|
|
testCases = testCases.concat([
|
|
{ target: gl.TEXTURE_2D,
|
|
internalFormat: gl.RGBA,
|
|
border: 0,
|
|
format: gl.RGBA,
|
|
type: gl.BYTE,
|
|
expectedError: gl.INVALID_ENUM }
|
|
]);
|
|
} else {
|
|
testCases = testCases.concat([
|
|
{ target: gl.TEXTURE_2D,
|
|
internalFormat: gl.RGBA,
|
|
border: 0,
|
|
format: gl.RGBA,
|
|
type: gl.BYTE,
|
|
expectedError: gl.INVALID_OPERATION },
|
|
{ target: gl.TEXTURE_3D,
|
|
internalFormat: gl.RGBA,
|
|
border: 0,
|
|
format: gl.RGBA,
|
|
type: gl.UNSIGNED_BYTE,
|
|
expectedError: gl.INVALID_ENUM }
|
|
]);
|
|
}
|
|
|
|
for (var ii = 0; ii < testCases.length; ++ii) {
|
|
testTexImage2D(testCases[ii]);
|
|
}
|
|
|
|
debug("");
|
|
debug("Checking TexSubImage2D: a set of inputs that are valid in GL but invalid in WebGL");
|
|
|
|
testCases = [
|
|
{ target: gl.TEXTURE_2D,
|
|
format: gl.RGBA,
|
|
type: gl.UNSIGNED_BYTE,
|
|
expectedError: gl.NO_ERROR }
|
|
];
|
|
|
|
if (contextVersion < 2) {
|
|
testCases = testCases.concat([
|
|
{ target: gl.TEXTURE_2D,
|
|
format: 0x1903, // GL_RED
|
|
type: gl.UNSIGNED_BYTE,
|
|
expectedError: [gl.INVALID_ENUM, gl.INVALID_OPERATION] },
|
|
{ target: gl.TEXTURE_2D,
|
|
format: gl.RGBA,
|
|
type: gl.BYTE,
|
|
expectedError: [gl.INVALID_ENUM, gl.INVALID_OPERATION] }
|
|
]);
|
|
} else {
|
|
testCases = testCases.concat([
|
|
{ target: gl.TEXTURE_2D,
|
|
format: gl.RED,
|
|
type: gl.UNSIGNED_BYTE,
|
|
expectedError: gl.INVALID_OPERATION },
|
|
{ target: gl.TEXTURE_2D,
|
|
format: gl.RGBA,
|
|
type: gl.BYTE,
|
|
expectedError: gl.INVALID_OPERATION },
|
|
{ target: gl.TEXTURE_3D,
|
|
format: gl.RGBA,
|
|
type: gl.UNSIGNED_BYTE,
|
|
expectedError: gl.INVALID_ENUM },
|
|
]);
|
|
}
|
|
|
|
for (var ii = 0; ii < testCases.length; ++ii) {
|
|
testTexSubImage2D(testCases[ii]);
|
|
}
|
|
|
|
debug("");
|
|
debug("Checking CopyTexImage2D: a set of inputs that are valid in GL but invalid in WebGL");
|
|
|
|
var colorBuffer = null;
|
|
var fbo = null;
|
|
|
|
shouldBeNonNull("fbo = gl.createFramebuffer()");
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
|
shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
|
|
gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
|
|
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
|
|
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
|
|
|
testCases = [
|
|
{ target: gl.TEXTURE_2D,
|
|
colorBufferFormat: gl.RGB565,
|
|
internalFormat: 0x8054, // GL_RGB16
|
|
border: 0,
|
|
expectedError: gl.INVALID_ENUM },
|
|
{ target: gl.TEXTURE_2D,
|
|
colorBufferFormat: gl.RGB565,
|
|
internalFormat: gl.RGBA,
|
|
border: 1,
|
|
expectedError: gl.INVALID_VALUE },
|
|
{ target: gl.TEXTURE_2D,
|
|
colorBufferFormat: gl.RGB565,
|
|
internalFormat: gl.RGBA,
|
|
border: 0,
|
|
expectedError: gl.INVALID_OPERATION },
|
|
{ target: gl.TEXTURE_2D,
|
|
colorBufferFormat: gl.RGB565,
|
|
internalFormat: gl.RGB,
|
|
border: 0,
|
|
expectedError: gl.NO_ERROR }
|
|
];
|
|
|
|
if (contextVersion > 1) {
|
|
testCases = testCases.concat([
|
|
{ target: gl.TEXTURE_3D,
|
|
colorBufferFormat: gl.RGB5_A1,
|
|
internalFormat: gl.RGBA,
|
|
border: 0,
|
|
expectedError: gl.INVALID_ENUM }
|
|
]);
|
|
}
|
|
|
|
for (var ii = 0; ii < testCases.length; ++ii) {
|
|
testCopyTexImage2D(testCases[ii]);
|
|
}
|
|
|
|
debug("");
|
|
debug("Checking CopyTexSubImage2D: a set of inputs that are valid in GL but invalid in WebGL");
|
|
|
|
testCases = [
|
|
{ target: gl.TEXTURE_2D,
|
|
colorBufferFormat: gl.RGB5_A1,
|
|
internalFormat: gl.RGBA,
|
|
expectedError: gl.NO_ERROR },
|
|
{ target: gl.TEXTURE_2D,
|
|
colorBufferFormat: gl.RGB565,
|
|
internalFormat: gl.RGBA,
|
|
expectedError: gl.INVALID_OPERATION }
|
|
];
|
|
|
|
for (var ii = 0; ii < testCases.length; ++ii) {
|
|
testCopyTexSubImage2D(testCases[ii]);
|
|
}
|
|
|
|
debug("");
|
|
debug("Checking CopyTex{Sub}Image2D: copy from WebGL internal framebuffer");
|
|
|
|
testCases = [
|
|
{ contextAlpha: true,
|
|
internalFormat: gl.RGBA,
|
|
subImage: false,
|
|
expectedError: gl.NO_ERROR },
|
|
{ contextAlpha: false,
|
|
internalFormat: gl.RGBA,
|
|
subImage: false,
|
|
expectedError: gl.INVALID_OPERATION },
|
|
{ contextAlpha: true,
|
|
internalFormat: gl.RGBA,
|
|
subImage: true,
|
|
expectedError: gl.NO_ERROR },
|
|
{ contextAlpha: false,
|
|
internalFormat: gl.RGBA,
|
|
subImage: true,
|
|
expectedError: gl.INVALID_OPERATION }
|
|
];
|
|
|
|
for (var ii = 0; ii < testCases.length; ++ii) {
|
|
testCopyFromInternalFBO(testCases[ii]);
|
|
}
|
|
|
|
if (contextVersion > 1) {
|
|
// Create new texture for testing api of WebGL 2.0.
|
|
shouldBeNonNull("tex = gl.createTexture()");
|
|
gl.bindTexture(gl.TEXTURE_3D, tex);
|
|
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
|
|
|
debug("");
|
|
debug("Checking TexImage3D: a set of inputs that are valid in GL but invalid in WebGL");
|
|
|
|
var testCases = [
|
|
{ target: 0x8070, // GL_PROXY_TEXTURE_3D
|
|
internalFormat: gl.RGBA,
|
|
border: 0,
|
|
format: gl.RGBA,
|
|
type: gl.UNSIGNED_BYTE,
|
|
expectedError: gl.INVALID_ENUM },
|
|
{ target: gl.TEXTURE_3D,
|
|
internalFormat: gl.RGBA,
|
|
border: 0,
|
|
format: gl.RGB,
|
|
type: gl.UNSIGNED_BYTE,
|
|
expectedError: gl.INVALID_OPERATION },
|
|
{ target: gl.TEXTURE_3D,
|
|
internalFormat: gl.RGBA,
|
|
border: 0,
|
|
format: gl.RGBA,
|
|
type: gl.BYTE,
|
|
expectedError: gl.INVALID_OPERATION},
|
|
{ target: gl.TEXTURE_3D,
|
|
internalFormat: gl.RGBA,
|
|
border: 0,
|
|
format: gl.RGBA,
|
|
type: gl.UNSIGNED_BYTE,
|
|
expectedError: gl.NO_ERROR }
|
|
];
|
|
|
|
for (var ii = 0; ii < testCases.length; ++ii) {
|
|
testTexImage3D(testCases[ii]);
|
|
}
|
|
|
|
debug("");
|
|
debug("Checking TexImage3D: bad target, internalformats, formats, types");
|
|
|
|
var testCases = [
|
|
{ target: gl.TEXTURE_2D,
|
|
internalFormat: gl.RGBA,
|
|
border: 0,
|
|
format: gl.RGBA,
|
|
type: gl.UNSIGNED_BYTE,
|
|
expectedError: gl.INVALID_ENUM },
|
|
{ target: gl.TEXTURE_3D,
|
|
internalFormat: gl.RG,
|
|
border: 0,
|
|
format: gl.RGBA,
|
|
type: gl.UNSIGNED_BYTE,
|
|
expectedError: [gl.INVALID_VALUE, gl.INVALID_OPERATION]},
|
|
{ target: gl.TEXTURE_3D,
|
|
internalFormat: gl.RGBA,
|
|
border: 0,
|
|
format: gl.RG8,
|
|
type: gl.UNSIGNED_BYTE,
|
|
expectedError: gl.INVALID_ENUM },
|
|
{ target: gl.TEXTURE_3D,
|
|
internalFormat: gl.RGBA,
|
|
border: 0,
|
|
format: gl.RGBA,
|
|
type: gl.INT,
|
|
expectedError: gl.INVALID_OPERATION},
|
|
];
|
|
|
|
for (var ii = 0; ii < testCases.length; ++ii) {
|
|
testTexImage3D(testCases[ii]);
|
|
}
|
|
|
|
debug("");
|
|
debug("Checking TexSubImage3D: a set of inputs that are valid in GL but invalid in WebGL");
|
|
|
|
testCases = [
|
|
{ target: gl.TEXTURE_3D,
|
|
format: 0x80E0, // GL_BGR
|
|
type: gl.UNSIGNED_BYTE,
|
|
expectedError: gl.INVALID_ENUM },
|
|
{ target: gl.TEXTURE_3D,
|
|
format: gl.RGBA,
|
|
type: 0x8032, // GL_UNSIGNED_BYTE_3_3_2
|
|
expectedError: gl.INVALID_ENUM },
|
|
{ target: gl.TEXTURE_3D,
|
|
format: gl.RGBA,
|
|
type: gl.UNSIGNED_BYTE,
|
|
expectedError: gl.NO_ERROR }
|
|
];
|
|
|
|
for (var ii = 0; ii < testCases.length; ++ii) {
|
|
testTexSubImage3D(testCases[ii]);
|
|
}
|
|
|
|
}
|
|
|
|
var successfullyParsed = true;
|