290 lines
181 KiB
Text
290 lines
181 KiB
Text
|
//
|
||
|
// This program is free software: you can redistribute it and/or modify
|
||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||
|
// the Free Software Foundation, either version 3 of the License, or
|
||
|
// (at your option) any later version.
|
||
|
//
|
||
|
// This program is distributed in the hope that it will be useful,
|
||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
// GNU Lesser General Public License for more details.
|
||
|
//
|
||
|
// You should have received a copy of the GNU Lesser General Public License
|
||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
//!DESC RAVU-3x (luma, r4)
|
||
|
//!HOOK LUMA
|
||
|
//!BIND HOOKED
|
||
|
//!BIND ravu_3x_lut4
|
||
|
//!WIDTH 3 HOOKED.w *
|
||
|
//!HEIGHT 3 HOOKED.h *
|
||
|
//!WHEN HOOKED.w OUTPUT.w / 0.471404 < HOOKED.h OUTPUT.h / 0.471404 < *
|
||
|
//!COMPUTE 96 24 32 8
|
||
|
shared float inp[532];
|
||
|
void hook() {
|
||
|
ivec2 group_base = ivec2(gl_WorkGroupID) * ivec2(gl_WorkGroupSize);
|
||
|
int local_pos = int(gl_LocalInvocationID.x) * 14 + int(gl_LocalInvocationID.y);
|
||
|
for (int id = int(gl_LocalInvocationIndex); id < 532; id += int(gl_WorkGroupSize.x * gl_WorkGroupSize.y)) {
|
||
|
int x = id / 14, y = id % 14;
|
||
|
inp[id] = HOOKED_tex(HOOKED_pt * vec2(float(group_base.x+x)+(-2.5), float(group_base.y+y)+(-2.5))).x;
|
||
|
}
|
||
|
groupMemoryBarrier();
|
||
|
barrier();
|
||
|
float luma0 = inp[local_pos + 0];
|
||
|
float luma1 = inp[local_pos + 1];
|
||
|
float luma2 = inp[local_pos + 2];
|
||
|
float luma3 = inp[local_pos + 3];
|
||
|
float luma4 = inp[local_pos + 4];
|
||
|
float luma5 = inp[local_pos + 5];
|
||
|
float luma6 = inp[local_pos + 6];
|
||
|
float luma7 = inp[local_pos + 14];
|
||
|
float luma8 = inp[local_pos + 15];
|
||
|
float luma9 = inp[local_pos + 16];
|
||
|
float luma10 = inp[local_pos + 17];
|
||
|
float luma11 = inp[local_pos + 18];
|
||
|
float luma12 = inp[local_pos + 19];
|
||
|
float luma13 = inp[local_pos + 20];
|
||
|
float luma14 = inp[local_pos + 28];
|
||
|
float luma15 = inp[local_pos + 29];
|
||
|
float luma16 = inp[local_pos + 30];
|
||
|
float luma17 = inp[local_pos + 31];
|
||
|
float luma18 = inp[local_pos + 32];
|
||
|
float luma19 = inp[local_pos + 33];
|
||
|
float luma20 = inp[local_pos + 34];
|
||
|
float luma21 = inp[local_pos + 42];
|
||
|
float luma22 = inp[local_pos + 43];
|
||
|
float luma23 = inp[local_pos + 44];
|
||
|
float luma24 = inp[local_pos + 45];
|
||
|
float luma25 = inp[local_pos + 46];
|
||
|
float luma26 = inp[local_pos + 47];
|
||
|
float luma27 = inp[local_pos + 48];
|
||
|
float luma28 = inp[local_pos + 56];
|
||
|
float luma29 = inp[local_pos + 57];
|
||
|
float luma30 = inp[local_pos + 58];
|
||
|
float luma31 = inp[local_pos + 59];
|
||
|
float luma32 = inp[local_pos + 60];
|
||
|
float luma33 = inp[local_pos + 61];
|
||
|
float luma34 = inp[local_pos + 62];
|
||
|
float luma35 = inp[local_pos + 70];
|
||
|
float luma36 = inp[local_pos + 71];
|
||
|
float luma37 = inp[local_pos + 72];
|
||
|
float luma38 = inp[local_pos + 73];
|
||
|
float luma39 = inp[local_pos + 74];
|
||
|
float luma40 = inp[local_pos + 75];
|
||
|
float luma41 = inp[local_pos + 76];
|
||
|
float luma42 = inp[local_pos + 84];
|
||
|
float luma43 = inp[local_pos + 85];
|
||
|
float luma44 = inp[local_pos + 86];
|
||
|
float luma45 = inp[local_pos + 87];
|
||
|
float luma46 = inp[local_pos + 88];
|
||
|
float luma47 = inp[local_pos + 89];
|
||
|
float luma48 = inp[local_pos + 90];
|
||
|
vec3 abd = vec3(0.0);
|
||
|
float gx, gy;
|
||
|
gx = (luma15-luma1)/2.0;
|
||
|
gy = (luma9-luma7)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02324683987829437;
|
||
|
gx = (luma16-luma2)/2.0;
|
||
|
gy = (luma10-luma8)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.033823952439922346;
|
||
|
gx = (luma17-luma3)/2.0;
|
||
|
gy = (luma11-luma9)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.038327559383903906;
|
||
|
gx = (luma18-luma4)/2.0;
|
||
|
gy = (luma12-luma10)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.033823952439922346;
|
||
|
gx = (luma19-luma5)/2.0;
|
||
|
gy = (luma13-luma11)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02324683987829437;
|
||
|
gx = (luma22-luma8)/2.0;
|
||
|
gy = (luma16-luma14)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.033823952439922346;
|
||
|
gx = (luma23-luma9)/2.0;
|
||
|
gy = (luma17-luma15)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04921356040854137;
|
||
|
gx = (luma24-luma10)/2.0;
|
||
|
gy = (luma18-luma16)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.055766269846849466;
|
||
|
gx = (luma25-luma11)/2.0;
|
||
|
gy = (luma19-luma17)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04921356040854137;
|
||
|
gx = (luma26-luma12)/2.0;
|
||
|
gy = (luma20-luma18)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.033823952439922346;
|
||
|
gx = (luma29-luma15)/2.0;
|
||
|
gy = (luma23-luma21)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.038327559383903906;
|
||
|
gx = (luma30-luma16)/2.0;
|
||
|
gy = (luma24-luma22)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.055766269846849466;
|
||
|
gx = (luma31-luma17)/2.0;
|
||
|
gy = (luma25-luma23)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.06319146241026467;
|
||
|
gx = (luma32-luma18)/2.0;
|
||
|
gy = (luma26-luma24)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.055766269846849466;
|
||
|
gx = (luma33-luma19)/2.0;
|
||
|
gy = (luma27-luma25)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.038327559383903906;
|
||
|
gx = (luma36-luma22)/2.0;
|
||
|
gy = (luma30-luma28)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.033823952439922346;
|
||
|
gx = (luma37-luma23)/2.0;
|
||
|
gy = (luma31-luma29)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04921356040854137;
|
||
|
gx = (luma38-luma24)/2.0;
|
||
|
gy = (luma32-luma30)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.055766269846849466;
|
||
|
gx = (luma39-luma25)/2.0;
|
||
|
gy = (luma33-luma31)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.04921356040854137;
|
||
|
gx = (luma40-luma26)/2.0;
|
||
|
gy = (luma34-luma32)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.033823952439922346;
|
||
|
gx = (luma43-luma29)/2.0;
|
||
|
gy = (luma37-luma35)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02324683987829437;
|
||
|
gx = (luma44-luma30)/2.0;
|
||
|
gy = (luma38-luma36)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.033823952439922346;
|
||
|
gx = (luma45-luma31)/2.0;
|
||
|
gy = (luma39-luma37)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.038327559383903906;
|
||
|
gx = (luma46-luma32)/2.0;
|
||
|
gy = (luma40-luma38)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.033823952439922346;
|
||
|
gx = (luma47-luma33)/2.0;
|
||
|
gy = (luma41-luma39)/2.0;
|
||
|
abd += vec3(gx * gx, gx * gy, gy * gy) * 0.02324683987829437;
|
||
|
float a = abd.x, b = abd.y, d = abd.z;
|
||
|
float T = a + d, D = a * d - b * b;
|
||
|
float delta = sqrt(max(T * T / 4.0 - D, 0.0));
|
||
|
float L1 = T / 2.0 + delta, L2 = T / 2.0 - delta;
|
||
|
float sqrtL1 = sqrt(L1), sqrtL2 = sqrt(L2);
|
||
|
float theta = mix(mod(atan(L1 - a, b) + 3.141592653589793, 3.141592653589793), 0.0, abs(b) < 1.192092896e-7);
|
||
|
float lambda = sqrtL1;
|
||
|
float mu = mix((sqrtL1 - sqrtL2) / (sqrtL1 + sqrtL2), 0.0, sqrtL1 + sqrtL2 < 1.192092896e-7);
|
||
|
float angle = floor(theta * 24.0 / 3.141592653589793);
|
||
|
float strength = mix(mix(0.0, 1.0, lambda >= 0.005), 2.0, lambda >= 0.02);
|
||
|
float coherence = mix(mix(0.0, 1.0, mu >= 0.25), 2.0, mu >= 0.5);
|
||
|
float coord_y = ((angle * 3.0 + strength) * 3.0 + coherence + 0.5) / 216.0;
|
||
|
vec4 res0 = vec4(0.0), res1 = vec4(0.0);
|
||
|
vec4 w0, w1;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.01, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.03, coord_y));
|
||
|
res0 += luma0 * w0 + luma48 * w1.wzyx;
|
||
|
res1 += luma0 * w1 + luma48 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.05, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.07, coord_y));
|
||
|
res0 += luma1 * w0 + luma47 * w1.wzyx;
|
||
|
res1 += luma1 * w1 + luma47 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.09, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.11, coord_y));
|
||
|
res0 += luma2 * w0 + luma46 * w1.wzyx;
|
||
|
res1 += luma2 * w1 + luma46 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.13, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.15, coord_y));
|
||
|
res0 += luma3 * w0 + luma45 * w1.wzyx;
|
||
|
res1 += luma3 * w1 + luma45 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.17, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.19, coord_y));
|
||
|
res0 += luma4 * w0 + luma44 * w1.wzyx;
|
||
|
res1 += luma4 * w1 + luma44 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.21, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.23, coord_y));
|
||
|
res0 += luma5 * w0 + luma43 * w1.wzyx;
|
||
|
res1 += luma5 * w1 + luma43 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.25, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.27, coord_y));
|
||
|
res0 += luma6 * w0 + luma42 * w1.wzyx;
|
||
|
res1 += luma6 * w1 + luma42 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.29, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.31, coord_y));
|
||
|
res0 += luma7 * w0 + luma41 * w1.wzyx;
|
||
|
res1 += luma7 * w1 + luma41 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.33, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.35, coord_y));
|
||
|
res0 += luma8 * w0 + luma40 * w1.wzyx;
|
||
|
res1 += luma8 * w1 + luma40 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.37, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.39, coord_y));
|
||
|
res0 += luma9 * w0 + luma39 * w1.wzyx;
|
||
|
res1 += luma9 * w1 + luma39 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.41, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.43, coord_y));
|
||
|
res0 += luma10 * w0 + luma38 * w1.wzyx;
|
||
|
res1 += luma10 * w1 + luma38 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.45, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.47, coord_y));
|
||
|
res0 += luma11 * w0 + luma37 * w1.wzyx;
|
||
|
res1 += luma11 * w1 + luma37 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.49, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.51, coord_y));
|
||
|
res0 += luma12 * w0 + luma36 * w1.wzyx;
|
||
|
res1 += luma12 * w1 + luma36 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.53, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.55, coord_y));
|
||
|
res0 += luma13 * w0 + luma35 * w1.wzyx;
|
||
|
res1 += luma13 * w1 + luma35 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.57, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.59, coord_y));
|
||
|
res0 += luma14 * w0 + luma34 * w1.wzyx;
|
||
|
res1 += luma14 * w1 + luma34 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.61, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.63, coord_y));
|
||
|
res0 += luma15 * w0 + luma33 * w1.wzyx;
|
||
|
res1 += luma15 * w1 + luma33 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.65, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.67, coord_y));
|
||
|
res0 += luma16 * w0 + luma32 * w1.wzyx;
|
||
|
res1 += luma16 * w1 + luma32 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.69, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.71, coord_y));
|
||
|
res0 += luma17 * w0 + luma31 * w1.wzyx;
|
||
|
res1 += luma17 * w1 + luma31 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.73, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.75, coord_y));
|
||
|
res0 += luma18 * w0 + luma30 * w1.wzyx;
|
||
|
res1 += luma18 * w1 + luma30 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.77, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.79, coord_y));
|
||
|
res0 += luma19 * w0 + luma29 * w1.wzyx;
|
||
|
res1 += luma19 * w1 + luma29 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.81, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.83, coord_y));
|
||
|
res0 += luma20 * w0 + luma28 * w1.wzyx;
|
||
|
res1 += luma20 * w1 + luma28 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.85, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.87, coord_y));
|
||
|
res0 += luma21 * w0 + luma27 * w1.wzyx;
|
||
|
res1 += luma21 * w1 + luma27 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.89, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.91, coord_y));
|
||
|
res0 += luma22 * w0 + luma26 * w1.wzyx;
|
||
|
res1 += luma22 * w1 + luma26 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.93, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.95, coord_y));
|
||
|
res0 += luma23 * w0 + luma25 * w1.wzyx;
|
||
|
res1 += luma23 * w1 + luma25 * w0.wzyx;
|
||
|
w0 = texture(ravu_3x_lut4, vec2(0.97, coord_y));
|
||
|
w1 = texture(ravu_3x_lut4, vec2(0.99, coord_y));
|
||
|
res0 += luma24 * w0;
|
||
|
res1 += luma24 * w1;
|
||
|
res0 = clamp(res0, 0.0, 1.0);
|
||
|
res1 = clamp(res1, 0.0, 1.0);
|
||
|
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 3 + ivec2(0, 0), vec4(res0[0], 0.0, 0.0, 0.0));
|
||
|
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 3 + ivec2(0, 1), vec4(res0[1], 0.0, 0.0, 0.0));
|
||
|
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 3 + ivec2(0, 2), vec4(res0[2], 0.0, 0.0, 0.0));
|
||
|
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 3 + ivec2(1, 0), vec4(res0[3], 0.0, 0.0, 0.0));
|
||
|
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 3 + ivec2(1, 1), vec4(luma24, 0.0, 0.0, 0.0));
|
||
|
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 3 + ivec2(1, 2), vec4(res1[0], 0.0, 0.0, 0.0));
|
||
|
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 3 + ivec2(2, 0), vec4(res1[1], 0.0, 0.0, 0.0));
|
||
|
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 3 + ivec2(2, 1), vec4(res1[2], 0.0, 0.0, 0.0));
|
||
|
imageStore(out_image, ivec2(gl_GlobalInvocationID) * 3 + ivec2(2, 2), vec4(res1[3], 0.0, 0.0, 0.0));
|
||
|
}
|
||
|
//!TEXTURE ravu_3x_lut4
|
||
|
//!SIZE 50 216
|
||
|
//!FORMAT rgba16hf
|
||
|
//!FILTER NEAREST
|
||
|
570beb025f0b7c068706fa0a7c01b70bc69c9f1cf29aa6a017a08a9c031d3b9b6e23bb901721f820201e75227598a3208b073e22ef06a29fa39f4b96c62152961421c9907623141efc209f207a987922039b9e1cd49c1fa0b1a0399b111d8b9c510bfd02770b3406ae06b90b7501fb0a429ce5a00c9c651d901d97978e9f4798a7a3d39cb6a3339e039e4fa3169caba2122009a331943d24bb215a1e2ba17815a8996f21b9998c109a1045a0c0183ea09993fda22520bd214024271539a14c1ebda3f29cb5a3059e399eaea2289c57a3369cf9a0689c831d581d7198979fb6979b23a8209d2245912b96c51f2c1a6e1fa71f4524631b80a38fa2089d5820069cf32f302908281329ce1af626318dac21c2318533bb3190266826482123241d21302859290530151c2c29dd2190801327c41c85247c205ea23ca3b19b5420cc9cff220f210a246d95278e531fe319b21fe41d2c9c3919f9238722fa1c029d68172c1be81e869c0123751a1919f11d6d9d07322a286425bb33e625fd31052821253e369538413696389638413695383e36c20b7e073609fe0742044e05f9876003f89a81004c958e9a5796a3977518658d3e1cf999d294fe18b4969e15229f1e9a651ca820501c5712bd0ac81cdf21971cce96759a721c31990e1a479b749f0b16bc95cd85f59bae95d79b9a8b7818b59801095207020c3202d8087d02ae870406bb9ea09f689db70a83138a919895788ef6a01395cd9f489c3696919fb191d29abd19c5a4e6a1b4201b94831f4f9e759be02325270224ce204521e320012447213ca210a51218348c2f20779a7c9ed31e96a0539985a11a99f89afe9be290c49e699e4da0e49f2e14158e2b8cb995f793081b4a189316b09ef99e90a09da02ca04a1e8d209f19aba390a14aa3879bf4a1eb2e5e271724e32558a1351c18a543a3f331d133da312828df270723a325b6229b257128502f72a09a2685a330a57b1c42207b239022b7a03fa31fa2489d0ca4921ef91e6920899e869deaa046a10da15124ba20962207245322f721621c0320432894269e254928f524db2616255224aa32af2aa828403406287a32022af827893699389536ae38ae389536993889360c0c13096309fc05f601520785009003ab956a8f57900e924782e190630f810bb895629c0d9dcf91f09aaf89369a1b9be41d961f5d1e211c281c461f6220851f959eeb9d00994e9c07946b9ce99ba9926493ab92729858067894bf0ee71003931009f3085c0c8a005807f6027a005808f69ca89bc19a099511881598e6936492dda1599f64a17e9cef96c7a0ae9b8d9c83156aa50aa59017b8a1ce11eca367a45129312b4d29bf25ea25e427dc28122833a5bda5e61162a1081587a43aa4478f67a29ba0a6a269990e9c4a9e0d9d0da1569cd79c1d9ed0884d96d5939494aa98449ca999289af29f8e9d70a23da13aa12c213a1c821368a1aba156a4d4a2b3a4a72d8b24cf201d2135a4cd93ffa660a6d031cb33a7311729df281629702b1a297c2598276e2e42a38b22c0a68da73099ba23c82498269ea0aca02ba540a429a5991a9f1b261a079d179fc6a1f7a13aa3ce245523d9239a213320a6219d1f9220582c552a102ad72a9527742a312826288c326a2cb52b4b34472a14320b2bfb29ed35343808368938893808363438ed358f98cd945f179993d6193816e018661d45941897b9a0e614e89fce1dc21c499b34981c9c3f19a1146d1ed61d8b1ba121fd9ca894229e249b6b9ca8184a1f59166b19919b308e341e48189321e91bd11ea3a03c96ed95f19fe912aa9a1d1de01d9f18bd92a797231adb93941ddc1808165c9664895e1ca097c11cc1a19fa0489c251cde18729f791853a0b09c889e5aa334987d904d202a17941fb89ebda086960fa2e3a15ea2329afc9b07a1079d5ca1251d669ace994b1f20198c9599a0049e47a1c98dfe1187a0e01783a3819edf9cff0dbc9c509ec81cc3977b99cd9f1ba1bd94861680209e9a4d1e2215551bfc20daa0a10e01a1949921a2891dab1cd0a0892e2d1dfaa2ae20e61712a11a96a321563396340b33761ef21976a872a979a80d9a8224732f4a045222751ce69e48a2529029219908c0a1599cbda2038b50945e24ed218121581e40998f1c0099e99c03207e1e10226f119a1f719cc59bc41b00a0e5209694ada580a04ea54a98c9a116346725a5a60d35e7aaa033051c56a97038dd398438ff39ff398438dd3970385914400e02134211ca0ec612c507e9102d99d70ce594a898d49535950a15b18f7117e496c2107119bb162b1b9309bd1897952d1608984398f698a08f20197d910a171c92bc1ba717d11aa418738c9a1bae96150c619a0e9773997691a8159296a815c2110e166f104c127d1181014e132f9d9b9f2c9ef516c7170e15fd8dea17109d9211409d289de19c909f6f94fe9da71d4f8d3b1fb81efa1dc219609ea21052a0a0993ea0539d179e069d3b1a989dc588899e0c187a1d861fa615659d211c10a2839ecea2ed9cc79d449c2f12f59d47a4d0a453a403181517e11d1f1b2d1dbe1a2213f51d74191f193b99b79ef09c85a7e49dc1a004a4199e3b9f151c889c382ed69d18a73624b899b819a1936a20d53241345832ed1c6711fca6caa69aa6161680261d306c9c3425929d96a2559df2240b26ba12c99d51a4d6a4fba128a65328302809293519461ac4a5b6a61ca6db283a272f27dd1e6217089c2ea0bd9acd887827b2263da8ee141ba99fa035a16d342a29e5a04b35acaa9f33a10b32aa3d38a2396038f139f1396038a2393d382f002480680291018802d50ad009bb0a798e3d8c2d8e7a8403884800a90862002b956b979a9524065609021884152a1
|