redfordxx
9th June 2006, 21:25
Hi,
I am sharing something I made for myself, few functions can by usable for you too (hope there are not bugs anymore).
So here is some small description
function bt_cutter(clip clp, int lc, int la, int lb, int tc, int ta, int tb, int rc, int ra, int rb, int bc, int ba, int bb)
This function cuts borders of the clip, and adds borders. There are two borders to be added. Mirrored clip or black borders.
parameters
lc, la, lb - pixels to cut left, mirror to add left, border to add left after mirror
top, right, bottom similarily
BTW: rc,bc - behave same as in crop function, meaning the positive and negative values
try:
source.bt_cutter(10,20,10, 0,0,0, 0,0,0, 0,0,0)
function bt_shift(clip clp, int pixels_x, int pixels_y, int mod_h, int "mod_v", bool "mirror", int "yy", int "uu", int "vv", int "left", int "top", int "right", int "bottom", int "addright", int "addbottom")
use for shifting clip. The luma and chroma is shifted separately, i.e. chroma is 2xfaster than luma.
pixels_x, pixels_y - mow much to shift (pos, neg)
mod_h, mod_v - modulo dimension of the output
mirror - true flips the borders, false makes blackborders
yy, uu, vv - like y,u,v in masktools
left,top,right,bottom - croping before shifting, but the clip is not really cropped - the borders are restored again depending on mirror param
addright, addbottom - pos/neg numbers will add more borders right and down (note that the dimensions of the clip changed already according to shifting)
usage:
source.bt_shift(0, 0, 16, 16, true)#making clip modulo 16
source.bt_shift(8, 8, 16, 16, true, 3, 2, 2, 2)#shifting luma (8,8) pixels and repairing 2 pix thin black line on left
source.bt_shift(100, 0, 16, 16, true, 3, 2, 3)#this is interesting (only y,v are shifted)
2B continued.
redfordxx
9th June 2006, 21:26
function bt_modup(int m,int n)
{
floor(float(m)/float(n)+0.999)*n
}
function bt_modown(int m,int n)
{
floor(float(m)/float(n))*n
}
function bt_constr(int len, int pos)
{
s = \
(len<1) ? \
"" \
: (len==1) ? \
"1" \
: (len==2) ? \
Select(pos+1,"0 1 1","1 0 1","1 1 0") \
: \
Select(pos+1,"","1 ","1 1 ")+bt_constr(len-2,pos)+Select(pos+1," 1 1"," 1","")
return(s)
}
function bt_cutter(clip clp, int lc, int la, int lb, int tc, int ta, int tb, int rc, int ra, int rb, int bc, int ba, int bb)
{
cw=clp.width
ch=clp.height
cw0=cw-lc+rc
ch0=ch-tc+bc
rb=(ra>cw0) ? ra-cw0+rb : rb
ra=(ra>cw0) ? cw0 : ra
lb=(la>cw0) ? la-cw0+lb : lb
la=(la>cw0) ? cw0 : la
tb=(ta>ch0) ? ta-ch0+tb : tb
ta=(ta>ch0) ? ch0 : ta
bb=(ba>ch0) ? ba-ch0+bb : bb
ba=(ba>ch0) ? ch0 : ba
cropped = ((lc==0)&&(tc==0)&&(rc==0)&&(bc==0)) ? clp : clp.crop(lc,tc,rc,bc)
horizon = \
(la==0) && (ra==0) ? \
cropped \
: (la!=0) && (ra!=0) ? \
StackHorizontal(cropped.Crop(0,0,la,0).FlipHorizontal(),cropped,cropped.Crop(cropped.Width()-ra,0,ra,0).FlipHorizontal()) \
: (la!=0) ? \
StackHorizontal(cropped.Crop(0,0,la,0).FlipHorizontal(),cropped) \
: \
StackHorizontal(cropped,cropped.Crop(cropped.Width()-ra,0,ra,0).FlipHorizontal())
vertica = \
(ta==0) && (ba==0) ? \
horizon \
: (ta!=0) && (ba!=0) ? \
StackVertical(horizon.Crop(0,0,0,ta).FlipVertical(),horizon,horizon.Crop(0,horizon.Height()-ba,0,ba).FlipVertical()) \
: (ta!=0) ? \
StackVertical(horizon.Crop(0,0,0,ta).FlipVertical(),horizon) \
: \
StackVertical(horizon,horizon.Crop(0,horizon.Height()-ba,0,ba).FlipVertical())
((lb==0)&&(tb==0)&&(rb==0)&&(bb==0)) ? vertica : vertica.AddBorders(lb,tb,rb,bb) \
}
function bt_shift(clip clp, int pixels_x, int pixels_y, int mod_h, int "mod_v", bool "mirror", int "yy", int "uu", int "vv", int "left", int "top", int "right", int "bottom", int "addright", int "addbottom")
{
mod_v=default(mod_v,mod_h)
mirror=default(mirror,false)
yy=(default(yy,3)>2) ? 3 : default(yy,3)
uu=(default(uu,3)>2) ? 3 : default(uu,3)
vv=(default(vv,uu)>2) ? 3 : default(vv,uu)
uv=(uu > vv) ? uu : vv
ar= (pixels_x>0) ? \
(uv>2) ? \
pixels_x*2 \
: \
pixels_x \
: \
((uu>2)&&(vv>2)&&(yy>2)) ? \
pixels_x \
: \
0
ab= (pixels_y>0) ? \
(uv>2) ? \
pixels_y*2 \
: \
pixels_y \
: \
((uu>2)&&(vv>2)&&(yy>2)) ? \
pixels_y \
: \
0
addright= bt_modup(default(addright ,0)+ar,2)
addbottom=bt_modup(default(addbottom,0)+ab,2)
cw=clp.width
ch=clp.height
left= default(left,0)
top= default(top,0)
right= default(right,0)
right=(right>0) ? right-cw : right
bottom=default(bottom,0)
bottom=(bottom>0) ? bottom-ch : bottom
cw2=bt_modup(cw+addright,mod_h)
ch2=bt_modup(ch+addbottom,mod_v)
lc=(-pixels_x > left) ? -pixels_x : left
tc=(-pixels_y > top) ? -pixels_y : top
rc=(right> (cw2-pixels_x-cw)) ? (cw2-pixels_x-cw) : right
bc=(bottom>(ch2-pixels_y-ch)) ? (ch2-pixels_y-ch) : bottom
la= lc + pixels_x
ta= tc + pixels_y
ra=cw2-(cw-lc+rc)-la
ba=ch2-(ch-tc+bc)-ta
lc=((((pixels_x % 2)==0)&&((pixels_y % 2)==0)) ? 1 : 2)*lc
rc=((((pixels_x % 2)==0)&&((pixels_y % 2)==0)) ? 1 : 2)*rc
tc=((((pixels_x % 2)==0)&&((pixels_y % 2)==0)) ? 1 : 2)*tc
bc=((((pixels_x % 2)==0)&&((pixels_y % 2)==0)) ? 1 : 2)*bc
la=((((pixels_x % 2)==0)&&((pixels_y % 2)==0)) ? 1 : 2)*la
ra=((((pixels_x % 2)==0)&&((pixels_y % 2)==0)) ? 1 : 2)*ra
ta=((((pixels_x % 2)==0)&&((pixels_y % 2)==0)) ? 1 : 2)*ta
ba=((((pixels_x % 2)==0)&&((pixels_y % 2)==0)) ? 1 : 2)*ba
clc=(-pixels_x*2 > left) ? -pixels_x*2 : left
ctc=(-pixels_y*2 > top) ? -pixels_y*2 : top
crc=(right> (cw2-pixels_x*2-cw)) ? (cw2-pixels_x*2-cw) : right
cbc=(bottom>(ch2-pixels_y*2-ch)) ? (ch2-pixels_y*2-ch) : bottom
cla= clc + pixels_x*2
cta= ctc + pixels_y*2
cra=cw2-(cw-clc+crc)-cla
cba=ch2-(ch-ctc+cbc)-cta
(right> (bt_modup(cw+addright,mod_h)-cw)) ? (bt_modup(cw+addright,mod_h)-cw) : right
clipY= (((pixels_x % 2)==0)&&((pixels_y % 2)==0)) ? clp : YtoUV(clp,clp)
clipY= \
(yy==3) ? \
((abs(lc)+abs(la)+abs(tc)+abs(ta)+abs(rc)+abs(ra)+abs(bc)+abs(ba))!=0) ?\
(mirror==true) ? \
clipY.bt_cutter(lc,la,0, tc,ta,0, rc,ra,0, bc,ba,0) \
: \
clipY.bt_cutter(lc,0,la, tc,0,ta, rc,0,ra, bc,0,ba) \
: \
clipY \
: (yy==2) ? \
((abs(left)+abs(top)+abs((right> (cw2-cw)) ? (cw2-cw) : right)+abs(cw2-cw-((right> (cw2-cw)) ? (cw2-cw) : right))+abs((bottom> (ch2-ch)) ? (ch2-ch) : bottom)+abs(ch2-ch-((bottom> (ch2-ch)) ? (ch2-ch) : bottom)))!=0) ? \
(mirror==true) ? \
clipY.bt_cutter(left,left,0, top,top,0, (right> (cw2-cw)) ? (cw2-cw) : right,cw2-cw-((right> (cw2-cw)) ? (cw2-cw) : right),0, (bottom> (ch2-ch)) ? (ch2-ch) : bottom,ch2-ch-((bottom> (ch2-ch)) ? (ch2-ch) : bottom),0) \
: \
clipY.bt_cutter(left,0,left, top,0,top, (right> (cw2-cw)) ? (cw2-cw) : right,0,cw2-cw-((right> (cw2-cw)) ? (cw2-cw) : right), (bottom> (ch2-ch)) ? (ch2-ch) : bottom,0,ch2-ch-((bottom> (ch2-ch)) ? (ch2-ch) : bottom)) \
: \
clipY \
: \
clipY
clipY= (((pixels_x % 2)==0)&&((pixels_y % 2)==0)) ? clipY : clipY.UToY()
clipU= \
(((pixels_x==0)&&(pixels_y==0))||((yy==2) && (uu==2))) ? \
clipY \
: \
(uu==3) ? \
((abs(clc)+abs(cla)+abs(ctc)+abs(cta)+abs(crc)+abs(cra)+abs(cbc)+abs(cba))!=0) ?\
(mirror==true) ? \
clp.bt_cutter(clc,cla,0, ctc,cta,0, crc,cra,0, cbc,cba,0) \
: \
clp.bt_cutter(clc,0,cla, ctc,0,cta, crc,0,cra, cbc,0,cba) \
: \
clp \
: (uu==2) ? \
((abs(left)+abs(top)+abs((right> (cw2-cw)) ? (cw2-cw) : right)+abs(cw2-cw-((right> (cw2-cw)) ? (cw2-cw) : right))+abs((bottom> (ch2-ch)) ? (ch2-ch) : bottom)+abs(ch2-ch-((bottom> (ch2-ch)) ? (ch2-ch) : bottom)))!=0) ? \
(mirror==true) ? \
clp.bt_cutter(left,left,0, top,top,0, (right> (cw2-cw)) ? (cw2-cw) : right,cw2-cw-((right> (cw2-cw)) ? (cw2-cw) : right),0, (bottom> (ch2-ch)) ? (ch2-ch) : bottom,ch2-ch-((bottom> (ch2-ch)) ? (ch2-ch) : bottom),0) \
: \
clp.bt_cutter(left,0,left, top,0,top, (right> (cw2-cw)) ? (cw2-cw) : right,0,cw2-cw-((right> (cw2-cw)) ? (cw2-cw) : right), (bottom> (ch2-ch)) ? (ch2-ch) : bottom,0,ch2-ch-((bottom> (ch2-ch)) ? (ch2-ch) : bottom)) \
: \
clp \
: \
clp
clipV= \
(((pixels_x==0)&&(pixels_y==0))||((yy==2) && (vv==2))) ? \
clipY \
: (vv==uu) ? \
clipU \
: \
(vv==3) ? \
((abs(clc)+abs(cla)+abs(ctc)+abs(cta)+abs(crc)+abs(cra)+abs(cbc)+abs(cba))!=0) ?\
(mirror==true) ? \
clp.bt_cutter(clc,cla,0, ctc,cta,0, crc,cra,0, cbc,cba,0) \
: \
clp.bt_cutter(clc,0,cla, ctc,0,cta, crc,0,cra, cbc,0,cba) \
: \
clp \
: (vv==2) ? \
((abs(left)+abs(top)+abs((right> (cw2-cw)) ? (cw2-cw) : right)+abs(cw2-cw-((right> (cw2-cw)) ? (cw2-cw) : right))+abs((bottom> (ch2-ch)) ? (ch2-ch) : bottom)+abs(ch2-ch-((bottom> (ch2-ch)) ? (ch2-ch) : bottom)))!=0) ? \
(mirror==true) ? \
clp.bt_cutter(left,left,0, top,top,0, (right> (cw2-cw)) ? (cw2-cw) : right,cw2-cw-((right> (cw2-cw)) ? (cw2-cw) : right),0, (bottom> (ch2-ch)) ? (ch2-ch) : bottom,ch2-ch-((bottom> (ch2-ch)) ? (ch2-ch) : bottom),0) \
: \
clp.bt_cutter(left,0,left, top,0,top, (right> (cw2-cw)) ? (cw2-cw) : right,0,cw2-cw-((right> (cw2-cw)) ? (cw2-cw) : right), (bottom> (ch2-ch)) ? (ch2-ch) : bottom,0,ch2-ch-((bottom> (ch2-ch)) ? (ch2-ch) : bottom)) \
: \
clp \
: \
clipU
(((pixels_x==0)&&(pixels_y==0))||((yy==2) && (uu==2) && (vv==2)))? \
clipY \
: ((yy>1) && (uu>1) && (vv>1) && (uu!=vv))? \
YtoUV(clipU.UtoY,clipV.VtoY,clipY) \
: ((yy>1) && (uv>1))? \
MergeChroma(clipY,clipV) \
: (yy>1)? \
clipY \
: ((uu==vv)||(vv<2))? \
clipU \
: (uu<2) ? \
clipV \
: \
YtoUV(clipU.UtoY,clipV.VtoY)
((yy<1)||(vv<1)||(vv<1)) ? last.mt_lut(y=yy,u=uu,v=vv) : last
}
function bt_block22(clip clp, string mode, int yy, int uu, int vv)
{
cw=clp.width
ch=clp.height
(mode=="min") || (mode=="max") ? \
clp.bt_shift(0,0,4,4,false, yy, uu, vv).PointResize(cw*3/2,ch*3/2).bt_block33(mode, yy, uu, vv) \
: (mode=="excavg") || (mode=="dctavg") || (mode=="apxavg") || (mode=="avg")? \
clp.mt_convolution("0 1 1", "0 1 1", y=yy, u=uu, v=vv).bt_shift(0,0,8,8,false, yy, uu, vv).PointResize(cw/2,ch/2) \
: \
clp.Subtitle("Unknown mode for 2x2 "+mode)
Crop(0,0,cw/2,ch/2)
}
function bt_block33(clip clp, string mode, int yy, int uu, int vv)
{
cw=clp.width
ch=clp.height
(mode=="min") ? \
clp.mt_inpand(y=yy, u=uu, v=vv) \
: (mode=="max") ? \
clp.mt_expand(y=yy, u=uu, v=vv) \
: (mode=="excavg") || (mode=="dctavg") || (mode=="apxavg") || (mode=="avg")? \
clp.mt_convolution("1 1 1", "1 1 1", y=yy, u=uu, v=vv) \
: \
clp.Subtitle("Unknown mode for 3x3 "+mode)
bt_shift(2, 2, 12, 12, false, yy, uu, vv)
PointResize(last.width*2/3,last.height*2/3)
bt_shift(-2, -2, 8, 8, false, yy, uu, vv)
PointResize(last.width/2,last.height/2)
crop(0,0,cw/3,ch/3)
}
function bt_blockxx(clip clp, string mode, int pixels_x, int pixels_y, int yy, int uu, int vv)
{
cw=clp.width
ch=clp.height
strx=(int(pixels_x/2)%2==1) ? bt_constr(pixels_x,-1 ) : bt_constr(pixels_x,1)
stry=(int(pixels_y/2)%2==1) ? bt_constr(pixels_y,-1 ) : bt_constr(pixels_y,1)
shfx=bt_modown(int(pixels_x/2),2) + (((pixels_x % 4)==3) ? 1 : 0)
shfy=bt_modown(int(pixels_y/2),2) + (((pixels_y % 4)==3) ? 1 : 0)
(mode=="excavg") || (mode=="dctavg") || (mode=="apxavg") || (mode=="avg")? \
clp.mt_convolution(horizontal=strx, vertical=stry, y=yy, u=uu, v=vv).bt_shift(-shfx,-shfy,pixels_x*4,pixels_y*4,false,3,3,3).PointResize(cw/pixels_x,ch/pixels_y) \
: \
clp.Subtitle("Unknown mode for general "+mode)
crop(0,0,cw/pixels_x,ch/pixels_y)
}
function bt_blockhv(clip clp, string mode, int pixels_x, int pixels_y, int yy, int uu, int vv)
{
cw=clp.width
ch=clp.height
strx=(int(pixels_x/2)%2==1) ? bt_constr(pixels_x,-1 ) : bt_constr(pixels_x,1)
stry=(int(pixels_y/2)%2==1) ? bt_constr(pixels_y,-1 ) : bt_constr(pixels_y,1)
shfx=bt_modown(int(pixels_x/2),2) + (((pixels_x % 4)==3) ? 1 : 0)
shfy=bt_modown(int(pixels_y/2),2) + (((pixels_y % 4)==3) ? 1 : 0)
h1=(pixels_x>pixels_y) ? "1" : strx
h2=(pixels_x>pixels_y) ? strx : "1"
v1=(pixels_x>pixels_y) ? stry : "1"
v2=(pixels_x>pixels_y) ? "1" : stry
x1=(pixels_x>pixels_y) ? 0 : shfx
x2=(pixels_x>pixels_y) ? shfx : 0
y1=(pixels_x>pixels_y) ? shfy : 0
y2=(pixels_x>pixels_y) ? 0 : shfy
(mode=="excavg") || (mode=="dctavg") || (mode=="apxavg") || (mode=="avg")? \
clp.mt_convolution(horizontal=h1, vertical=v1, y=yy, u=uu, v=vv).bt_shift(-shfx,-shfy, pixels_x*4, pixels_y*4,false) : clp
(mode=="excavg") || (mode=="dctavg") || (mode=="apxavg") || (mode=="avg")? \
PointResize((pixels_x>pixels_y) ? last.width : last.width/pixels_x,(pixels_x>pixels_y) ? last.height/pixels_y : last.height) : clp
(mode=="excavg") || (mode=="dctavg") || (mode=="apxavg") || (mode=="avg")? \
last.mt_convolution(horizontal=h2, vertical=v2, y=yy, u=uu, v=vv).PointResize(!(pixels_x>pixels_y) ? last.width : last.width/pixels_x,!(pixels_x>pixels_y) ? last.height/pixels_y : last.height) \
: \
clp.Subtitle("Unknown mode for general "+mode)
crop(0,0,cw/pixels_x,ch/pixels_y)
}
function bt_block4422(clip clp, string mode, int yy, int uu, int vv)
{
cw=clp.width
ch=clp.height
(mode=="min") ? \
clp.mt_inpand(y=yy, u=uu, v=vv) \
: (mode=="max") ? \
clp.mt_expand(y=yy, u=uu, v=vv) \
: (mode=="excavg") || (mode=="dctavg") || (mode=="apxavg") || (mode=="avg")? \
clp.bt_block22(mode, yy, uu, vv) \
: \
clp.Subtitle("Unknown mode for 4x4 2x2 "+mode)
((mode=="min") || (mode=="max")) ? PointResize(cw*3/4,ch*3/4).bt_shift(2, 2, 6, 6, false, yy, uu, vv) : last
((mode=="min") || (mode=="max")) ? PointResize(last.width*2/3,last.height*2/3).bt_shift(-2, -2, 2, 2, false, yy, uu, vv).crop(0,0,cw/2,ch/2) : last
}
function bt_block88(clip clp, string mode, int yy, int uu, int vv)
{
cw=clp.width
ch=clp.height
(mode=="excavg") || (mode=="dctavg") || (mode=="apxavg") || (mode=="avg")? \
clp.DCTFilter(1,0,0,0,0,0,0,0).PointResize(cw/8,ch/8) \
: \
clp.Subtitle("Unknown mode for 8x8 "+mode)
}
function bt_block(clip clp, string mode, int pixels_x, int pixels_y, int "yy", int "uu", int "vv", int "upsize")
{
yy=(default(yy,3)>1) ? 3 : default(yy,3)
uu=(default(uu,3)>1) ? 3 : default(uu,3)
vv=(default(vv,uu)>1) ? 3 : default(vv,uu)
upsize=default(upsize,0)
cw=clp.width
ch=clp.height
clp=clp.bt_shift(0,0,pixels_x*4,pixels_y*4,true,yy,uu,vv)
cw2=clp.width
ch2=clp.height
((pixels_x == 1) && (pixels_y == 1)) ? \
clp \
: (mode=="range") ? \
mt_lutxy(clp.bt_block("max", pixels_x, pixels_y, yy, uu, vv, 0),clp.bt_block("min", pixels_x, pixels_y, yy, uu, vv, 0),expr="x y -",y=yy, u=uu, v=vv) \
: (((pixels_x % 8) == 0) && ((pixels_y % 8) == 0)) && ((mode=="dctavg")||(mode=="apxavg")) ? \
clp.bt_block88(mode,yy,uu,vv).bt_block("excavg", pixels_x/8, pixels_y/8, yy, uu, vv, -1) \
: (((pixels_x % 3) == 0) && ((pixels_y % 3) == 0)) && ((mode=="min") || (mode=="max")) ? \
clp.bt_block33(mode,yy,uu,vv).bt_block(mode, pixels_x/3, pixels_y/3, yy, uu, vv, -1) \
: (((pixels_x % 4) == 0) && ((pixels_y % 4) == 0)) && (mode=="apxavg") ? \
clp.bt_blockxx(mode,4,4,yy,uu,vv).bt_block(mode, pixels_x/4, pixels_y/4, yy, uu, vv, -1) \
: (((pixels_x % 4) == 0) && ((pixels_y % 4) == 0)) && ((mode=="min") || (mode=="max")) ? \
clp.bt_block4422(mode,yy,uu,vv).bt_block(mode, pixels_x/2, pixels_y/2, yy, uu, vv, -1) \
: (((pixels_x % 3) == 0) && ((pixels_y % 2) == 0)) && ((mode=="min") || (mode=="max")) ? \
clp.PointResize(cw2,ch2*3/2).bt_block33(mode,yy,uu,vv).bt_block(mode, pixels_x/3, pixels_y/2, yy, uu, vv, -1) \
: (((pixels_x % 2) == 0) && ((pixels_y % 3) == 0)) && ((mode=="min") || (mode=="max")) ? \
clp.PointResize(cw2*3/2,ch2).bt_block33(mode,yy,uu,vv).bt_block(mode, pixels_x/2, pixels_y/3, yy, uu, vv, -1) \
: (((pixels_x % 2) == 0) && ((pixels_y % 2) == 0)) && ((mode=="min") || (mode=="max")) ? \
clp.bt_block22(mode,yy,uu,vv).bt_block(mode, pixels_x/2, pixels_y/2, yy, uu, vv, -1) \
: ((mode=="excavg") || (mode=="dctavg") || (mode=="apxavg")) ? \
clp.bt_blockxx(mode,pixels_x,pixels_y,yy,uu,vv) \
: \
clp.Subtitle("Unhandled mode/block")
(upsize==1) ? PointResize(cw2,ch2).Crop(0,0,cw,ch) : (upsize>-1) ? Crop(0,0,bt_modup(cw/pixels_x,4),bt_modup(ch/pixels_y,4)) : last
}
function bt_lutf(clip clp1, clip clp2, string mode, int pixels_x, int pixels_y, string "yyexpr", string "uuexpr", string "vvexpr", int "yy", int "uu", int "vv")
{
yy=default(yy,3)
uu=default(uu,3)
vv=default(vv,uu)
yyexpr=default(yyexpr,"x")
uuexpr=default(uuexpr,yyexpr)
vvexpr=default(vvexpr,uuexpr)
cw=clp1.width
ch=clp1.height
clp1.bt_shift(0,0,pixels_x*4,pixels_y*4,true,yy,uu,vv)
bt_block(mode, pixels_x, pixels_y, yy, uu, vv, 0)
PointResize(cw,ch)
((yyexpr=="x") && (uuexpr=="x") && (vvexpr=="x")) ? \
last \
: ((yyexpr=="y") && (uuexpr=="y") && (vvexpr=="y")) ? \
clp2 \
: \
mt_lutxy(last,clp2,yexpr=yyexpr,uexpr=uuexpr,vexpr=vvexpr,y=yy, u=uu, v=vv)
}
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.