/**
 * 判断数组是否是两条线段组成
 * @param {线段数组} arr 
 */
function isTwoLine(arr) {
    var max = 0,
        min = 1;
    for (var i = 0; i < arr.length; i++) {
        if (arr[i][0] > max) {
            max = arr[i][0];
        }
        if (arr[i][0] < min) {
            min = arr[i][0];
        }
    }
    return [min === 0, max];
}

/*
    @function: 加载3D线段，需要根据平台自行实现
    @info: 这里生成一个3D单位CUBE的所有线段
*/
function _3dLine(r2x, r3x, ret) {
    // 坐标点长度
    var r1x = 0.5;
    // 矩形的各个定点
    var r2x_t = [
        [-r1x, -r1x, +r1x],
        [-r1x, +r1x, +r1x],
        [+r1x, +r1x, +r1x],
        [+r1x, -r1x, +r1x],
        [-r1x, -r1x, -r1x],
        [-r1x, +r1x, -r1x],
        [+r1x, +r1x, -r1x],
        [+r1x, -r1x, -r1x]
    ];
    // 线段的坐标
    // z轴
    var r3x_t = [
        [0, 1],
        [1, 2],
        [2, 3],
        [3, 0],
        [4, 5],
        [5, 6],
        [6, 7],
        [7, 4],
        [0, 4],
        [1, 5],
        [2, 6],
        [3, 7]
    ];

    // 各个线段的坐标
    var ret_t = [
        ["", ""],
        ["", ""],
        ["", ""],
        ["", ""],
        ["", ""],
        ["", ""],
        ["", ""],
        ["", ""],
        ["", ""],
        ["", ""],
        ["", ""],
        ["", ""]
    ];
    // ret[0][0] = r2x[r3x[0][0]];
    for (var i = 0; i < r3x.length; i++) {
        ret[i] = {
            "3d_id": i,
            "3d_point1": r2x[r3x[i][0]],
            "3d_point2": r2x[r3x[i][1]]
        }
        //   ret[i][0] = r2x[r3x[i][0]];
        //   ret[i][1] = r2x[r3x[i][1]];
    }
    ret_t[0][0] = r2x_t[r3x_t[0][0]];
    for (var i = 0; i < r3x_t.length; i++) {
        ret_t[i][0] = r2x_t[r3x_t[i][0]];
        ret_t[i][1] = r2x_t[r3x_t[i][1]];
    }

    return ret;
}

/**
 * 生成3D格式数据
 * @param {三维线段数组} arr 
 * @param {组成面得线段数组} faceArr 
 */
function fix3dLineArr(arr, faceArr) {
    var ret = []
    for (let i = 0; i < faceArr.length; i++) {
        var item = {
            faceLine: [],
            index: [],
            verticalLine: []
        }
        for (let j = 0; j < faceArr[i].length; j++) {
            for (let k = 0; k < arr.length; k++) {
                if (faceArr[i][j] == arr[k]['3d_id']) {
                    item.faceLine.push({
                        id: faceArr[i][j],
                        points: [arr[k]["3d_point1"], arr[k]["3d_point2"]]
                    })
                    item.index.push(faceArr[i][j])
                }
            }
        }
        ret.push(item)
    }

    return ret
}

// 归一化
function normalize(xyz, isFixed) {
    var _mo_ = Math.sqrt(xyz[0] * xyz[0] + xyz[1] * xyz[1] + xyz[2] * xyz[2]);
    var x = xyz[0] / _mo_;
    var y = xyz[1] / _mo_;
    var z = xyz[2] / _mo_;

    var r1x;
    if (isFixed) {
        r1x = [-y, -x, z];
    } else {
        r1x = [x, y, z];
    }

    return r1x;
}

/*
    @function: 相机在坐标原点上，返回空间点在球目图片上的投影点，和'_calculate3dPoint'互逆
    @param {xyz}: 空间中的3D点，不需要先进行归一化
    @return {ret}: 纹理空间的2D点，范围为[0 ,1]
*/

function _calculate2dPoint(xyz) {
    var ret = ["", ""];
    //@info: 这一步是为了兼容我们所用的球目相机的正方向，并且进行归一化
    // const auto r1x = Vector<VAL64> {-xyz[1] ,-xyz[0] ,xyz[2] ,0}.normalize () ;

    var r1x = normalize(xyz, true);
    // var r1x = xyz
    ret[0] = Math.atan2(r1x[1], r1x[0]) / (Math.PI * 2) + 0.5;

    ret[1] = (Math.acos(r1x[2]) / (Math.PI * 2)) * 2;

    return ret;

    // ARRAY2<VAL64> ret ;
    // //@info: 这一步是为了兼容我们所用的球目相机的正方向，并且进行归一化
    // const auto r1x = Vector<VAL64> {-xyz[1] ,-xyz[0] ,xyz[2] ,0}.normalize () ;
    // //@info: 分别计算投影点坐标
    // //@info: 反三角函数，缩放，平移
    // ret[0] = _ATAN_ (r1x[1] , r1x[0]) / VAL64 (VALX_PI * 2) + VAL64 (0.5) ;
    // ret[1] = _ACOS_ (r1x[2]) / VAL64 (VALX_PI * 2) * 2 ;
    // return std::move (ret) ;
}

/*
    @function: 相机在坐标原点上，返回球目图片上的投影点所在单位球上的原点，和'_calculate2dPoint'互逆
    @param {txy}: 纹理空间的2D点，范围为[0 ,1]
    @return {ret}: 空间中的3D点，在单位球上
*/

function _calculate3dPoint(txy) {
    var ret = ["", "", ""];

    var r1x = (txy[1] / 2) * (Math.PI * 2);
    var r2x = (txy[0] - 0.5) * (Math.PI * 2);

    ret[0] = -Math.sin(r1x) * Math.sin(r2x);
    ret[1] = -Math.sin(r1x) * Math.cos(r2x);
    ret[2] = Math.cos(r1x);

    return ret;
}

/*
    @function: 计算栅格化所有线段后最大生成点的数量
    @param {line}: 线段的数组，line[i][0]为第一个点，line[i][1]为第二个点
    @param {gap}: 栅格化所需的步长，既每多长生成一个点
    @return {ret}: 最大生成点的数量
*/

function _calculateMaxPoint(line, gap) {
    var ret = 0;
    for (var i = 0; i < line.length; i++) {
        var r1x = line[i][0];
        var r2x = line[i][1];
        // Math.hypot(x1 - x0, y1 - y0);
        ret += Math.ceil(
            Math.hypot(r1x[0] - r2x[0], r1x[1] - r2x[1], r1x[2] - r2x[2]) / gap + 0.5
        );
    }
    return ret;
}

/*
    @function: 计算3D线段在球目图片上的栅格化投影
    @param {camera_pose_matrix}: 相机位置，外参矩阵
    @param {line}: 线段的数组，line[i][0]为第一个点，line[i][1]为第二个点
    @param {gap}: 栅格化所需的步长，既每多长生成一个点
    @return {ret}: 栅格化投影投影后的2D线段，点坐标属于纹理空间，范围为[0 ,1]
*/
function _3dTo2d(camera_pose_matrix, line, gap) {
    var ret = [];
    var ret_t = [];
    var item;
    var r10x = numbers.matrix.inverse(camera_pose_matrix);

    for (var i = 0; i < line.length; i++) {
        ret_t.push({ line: [] });
        item = []
        var r1x_temp = [[line[i]["3d_point1"][0]], [line[i]['3d_point1'][1]], [line[i]['3d_point1'][2]], [1]];
        var r2x_temp = [[line[i]['3d_point2'][0]], [line[i]['3d_point2'][1]], [line[i]['3d_point2'][2]], [1]];
        var r1x = numbers.matrix.multiply(r10x, r1x_temp);
        var r2x = numbers.matrix.multiply(r10x, r2x_temp);
        var r3x = Math.hypot(r2x[0] - r1x[0], r2x[1] - r1x[1], r2x[2] - r1x[2]) / gap

        var r2r1 = [r2x[0] - r1x[0], r2x[1] - r1x[1], r2x[2] - r1x[2]];
        var hasNormalize = normalize(r2r1, false);

        var r5x = [
            hasNormalize[0] * gap,
            hasNormalize[1] * gap,
            hasNormalize[2] * gap
        ];

        for (var j = 0; j < r3x; j++) {
            var r6x = [
                parseFloat(r1x[0]) + parseFloat(r5x[0]) * j,
                parseFloat(r1x[1]) + parseFloat(r5x[1]) * j,
                parseFloat(r1x[2]) + parseFloat(r5x[2]) * j
            ];
            var r7x = _calculate2dPoint(r6x);
            if (r7x[0] > maxX) {
                maxX = r7x[0];
            }
            ret_t[i].line.push(toDecimal(r7x));
            item.push(toDecimal(r7x))
        }
        var r6x_t = [
            parseFloat(r1x[0]) + parseFloat(r5x[0]) * r3x,
            parseFloat(r1x[1]) + parseFloat(r5x[1]) * r3x,
            parseFloat(r1x[2]) + parseFloat(r5x[2]) * r3x
        ];
        var r7x_t = _calculate2dPoint(r6x_t);
        ret_t[i].line.push(toDecimal(r7x_t));
        item.push(toDecimal(r7x_t))
        ret.push({
            "3d_id": [line[i]["3d_id"]][0],
            '2d_arr': fixLine(item)
        })
    }

    // ret2dObj(ret)
    return {
        drawArr: ret_t,
        to3d: ret2dObj(ret)
    };
    // return ret_t;

}

/**
 * 生成对应的2d线段
 * @param {三维线段数组} arr 
 */
function ret2dObj(arr) {
    var ret = [];
    var count = 0
    for (var i = 0; i < arr.length; i++) {
        for (var j = 0; j < arr[i]["2d_arr"].length; j++) {
            ret.push({
                "2d_id": count,
                "3d_id": i,
                "2d_point1": arr[i]["2d_arr"][j]["2d_point1"],
                "2d_point2": arr[i]["2d_arr"][j]["2d_point2"]
            })
            count++
        }
    }
    return {
        panorama_line_2d: ret
    }
}

function fixLine(arr) {
    var obj,
        t_arr = [];
    for (var i = 0; i < arr.length; i++) {
        obj = {
            "2d_point1": arr[i],
            "2d_point2": arr[i + 1]
        };
        if (obj["2d_point2"] && obj["2d_point2"] != obj["2d_point1"]) {
            t_arr.push(obj);
        }
    }
    return t_arr;
}

/**
 * 四舍五入保留6位小数
 * @param {数组} arr 
 */
function toDecimal(arr) {
    var xf = parseFloat(arr[0]);
    var yf = parseFloat(arr[1]);

    if (isNaN(xf) || isNaN(yf)) {
        return;
    }
    tx = Math.round(xf * 10e5) / 10e5;
    ty = Math.round(yf * 10e5) / 10e5;

    return [tx, ty];
}

function make_matrix_from_quat(quat) {
    var ret = numbers.matrix.identity(4);
    var r1x =
        quat[0] * quat[0] +
        quat[1] * quat[1] +
        quat[2] * quat[2] +
        quat[3] * quat[3];
    if (r1x != 0) {
        var x2 = (2 / r1x) * quat[0];
        var y2 = (2 / r1x) * quat[1];
        var z2 = (2 / r1x) * quat[2];
        var xx = quat[0] * x2;
        var xy = quat[0] * y2;
        var xz = quat[0] * z2;
        var yy = quat[1] * y2;
        var yz = quat[1] * z2;
        var zz = quat[2] * z2;
        var wx = quat[3] * x2;
        var wy = quat[3] * y2;
        var wz = quat[3] * z2;

        ret[0][0] = 1 - (yy + zz);
        ret[1][0] = xy - wz;
        ret[2][0] = xz + wy;
        ret[0][1] = xy + wz;
        ret[1][1] = 1 - (xx + zz);
        ret[2][1] = yz - wx;
        ret[0][2] = xz - wy;
        ret[1][2] = yz + wx;
        ret[2][2] = 1 - (xx + yy);
    }
    // ret = numbers.matrix.multiply([[1, 0, 0], [0, 1, 0], [0, 0, 1]], transpose(ret))

    var tran = [
        [1, 0, 0, quat[4]],
        [0, 1, 0, quat[5]],
        [0, 0, 1, quat[6]],
        [0, 0, 0, 1]
    ];

    ret = numbers.matrix.multiply(tran, transpose(ret));

    return ret;
    //   [
    //     [1, 0, 0, quat[4]],
    //     [0, 1, 0, quat[5]],
    //     [0, 0, 1, quat[6]],
    //     [0 ,0 ,0 ,1]
    //   ]
}
/**
 * 矩阵转置
 * @param {矩阵} arr
 */
function transpose(arr) {
    var arr2 = [];
    for (var i = 0; i < arr[0].length; i++) {
        arr2[i] = [];
    }
    for (var i = 0; i < arr.length; i++) {
        for (var j = 0; j < arr[i].length; j++) {
            arr2[j][i] = arr[i][j];
        }
    }
    return arr2;
}

/**
 * 画线
 * @param {*画布} context
 * @param {*画布宽度 } w
 * @param {*画布高度} h
 * @param {*水平缩放倍数} scaleTime
 * @param {*垂直缩放倍数} scaleTimeH
 * @param {*线条数组} lineArr
 * @param {*是否重画} isclear
 */
function drawSingleLine(
    context,
    w,
    h,
    scaleTime,
    scaleTimeH,
    lineArr,
    isclear
) {

    context.beginPath();

    if (isclear) {
        context.clearRect(0, 0, w, h);
        context.drawImage(img, 0, 0, w, h);
    }
    context.moveTo(
        lineArr[0].line[0][0] * scaleTime,
        lineArr[0].line[0][1] * scaleTimeH
    );

    for (var i = 0; i < lineArr.length; i++) {
        if (isTwoLine(lineArr[i].line)[0]) {
            for (var k = 0; k < lineArr[i].line.length; k++) {
                if (lineArr[i].line[k][0] < 0.5) {
                    var temp = lineArr[i].line[k][0] + isTwoLine(lineArr[i].line)[1];
                    if (temp <= 1) {
                        lineArr[i].line.push([temp, lineArr[i].line[k][1]]);
                    }
                }
            }
        }
        context.moveTo(
            lineArr[i].line[0][0] * scaleTime,
            lineArr[i].line[0][1] * scaleTimeH
        );
        for (var j = 0; j < lineArr[i].line.length; j++) {
            if (j + 1 < lineArr[i].line.length) {
                // Math.hypot(
                //   lineArr[i].line[j+1][0] - lineArr[i].line[j][0],
                //   lineArr[i].line[j+1][1] - lineArr[i].line[j][1]
                // ) < 0.05
                if (Math.abs(lineArr[i].line[j + 1][0] - lineArr[i].line[j][0]) > 0.5) {
                    context.moveTo(
                        lineArr[i].line[j + 1][0] * scaleTime,
                        lineArr[i].line[j + 1][1] * scaleTimeH
                    );
                } else {
                    context.lineTo(
                        lineArr[i].line[j][0] * scaleTime,
                        lineArr[i].line[j][1] * scaleTimeH
                    );
                }
            }
            if (j + 1 === lineArr[i].line.length) {
                context.lineTo(
                    lineArr[i].line[j][0] * scaleTime,
                    lineArr[i].line[j][1] * scaleTimeH
                );
            }
        }
    }

    context.stroke();
}

/**
 * 选中伸缩的墙进行画线
 * @param {画布} context
 * @param {画布宽度} w
 * @param {画布高度} h
 * @param {水平缩放倍数} scaleTime
 * @param {垂直缩放倍数} scaleTimeH
 * @param {线条数组} lineArr
 */
function selectDragLine(context, w, h, scaleTime, scaleTimeH, lineArr, test) {
    context.strokeStyle = "#ff0000";
    drawSingleLine(context, w, h, scaleTime, scaleTimeH, lineArr, true);
    context.strokeStyle = "#00ff00";
    drawSingleLine(context, w, h, scaleTime, scaleTimeH, test, false);
}

/**
 * 找到面得中心坐标
 * @param {线段数组} lineArr
 * @param {水平缩放倍数} scaleTime
 * @param {垂直缩放倍数} scaleTimeH
 */
function _calculateMiddlePoint(test, scaleTime, scaleTimeH) {
    var minX = 1,
        minY = 1,
        maxX = 0,
        maxY = 0;
    for (var i = 0; i < test.length; i++) {
        for (var j = 0; j < test[i].line.length; j++) {
            minX = Math.min(minX, test[i].line[j][0]);
            minY = Math.min(minY, test[i].line[j][1]);
            maxX = Math.max(maxX, test[i].line[j][0]);
            maxY = Math.max(maxY, test[i].line[j][1]);
        }
    }
    return [
        ((maxX - minX) / 2 + minX) * scaleTime,
        ((maxY - minY) / 2 + minY) * scaleTimeH
    ];
}

/**
 * 计算墙体中心和鼠标坐标点的距离
 * @param {当前鼠标点击的坐标点} current
 * @param {墙体的中心点坐标} middle
 */
function _calculateMiddlePointDistance(current, middle) {
    return _calculateDistance(current, middle);
}

/**
 * 计算两点之间的距离
 * @param {坐标点} p1
 * @param {坐标点} p2
 */
function _calculateDistance(p1, p2) {
    return Math.sqrt(Math.pow(p2[1] - p1[1], 2) + Math.pow(p2[0] - p1[0], 2));
}

/**
 * 判断点是否在墙体上
 * @param {鼠标当前坐标点} current
 * @param {墙体线段} lineArr
 * @param {水平缩放倍数} scaleTime
 * @param {垂直缩放倍数} scaleTimeH
 */
function isInFace(current, test, scaleTime, scaleTimeH) {
    var fixArr = [];
    var selectYArr = [];
    var minX = 1,
        minY = 1,
        maxX = 0,
        maxY = 0;
    for (var i = 0; i < test.length; i++) {
        for (var j = 0; j < test[i].line.length; j++) {
            minX = Math.min(minX, test[i].line[j][0]);
            // minY = Math.min(minY, test[i].line[j][1]);
            maxX = Math.max(maxX, test[i].line[j][0]);
            // maxY = Math.max(maxY, test[i].line[j][1]);
            fixArr.push({
                id: parseFloat(test[i].line[j][0]).toFixed(1),
                y: test[i].line[j][1]
            });
        }
    }
    for (var i = 0; i < fixArr.length; i++) {
        if (fixArr[i].id == parseFloat(current[0] / scaleTime).toFixed(1)) {
            selectYArr.push(fixArr[i].y);
        }
    }
    for (var i = 0; i < selectYArr.length; i++) {
        minY = Math.min(minY, selectYArr[i]);
        maxY = Math.max(maxY, selectYArr[i]);
    }
    return (
        current[0] > minX * scaleTime &&
        current[0] < maxX * scaleTime &&
        current[1] > minY * scaleTimeH &&
        current[1] < maxY * scaleTimeH
    );
}

/**
 * 更新墙体线段的位置
 * @param {缩放的大小} distance
 * @param {墙体线段} lineArr
 */
function updateLineArr(distance, lineArr, _3dPoint, tag) {
    // deltaX：值为负的（-1），则表示滚轮向左滚动。值为正的（1），则表示滚轮向右滚动。
    // deltaY：值为负的（-1），则表示滚轮向下滚动。值为正的（1），则表示滚轮向上滚动。
    // deltaFactor：增量因子。通过 deltaFactor * deltaX 或者 deltaFactor * deltaY 可以得到浏览器实际的滚动距离。
    // distance = -10

    if (tag) {
        _3dPoint[2][0] += distance
        _3dPoint[3][0] += distance
        _3dPoint[((_3dPoint.length) / 2 + 2)][0] += distance
        _3dPoint[((_3dPoint.length) / 2 + 3)][0] += distance
    } else {
        _3dPoint[1][1] += distance
        _3dPoint[2][1] += distance
        _3dPoint[((_3dPoint.length) / 2 + 1)][1] += distance
        _3dPoint[((_3dPoint.length) / 2 + 2)][1] += distance
    }
    rx1 = _3dLine(r2x, r3x, ret);

    lineArr = _3dTo2d(
        make_matrix_from_quat([
            0.008515,
            -0.014279,
            0.016179,
            0.999731,
            -5.438891,
            2.167653,
            0.165233
        ]),
        rx1,
        0.05
    )["drawArr"];
    drawGeometry(rx1)
    return lineArr;
}

function updateSelectArr(lineArr, idxArr) {
    var ret = [];
    for (var i = 0; i < idxArr.length; i++) {
        ret.push(lineArr[idxArr[i]])
    }

    return ret
}

function _culaculateFaceArr(lineArr, faceArr) {
    var ret = [];
    for (var i = 0; i < faceArr.length; i++) {
        var item = [];
        for (var j = 0; j < faceArr[i].length; j++) {
            item.push(lineArr[faceArr[i][j]]);
        }
        ret.push({
            id: i,
            arr: item
        });
    }

    return ret;
}

function selectWhichFace(lineArr, faceArr, current, scaleTime, scaleTimeH) {
    var allFaceArr = _culaculateFaceArr(lineArr, faceArr);
    var ret = 0;
    var tempRet = 0;
    var minDist =
        faceArr &&
        _calculateMiddlePointDistance(
            current,
            _calculateMiddlePoint(allFaceArr[0].arr, scaleTime, scaleTimeH)
        );
    for (var i = 0; i < allFaceArr.length; i++) {
        if (isInFace(current, allFaceArr[i].arr, scaleTime, scaleTimeH)) {
            // tempRet = i
            ret = i
            if (
                _calculateMiddlePointDistance(
                    current,
                    _calculateMiddlePoint(allFaceArr[i].arr, scaleTime, scaleTimeH)
                ) < minDist
            ) {
                minDist = _calculateMiddlePointDistance(
                    current,
                    _calculateMiddlePoint(allFaceArr[i].arr, scaleTime, scaleTimeH)
                );
            } else {
                ret = i
            }
        }
    }
    return allFaceArr[ret];
}

/**
* 
* @param {*} point 
*/
function findverticalLine(point, faceLine) {
    let lineAry = [];
    for (let k = 0; k < faceLine.length; k++) {
        n_panorama_line_3d.find(item => {
            if (item['3d_id'] === faceLine[k]) {
                for (let l = 0; l < geoKeys.length; l++) {
                    let sta_point = item[geoKeys[l]];
                    for (let i = 0; i < n_panorama_line_3d.length; i++) {
                        for (let j = 0; j < geoKeys.length; j++) {
                            let curpoint = n_panorama_line_3d[i][geoKeys[j]];
                            let id = n_panorama_line_3d[i]['3d_id'];
                            if (arrayEquals(sta_point, curpoint) && faceLine.indexOf(id) < 0 && lineAry.indexOf(id) < 0) {
                                lineAry.push(id);
                            }
                        }
                    }
                }
            }
        })

    }
    console.log(lineAry);
    return lineAry;

}


/**
 * 根据sta查找点
 * @param {array} line1 第一条线段的点坐标
 * @param {array} line2 第二条线段的点坐标
 * @param {Boolean} sta 决定查找相同的点或不相同的点 
 */
function findPoint(line1, line2, sta) {
    if (!line1 || !line2) {
        console.log('线段未定义' + line1 + '  ' + line2);
        return null;
    }
    if (line1.length < 2 || line2.length < 2) {
        console.log('线段点坐标个数小于3, 请检查')
        return
    }
    if (sta === null || typeof sta === 'undefined') {
        sta = true;
    }
    // 根据sta值寻找当前线段与下一线段中符合要求的点
    for (let i = 0; i < line1.length; i++) {
        // sta为false, 寻找与下一线段都不相同的点
        if (!sta && sta === arrayEquals(line1[i], line2[0]) && sta === arrayEquals(line1[i], line2[1])) {

            return line1[i];
        }
        // sta为true, 寻找与下一线段相交的点
        if (sta && (sta === arrayEquals(line1[i], line2[0]) || sta === arrayEquals(line1[i], line2[1]))) {
            return line1[i];
        }
    }
    return null;
}

/**
 * 判断两个数组是否相等
 * @param {array} array1 
 * @param {array} array2 
 */
function arrayEquals(array1, array2) {
    if (!array1 || !array2) {
        return false;
    }
    if (array1.length !== array2.length) {
        return false;
    }
    for (let i = 0, len = array1.length; i < len; i++) {
        if (array1[i] instanceof Array && array2[i] instanceof Array) {
            if (!equals(array1[i], array2[2])) {
                return false;
            }
        } else if (array1[i] !== array2[i]) {
            return false;
        }
    }
    return true;
}

/**
 * 判断一个数组中的元素是否都包含在另一个数组中
 * @param {array} arrays
 * @param {array} array2 
 * @returns {boolean} true-表示数组元素唯一, false表示数组元素不唯一
 */
function arrayOnly(array1, array2) {
    if (!array1 || !array2) {
        console.log('数组未定义, 请检查');
        return;
    }
    if (!array1.length || !array2.length || array1.length === 0) {
        return false;
    }
    for (let i = 0; i < array1.length; i++) {
        let num = 0;
        for (let j = 0; j < array1[i].length; j++) {
            if (array2.indexOf(array1[i][j]) >= 0) {
                // return false;
                num++;
            }
        }
        if (num === array1[i].length) {
            return true;
        }
    }
    return false;
}
