首页
社区
课程
招聘
[原创]逆向中的GL与着色器逆向
发表于: 2024-7-25 15:10 6300

[原创]逆向中的GL与着色器逆向

2024-7-25 15:10
6300

着色器是一种运行在图形处理单元(GPU)上的小程序,用于对图形渲染管线的特定部分进行处理。着色器的主要作用是将输入数据(如顶点位置、颜色等)转化为输出数据(如像素颜色),从而实现对图像的渲染和处理。

从着色器代码到GPU可以理解的着色器程序,一般需要经过编译。
针对较低版本的OpenGL,这一般意味着从文件或者data段读取源代码直接编译。这给了我们修改shader以控制最终渲染表现的机会。例如笔者在VNCTF2024中的题目LearnOpenGL,就可以通过直接修改着色器的方法得到flag。
更为细致的,这里的”编译“其实包含了编译与链接两步。
一般而言,如果最后需要着色器生成一个图像,那么顶点着色器与片段着色器是不可缺的。因为图形的渲染必然涉及到以下两步:第一步把3D坐标转换为2D坐标,第二步是把2D坐标转变为实际的有颜色的像素。
可以大致理解成顶点着色器负责第一步,片段着色器负责第二步。那么两步加在一起才是一个完整的过程。反映到代码层面,就是在编译好顶点与片段着色器后,需要把两者链接起来,变成一个program,后续调用会直接调用这个program进行渲染。
一个着色器的一般流程
而对于OpenGL之外的其它环境,着色器代码可能会被预编译为中间表示,如Vulkan平台通常使用SPIR-V作为中间表示,而DirectX平台则使用DXBC。

根据题目名,以及调用的动态链接库,我们初步怀疑是Vulkan平台的shader逆向。运行程序,发现没有图形界面,那么看来它调用vulkan不是用来绘图的。直接猜测一手,核心的加密逻辑在vulkan调用的着色器里。
ida分析main_0函数,很容易发现dword_140021000里存的是加密后的密文。往前翻哪里读入了着色器,因为着色器读入后需要平台进行加载,所以在vkCreateShaderModule函数之前的sub_14001135C函数中
sub_14001135C函数
分析代码,着色器在程序的resource里,可以使用resource hacker等工具提取出来。发现是二进制格式的,需要反编译。根据我们前置介绍里讲的,Vulkan平台通常使用SPIR-V作为中间表示,那么现在我们需要找一个SPIR-V的反编译器。经过一番搜索,发现百度只能找到spirv-dis,是反编译成字节码,逆向难度仍然较大。GitHub能找到spirv-cross,直接把我们提取出来的中间表示还原成GLSL:

到了这步,xtea加密的特征就很明显了,我们写出对应的解密代码:

头尾有些问题。头可以确定是DubheCTF,根据flag规则与tea加密原理,尾部只有一位未知,即^^*},在本地用python的subprocess爆破一下

js先上下面这个网站去一点混淆:https://deobfuscate.relative.im/
flag解密部分的代码如下,记该函数为get_flag:

现在我们要求的变成了这个函数的parm
与检查flag相关的顶点着色器代码如下,传入vec3(三个数构成的数组),前两个被用来确定顶点的位置,第三个作为一个可以在着色器间传递的变量,进入了片段着色器:

片段着色器代码如下:

稍微去一下名称混淆如下:

后面就是根据功能恢复一下代码里的函数与变量名:

本来的打算是使用z3,对输入进行规约,但是存在两个难点:

赛后参考其它队伍的做法,发现能通过重放爆破的方式,把输入逐渐爆破出来,感觉这题有点过于偏技巧了
以下均来自r3kapig的wp

只涉及到输入里的5个变量(input[0xb], input[0x3], input[0x1], input[0x15], input[0x8]),可以考虑爆破出来

后续进行结果的组装
input = [19, 9, 8, 15, 3, 18, 17, 10, 23, 5, 0, 6, 24, 14, 12, 11, 2, 13, 16, 4, 7, 1, 21, 22, 20];
手动执行check,即可拿到flag
参考链接

#version 450
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 
const uint _80[5] = uint[](1214346853u, 558265710u, 559376756u, 1747010677u, 1651008801u);
 
layout(binding = 0, std430) buffer V
{
    uint v[];
} _23;
 
void main()
{
    uint cnt = gl_GlobalInvocationID.x * 2u;
    uint sum = 0u;
    uint l = _23.v[cnt];
    uint r = _23.v[cnt + 1u];
    for (int i = 1; i <= 40; i++)
    {
        l += ((((((~(r << uint(3))) & (r >> uint(5))) | ((r << uint(3)) & (~(r >> uint(5))))) ^ (~r)) & ((r << uint(3)) ^ (r >> uint(5)))) ^ ((~((~(sum + _80[sum & 4u])) | (~((r >> uint(3)) & (r << uint(2))))))));
        sum += 1932555628u;
        r += ((((((~(l << uint(3))) & (l >> uint(5))) | ((l << uint(3)) & (~(l >> uint(5))))) ^ (~l)) & ((l << uint(3)) ^ (l >> uint(5)))) ^ ((~((~(sum + _80[(sum >> uint(11)) & 4u])) | (~((l >> uint(3)) & (l << uint(2))))))));
    }
    _23.v[cnt] = l;
    _23.v[cnt + 1u] = r;
}
#version 450
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 
const uint _80[5] = uint[](1214346853u, 558265710u, 559376756u, 1747010677u, 1651008801u);
 
layout(binding = 0, std430) buffer V
{
    uint v[];
} _23;
 
void main()
{
    uint cnt = gl_GlobalInvocationID.x * 2u;
    uint sum = 0u;
    uint l = _23.v[cnt];
    uint r = _23.v[cnt + 1u];
    for (int i = 1; i <= 40; i++)
    {
        l += ((((((~(r << uint(3))) & (r >> uint(5))) | ((r << uint(3)) & (~(r >> uint(5))))) ^ (~r)) & ((r << uint(3)) ^ (r >> uint(5)))) ^ ((~((~(sum + _80[sum & 4u])) | (~((r >> uint(3)) & (r << uint(2))))))));
        sum += 1932555628u;
        r += ((((((~(l << uint(3))) & (l >> uint(5))) | ((l << uint(3)) & (~(l >> uint(5))))) ^ (~l)) & ((l << uint(3)) ^ (l >> uint(5)))) ^ ((~((~(sum + _80[(sum >> uint(11)) & 4u])) | (~((l >> uint(3)) & (l << uint(2))))))));
    }
    _23.v[cnt] = l;
    _23.v[cnt + 1u] = r;
}
#include <stdint.h>
#include <stdio.h>
 
// 解密函数
void decrypt(uint32_t *v, uint32_t *k) {
  uint32_t v0 = v[0], v1 = v[1], sum = 0, i; /* set up */
  uint32_t delta = 1932555628u;              /* a key schedule constant */
  for (i = 0; i < 40; i++) {
    sum += delta;
  }
  for (i = 0; i < 40; i++) { /* basic cycle start */
    v1 -=
        ((((((~(v0 << 3u)) & (v0 >> 5u)) | ((v0 << 3u) & (~(v0 >> 5u)))) ^
           (~v0)) &
          ((v0 << 3u) ^ (v0 >> 5u))) ^
         ((~((~(sum + k[(sum >> 11u) & 4u])) | (~((v0 >> 3u) & (v0 << 2u)))))));
    sum -= delta;
    v0 -= ((((((~(v1 << 3u)) & (v1 >> 5u)) | ((v1 << 3u) & (~(v1 >> 5u)))) ^
             (~v1)) &
            ((v1 << 3u) ^ (v1 >> 5u))) ^
           ((~((~(sum + k[sum & 4u])) | (~((v1 >> 3u) & (v1 << 2u)))))));
  } /* end cycle */
  v[0] = v0;
  v[1] = v1;
}
 
int main() {
  uint32_t ida_chars[] = {0x185B72AF, 0X631D2C6,  0XDE8B33CC, 0X31EBCD9F,
                          0X5DB8B33,  0XA8D77D0,  0X865C6111, 0XBF032335,
                          0X722228A5, 0XAD833A57, 0XB7C3456F};
  uint32_t key[] = {1214346853u, 558265710u, 559376756u, 1747010677u,
                    1651008801u};
  decrypt(ida_chars, key);
  decrypt(ida_chars + 2, key);
  decrypt(ida_chars + 4, key);
  decrypt(ida_chars + 6, key);
  decrypt(ida_chars + 8, key);
  decrypt(ida_chars + 10, key);
  decrypt(ida_chars + 12, key);
  decrypt(ida_chars + 14, key);
  printf("%s", ida_chars);
  return 0;
}
// :8�eCTF{Go0Od!!!You_4re_Vu1k@N_Mast3r^^ݙ�
#include <stdint.h>
#include <stdio.h>
 
// 解密函数
void decrypt(uint32_t *v, uint32_t *k) {
  uint32_t v0 = v[0], v1 = v[1], sum = 0, i; /* set up */
  uint32_t delta = 1932555628u;              /* a key schedule constant */
  for (i = 0; i < 40; i++) {
    sum += delta;
  }
  for (i = 0; i < 40; i++) { /* basic cycle start */
    v1 -=
        ((((((~(v0 << 3u)) & (v0 >> 5u)) | ((v0 << 3u) & (~(v0 >> 5u)))) ^
           (~v0)) &
          ((v0 << 3u) ^ (v0 >> 5u))) ^
         ((~((~(sum + k[(sum >> 11u) & 4u])) | (~((v0 >> 3u) & (v0 << 2u)))))));
    sum -= delta;
    v0 -= ((((((~(v1 << 3u)) & (v1 >> 5u)) | ((v1 << 3u) & (~(v1 >> 5u)))) ^
             (~v1)) &
            ((v1 << 3u) ^ (v1 >> 5u))) ^
           ((~((~(sum + k[sum & 4u])) | (~((v1 >> 3u) & (v1 << 2u)))))));
  } /* end cycle */
  v[0] = v0;
  v[1] = v1;
}
 
int main() {
  uint32_t ida_chars[] = {0x185B72AF, 0X631D2C6,  0XDE8B33CC, 0X31EBCD9F,
                          0X5DB8B33,  0XA8D77D0,  0X865C6111, 0XBF032335,
                          0X722228A5, 0XAD833A57, 0XB7C3456F};
  uint32_t key[] = {1214346853u, 558265710u, 559376756u, 1747010677u,
                    1651008801u};
  decrypt(ida_chars, key);
  decrypt(ida_chars + 2, key);
  decrypt(ida_chars + 4, key);
  decrypt(ida_chars + 6, key);
  decrypt(ida_chars + 8, key);
  decrypt(ida_chars + 10, key);
  decrypt(ida_chars + 12, key);
  decrypt(ida_chars + 14, key);
  printf("%s", ida_chars);
  return 0;
}
// :8�eCTF{Go0Od!!!You_4re_Vu1k@N_Mast3r^^ݙ�
import string
import subprocess
 
known_chars = "DubheCTF{Go0Od!!!You_4re_Vu1k@N_Mast3r^^"  # 已知的40位字符
 
for ch in string.printable:
    flag = known_chars + ch + "}"
    with subprocess.Popen(
        ["./ezVK.exe"], stdin=subprocess.PIPE, stdout=subprocess.PIPE
    ) as p:
        stdout, _ = p.communicate(input=flag.encode())
        if "You Are GENIUS!!!" in stdout.decode():
            print("flag found:", flag)
            exit(0)
# flag found: DubheCTF{Go0Od!!!You_4re_Vu1k@N_Mast3r^^_}
import string
import subprocess
 
known_chars = "DubheCTF{Go0Od!!!You_4re_Vu1k@N_Mast3r^^"  # 已知的40位字符
 
for ch in string.printable:
    flag = known_chars + ch + "}"
    with subprocess.Popen(
        ["./ezVK.exe"], stdin=subprocess.PIPE, stdout=subprocess.PIPE
    ) as p:
        stdout, _ = p.communicate(input=flag.encode())
        if "You Are GENIUS!!!" in stdout.decode():
            print("flag found:", flag)
            exit(0)
# flag found: DubheCTF{Go0Od!!!You_4re_Vu1k@N_Mast3r^^_}
function _0x52fd86(parm) {
    let salt = CryptoJS.enc.Hex.parse(
        CryptoJS.SHA256(parm).toString(CryptoJS.enc.Hex)
    ),
        iv_ = CryptoJS.enc.Hex.parse('fd3cb6c1be89457ba82919a33f02707c'),
        enc = CryptoJS.enc.Hex.parse(
            '4f6b9161b29e59e2d94fa90529d745601473cb4203c02d9549eea6e322908d71e0472241d86f3821b3c96dd82937b04dcef80b9f68b23dd2371d2a56ef873ce857563eefc6f9057aa0cc5b41ff87477256f6b56ef342da815099d1217d301d03b76e4fae675d27bf95ca43154015b964'
        ),
        flag = CryptoJS.AES.decrypt({ ciphertext: enc }, salt, {
            iv: iv_,
            padding: CryptoJS.pad.Pkcs7,
            mode: CryptoJS.mode.CBC,
            hasher: CryptoJS.algo.SHA256,
        })
    return flag.toString(CryptoJS.enc.Utf8)
}
function _0x52fd86(parm) {
    let salt = CryptoJS.enc.Hex.parse(
        CryptoJS.SHA256(parm).toString(CryptoJS.enc.Hex)
    ),
        iv_ = CryptoJS.enc.Hex.parse('fd3cb6c1be89457ba82919a33f02707c'),
        enc = CryptoJS.enc.Hex.parse(
            '4f6b9161b29e59e2d94fa90529d745601473cb4203c02d9549eea6e322908d71e0472241d86f3821b3c96dd82937b04dcef80b9f68b23dd2371d2a56ef873ce857563eefc6f9057aa0cc5b41ff87477256f6b56ef342da815099d1217d301d03b76e4fae675d27bf95ca43154015b964'
        ),
        flag = CryptoJS.AES.decrypt({ ciphertext: enc }, salt, {
            iv: iv_,
            padding: CryptoJS.pad.Pkcs7,
            mode: CryptoJS.mode.CBC,
            hasher: CryptoJS.algo.SHA256,
        })
    return flag.toString(CryptoJS.enc.Utf8)
}
attribute vec3 position;
varying   float owO;
void main(void){   
    gl_Position = vec4(position.xy, 0.0, 1.0);
    owO = position.z;
}
attribute vec3 position;
varying   float owO;
void main(void){   
    gl_Position = vec4(position.xy, 0.0, 1.0);
    owO = position.z;
}
#ifdef GL_ES
precision highp float//设置为高精度浮点数
#endif
varying float owO;  //顶点着色器传入
#define OvO 255.0
#define Ovo 128.0
#define OVO 23.0
float OwO (float Owo, float OWO, float owO) {
    OWO = floor(OWO + 0.5);
    owO = floor(owO + 0.5);
    return mod(floor((floor(Owo) + 0.5) / exp2(OWO)), floor(1.0*exp2(owO - OWO) + 0.5));
}
vec4 oWo (float Ow0) {
    if (Ow0 == 0.0) return vec4(0.0);   
    float Owo = Ow0 > 0.0 ? 0.0 : 1.0;   
    Ow0 = abs(Ow0);  
    float OWO = floor(log2(Ow0));  
    float oWo = OWO + OvO - Ovo;
    OWO = ((Ow0 / exp2(OWO)) - 1.0) * pow(2.0, OVO);  
    float owO = oWo / 2.0
    oWo = fract(owO) + fract(owO); 
    float oWO = floor(owO);
    owO = OwO(OWO, 0.0, 8.0) / OvO;   
    Ow0 = OwO(OWO, 8.0, 16.0) / OvO;   
    OWO = (oWo * Ovo + OwO(OWO, 16.0, OVO)) / OvO;  
    Owo = (Owo * Ovo + oWO) / OvO; 
    return vec4(owO, Ow0, OWO, Owo);
}
void main(){
    gl_FragColor = oWo(owO); //RGBA
#ifdef GL_ES
precision highp float//设置为高精度浮点数
#endif
varying float owO;  //顶点着色器传入
#define OvO 255.0
#define Ovo 128.0
#define OVO 23.0
float OwO (float Owo, float OWO, float owO) {
    OWO = floor(OWO + 0.5);
    owO = floor(owO + 0.5);
    return mod(floor((floor(Owo) + 0.5) / exp2(OWO)), floor(1.0*exp2(owO - OWO) + 0.5));
}
vec4 oWo (float Ow0) {
    if (Ow0 == 0.0) return vec4(0.0);   
    float Owo = Ow0 > 0.0 ? 0.0 : 1.0;   
    Ow0 = abs(Ow0);  
    float OWO = floor(log2(Ow0));  
    float oWo = OWO + OvO - Ovo;
    OWO = ((Ow0 / exp2(OWO)) - 1.0) * pow(2.0, OVO);  
    float owO = oWo / 2.0
    oWo = fract(owO) + fract(owO); 
    float oWO = floor(owO);
    owO = OwO(OWO, 0.0, 8.0) / OvO;   
    Ow0 = OwO(OWO, 8.0, 16.0) / OvO;   
    OWO = (oWo * Ovo + OwO(OWO, 16.0, OVO)) / OvO;  
    Owo = (Owo * Ovo + oWO) / OvO; 
    return vec4(owO, Ow0, OWO, Owo);
}
void main(){
    gl_FragColor = oWo(owO); //RGBA
#ifdef GL_ES
precision highp float//设置为高精度浮点数
#endif
varying float vert_in;  //顶点着色器传入,即owO
#define val_255 255.0
#define val_128 128.0
#define val_23 23.0
float func1 (float parm1, float parm2, float vert_in) {
    parm2 = floor(parm2 + 0.5);
    vert_in = floor(vert_in + 0.5);
    return mod(floor((floor(parm1) + 0.5) / exp2(parm2)), floor(1.0*exp2(vert_in - parm2) + 0.5));
}
vec4 func2 (float parm1) {
    if (parm1 == 0.0) return vec4(0.0);   
    float temp1 = parm1 > 0.0 ? 0.0 : 1.0;   
    parm1 = abs(parm1);  
    float temp2 = floor(log2(parm1));  
    float temp3 = temp2 + val_255 - val_128;
    temp2 = ((parm1 / exp2(temp2)) - 1.0) * pow(2.0, val_23);  
    float vert_in = temp3 / 2.0
    temp3 = fract(vert_in) + fract(vert_in); 
    float temp4 = floor(vert_in);
    vert_in = func1(temp2, 0.0, 8.0) / val_255;   
    parm1 = func1(temp2, 8.0, 16.0) / val_255;   
    temp2 = (temp3 * val_128 + func1(temp2, 16.0, val_23)) / val_255;  
    temp1 = (temp1 * val_128 + temp4) / val_255; 
    return vec4(vert_in, parm1, temp2, temp1);
}
void main(){
    gl_FragColor = func2(vert_in); //RGBA
#ifdef GL_ES
precision highp float//设置为高精度浮点数
#endif
varying float vert_in;  //顶点着色器传入,即owO
#define val_255 255.0
#define val_128 128.0
#define val_23 23.0
float func1 (float parm1, float parm2, float vert_in) {
    parm2 = floor(parm2 + 0.5);
    vert_in = floor(vert_in + 0.5);
    return mod(floor((floor(parm1) + 0.5) / exp2(parm2)), floor(1.0*exp2(vert_in - parm2) + 0.5));
}
vec4 func2 (float parm1) {
    if (parm1 == 0.0) return vec4(0.0);   
    float temp1 = parm1 > 0.0 ? 0.0 : 1.0;   
    parm1 = abs(parm1);  
    float temp2 = floor(log2(parm1));  
    float temp3 = temp2 + val_255 - val_128;
    temp2 = ((parm1 / exp2(temp2)) - 1.0) * pow(2.0, val_23);  
    float vert_in = temp3 / 2.0
    temp3 = fract(vert_in) + fract(vert_in); 
    float temp4 = floor(vert_in);
    vert_in = func1(temp2, 0.0, 8.0) / val_255;   
    parm1 = func1(temp2, 8.0, 16.0) / val_255;   
    temp2 = (temp3 * val_128 + func1(temp2, 16.0, val_23)) / val_255;  
    temp1 = (temp1 * val_128 + temp4) / val_255; 
    return vec4(vert_in, parm1, temp2, temp1);
}
void main(){
    gl_FragColor = func2(vert_in); //RGBA
const _0x464c09 = (function () {
    let _0x451913 = true
    return function (_0x258426, _0x4b7b8d) {
        const _0x1bb18e = _0x451913
            ? function () {
                if (_0x4b7b8d) {
                    const _0x2d8886 = _0x4b7b8d.apply(_0x258426, arguments)
                    return (_0x4b7b8d = null), _0x2d8886
                }
            }
            : function () { }
        return (_0x451913 = false), _0x1bb18e
    }
})(),
    _0x4c494b = _0x464c09(this, function () {
        return _0x4c494b
            .toString()
            .search(_0x9bd70f.dnYkL)
            .toString()
            .constructor(_0x4c494b)
            .search(_0x9bd70f.dnYkL)
    })
_0x4c494b()
window.addEventListener('load', load)
var draw_canvas, calc_canvas
function load() {
    let draw_canvas_vert =
        '\n  attribute vec3 position;\n  uniform   mat4 mvpMatrix;\n  varying   vec2 vPosition;\n\n  void main(void){\n      gl_Position = mvpMatrix * vec4(position, 1.0);\n      vPosition = position.xy;\n  }\n  ',
        draw_canvas_frag =
            '\n#ifdef GL_ES\nprecision mediump float;\n#endif            \n\nuniform float u_time;\nuniform vec2 u_resolution;\nvarying vec2 vPosition;\n\nvec3 hash(vec2 seed){\n    vec3 p3 = fract(float(seed.x + seed.y*86.) * vec3(.1051, .1020, .0983));\n\tp3 += dot(p3, p3.yzx + 33.33);\n    return fract(p3);\n}\n\nvec3 layer(float scale, vec2 uv, float time){\n    // uv coord in cell\n    vec2 scaled_uv = uv * scale - 0.5;\n    vec2 uv0 = fract( scaled_uv ) - 0.5;\n    // cell id\n    vec2 cell_id = scaled_uv - fract(scaled_uv);\n    \n    \n    vec3 col = vec3(0);\n    float speed = 1.5;\n    // distance to a spinning random point in the cell (also surrounding cells)\n    vec3 seed = hash(cell_id);\n\n    float radiance = seed.x + time * seed.y;\n    vec2 center_of_star = vec2(sin(radiance), cos(radiance))*0.3;\n\n    // radial distort effect for star shine\n    vec2 v_to_star = uv0 - center_of_star;\n    float star_radiance = atan(v_to_star.x/v_to_star.y);\n    float star_spark_1 = sin(star_radiance*14.+radiance*6.);\n    float star_spark_2 = sin(star_radiance*8.-radiance*2.);\n    float stars = length(v_to_star) * (5.+star_spark_1+star_spark_2) * 0.03;\n    col += smoothstep(length(seed) * 0.01, 0., stars);\n    return col;\n}\nvoid main()\n{    // center global uv from -1 to 1\n    vec2 virtual_resolution = vec2(2.0, 2.0);\n    vec2 uv = (vPosition * 2. - virtual_resolution.xy) / virtual_resolution.y;\n    vec3 col = vec3(0.);//vColor.xyz;\n    \n    const float layer_count = 6.5;\n    for(float i = 0.0; i < layer_count; i+=1.){\n        float rotate_speed = u_time*0.4;\n        float scale = mod(i - rotate_speed, layer_count)*1.5;\n        vec2 offseted_uv = uv + vec2(sin(rotate_speed), cos(rotate_speed));\n        vec3 layer_col = layer(scale, offseted_uv, u_time + i*1.5);\n        \n        // we want the star to smoothly show up\n        float max_scale = layer_count * 1.5;\n        float color_amp = smoothstep(0., 1., smoothstep(max_scale, 0., scale));\n        col += layer_col * color_amp;\n    }\n    // blue background\n    col += vec3(0., 0., -0.15) * (uv.y - 0.7) * pow(length(uv), 0.5);\n    gl_FragColor = vec4(col, 1.);\n}\n  ',
        calc_canvas_vert =
            `\nattribute vec3 position;
            varying   float owO;\n  \n 
            void main(void){\n     
            gl_Position = vec4(position.xy, 0.0, 1.0);\n     
            owO = position.z;\n  }\n  `,
        calc_canvas_frag =
            `\n#ifdef GL_ES\n
            precision highp float;\n
            #endif            \n
            varying float owO;\n
            #define OvO 255.0\n
            #define Ovo 128.0\n
            #define OVO 23.0\n\n
            float OwO (float Owo, float OWO, float owO) {
             \n    OWO = floor(OWO + 0.5);
             owO = floor(owO + 0.5);
             \n    return mod(floor((floor(Owo) + 0.5) / exp2(OWO)), floor(1.0*exp2(owO - OWO) + 0.5));
              \n}\n
            vec4 oWo (float Ow0) {
            \n    if (Ow0 == 0.0) return vec4(0.0); \n   
            float Owo = Ow0 > 0.0 ? 0.0 : 1.0; \n   
            Ow0 = abs(Ow0); \n   
            float OWO = floor(log2(Ow0)); \n   
            float oWo = OWO + OvO - Ovo; \n   
            OWO = ((Ow0 / exp2(OWO)) - 1.0) * pow(2.0, OVO);\n   
            float owO = oWo / 2.0; \n   
            oWo = fract(owO) + fract(owO); \n   
            float oWO = floor(owO); \n   
            owO = OwO(OWO, 0.0, 8.0) / OvO; \n   
            Ow0 = OwO(OWO, 8.0, 16.0) / OvO; \n   
            OWO = (oWo * Ovo + OwO(OWO, 16.0, OVO)) / OvO; \n   
            Owo = (Owo * Ovo + oWO) / OvO; \n  
             return vec4(owO, Ow0, OWO, Owo); \n
             }\n\nvoid main()\n{
             \n    gl_FragColor = oWo(owO);\n
             }\n  `
    draw_canvas = new ShaderManager('canvas', 0, 0, draw_canvas_vert, draw_canvas_frag, true)
    draw_canvas.render()
    calc_canvas = new ShaderManager(
        'canvas-calc',
        650,
        650,
        calc_canvas_vert,
        calc_canvas_frag,
        false
    )
    calc_canvas.render()
    let pattern_container = document.getElementById('pattern-container'),
        lines = document.getElementById('lines'),
        latest_selected_dot = null,
        line = null,
        selected = false,
        selected_dot = []
    pattern_container.childNodes.forEach((dot) => {
        if (!dot.classList) {
            return
        }
        if (!dot.classList.contains('dot')) {
            return
        }
        dot.addEventListener('mousedown', (_0x5be741) => {
            selected_dot.forEach((dot) => {
                dot.classList.remove('selected')
                dot.classList.remove('select')
                dot.classList.remove('lose')
                dot.classList.remove('win')
            })
            lines.innerHTML = ''
            selected_dot = []
            selected = true
            dot.classList.add('select')
            line = document.createElementNS('http://www.w3.org/2000/svg', 'line')
            line.setAttribute(
                'x1',
                dot.offsetLeft + dot.offsetWidth / 2
            )
            line.setAttribute(
                'y1',
                dot.offsetTop + dot.offsetHeight / 2
            )
            line.setAttribute(
                'x2',
                dot.offsetLeft + dot.offsetWidth / 2
            )
            line.setAttribute(
                'y2',
                dot.offsetTop + dot.offsetHeight / 2
            )
            line.setAttribute('stroke', 'white')
            line.setAttribute('stroke-width', '5')
            lines.appendChild(line)  //画线,但是头尾是同一个点
            selected_dot.push(dot)
            latest_selected_dot = dot
        })
        dot.addEventListener('mouseover', (_0x1cae46) => {  //鼠标移入
            if (!selected) {
                return
            }
            if (dot.classList.contains('selected')) {
                return
            }
            if (dot.classList.contains('select')) {
                return
            }
            line &&
                (line.setAttribute(
                    'x2',
                    dot.offsetLeft + dot.offsetWidth / 2
                ),
                    line.setAttribute(
                        'y2',
                        dot.offsetTop + dot.offsetHeight / 2
                    ),
                    latest_selected_dot.classList.add('selected'),
                    latest_selected_dot.classList.remove('select'))  // 把线从上一个点连到当前点
            dot.classList.add('select')
            line = document.createElementNS('http://www.w3.org/2000/svg', 'line')
            line.setAttribute(
                'x1',
                dot.offsetLeft + dot.offsetWidth / 2
            )
            line.setAttribute(
                'y1',
                dot.offsetTop + dot.offsetHeight / 2
            )
            line.setAttribute(
                'x2',
                dot.offsetLeft + dot.offsetWidth / 2
            )
            line.setAttribute(
                'y2',
                dot.offsetTop + dot.offsetHeight / 2
            )
            line.setAttribute('stroke', 'white')
            line.setAttribute('stroke-width', '5')
            lines.appendChild(line)
            selected_dot.push(dot)
            latest_selected_dot = dot
        })
    })
    pattern_container.addEventListener('mousemove', (pos) => {
        if (!selected) {
            return
        }
        latest_selected_dot &&
            line &&
            (line.setAttribute(
                'x2',
                pos.clientX - pattern_container.getBoundingClientRect().left
            ),
                line.setAttribute(
                    'y2',
                    pos.clientY - pattern_container.getBoundingClientRect().top
                ))
    })  // 连线跟随鼠标
    pattern_container.addEventListener('mouseup', (_0x3584c1) => {  //鼠标松开
        if (latest_selected_dot && line) {
            line.setAttribute(
                'x2',
                latest_selected_dot.offsetLeft + latest_selected_dot.offsetWidth / 2
            )
            line.setAttribute(
                'y2',
                latest_selected_dot.offsetTop + latest_selected_dot.offsetHeight / 2
            )
            latest_selected_dot.classList.add('selected')
            latest_selected_dot = null
            let flag = check_flag(
                selected_dot.map((dot) => parseInt(dot.dataset.number)) // 传入选中的点的顺序
            )
            if (flag !== null) {
                selected_dot.forEach((dot) => {
                    dot.classList.add('win')
                })
                let flag_p = document.getElementById('flag')
                flag_p.innerText = flag
            } else {
                selected_dot.forEach((dot) => {
                    dot.classList.add('lose')
                })
            }
        }
        selected = false
    })
}
function abs(num) {
    return Math.abs(num)
}
const _0xdf21a4 = async (_0x5c1638) => {
    const _0x4f0cab = new TextEncoder().encode(_0x5c1638),
        _0x336245 = await window.crypto.subtle.digest(_0x37cc4d.tNPCS, _0x4f0cab),
        _0x587059 = Array.from(new Uint8Array(_0x336245)),
        _0x49519a = _0x587059
            .map((_0x29f99c) => _0x29f99c.toString(16).padStart(2, '0'))
            .join('')
    return _0x49519a
}
function check_flag(index_list) {
    let _0x526465 = calc_canvas.wtf(index_list[19], index_list[3], index_list[5]) * 25,
        _0x27d483 = calc_canvas.wtf(index_list[7], index_list[20], index_list[18]) * 25,
        _0x47edd7 = calc_canvas.wtf(index_list[11], index_list[22], index_list[18]) * 25,
        _0x3c8060 = calc_canvas.wtf(index_list[5], index_list[17], index_list[2]) * 25,
        _0x315313 = calc_canvas.wtf(index_list[20], index_list[13], index_list[5]) * 25,
        _0x3cef24 = calc_canvas.wtf(index_list[11], index_list[1], index_list[21]) * 25,
        _0x2ee445 = calc_canvas.wtf(index_list[8], index_list[11], index_list[1]) * 25,
        _0x5e280a = calc_canvas.wtf(index_list[9], index_list[5], index_list[4]) * 25,
        _0x5f6c26 = calc_canvas.wtf(index_list[17], index_list[9], index_list[21]) * 25,
        _0x13e7aa = calc_canvas.wtf(index_list[23], index_list[9], index_list[20]) * 25,
        _0x9d682e = calc_canvas.wtf(index_list[16], index_list[5], index_list[4]) * 25,
        _0x277f3c = calc_canvas.wtf(index_list[16], index_list[14], index_list[13]) * 25,
        _0x2f58be = calc_canvas.wtf(index_list[5], index_list[6], index_list[10]) * 25,
        _0x5a6698 = calc_canvas.wtf(index_list[2], index_list[11], index_list[5]) * 25,
        _0x52d3ed = calc_canvas.wtf(index_list[11], index_list[3], index_list[1]) * 25,
        _0x4320e6 = calc_canvas.wtf(index_list[12], index_list[3], index_list[10]) * 25,
        _0xf9ef4b = calc_canvas.wtf(index_list[14], index_list[1], index_list[9]) * 25,
        _0x429aaf = calc_canvas.wtf(index_list[18], index_list[11], index_list[17]) * 25,
        _0x1a4487 = calc_canvas.wtf(index_list[12], index_list[15], index_list[2]) * 25,
        _0x4c135d = calc_canvas.wtf(index_list[22], index_list[0], index_list[19]) * 25,
        _0x5c13fb = 0
    _0x5c13fb += abs(
        0.3837876686390533 - calc_canvas.gtfo(_0x3cef24, _0xf9ef4b, _0x5f6c26, 16, 21)
    )
    _0x5c13fb += abs(
        0.21054889940828397 - calc_canvas.gtfo(_0x52d3ed, _0x3cef24, _0x2ee445, 8, 2)
    )
    _0x5c13fb += abs(
        0.475323349112426 - calc_canvas.gtfo(_0x3cef24, _0x429aaf, _0x2f58be, 0, 20)
    )
    _0x5c13fb += abs(
        0.6338370887573964 - calc_canvas.gtfo(_0x3c8060, _0x27d483, _0x2f58be, 8, 4)
    )
    _0x5c13fb += abs(
        0.4111607928994082 - calc_canvas.gtfo(_0x47edd7, _0x52d3ed, _0x4320e6, 23, 1)
    )
    _0x5c13fb += abs(
        0.7707577751479291 - calc_canvas.gtfo(_0x429aaf, _0x3c8060, _0x277f3c, 20, 6)
    )
    _0x5c13fb += abs(
        0.7743081420118344 - calc_canvas.gtfo(_0x13e7aa, _0x5a6698, _0x3c8060, 9, 10)
    )
    _0x5c13fb += abs(
        0.36471487573964495 - calc_canvas.gtfo(_0x5f6c26, _0x526465, _0x315313, 18, 8)
    )
    _0x5c13fb += abs(
        0.312678449704142 - calc_canvas.gtfo(_0x4320e6, _0x13e7aa, _0x429aaf, 0, 17)
    )
    _0x5c13fb += abs(
        0.9502808165680473 - calc_canvas.gtfo(_0x1a4487, _0x13e7aa, _0x3c8060, 22, 10)
    )
    _0x5c13fb += abs(
        0.5869052899408282 - calc_canvas.gtfo(_0x2f58be, _0x5e280a, _0x47edd7, 14, 10)
    )
    _0x5c13fb += abs(
        0.9323389467455623 - calc_canvas.gtfo(_0x429aaf, _0x47edd7, _0x2f58be, 12, 7)
    )
    _0x5c13fb += abs(
        0.4587118106508875 - calc_canvas.gtfo(_0x2ee445, _0x5a6698, _0x47edd7, 4, 21)
    )
    _0x5c13fb += abs(
        0.14484472189349107 - calc_canvas.gtfo(_0x4320e6, _0x13e7aa, _0x52d3ed, 7, 15)
    )
    _0x5c13fb += abs(
        0.7255550059171598 - calc_canvas.gtfo(_0x3cef24, _0x429aaf, _0x1a4487, 9, 23)
    )
    _0x5c13fb += abs(
        0.5031261301775147 - calc_canvas.gtfo(_0x3c8060, _0x47edd7, _0x52d3ed, 7, 1)
    )
    _0x5c13fb += abs(
        0.1417352189349112 - calc_canvas.gtfo(_0x2ee445, _0x52d3ed, _0x5f6c26, 16, 14)
    )
    _0x5c13fb += abs(
        0.5579334437869822 - calc_canvas.gtfo(_0x52d3ed, _0x47edd7, _0x1a4487, 19, 11)
    )
    _0x5c13fb += abs(
        0.48502262721893485 -
        calc_canvas.gtfo(_0x9d682e, _0x315313, _0x5e280a, 23, 18)
    )
    _0x5c13fb += abs(
        0.5920916568047336 - calc_canvas.gtfo(_0x5e280a, _0x5f6c26, _0x27d483, 19, 6)
    )
    _0x5c13fb += abs(
        0.7222713017751479 - calc_canvas.gtfo(_0xf9ef4b, _0x47edd7, _0x315313, 8, 16)
    )
    _0x5c13fb += abs(
        0.12367382248520711 - calc_canvas.gtfo(_0x9d682e, _0x4320e6, _0x2f58be, 9, 5)
    )
    _0x5c13fb += abs(
        0.4558028402366864 - calc_canvas.gtfo(_0x277f3c, _0x9d682e, _0x47edd7, 10, 2)
    )
    _0x5c13fb += abs(
        0.8537692426035504 - calc_canvas.gtfo(_0x429aaf, _0x13e7aa, _0x5a6698, 4, 11)
    )
    _0x5c13fb += abs(
        0.9618170650887574 - calc_canvas.gtfo(_0x2f58be, _0x1a4487, _0x429aaf, 15, 2)
    )
    _0x5c13fb += abs(
        0.22088933727810647 - calc_canvas.gtfo(_0x526465, _0x5e280a, _0xf9ef4b, 10, 5)
    )
    _0x5c13fb += abs(
        0.4302783550295858 - calc_canvas.gtfo(_0xf9ef4b, _0x277f3c, _0x3cef24, 14, 2)
    )
    _0x5c13fb += abs(
        0.6262803313609467 - calc_canvas.gtfo(_0x4c135d, _0x52d3ed, _0x47edd7, 17, 22)
    )
    if (_0x5c13fb > 0.00001) {
        return null
    }
    s = ''
    s += Math.round(
        calc_canvas.wtf(index_list[4], index_list[2], index_list[22]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[17], index_list[9], index_list[14]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[4], index_list[13], index_list[7]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[4], index_list[20], index_list[23]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[5], index_list[7], index_list[12]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[20], index_list[19], index_list[4]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[17], index_list[6], index_list[19]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[6], index_list[21], index_list[18]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[4], index_list[3], index_list[8]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[11], index_list[7], index_list[14]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[9], index_list[2], index_list[13]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[22], index_list[10], index_list[3]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[15], index_list[22], index_list[13]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[16], index_list[12], index_list[9]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[14], index_list[8], index_list[17]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[1], index_list[18], index_list[6]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[10], index_list[11], index_list[3]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[8], index_list[12], index_list[5]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[1], index_list[3], index_list[12]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[9], index_list[13], index_list[7]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[22],
            index_list[13],
            index_list[5],
            index_list[4],
            index_list[7]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[10],
            index_list[14],
            index_list[17],
            index_list[23],
            index_list[11]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[23],
            index_list[20],
            index_list[6],
            index_list[1],
            index_list[3]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[15],
            index_list[12],
            index_list[2],
            index_list[13],
            index_list[9]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[16],
            index_list[20],
            index_list[6],
            index_list[5],
            index_list[18]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[3],
            index_list[6],
            index_list[7],
            index_list[8],
            index_list[23]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[21],
            index_list[9],
            index_list[10],
            index_list[3],
            index_list[22]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[14],
            index_list[6],
            index_list[15],
            index_list[12],
            index_list[19]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[13],
            index_list[19],
            index_list[22],
            index_list[23],
            index_list[1]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[21],
            index_list[2],
            index_list[9],
            index_list[0],
            index_list[19]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[5],
            index_list[19],
            index_list[21],
            index_list[14],
            index_list[6]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[16],
            index_list[15],
            index_list[20],
            index_list[13],
            index_list[3]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[20],
            index_list[15],
            index_list[10],
            index_list[21],
            index_list[6]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[7],
            index_list[1],
            index_list[21],
            index_list[20],
            index_list[3]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[9],
            index_list[20],
            index_list[1],
            index_list[10],
            index_list[6]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[10],
            index_list[2],
            index_list[1],
            index_list[16],
            index_list[4]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[15],
            index_list[5],
            index_list[20],
            index_list[19],
            index_list[8]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[20],
            index_list[8],
            index_list[21],
            index_list[10],
            index_list[12]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[19],
            index_list[5],
            index_list[4],
            index_list[2],
            index_list[22]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[10],
            index_list[20],
            index_list[14],
            index_list[9],
            index_list[7]
        ) * 100000
    ).toString()
    let flag = get_flag(s)
    return (
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[5],
                index_list[15],
                index_list[9],
                index_list[13],
                index_list[16]
            ) * 100000
        ).toString()),
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[20],
                index_list[8],
                index_list[11],
                index_list[22],
                index_list[23]
            ) * 100000
        ).toString()),
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[22],
                index_list[3],
                index_list[1],
                index_list[17],
                index_list[15]
            ) * 100000
        ).toString()),
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[4],
                index_list[8],
                index_list[14],
                index_list[3],
                index_list[17]
            ) * 100000
        ).toString()),
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[12],
                index_list[6],
                index_list[11],
                index_list[10],
                index_list[15]
            ) * 100000
        ).toString()),
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[13],
                index_list[5],
                index_list[2],
                index_list[4],
                index_list[9]
            ) * 100000
        ).toString()),
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[21],
                index_list[12],
                index_list[19],
                index_list[11],
                index_list[20]
            ) * 100000
        ).toString()),
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[13],
                index_list[11],
                index_list[18],
                index_list[12],
                index_list[20]
            ) * 100000
        ).toString()),
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[11],
                index_list[2],
                index_list[8],
                index_list[3],
                index_list[16]
            ) * 100000
        ).toString()),
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[16],
                index_list[1],
                index_list[5],
                index_list[4],
                index_list[22]
            ) * 100000
        ).toString()),
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[0],
                index_list[3],
                index_list[12],
                index_list[10],
                index_list[1]
            ) * 100000
        ).toString()),
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[19],
                index_list[22],
                index_list[17],
                index_list[14],
                index_list[13]
            ) * 100000
        ).toString()),
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[14],
                index_list[2],
                index_list[10],
                index_list[18],
                index_list[16]
            ) * 100000
        ).toString()),
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[21],
                index_list[0],
                index_list[18],
                index_list[19],
                index_list[4]
            ) * 100000
        ).toString()),
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[22],
                index_list[12],
                index_list[9],
                index_list[16],
                index_list[17]
            ) * 100000
        ).toString()),
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[4],
                index_list[18],
                index_list[15],
                index_list[0],
                index_list[14]
            ) * 100000
        ).toString()),
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[9],
                index_list[5],
                index_list[19],
                index_list[20],
                index_list[12]
            ) * 100000
        ).toString()),
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[10],
                index_list[6],
                index_list[20],
                index_list[11],
                index_list[5]
            ) * 100000
        ).toString()),
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[1],
                index_list[11],
                index_list[22],
                index_list[13],
                index_list[9]
            ) * 100000
        ).toString()),
        (s += Math.round(
            calc_canvas.gtfo(
                index_list[1],
                index_list[19],
                index_list[10],
                index_list[0],
                index_list[18]
            ) * 100000
        ).toString()),
        flag
    )
}
function get_flag(parm) {
    let salt = CryptoJS.enc.Hex.parse(
        CryptoJS.SHA256(parm).toString(CryptoJS.enc.Hex)
    ),
        iv_ = CryptoJS.enc.Hex.parse('fd3cb6c1be89457ba82919a33f02707c'),
        enc = CryptoJS.enc.Hex.parse(
            '4f6b9161b29e59e2d94fa90529d745601473cb4203c02d9549eea6e322908d71e0472241d86f3821b3c96dd82937b04dcef80b9f68b23dd2371d2a56ef873ce857563eefc6f9057aa0cc5b41ff87477256f6b56ef342da815099d1217d301d03b76e4fae675d27bf95ca43154015b964'
        ),
        flag = CryptoJS.AES.decrypt({ ciphertext: enc }, salt, {
            iv: iv_,
            padding: CryptoJS.pad.Pkcs7,
            mode: CryptoJS.mode.CBC,
            hasher: CryptoJS.algo.SHA256,
        })
    return flag.toString(CryptoJS.enc.Utf8)
}
class ShaderManager {
    constructor(
        canvas_id,
        _width,
        _height,
        vert,
        frag,
        render_now
    ) {
        this.canvas = document.getElementById(canvas_id)
        _width != 0 && _height != 0
            ? ((this.canvas.width = _width), (this.canvas.height = _height))
            : ((this.canvas.width = window.innerWidth),
                (this.canvas.height = window.innerHeight))
        this.w = this.canvas.width
        this.h = this.canvas.height
        this.d = [
            4, 20, 23, 13, 11, 0, 15, 1, 14, 21, 9, 19, 8, 3, 17, 24, 16, 6, 22, 10,
            7, 18, 2, 5, 12,
        ]
        this.timeLoad = performance.now()
        this.gl = this.canvas.getContext('webgl2')
        this.gl.getExtension('EXT_color_buffer_float')
        this.v_shader = this.create_shader(vert, 'OuO')
        this.f_shader = this.create_shader(frag, '>w<')
        this.prg = this.create_program(this.v_shader, this.f_shader)
        let _this = this
        function _0x52ad9c() {
            _this.render()
            _this.animationFrameRequest = window.requestAnimationFrame(_0x52ad9c)
        }
        return render_now && _0x52ad9c(), this
    }
    ['wtf'](parm1, parm2, parm3) {
        this.gl.clearColor(0, 0, 0, 1)
        this.gl.clearDepth(1)
        this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT)
        const _0x4b856b = this.gl.getAttribLocation(this.prg, 'position'),
            position_array = [
                -1,
                -1,
                ((parm1 % 1) + this.d[~~parm1]) / 25,
                -1,
                1,
                ((parm2 % 1) + this.d[~~parm2]) / 25,
                1,
                1,
                ((parm2 % 1) + this.d[~~parm2]) / 25,
                -1,
                -1,
                ((parm1 % 1) + this.d[~~parm1]) / 25,
                1,
                1,
                ((parm2 % 1) + this.d[~~parm2]) / 25,
                1,
                -1,
                ((parm1 % 1) + this.d[~~parm1]) / 25,
            ],
            _0x3e2e26 = this.create_vbo(position_array)
        this.gl.bindBuffer(this.gl.ARRAY_BUFFER, _0x3e2e26)
        this.gl.enableVertexAttribArray(_0x4b856b)
        this.gl.vertexAttribPointer(_0x4b856b, 3, this.gl.FLOAT, false, 0, 0)
        this.gl.useProgram(this.prg)
        this.gl.drawArrays(this.gl.TRIANGLES, 0, 6)
        this.gl.flush()
        const _0x2fa9a7 = new Uint8Array(4)
        this.gl.readPixels(
            this.w / 2,
            (((parm3 % 1) + this.d[~~parm3]) * this.h) / 25,
            1,
            1,
            this.gl.RGBA,
            this.gl.UNSIGNED_BYTE,
            _0x2fa9a7
        )
        let _0x511406 = new Float32Array(_0x2fa9a7.buffer)
        return _0x511406[0].toFixed(15)
    }
    ['gtfo'](parm1, parm2, parm3, parm4, parm5) {
        this.gl.clearColor(0, 0, 0, 1)
        this.gl.clearDepth(1)
        this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT)
        const _0x16760a = this.gl.getAttribLocation(this.prg, 'position'),
            _0x13e5e0 = [
                -1,
                -1,
                ((parm1 % 1) + this.d[~~parm1]) / 25,
                3,
                -1,
                ((parm2 % 1) + this.d[~~parm2]) / 25,
                -1,
                3,
                ((parm3 % 1) + this.d[~~parm3]) / 25,
            ],
            _0x49be08 = this.create_vbo(_0x13e5e0)
        this.gl.bindBuffer(this.gl.ARRAY_BUFFER, _0x49be08)
        this.gl.enableVertexAttribArray(_0x16760a)
        this.gl.vertexAttribPointer(_0x16760a, 3, this.gl.FLOAT, false, 0, 0)
        this.gl.useProgram(this.prg)
        this.gl.drawArrays(this.gl.TRIANGLES, 0, 3)
        this.gl.flush()
        const _0x3da8ae = new Uint8Array(4)
        this.gl.readPixels(
            (((parm4 % 1) + this.d[~~parm4]) * this.w) / 25,
            (((parm5 % 1) + this.d[~~parm5]) * this.h) / 25,
            1,
            1,
            this.gl.RGBA,
            this.gl.UNSIGNED_BYTE,
            _0x3da8ae
        )
        let _0x2e76ac = new Float32Array(_0x3da8ae.buffer)
        return _0x2e76ac[0].toFixed(15)
    }
    ['render']() {
        this.gl.clearColor(0, 0, 0, 1)
        this.gl.clearDepth(1)
        this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT)
        let _0x39f658 = performance.now()
        this.timeDelta = (_0x39f658 - this.timePrev) / 1000
        this.timePrev = _0x39f658
        const _0x18111e = new Array(2)
        _0x18111e[0] = this.gl.getAttribLocation(this.prg, 'position')
        const _0x15ddf2 = new Array(2)
        _0x15ddf2[0] = 3
        _0x15ddf2[1] = 4
        const _0x2626af = [
            3, 8, 0, 7, -3, 5, 3, -8, 0, 3, 8, 0, 7, -3, 5, 7, 3, 5, 3, 8, 0, -3,
            -8, 0, 3, -8, 0, 3, 8, 0, -3, -8, 0, -3, 8, 0, -3, 8, 0, -7, -3, 5, -3,
            -8, 0, -3, 8, 0, -7, -3, 5, -7, 3, 5,
        ],
            _0x1ebfe3 = this.create_vbo(_0x2626af)
        this.gl.bindBuffer(this.gl.ARRAY_BUFFER, _0x1ebfe3)
        this.gl.enableVertexAttribArray(_0x18111e[0])
        this.gl.vertexAttribPointer(
            _0x18111e[0],
            _0x15ddf2[0],
            this.gl.FLOAT,
            false,
            0,
            0
        )
        const _0x570653 = new matIV(),
            _0x5a4b24 = _0x570653.identity(_0x570653.create()),
            _0x5f594b = _0x570653.identity(_0x570653.create()),
            _0x15df66 = _0x570653.identity(_0x570653.create()),
            _0x28d80f = _0x570653.identity(_0x570653.create()),
            _0xf54bc7 = (_0x39f658 - this.timeLoad) / 1000,
            _0x404188 = [
                Math.sin(Math.sin(_0xf54bc7) / 3),
                Math.cos(Math.sin(_0xf54bc7) / 3),
                0,
            ]
        _0x570653.lookAt([0, 0, 5], [0, 0, 0], _0x404188, _0x5f594b)
        _0x570653.perspective(
            90,
            this.canvas.width / this.canvas.height,
            0.1,
            100,
            _0x15df66
        )
        _0x570653.multiply(_0x15df66, _0x5f594b, _0x28d80f)
        _0x570653.multiply(_0x28d80f, _0x5a4b24, _0x28d80f)
        const _0x4d0a27 = this.gl.getUniformLocation(this.prg, 'mvpMatrix')
        this.gl.uniformMatrix4fv(_0x4d0a27, false, _0x28d80f)
        const _0x504e76 = this.gl.getUniformLocation(this.prg, 'u_time')
        this.gl.uniform1f(_0x504e76, _0xf54bc7)
        const _0x15e050 = this.gl.getUniformLocation(this.prg, 'u_resolution')
        this.gl.uniform2f(_0x15e050, this.canvas.width, this.canvas.height)
        this.gl.useProgram(this.prg)
        this.gl.drawArrays(this.gl.TRIANGLES, 0, 18)
        this.gl.flush()
    }
    ['create_shader'](_0x217f95, _0x50b1bf) {
        let _0x333f8e
        switch (_0x50b1bf) {
            case 'OuO':
                _0x333f8e = this.gl.createShader(this.gl.VERTEX_SHADER)
                break
            case '>w<':
                _0x333f8e = this.gl.createShader(this.gl.FRAGMENT_SHADER)
                break
            default:
                return
        }
        this.gl.shaderSource(_0x333f8e, _0x217f95)
        this.gl.compileShader(_0x333f8e)
        if (this.gl.getShaderParameter(_0x333f8e, this.gl.COMPILE_STATUS)) {
            return _0x333f8e
        } else {
            alert(this.gl.getShaderInfoLog(_0x333f8e))
        }
    }
    ['create_program'](_0x4d159e, _0x135a44) {
        const _0x171a80 = this.gl.createProgram()
        this.gl.attachShader(_0x171a80, _0x4d159e)
        this.gl.attachShader(_0x171a80, _0x135a44)
        this.gl.linkProgram(_0x171a80)
        if (this.gl.getProgramParameter(_0x171a80, this.gl.LINK_STATUS)) {
            return this.gl.useProgram(_0x171a80), _0x171a80
        } else {
            alert(this.gl.getProgramInfoLog(_0x171a80))
        }
    }
    ['create_vbo'](_0xbcae1c) {
        const _0x9500e2 = this.gl.createBuffer()
        return (
            this.gl.bindBuffer(this.gl.ARRAY_BUFFER, _0x9500e2),
            this.gl.bufferData(
                this.gl.ARRAY_BUFFER,
                new Float32Array(_0xbcae1c),
                this.gl.STATIC_DRAW
            ),
            this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null),
            _0x9500e2
        )
    }
}
const _0x464c09 = (function () {
    let _0x451913 = true
    return function (_0x258426, _0x4b7b8d) {
        const _0x1bb18e = _0x451913
            ? function () {
                if (_0x4b7b8d) {
                    const _0x2d8886 = _0x4b7b8d.apply(_0x258426, arguments)
                    return (_0x4b7b8d = null), _0x2d8886
                }
            }
            : function () { }
        return (_0x451913 = false), _0x1bb18e
    }
})(),
    _0x4c494b = _0x464c09(this, function () {
        return _0x4c494b
            .toString()
            .search(_0x9bd70f.dnYkL)
            .toString()
            .constructor(_0x4c494b)
            .search(_0x9bd70f.dnYkL)
    })
_0x4c494b()
window.addEventListener('load', load)
var draw_canvas, calc_canvas
function load() {
    let draw_canvas_vert =
        '\n  attribute vec3 position;\n  uniform   mat4 mvpMatrix;\n  varying   vec2 vPosition;\n\n  void main(void){\n      gl_Position = mvpMatrix * vec4(position, 1.0);\n      vPosition = position.xy;\n  }\n  ',
        draw_canvas_frag =
            '\n#ifdef GL_ES\nprecision mediump float;\n#endif            \n\nuniform float u_time;\nuniform vec2 u_resolution;\nvarying vec2 vPosition;\n\nvec3 hash(vec2 seed){\n    vec3 p3 = fract(float(seed.x + seed.y*86.) * vec3(.1051, .1020, .0983));\n\tp3 += dot(p3, p3.yzx + 33.33);\n    return fract(p3);\n}\n\nvec3 layer(float scale, vec2 uv, float time){\n    // uv coord in cell\n    vec2 scaled_uv = uv * scale - 0.5;\n    vec2 uv0 = fract( scaled_uv ) - 0.5;\n    // cell id\n    vec2 cell_id = scaled_uv - fract(scaled_uv);\n    \n    \n    vec3 col = vec3(0);\n    float speed = 1.5;\n    // distance to a spinning random point in the cell (also surrounding cells)\n    vec3 seed = hash(cell_id);\n\n    float radiance = seed.x + time * seed.y;\n    vec2 center_of_star = vec2(sin(radiance), cos(radiance))*0.3;\n\n    // radial distort effect for star shine\n    vec2 v_to_star = uv0 - center_of_star;\n    float star_radiance = atan(v_to_star.x/v_to_star.y);\n    float star_spark_1 = sin(star_radiance*14.+radiance*6.);\n    float star_spark_2 = sin(star_radiance*8.-radiance*2.);\n    float stars = length(v_to_star) * (5.+star_spark_1+star_spark_2) * 0.03;\n    col += smoothstep(length(seed) * 0.01, 0., stars);\n    return col;\n}\nvoid main()\n{    // center global uv from -1 to 1\n    vec2 virtual_resolution = vec2(2.0, 2.0);\n    vec2 uv = (vPosition * 2. - virtual_resolution.xy) / virtual_resolution.y;\n    vec3 col = vec3(0.);//vColor.xyz;\n    \n    const float layer_count = 6.5;\n    for(float i = 0.0; i < layer_count; i+=1.){\n        float rotate_speed = u_time*0.4;\n        float scale = mod(i - rotate_speed, layer_count)*1.5;\n        vec2 offseted_uv = uv + vec2(sin(rotate_speed), cos(rotate_speed));\n        vec3 layer_col = layer(scale, offseted_uv, u_time + i*1.5);\n        \n        // we want the star to smoothly show up\n        float max_scale = layer_count * 1.5;\n        float color_amp = smoothstep(0., 1., smoothstep(max_scale, 0., scale));\n        col += layer_col * color_amp;\n    }\n    // blue background\n    col += vec3(0., 0., -0.15) * (uv.y - 0.7) * pow(length(uv), 0.5);\n    gl_FragColor = vec4(col, 1.);\n}\n  ',
        calc_canvas_vert =
            `\nattribute vec3 position;
            varying   float owO;\n  \n 
            void main(void){\n     
            gl_Position = vec4(position.xy, 0.0, 1.0);\n     
            owO = position.z;\n  }\n  `,
        calc_canvas_frag =
            `\n#ifdef GL_ES\n
            precision highp float;\n
            #endif            \n
            varying float owO;\n
            #define OvO 255.0\n
            #define Ovo 128.0\n
            #define OVO 23.0\n\n
            float OwO (float Owo, float OWO, float owO) {
             \n    OWO = floor(OWO + 0.5);
             owO = floor(owO + 0.5);
             \n    return mod(floor((floor(Owo) + 0.5) / exp2(OWO)), floor(1.0*exp2(owO - OWO) + 0.5));
              \n}\n
            vec4 oWo (float Ow0) {
            \n    if (Ow0 == 0.0) return vec4(0.0); \n   
            float Owo = Ow0 > 0.0 ? 0.0 : 1.0; \n   
            Ow0 = abs(Ow0); \n   
            float OWO = floor(log2(Ow0)); \n   
            float oWo = OWO + OvO - Ovo; \n   
            OWO = ((Ow0 / exp2(OWO)) - 1.0) * pow(2.0, OVO);\n   
            float owO = oWo / 2.0; \n   
            oWo = fract(owO) + fract(owO); \n   
            float oWO = floor(owO); \n   
            owO = OwO(OWO, 0.0, 8.0) / OvO; \n   
            Ow0 = OwO(OWO, 8.0, 16.0) / OvO; \n   
            OWO = (oWo * Ovo + OwO(OWO, 16.0, OVO)) / OvO; \n   
            Owo = (Owo * Ovo + oWO) / OvO; \n  
             return vec4(owO, Ow0, OWO, Owo); \n
             }\n\nvoid main()\n{
             \n    gl_FragColor = oWo(owO);\n
             }\n  `
    draw_canvas = new ShaderManager('canvas', 0, 0, draw_canvas_vert, draw_canvas_frag, true)
    draw_canvas.render()
    calc_canvas = new ShaderManager(
        'canvas-calc',
        650,
        650,
        calc_canvas_vert,
        calc_canvas_frag,
        false
    )
    calc_canvas.render()
    let pattern_container = document.getElementById('pattern-container'),
        lines = document.getElementById('lines'),
        latest_selected_dot = null,
        line = null,
        selected = false,
        selected_dot = []
    pattern_container.childNodes.forEach((dot) => {
        if (!dot.classList) {
            return
        }
        if (!dot.classList.contains('dot')) {
            return
        }
        dot.addEventListener('mousedown', (_0x5be741) => {
            selected_dot.forEach((dot) => {
                dot.classList.remove('selected')
                dot.classList.remove('select')
                dot.classList.remove('lose')
                dot.classList.remove('win')
            })
            lines.innerHTML = ''
            selected_dot = []
            selected = true
            dot.classList.add('select')
            line = document.createElementNS('http://www.w3.org/2000/svg', 'line')
            line.setAttribute(
                'x1',
                dot.offsetLeft + dot.offsetWidth / 2
            )
            line.setAttribute(
                'y1',
                dot.offsetTop + dot.offsetHeight / 2
            )
            line.setAttribute(
                'x2',
                dot.offsetLeft + dot.offsetWidth / 2
            )
            line.setAttribute(
                'y2',
                dot.offsetTop + dot.offsetHeight / 2
            )
            line.setAttribute('stroke', 'white')
            line.setAttribute('stroke-width', '5')
            lines.appendChild(line)  //画线,但是头尾是同一个点
            selected_dot.push(dot)
            latest_selected_dot = dot
        })
        dot.addEventListener('mouseover', (_0x1cae46) => {  //鼠标移入
            if (!selected) {
                return
            }
            if (dot.classList.contains('selected')) {
                return
            }
            if (dot.classList.contains('select')) {
                return
            }
            line &&
                (line.setAttribute(
                    'x2',
                    dot.offsetLeft + dot.offsetWidth / 2
                ),
                    line.setAttribute(
                        'y2',
                        dot.offsetTop + dot.offsetHeight / 2
                    ),
                    latest_selected_dot.classList.add('selected'),
                    latest_selected_dot.classList.remove('select'))  // 把线从上一个点连到当前点
            dot.classList.add('select')
            line = document.createElementNS('http://www.w3.org/2000/svg', 'line')
            line.setAttribute(
                'x1',
                dot.offsetLeft + dot.offsetWidth / 2
            )
            line.setAttribute(
                'y1',
                dot.offsetTop + dot.offsetHeight / 2
            )
            line.setAttribute(
                'x2',
                dot.offsetLeft + dot.offsetWidth / 2
            )
            line.setAttribute(
                'y2',
                dot.offsetTop + dot.offsetHeight / 2
            )
            line.setAttribute('stroke', 'white')
            line.setAttribute('stroke-width', '5')
            lines.appendChild(line)
            selected_dot.push(dot)
            latest_selected_dot = dot
        })
    })
    pattern_container.addEventListener('mousemove', (pos) => {
        if (!selected) {
            return
        }
        latest_selected_dot &&
            line &&
            (line.setAttribute(
                'x2',
                pos.clientX - pattern_container.getBoundingClientRect().left
            ),
                line.setAttribute(
                    'y2',
                    pos.clientY - pattern_container.getBoundingClientRect().top
                ))
    })  // 连线跟随鼠标
    pattern_container.addEventListener('mouseup', (_0x3584c1) => {  //鼠标松开
        if (latest_selected_dot && line) {
            line.setAttribute(
                'x2',
                latest_selected_dot.offsetLeft + latest_selected_dot.offsetWidth / 2
            )
            line.setAttribute(
                'y2',
                latest_selected_dot.offsetTop + latest_selected_dot.offsetHeight / 2
            )
            latest_selected_dot.classList.add('selected')
            latest_selected_dot = null
            let flag = check_flag(
                selected_dot.map((dot) => parseInt(dot.dataset.number)) // 传入选中的点的顺序
            )
            if (flag !== null) {
                selected_dot.forEach((dot) => {
                    dot.classList.add('win')
                })
                let flag_p = document.getElementById('flag')
                flag_p.innerText = flag
            } else {
                selected_dot.forEach((dot) => {
                    dot.classList.add('lose')
                })
            }
        }
        selected = false
    })
}
function abs(num) {
    return Math.abs(num)
}
const _0xdf21a4 = async (_0x5c1638) => {
    const _0x4f0cab = new TextEncoder().encode(_0x5c1638),
        _0x336245 = await window.crypto.subtle.digest(_0x37cc4d.tNPCS, _0x4f0cab),
        _0x587059 = Array.from(new Uint8Array(_0x336245)),
        _0x49519a = _0x587059
            .map((_0x29f99c) => _0x29f99c.toString(16).padStart(2, '0'))
            .join('')
    return _0x49519a
}
function check_flag(index_list) {
    let _0x526465 = calc_canvas.wtf(index_list[19], index_list[3], index_list[5]) * 25,
        _0x27d483 = calc_canvas.wtf(index_list[7], index_list[20], index_list[18]) * 25,
        _0x47edd7 = calc_canvas.wtf(index_list[11], index_list[22], index_list[18]) * 25,
        _0x3c8060 = calc_canvas.wtf(index_list[5], index_list[17], index_list[2]) * 25,
        _0x315313 = calc_canvas.wtf(index_list[20], index_list[13], index_list[5]) * 25,
        _0x3cef24 = calc_canvas.wtf(index_list[11], index_list[1], index_list[21]) * 25,
        _0x2ee445 = calc_canvas.wtf(index_list[8], index_list[11], index_list[1]) * 25,
        _0x5e280a = calc_canvas.wtf(index_list[9], index_list[5], index_list[4]) * 25,
        _0x5f6c26 = calc_canvas.wtf(index_list[17], index_list[9], index_list[21]) * 25,
        _0x13e7aa = calc_canvas.wtf(index_list[23], index_list[9], index_list[20]) * 25,
        _0x9d682e = calc_canvas.wtf(index_list[16], index_list[5], index_list[4]) * 25,
        _0x277f3c = calc_canvas.wtf(index_list[16], index_list[14], index_list[13]) * 25,
        _0x2f58be = calc_canvas.wtf(index_list[5], index_list[6], index_list[10]) * 25,
        _0x5a6698 = calc_canvas.wtf(index_list[2], index_list[11], index_list[5]) * 25,
        _0x52d3ed = calc_canvas.wtf(index_list[11], index_list[3], index_list[1]) * 25,
        _0x4320e6 = calc_canvas.wtf(index_list[12], index_list[3], index_list[10]) * 25,
        _0xf9ef4b = calc_canvas.wtf(index_list[14], index_list[1], index_list[9]) * 25,
        _0x429aaf = calc_canvas.wtf(index_list[18], index_list[11], index_list[17]) * 25,
        _0x1a4487 = calc_canvas.wtf(index_list[12], index_list[15], index_list[2]) * 25,
        _0x4c135d = calc_canvas.wtf(index_list[22], index_list[0], index_list[19]) * 25,
        _0x5c13fb = 0
    _0x5c13fb += abs(
        0.3837876686390533 - calc_canvas.gtfo(_0x3cef24, _0xf9ef4b, _0x5f6c26, 16, 21)
    )
    _0x5c13fb += abs(
        0.21054889940828397 - calc_canvas.gtfo(_0x52d3ed, _0x3cef24, _0x2ee445, 8, 2)
    )
    _0x5c13fb += abs(
        0.475323349112426 - calc_canvas.gtfo(_0x3cef24, _0x429aaf, _0x2f58be, 0, 20)
    )
    _0x5c13fb += abs(
        0.6338370887573964 - calc_canvas.gtfo(_0x3c8060, _0x27d483, _0x2f58be, 8, 4)
    )
    _0x5c13fb += abs(
        0.4111607928994082 - calc_canvas.gtfo(_0x47edd7, _0x52d3ed, _0x4320e6, 23, 1)
    )
    _0x5c13fb += abs(
        0.7707577751479291 - calc_canvas.gtfo(_0x429aaf, _0x3c8060, _0x277f3c, 20, 6)
    )
    _0x5c13fb += abs(
        0.7743081420118344 - calc_canvas.gtfo(_0x13e7aa, _0x5a6698, _0x3c8060, 9, 10)
    )
    _0x5c13fb += abs(
        0.36471487573964495 - calc_canvas.gtfo(_0x5f6c26, _0x526465, _0x315313, 18, 8)
    )
    _0x5c13fb += abs(
        0.312678449704142 - calc_canvas.gtfo(_0x4320e6, _0x13e7aa, _0x429aaf, 0, 17)
    )
    _0x5c13fb += abs(
        0.9502808165680473 - calc_canvas.gtfo(_0x1a4487, _0x13e7aa, _0x3c8060, 22, 10)
    )
    _0x5c13fb += abs(
        0.5869052899408282 - calc_canvas.gtfo(_0x2f58be, _0x5e280a, _0x47edd7, 14, 10)
    )
    _0x5c13fb += abs(
        0.9323389467455623 - calc_canvas.gtfo(_0x429aaf, _0x47edd7, _0x2f58be, 12, 7)
    )
    _0x5c13fb += abs(
        0.4587118106508875 - calc_canvas.gtfo(_0x2ee445, _0x5a6698, _0x47edd7, 4, 21)
    )
    _0x5c13fb += abs(
        0.14484472189349107 - calc_canvas.gtfo(_0x4320e6, _0x13e7aa, _0x52d3ed, 7, 15)
    )
    _0x5c13fb += abs(
        0.7255550059171598 - calc_canvas.gtfo(_0x3cef24, _0x429aaf, _0x1a4487, 9, 23)
    )
    _0x5c13fb += abs(
        0.5031261301775147 - calc_canvas.gtfo(_0x3c8060, _0x47edd7, _0x52d3ed, 7, 1)
    )
    _0x5c13fb += abs(
        0.1417352189349112 - calc_canvas.gtfo(_0x2ee445, _0x52d3ed, _0x5f6c26, 16, 14)
    )
    _0x5c13fb += abs(
        0.5579334437869822 - calc_canvas.gtfo(_0x52d3ed, _0x47edd7, _0x1a4487, 19, 11)
    )
    _0x5c13fb += abs(
        0.48502262721893485 -
        calc_canvas.gtfo(_0x9d682e, _0x315313, _0x5e280a, 23, 18)
    )
    _0x5c13fb += abs(
        0.5920916568047336 - calc_canvas.gtfo(_0x5e280a, _0x5f6c26, _0x27d483, 19, 6)
    )
    _0x5c13fb += abs(
        0.7222713017751479 - calc_canvas.gtfo(_0xf9ef4b, _0x47edd7, _0x315313, 8, 16)
    )
    _0x5c13fb += abs(
        0.12367382248520711 - calc_canvas.gtfo(_0x9d682e, _0x4320e6, _0x2f58be, 9, 5)
    )
    _0x5c13fb += abs(
        0.4558028402366864 - calc_canvas.gtfo(_0x277f3c, _0x9d682e, _0x47edd7, 10, 2)
    )
    _0x5c13fb += abs(
        0.8537692426035504 - calc_canvas.gtfo(_0x429aaf, _0x13e7aa, _0x5a6698, 4, 11)
    )
    _0x5c13fb += abs(
        0.9618170650887574 - calc_canvas.gtfo(_0x2f58be, _0x1a4487, _0x429aaf, 15, 2)
    )
    _0x5c13fb += abs(
        0.22088933727810647 - calc_canvas.gtfo(_0x526465, _0x5e280a, _0xf9ef4b, 10, 5)
    )
    _0x5c13fb += abs(
        0.4302783550295858 - calc_canvas.gtfo(_0xf9ef4b, _0x277f3c, _0x3cef24, 14, 2)
    )
    _0x5c13fb += abs(
        0.6262803313609467 - calc_canvas.gtfo(_0x4c135d, _0x52d3ed, _0x47edd7, 17, 22)
    )
    if (_0x5c13fb > 0.00001) {
        return null
    }
    s = ''
    s += Math.round(
        calc_canvas.wtf(index_list[4], index_list[2], index_list[22]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[17], index_list[9], index_list[14]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[4], index_list[13], index_list[7]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[4], index_list[20], index_list[23]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[5], index_list[7], index_list[12]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[20], index_list[19], index_list[4]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[17], index_list[6], index_list[19]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[6], index_list[21], index_list[18]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[4], index_list[3], index_list[8]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[11], index_list[7], index_list[14]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[9], index_list[2], index_list[13]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[22], index_list[10], index_list[3]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[15], index_list[22], index_list[13]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[16], index_list[12], index_list[9]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[14], index_list[8], index_list[17]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[1], index_list[18], index_list[6]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[10], index_list[11], index_list[3]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[8], index_list[12], index_list[5]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[1], index_list[3], index_list[12]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.wtf(index_list[9], index_list[13], index_list[7]) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[22],
            index_list[13],
            index_list[5],
            index_list[4],
            index_list[7]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[10],
            index_list[14],
            index_list[17],
            index_list[23],
            index_list[11]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[23],
            index_list[20],
            index_list[6],
            index_list[1],
            index_list[3]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[15],
            index_list[12],
            index_list[2],
            index_list[13],
            index_list[9]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[16],
            index_list[20],
            index_list[6],
            index_list[5],
            index_list[18]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[3],
            index_list[6],
            index_list[7],
            index_list[8],
            index_list[23]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[21],
            index_list[9],
            index_list[10],
            index_list[3],
            index_list[22]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[14],
            index_list[6],
            index_list[15],
            index_list[12],
            index_list[19]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[13],
            index_list[19],
            index_list[22],
            index_list[23],
            index_list[1]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[21],
            index_list[2],
            index_list[9],
            index_list[0],
            index_list[19]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[5],
            index_list[19],
            index_list[21],
            index_list[14],
            index_list[6]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[16],
            index_list[15],
            index_list[20],
            index_list[13],
            index_list[3]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[20],
            index_list[15],
            index_list[10],
            index_list[21],
            index_list[6]
        ) * 100000
    ).toString()
    s += Math.round(
        calc_canvas.gtfo(
            index_list[7],
            index_list[1],

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 6
支持
分享
最新回复 (1)
雪    币: 572
活跃值: (65)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
视频版参见:https://www.bilibili.com/video/BV1Pb421J7nG
2024-7-29 12:59
0
游客
登录 | 注册 方可回帖
返回
//