Go Back   Cockos Incorporated Forums > REAPER Forums > REAPER for Video Editing/Mangling

Reply
 
Thread Tools Display Modes
Old 04-05-2020, 10:17 AM   #1
jak352
Human being with feelings
 
Join Date: Apr 2017
Location: Scotland, UK
Posts: 56
Default Code for showing a grid of any number of videos with automatic column and row count

I have made some code for showing a grid of videos while automatically allocating a column and row count (leaving black space where necessary). Here's the code to paste into the Video Processor plugin in an empty track with any number of video tracks below it:

Code:
// grid of videos - automatically draws any number of videos from tracks
x=0;
count_tracks = input_track_count();
cols = ceil(sqrt(count_tracks));
rows = ceil(count_tracks/cols);
loop(cols*rows,
gfx_blit(input_track(x), 1 /* preserve aspect */,
(x%cols)*project_w/cols, ((x - (x%cols))/cols)*project_h/rows, // position
project_w/cols,project_h/rows // output width and height
);
x += 1;
);
There are some more code examples in my feature request post at:
https://forum.cockos.com/showthread.php?t=233798
COVID-19 is currently inspiring lots of people to make videos like this.
jak352 is offline   Reply With Quote
Old 04-05-2020, 03:10 PM   #2
jak352
Human being with feelings
 
Join Date: Apr 2017
Location: Scotland, UK
Posts: 56
Default Video demo of automatic code for grid of videos

There's a video demo of this in action here:

Last edited by jak352; 04-05-2020 at 03:11 PM. Reason: square brackets instead of paranthesis required
jak352 is offline   Reply With Quote
Old 04-06-2020, 07:02 AM   #3
Eliseat
Human being with feelings
 
Eliseat's Avatar
 
Join Date: Mar 2018
Location: Cologne
Posts: 1,362
Default

Quote:
Originally Posted by jak352 View Post
There's a video demo of this in action here:
Jak352, this is amazing!

If you don't mind, I would put your video plugin into the video presets thread that I've started a while ago. (https://forum.cockos.com/showthread.php?p=2265562)

Many thanks
__________________
☆.。.:*・°☆.。.:*・°☆.。.:*・°☆REAPER//✿◔‿◔)°☆.。.:*・°☆.。.:*・°☆
Eliseat is offline   Reply With Quote
Old 04-07-2020, 02:44 AM   #4
Eliseat
Human being with feelings
 
Eliseat's Avatar
 
Join Date: Mar 2018
Location: Cologne
Posts: 1,362
Default

Would it be possible to create different patterns? I mean to combine four video instances to a bigger one while the others stay small all around. Is there a way to handle that like tables in HTML with rows and cols?

Greetings
Eli
__________________
☆.。.:*・°☆.。.:*・°☆.。.:*・°☆REAPER//✿◔‿◔)°☆.。.:*・°☆.。.:*・°☆

Last edited by Eliseat; 04-07-2020 at 02:59 AM.
Eliseat is offline   Reply With Quote
Old 04-07-2020, 06:33 AM   #5
TonE
Human being with feelings
 
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 3,949
Default

Cool, thanks for sharing, can Reaper render this to a new video, for uploading to youtube*? Automatic adjustment of the grid is elegant.

* Oh you answered already in your video, File, Render, Time selection, output format MPEG-4, render 1 file. So just a normal rendering does it already.
TonE is offline   Reply With Quote
Old 04-07-2020, 12:31 PM   #6
jak352
Human being with feelings
 
Join Date: Apr 2017
Location: Scotland, UK
Posts: 56
Default

Quote:
Originally Posted by Eliseat View Post
Would it be possible to create different patterns? I mean to combine four video instances to a bigger one while the others stay small all around. Is there a way to handle that like tables in HTML with rows and cols?

Greetings
Eli
(EDIT: The code below such as in post #34 now allows for this.)

My code doesn't allow for that as it stands but you could do it like this:

1. Put the videos you want small into tracks 1,2,3,4,5,8,9,12,13,14,15,16. Put a random image into tracks 6,7,10,11.

2. Make a track above all these and use my code and you'll get a 4x4 grid

3. Make a track above all that and put the video into that that you want big and add a new instance of Video Processor on it and choose the "Overlay: Image Overlay" preset and use the zoom knob in the preset to resize the big video.

Last edited by jak352; 05-12-2020 at 01:15 PM. Reason: Typo
jak352 is offline   Reply With Quote
Old 04-08-2020, 12:08 AM   #7
Eliseat
Human being with feelings
 
Eliseat's Avatar
 
Join Date: Mar 2018
Location: Cologne
Posts: 1,362
Default

Quote:
Originally Posted by jak352 View Post
My code doesn't allow for that as it stands but you could do it like this:

1. Put the videos you want small into tracks 1,2,3,4,5,8,9,12,13,14,15,16. Put a random image into tracks 6,7,10,11.

2. Make a track above all these and use my code and you'll get a 4x4 grid

3. Make a track above all that and put the video into that that you want big and add a new instance of Video Processor on it and choose the "Overlay: Image Overlay" preset and use the zoom knob in the preset to resize the big video.
That's a typical Reaper workaround.

Many thanks
__________________
☆.。.:*・°☆.。.:*・°☆.。.:*・°☆REAPER//✿◔‿◔)°☆.。.:*・°☆.。.:*・°☆
Eliseat is offline   Reply With Quote
Old 04-12-2020, 11:23 PM   #8
chema001
Human being with feelings
 
Join Date: Feb 2018
Posts: 41
Default

Quote:
Originally Posted by jak352 View Post
I have made some code for showing a grid of videos while automatically allocating a column and row count (leaving black space where necessary). Here's the code to paste into the Video Processor plugin in an empty track with any number of video tracks below it:

Code:
// grid of videos - automatically draws any number of videos from tracks
x=0;
count_tracks = input_track_count();
cols = ceil(sqrt(count_tracks));
rows = ceil(count_tracks/cols);
loop(cols*rows,
gfx_blit(input_track(x), 1 /* preserve aspect */,
(x%cols)*project_w/cols, ((x - (x%cols))/cols)*project_h/rows, // position
project_w/cols,project_h/rows // output width and height
);
x += 1;
);
There are some more code examples in my feature request post at:
https://forum.cockos.com/showthread.php?t=233798
COVID-19 is currently inspiring lots of people to make videos like this.
Thanks, jak352!!

It's really awesome.

How would you do the next idea? I start with your code, with a group of small videos in a grid, but after a seconds, how could I zoom in one of them and then continue in a full screen mode?

Or just how to zoom out a full screen video and finish in a small one that is a cell of a grid...

I repeat: THANKS!!
chema001 is offline   Reply With Quote
Old 04-15-2020, 12:23 AM   #9
jak352
Human being with feelings
 
Join Date: Apr 2017
Location: Scotland, UK
Posts: 56
Default

Quote:
Originally Posted by chema001 View Post
Thanks, jak352!!

It's really awesome.

How would you do the next idea? I start with your code, with a group of small videos in a grid, but after a seconds, how could I zoom in one of them and then continue in a full screen mode?

Or just how to zoom out a full screen video and finish in a small one that is a cell of a grid...

I repeat: THANKS!!
Hi, thanks! I think the easiest way to do this is to make a copy of the track that you want to be focussed in on (including its video item) and put that new track at the top of the project. This will then be put over the top of the grid. You can split at the cursor (using the S button) and delete the bits of the item that you don't want to hog the screen. To prevent getting the audio from the new track being doubled you can untick Master Send in the Route area for the new track. You can reposition and zoom the top track too with the grid in the background if you put Video Processor>Overlap: Image Overlay onto the new top track. Does this make sense?
jak352 is offline   Reply With Quote
Old 04-15-2020, 05:12 AM   #10
chema001
Human being with feelings
 
Join Date: Feb 2018
Posts: 41
Default

Quote:
Originally Posted by jak352 View Post
Hi, thanks! I think the easiest way to do this is to make a copy of the track that you want to be focussed in on (including its video item) and put that new track at the top of the project. This will then be put over the top of the grid. You can split at the cursor (using the S button) and delete the bits of the item that you don't want to hog the screen. To prevent getting the audio from the new track being doubled you can untick Master Send in the Route area for the new track. You can reposition and zoom the top track too with the grid in the background if you put Video Processor>Overlap: Image Overlay onto the new top track. Does this make sense?
First of all, thanks for your answer. I must try your idea. But it doesn't sound bad Thanks!
chema001 is offline   Reply With Quote
Old 04-23-2020, 02:17 PM   #11
fallforward
Human being with feelings
 
Join Date: Dec 2011
Posts: 43
Default

This is absolutely fantastic! Thank you!
fallforward is offline   Reply With Quote
Old 04-23-2020, 06:19 PM   #12
echan101
Human being with feelings
 
Join Date: Apr 2020
Posts: 5
Default Video Grid with Subtitles and centered last row

Here's some modifications to the code that allow two things:
  1. Centre the last row of videos (Zoom style).
  2. Adjustable black section at the bottom for lyrics.
Code:
// Grid of videos with Subtitles room - automatically draws any number of videos from tracks

//@param 2:ypos "y position" 1 0 600 150 1

height = project_h - ypos;
// width = project_w * height / (ypos + height);

width = project_w;

gfx_set(0);
gfx_fillrect(0,0,project_w,project_h);
x=0;
count_tracks = input_track_count();
cols = ceil(sqrt(count_tracks));
rows = ceil(count_tracks/cols);
loop(cols*rows,
  xpos = 0;
  lastLineCount = (count_tracks-1) % cols + 1; 
  lastLineOffset = (width - width/cols * lastLineCount) / 2 ;
  x >= (cols*rows - cols)                              // Is it the last line?
    ? xpos = (x%cols)*width/cols + lastLineOffset      // x position last line
    : xpos = (x%cols)*width/cols                       // x position non-last line
    ;
  gfx_blit(
    input_track(x), 
    1,                                   // preserve aspect
    xpos,                                // X position
    ((x - (x%cols))/cols)*(height)/rows, // y position
    width/cols,height/rows               // output width and height
  );
  x += 1;
);
echan101 is offline   Reply With Quote
Old 05-23-2020, 12:13 AM   #13
zacki
Human being with feelings
 
zacki's Avatar
 
Join Date: Feb 2013
Location: Germany
Posts: 231
Default

Thanks a lot, jak! Great script!

Quote:
Originally Posted by urednik View Post
Made another one with professional superstar hornplayers as well few days ago.
Thanks!

youtu.be/DPazNSxDDbM
wow, I mean... WOW
__________________
Some of my favourite posts: 1 2 3
zacki is offline   Reply With Quote
Old 05-23-2020, 02:38 AM   #14
urednik
Human being with feelings
 
urednik's Avatar
 
Join Date: Apr 2010
Posts: 1,247
Default

Well thanks for nice comments on my video. Again, Jonathan, big thanks for helping us out with this code. One final video will use all of your recent tweaks of course!
__________________
W10 (64) Lenovo E540 - SSD; Lenovo B590; W7 (32), Compaq 610 (2.1Ghz core 2 duo, L2 cache, 2GB RAM); DPA 4018, Schoeps MK2, Schoeps MTSC 64, Neumann mk184, AEA Ribbon 88mk, AKG SolidTUBE; Focusrite Scarlett 18i20, recording merely live acoustic music.
urednik is offline   Reply With Quote
Old 05-23-2020, 10:44 AM   #15
jak352
Human being with feelings
 
Join Date: Apr 2017
Location: Scotland, UK
Posts: 56
Default Revised code with option to crop videos automatically and approximately square grid

Code:
// Grid of videos - automatically draws any number of videos from tracks with grid 

//@param 1:boss "Lead Track Number" 2 2 10 6 1
//@param 2:Nbig "Lead Grid Size" 1 1 9 5 1
//@param 3:bossexpand "Expand Lead Track" 0 0 1 0.5 0.01
//@param 4:bossfront "Lead to Front" 0 0 1 0.5 1
//@param 5:yposratio "Y Offset" 0 0 1 0.5 0.01
//@param 6:border "Grid Borders" 5 0 720 360 1
//@param 7:presasp "Stretch/Crop/Full" 0.5 0 1 0.5 0.5
//@param 8:portrait "Landscape/Sq/Portrait" 0 0 1 0.5 0.5
//@param 9:background "Backdrop Color/Video" 0 0 1 0.5 1
//@param 10:R "Backdrop Red" 0.1 0 1 0.5 0.01
//@param 11:G "Backdrop Green" 0.1 0 1 0.5 0.01
//@param 12:B "Backdrop Blue" 0.5 0 1 0.5 0.01

presasp == 0.5 ? (crop = 1; presasp = 0) : crop = 0; //presasp = 0.5 means crop videos
aspect = project_w/project_h; // aspect ratio of project
boss = boss - 1; // boss is now relative to video processor track
ypos = yposratio*project_h;
 Ntracks = input_track_count(); // Number of video files
 boss>Ntracks ? boss = Ntracks; // If the lead video track set is greater than Ntracks use last
((boss>0)&(bossexpand==1)&(bossfront==1)) ? // if there is a lead track fully expanded on front then plot it
(
            crop == 1 ? //crop code
            (
            input_info(input_track(boss-1),prewidth,preheight);
            project_w/project_h<prewidth/preheight ? //crop from width
             (wsrc_expand = (preheight*(project_w/project_h));//source width
              hsrc_expand = preheight;//source height
              xsrc_expand = (prewidth - wsrc_expand)/2;//source x
              ysrc_expand = 0;)//source y
             : //else crop from height
              (wsrc_expand = prewidth;
              hsrc_expand = (prewidth*(project_h/project_w));
              xsrc_expand = 0;
              ysrc_expand = (preheight - hsrc_expand)/2;);
             )
             :
             (xsrc_expand = 0;ysrc_expand = 0;wsrc_expand = prewidth; hsrc_expand = preheight);
      gfx_blit(
        input_track(boss-1),
        presasp,// preserve aspect ratio
        0, 0, project_w, project_h, // output x, y, width and height
        xsrc_expand,ysrc_expand,wsrc_expand,hsrc_expand // source x, y, width and height
      );
)
: // if there isn't a lead track on front then do the rest of the code
(
 gfx_set(0);
 gfx_fillrect(0,0,project_w,project_h);
 x=0; // Counter for looping
 Ntracks > 0 // If there are video tracks
 ?
 count_tracks = Ntracks + Nbig^2 - 1 // Number of grid locations
 : //else
 count_tracks = 0  
 ;
 portrait == 0 
 ?// if landscape source videos
 (
  xoffset = 0;
  border_h = border;
  border_w = border*aspect;
  height = project_h - border_h;
  width = project_w - border_w;
  cols = ceil(sqrt(count_tracks));
  rows = ceil(count_tracks/cols);
  vHeight = height / cols - border_h; // Video height
  vWidth = width / cols - border_w; // Video Width
 )
 : portrait == 0.5 ? //else if sqaure grid
 (
  xoffset = 0;
  rows = ceil(sqrt(count_tracks/aspect));
  cols = ceil(count_tracks/rows);
  border_h = border;
  border_w = border*aspect*rows/cols;
  height = project_h - border_h;
  width = project_w - border_w;
  vHeight = height / rows - border_h;  
  vWidth = width / cols - border_w; 
 )
 : // else we assume portrait source videos
 (
  border_h = border*aspect;
  border_w = border;
  height = project_h - border_h;
  width = project_w - border_w;
  rows = ceil((sqrt(count_tracks))/aspect);
  cols = ceil(count_tracks/rows);
  rows_alt = rows - 1;
  cols_alt = ceil(count_tracks/rows_alt);
  rows*(aspect^2)>cols_alt ? (cols = cols_alt;rows = rows_alt;); // if reducing rows by one is better 
  rows<Nbig ? (rows = Nbig; cols = ceil(count_tracks/rows);); // if number of rows is less than Nbig
  vWidth = width / cols - border_w;
  vHeight = height / rows - border_h;
  aspect < (vHeight/vWidth) // if fitting to width
   ?      
   (xoffset = 0;
   vHeight = vWidth*aspect;)
   : // else fitting to height
    (vWidth = vHeight / aspect;
    xoffset = (project_w - (cols*vWidth + (cols+1)*border_w))/2;
  );   
 );
 Nbig>1 ? // if one of the videos is chosen to be big then put lead track in centre
  (
   left_cols = floor((cols - Nbig)/2); // Number of columns before big central video
   top_rows = floor((rows - Nbig)/2); // Number of rows before big central video
  )
  : // else all videos same size then lead tracks stays where it is
  (
   top_rows = floor((boss-1)/cols);
   left_cols = (boss-1) % cols;
  );
  background == 1 
    ? 
     gfx_blit(0) // If background is 1 then show current track image or video as background
    :
   (
    gfx_set(R,G,B,1); //Set color for background
    gfx_fillrect(0,0,project_w,project_h); // show color as background
 );
 bossfront==0 // if the lead track is behind plot it first
 ?
 (
   (boss-1 >= (cols*rows - cols)) // Is it the last line?
     ? 
      (
       lastLineCount = (count_tracks-1) % cols + 1; // Number of videos in last row
       lastLineOffset = (project_w - (lastLineCount*vWidth + (lastLineCount+1)*border_w))/2;
       xpos = left_cols*vWidth + lastLineOffset + border_w*left_cols; // x position last line
      )
     : 
      xpos = left_cols*vWidth + border_w*left_cols + xoffset; // x position non-last line
      input_info(input_track(boss-1),prewidth,preheight);
      xpos_expand = (1-bossexpand)*(border_w + xpos);
      ypos_expand = (1-bossexpand)*(border_h + vHeight*(top_rows) + border_h*(top_rows) + ypos);
      vWidth_expand = (1-bossexpand)*(Nbig*vWidth+(Nbig-1)*border_w) + bossexpand*project_w;
      vHeight_expand = (1-bossexpand)*(Nbig*vHeight+(Nbig-1)*border_h) + bossexpand*project_h;
      crop == 1 ? //crop code
      (
       vWidth_expand/vHeight_expand<prewidth/preheight ? //crop from width
       (wsrc_expand = (preheight*(vWidth_expand/vHeight_expand));//source width
        hsrc_expand = preheight;//source height
        xsrc_expand = (prewidth - wsrc_expand)/2;//source x
        ysrc_expand = 0;)//source y
       : //else
        (wsrc_expand = prewidth;
        hsrc_expand = (prewidth*(vHeight_expand/vWidth_expand));
        xsrc_expand = 0;
        ysrc_expand = (preheight - hsrc_expand)/2;);
        )
        :
        (
        xsrc_expand = 0;ysrc_expand = 0;wsrc_expand = prewidth; hsrc_expand = preheight;
        );
     //plot code
     gfx_blit(
      input_track(boss-1), presasp,
      xpos_expand, ypos_expand, vWidth_expand, vHeight_expand,
      xsrc_expand,ysrc_expand,wsrc_expand,hsrc_expand
      );
 );
 bosscount = 0; // Counter for taking into account boss video
 loop(count_tracks, //main loop
  row = floor(x/cols); // Column position (starts at 0)
  col = x % cols; // Row position (starts at 0)
  lastLineCount = (count_tracks-1) % cols + 1; // Number of videos in last row
  lastLineOffset = (project_w - (lastLineCount*vWidth + (lastLineCount+1)*border_w))/2;
  ((x >= (cols*rows - cols))&(bosscount > Nbig^2 - 2)) // Is it the last line and after any big video?
    ? xpos = col*vWidth + lastLineOffset + border_w*col // last line
    : xpos = col*vWidth + border_w*col + xoffset // non-last line
    ;
   ((row>top_rows-1)&(col>left_cols-1)&(row<top_rows+Nbig)&(col<left_cols+Nbig))
   ? // if the grid number is part of big video
      bosscount = bosscount + 1 // increment counter
    : // else
    x-bosscount+1 < Ntracks // if video exists
    ?
    (vidnum = x-bosscount+1;
      vidnum < boss ? vidnum = vidnum-1;
     //crop code
     input_info(input_track(vidnum),prewidth,preheight);
     vxpos = border_w + xpos; //x position
     vypos = border_h + vHeight*(row) + border_h*(row) + ypos; //y position
     crop == 1 ? //crop code
     (
     vWidth/vHeight<prewidth/preheight ? //crop from width
      (wsrc = preheight*(vWidth/vHeight);//source width
       hsrc = preheight;//source height
       xsrc = (prewidth - wsrc)/2;//source x
       ysrc = 0;)//source y
      : //else
       (wsrc = prewidth;
       hsrc = prewidth*(vHeight/vWidth);
       xsrc = 0;
       ysrc = (preheight - hsrc)/2;);
       )
       :
       (xsrc = 0; ysrc = 0; wsrc = prewidth; hsrc = preheight);
      //plot code
      gfx_blit(
        input_track(vidnum), presasp,
        vxpos, vypos, vWidth, vHeight,
        xsrc,ysrc,wsrc,hsrc
        );
   );
  x += 1;
 );
 bossfront==1 //If the boss is in front of everything else plot it now
  ?
  (
   (boss-1 >= (cols*rows - cols)) // Is it the last line?
       ? 
        (
         lastLineCount = (count_tracks-1) % cols + 1; // Number of videos in last row
         lastLineOffset = (project_w - (lastLineCount*vWidth + (lastLineCount+1)*border_w))/2;
         xpos = left_cols*vWidth + lastLineOffset + border_w*left_cols; // last line
        )
       : //else not the last line
        xpos = left_cols*vWidth + border_w*left_cols + xoffset; // non-last line
      //crop code
            input_info(input_track(boss-1),prewidth,preheight);
            xpos_expand = (1-bossexpand)*(border_w + xpos);
            ypos_expand = (1-bossexpand)*(border_h + vHeight*(top_rows) + border_h*(top_rows) + ypos);
            vWidth_expand = (1-bossexpand)*(Nbig*vWidth+(Nbig-1)*border_w) + bossexpand*project_w;
            vHeight_expand = (1-bossexpand)*(Nbig*vHeight+(Nbig-1)*border_h) + bossexpand*project_h;
            crop == 1 ? //crop code
             (
             vWidth_expand/vHeight_expand<prewidth/preheight ? //crop from width
             (wsrc_expand = (preheight*(vWidth_expand/vHeight_expand));//source width
              hsrc_expand = preheight;//source height
              xsrc_expand = (prewidth - wsrc_expand)/2;//source x
              ysrc_expand = 0;)//source y
             : //else
              (wsrc_expand = prewidth;
              hsrc_expand = (prewidth*(vHeight_expand/vWidth_expand));
              xsrc_expand = 0;
              ysrc_expand = (preheight - hsrc_expand)/2;);
              )
              :
              (
              xsrc_expand = 0; ysrc_expand = 0; wsrc_expand = prewidth; hsrc_expand = preheight;
              );
            gfx_blit(
               input_track(boss-1), presasp,
               xpos_expand, ypos_expand, vWidth_expand, vHeight_expand,
               xsrc_expand,ysrc_expand,wsrc_expand,hsrc_expand
            );
  );
);

Last edited by jak352; 05-23-2020 at 05:27 PM. Reason: Get rid of tiny lines around square videos
jak352 is offline   Reply With Quote
Old 05-23-2020, 12:31 PM   #16
jak352
Human being with feelings
 
Join Date: Apr 2017
Location: Scotland, UK
Posts: 56
Default

The code in post 51 now has about all the features I was hoping for (I think). It now allows for automatically cropping the videos by using Fill/Crop/Full at 12 o'clock position (value 0.5) meaning you don't have to resize videos by ticking boxes in Project Settings or use opacity/zoom/pan unless you want to. Leaving it on value 0 means you don't preserve aspect ratio (stretching to fill) and value 1 means the entire video is fitted preserving aspect ratio (as before). There is a new option for having an approximately square grid (setting Landscape/Sq/Portrait at 12 o'clock position so value 0.5) and this is especially useful for projects where you crop both landscapes and portrait source videos. Values 0 and 1 are optimised for landscape and portrait source videos respectively (or vice versa if the project width and height are set to portrait mode for IGTV or whatever).

Just place this code in the Video Processor in track 1. Put the videos you want in the grid in tracks 2 onwards. If you want a background image or background video (visible for non-zero Grid Borders values when Expand Lead Track is less than 1) while still preserving the video on the lead track within the grid then put an image or video in track 1 and set Background Color/Video to 1. Leave Background Color/Video on 0 if you want to specify a backround color using the RGB knobs instead. Images count as if they are videos and image items can be resized to fill space (to ensure tracks don't hop around if you don't want them to for instance). The default size/shape of the export video is set by the video or image in track 1 or track 2 if there's no background image/video in track 1. If you get low quality or output of the wrong size I recommend going to File>Project Settings>Video and setting the preserved video size to what you want (such as 1920 x 1080) and you might find it helps to tick "Always resize video output...". It is possible to use automation on any of the parameters if you want to get fancy. Thanks for positive feedback and enjoy!
jak352 is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 01:25 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2023, vBulletin Solutions Inc.