Old 01-10-2023, 12:59 PM   #1041
benmiller
Human being with feelings
 
benmiller's Avatar
 
Join Date: Dec 2015
Posts: 324
Default

is there a lua function to get the state of the groups? as in which groups are enabled and which ones are dissabled? can't seem to find that
benmiller is offline   Reply With Quote
Old 01-10-2023, 02:27 PM   #1042
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Quote:
Originally Posted by benmiller View Post
is there a lua function to get the state of the groups? as in which groups are enabled and which ones are dissabled? can't seem to find that
Which group exactly? Tracks or items or something else?
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 01-11-2023, 01:32 AM   #1043
benmiller
Human being with feelings
 
benmiller's Avatar
 
Join Date: Dec 2015
Posts: 324
Default

Quote:
Originally Posted by Meo-Ada Mespotine View Post
Which group exactly? Tracks or items or something else?
The track groups, the ones you see in the track grouping matrix. In that matrix you can enable/disable groups. I want to be able to see which groups are enabled/disabled.

Looking for something like reaper.GetSetTrackGroupEnablestate(setmask, setvalue) which would return a similar value to reaper.GetSetTrackGroupMembership() but where every bit would represent the enable state of a group.
benmiller is offline   Reply With Quote
Old 01-22-2023, 09:47 AM   #1044
Lubalin
Human being with feelings
 
Join Date: May 2020
Posts: 11
Default

hey folks! I'm using an iPhone as a mic (using an iOS app to route the mic to the headphone jack, then running that to my interface) and it's working great, but there's a delay of about 4860 samples.

I'd love to find a way to have the recordings sync'd up (ie, moved up 4850 spls) automatically.

I could write a script to "move selected items up 4860 samples" and run it manually every time, but I feel like there's a better way.

Anyone have a better idea?
Lubalin is offline   Reply With Quote
Old 01-22-2023, 04:36 PM   #1045
benmiller
Human being with feelings
 
benmiller's Avatar
 
Join Date: Dec 2015
Posts: 324
Default

Quote:
Originally Posted by Lubalin View Post
hey folks! I'm using an iPhone as a mic (using an iOS app to route the mic to the headphone jack, then running that to my interface) and it's working great, but there's a delay of about 4860 samples.

I'd love to find a way to have the recordings sync'd up (ie, moved up 4850 spls) automatically.

I could write a script to "move selected items up 4860 samples" and run it manually every time, but I feel like there's a better way.

Anyone have a better idea?
preference/audio/recording-> input manual offset
benmiller is offline   Reply With Quote
Old 02-04-2023, 11:51 AM   #1046
Kvebbs
Human being with feelings
 
Join Date: Oct 2009
Posts: 193
Default

Quote:
Originally Posted by mrelwood View Post
Here are a few ideas, is this what you had in mind?
Yes, wow - thank you! I have no excuse now but to learn enough about this to finish one of my own =)
Kvebbs is offline   Reply With Quote
Old 02-05-2023, 09:14 AM   #1047
Freex
Human being with feelings
 
Freex's Avatar
 
Join Date: Jul 2011
Location: Northern Ireland
Posts: 902
Default

Hopefully someone can explain this to me,

I'm trying to write a script (.lua) to cycle thru my inputs, it's in combination with CSI to allow me to jump thru input types (separate script) using the RotaryPush and then scroll thru those inputs using the Rotary encoder.


I played around with OpenAI's GPT to try and get something going, and whileit gave me "parts" of the solutions nothing in full.
So I started trying to understand the code.

So here's where I'm at, or where I'm stumbling,

the api reaper.GetNumMIDIInputs()

what is it giving me, is it
A. the Active midi inputs
B. all "potential" midi inputs

also if I understand the "I_RECINPUTS" correctly
"if 4096 set, input is MIDI and low 5 bits represent channel (0=all, 1-16=only chan), next 6 bits represent physical input (63=all, 62=VKB). "
4096 is where midi devices start,

What does this mean?

I get the whole bit counting, 1000000000000 being 4096, just don't understand that statement.

I have my audio working correctly, both mono and stereo pairs

But the midi is playing hard to get, and it's clearly my lack of understanding,

I worked out how to script to get real inputs work, but then VBK and ALL MIDI doesn't or I have another script that "works" for VBK and ALL MIDI but it was written by OpenAIs ChatGPT and I just don't understand the whys of it.

If anyone could steer my on this midi input end, I'll have the script sorted.
Freex is offline   Reply With Quote
Old 02-06-2023, 08:24 AM   #1048
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Rule #1: ignore ChatGPT. It mostly writes non functional code.

What inputs do you want to cycle through? The ones you can select by right clicking the recarm-button? And only Midi?

And do you mean by cycling:

input 1
input 2
input 3
...
...
...
input maximum-2
input maximum-1
input maximum

?
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 02-07-2023, 06:06 PM   #1049
Freex
Human being with feelings
 
Freex's Avatar
 
Join Date: Jul 2011
Location: Northern Ireland
Posts: 902
Default

Quote:
Originally Posted by Meo-Ada Mespotine View Post
Rule #1: ignore ChatGPT. It mostly writes non functional code.

What inputs do you want to cycle through? The ones you can select by right clicking the recarm-button? And only Midi?

And do you mean by cycling:

input 1
input 2
input 3
...
...
...
input maximum-2
input maximum-1
input maximum

?
Hey, thanks for the feedback,
Yeah ChatGPT seems to be very dependent on the quality of the information in.
But it did catch a syntax error that I just couldn't see.
I actually "cracked" most of it, last night, without ChatGPT
Not sure what it's called but basically groups of 32.

What I am trying to figure out now is if there's a way for the script to automatically know how many Midiports are "enabled"
This is for the push command to Jump to the next input type or device.
At the minute I have set it up that the script needs to be edited by the user, to show how many midi ports are enabled, then it all works fine.
I had tried using reaper.GetNumMIDIInputs and GetMaxMidiInputs but both seem to be telling me there are 63(sets of 32) as that the Midi-ALL value.
I'd like to have it that if the system has 2 ports enabled then Midi_Dev = 2
and if one was disabled then Midi_Dev would change to 1
Freex is offline   Reply With Quote
Old 02-11-2023, 01:07 PM   #1050
rubberDuck
Human being with feelings
 
Join Date: Jan 2023
Posts: 9
Default

Can I invoke a MIDI event on a specified track from an extension?
In the reaper API I see the function StuffMIDIMessage(), which looks similar to what I need, but it doesn't allow me to send an event to a specified track.
I want to trigger a sound like the midi editor does - when you click on the keyboard in the MIDI editor, the track that makes the sound is the one selected in the midi editor, not the active one.
rubberDuck is offline   Reply With Quote
Old 02-12-2023, 04:00 AM   #1051
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Quote:
Originally Posted by rubberDuck View Post
Can I invoke a MIDI event on a specified track from an extension?
In the reaper API I see the function StuffMIDIMessage(), which looks similar to what I need, but it doesn't allow me to send an event to a specified track.
I want to trigger a sound like the midi editor does - when you click on the keyboard in the MIDI editor, the track that makes the sound is the one selected in the midi editor, not the active one.
You can send to a Midi-channel. You need to set Midi channel 1 as input for the track. Then arm the track and it works.

You can find docs for StuffMidiMessage amongst my other docs here:
https://mespotin.uber.space/Ultrasch...Misc_Docs.html
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 02-12-2023, 07:11 PM   #1052
rubberDuck
Human being with feelings
 
Join Date: Jan 2023
Posts: 9
Default

Thanks for the answer
rubberDuck is offline   Reply With Quote
Old 02-16-2023, 04:37 PM   #1053
AZpercussion
Human being with feelings
 
Join Date: Oct 2019
Location: Moscow / Tbilisi
Posts: 909
Default

Hellow, folks!
I'm trying to get clipboard by using text = reaper.CF_GetClipboard() but I get empty string.
It works only if there is a text in clipboard, but if there is any userdata it doesn't work.
Is there any way to get project data?
AZpercussion is offline   Reply With Quote
Old 02-16-2023, 04:45 PM   #1054
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Nope, it only works for strings.
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 02-16-2023, 05:05 PM   #1055
AZpercussion
Human being with feelings
 
Join Date: Oct 2019
Location: Moscow / Tbilisi
Posts: 909
Default

Quote:
Originally Posted by Meo-Ada Mespotine View Post
Nope, it only works for strings.
Ah! Sadness. Thanks for the answer!
AZpercussion is offline   Reply With Quote
Old 03-02-2023, 06:31 PM   #1056
ambrosebs
Human being with feelings
 
Join Date: Feb 2023
Posts: 26
Default

How can I detect if a tempo marker explicitly sets BPM? To distinguish between, say, a time signature marker vs. a tempo marker that preserves the current BPM?
ambrosebs is offline   Reply With Quote
Old 03-04-2023, 12:57 AM   #1057
mrelwood
Human being with feelings
 
mrelwood's Avatar
 
Join Date: Nov 2006
Location: Finland
Posts: 1,528
Default

Quote:
Originally Posted by ambrosebs View Post
How can I detect if a tempo marker explicitly sets BPM? To distinguish between, say, a time signature marker vs. a tempo marker that preserves the current BPM?
If you're talking about JSFX, like this:

Code:
ts_num != ts_num_old || ts_denom != ts_denom_old ? (
  gfx_drawstr("Score!");
);
ts_num_old = ts_num;
ts_denom_old = ts_denom;
For scripts and other add-ons, need to wait for the next answer...
__________________
______Announcing__mrelwood plugins______
.. MacBook Pro 16" Late '19 .. Scarlett 6i6, Saffire Pro 24 DSP (+ADA8000) .. FCA610 .. EVE SC207 .. Focal: Shape 65, Alpha 65, CMS 40, Listen Pro ..
mrelwood is offline   Reply With Quote
Old 03-04-2023, 01:38 PM   #1058
ambrosebs
Human being with feelings
 
Join Date: Feb 2023
Posts: 26
Default

Quote:
Originally Posted by mrelwood View Post
For scripts and other add-ons, need to wait for the next answer...
Thanks, was wondering for SWS purposes (C++).
ambrosebs is offline   Reply With Quote
Old 03-17-2023, 12:08 PM   #1059
Bourrinlepoulpe
Human being with feelings
 
Join Date: Nov 2022
Posts: 26
Default Non linearity

Hello I wanted to see how it was possible to implement non linearity to existing plugins (ie compressors) I'm just starting to read about jsfx scripting, it feels like a new world to me opening haha. Many thanks !
Bourrinlepoulpe is offline   Reply With Quote
Old 03-17-2023, 01:01 PM   #1060
nofish
Human being with feelings
 
nofish's Avatar
 
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
Default

Quote:
Originally Posted by Bourrinlepoulpe View Post
Hello I wanted to see how it was possible to implement non linearity to existing plugins (ie compressors) I'm just starting to read about jsfx scripting, it feels like a new world to me opening haha. Many thanks !
I'm not sure what you mean, as dynamic effects (compressors, limiters etc.) are non-linear anyway (https://moinsound.wordpress.com/2015...ths-linearity/).
nofish is offline   Reply With Quote
Old 04-21-2023, 10:19 AM   #1061
frabert
Human being with feelings
 
Join Date: May 2020
Posts: 39
Default

What is the proper way to get frame data from a video processor plugin?

What I'm doing right now is

Code:
IVideoFrame * process_frame(IREAPERVideoProcessor *vproc, 
                                const double *parmlist, int nparms,
                                double project_time, double frate, 
                                int force_format) {
  for(int i = 0; i < vproc->getNumInputs(); ++i) {
    auto input = vproc->renderInputVideoFrame(i, 'RGBA');
    do_stuff(input);
    input->Release();
  }
  // do stuff with output_frame, which is allocated prior to this and reused
  return output_frame;
}
but the result is extremely unstable, sometimes the output will not be right (e.g. the output frame is ignored and the input frame is used instead), all stuff that reminds me of memory corruption. Is there another way of using the API?

Related, is there an API for getting the current video rendering resolution?
frabert is offline   Reply With Quote
Old 04-22-2023, 03:13 PM   #1062
AZpercussion
Human being with feelings
 
Join Date: Oct 2019
Location: Moscow / Tbilisi
Posts: 909
Default

Hi there! Does anybody knows how to get type of mouse cursor currently used?
I want my script works accordingly to mouse context, but function reaper.BR_GetMouseCursorContext() hasn't enough details and doesn't work with razor.
AZpercussion is offline   Reply With Quote
Old 04-22-2023, 04:03 PM   #1063
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 3,913
Default

Quote:
Originally Posted by AZpercussion View Post
Hi there! Does anybody knows how to get type of mouse cursor currently used?
I want my script works accordingly to mouse context, but function reaper.BR_GetMouseCursorContext() hasn't enough details and doesn't work with razor.
Would this help?

Code:
-- Cursor references, https://forum.cockos.com/showpost.php?p=2433770&postcount=80

local prev_cursor = nil
local cur_detect = reaper.JS_Mouse_LoadCursor(599) -- 599="Razor", 600="Razor move", 601="Razor +"

function Loop()
  local cur_cursor = reaper.JS_Mouse_GetCursor()
  if prev_cursor ~= cur_cursor then
    prev_cursor = cur_cursor
    if cur_cursor == cur_detect then
      reaper.ShowConsoleMsg("cursor detected \n")
    end
  end
  reaper.defer(Loop)
end

Loop()
Edgemeal is offline   Reply With Quote
Old 04-22-2023, 04:18 PM   #1064
AZpercussion
Human being with feelings
 
Join Date: Oct 2019
Location: Moscow / Tbilisi
Posts: 909
Default

Quote:
Originally Posted by Edgemeal View Post
Would this help?
Strange, because the function reaper.JS_Mouse_GetCursor() retrieves user data and it's different each time Reaper is run.

Also I don't see here razor envelope cursors: https://www.reaper.fm/sdk/cursors/cursors.php
AZpercussion is offline   Reply With Quote
Old 04-22-2023, 06:44 PM   #1065
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 3,913
Default

Quote:
Originally Posted by AZpercussion View Post
Strange, because the function reaper.JS_Mouse_GetCursor() retrieves user data and it's different each time Reaper is run.

Also I don't see here razor envelope cursors: https://www.reaper.fm/sdk/cursors/cursors.php
Not sure about all OS, but OK here on Windows as the code is simply comparing the cursor handle, Maybe not want you need?

FWIW...
JS_Mouse_LoadCursor
If successful, returns a handle to the cursor

JS_Mouse_GetCursor()
On Windows, retrieves a handle to the current mouse cursor.
On Linux and macOS, retrieves a handle to the last cursor set by REAPER or its extensions via SWELL.
Edgemeal is offline   Reply With Quote
Old 04-23-2023, 04:03 AM   #1066
AZpercussion
Human being with feelings
 
Join Date: Oct 2019
Location: Moscow / Tbilisi
Posts: 909
Default

Quote:
Originally Posted by Edgemeal View Post
Not sure about all OS, but OK here on Windows as the code is simply comparing the cursor handle, Maybe not want you need?
Maybe I don't understand the sence of JS_Mouse_LoadCursor?
I don't need to change the cursor. I just want to figure out what type of cursor is displayed when I start my script.
AZpercussion is offline   Reply With Quote
Old 04-26-2023, 10:30 AM   #1067
AZpercussion
Human being with feelings
 
Join Date: Oct 2019
Location: Moscow / Tbilisi
Posts: 909
Default

Quote:
Originally Posted by Edgemeal View Post
Would this help?
Ah, thanks Edgemeal! I figured it out eventually.
Load means not to change the cursor but to get a dynamic handle from static ID.

And for getting the IDs, that I haven't find in specs, I made a script which show the ID number of current mouse cursor.
It just goes through 100000 numbers and compares handles from cursors.

I leave it here, maybe it will useful for someone.



Download: https://stash.reaper.fm/v/46789/Get%...%20tool_AZ.lua
AZpercussion is offline   Reply With Quote
Old 05-19-2023, 06:03 PM   #1068
AudioBabble
Human being with feelings
 
AudioBabble's Avatar
 
Join Date: Dec 2021
Location: Jupiter Island
Posts: 924
Default TrackFX_SetPreset -- bad argument #1

Code:
selected_trk = reaper.GetSelectedTrack( 0, 0 )
tracknumber = reaper.GetMediaTrackInfo_Value(selected_trk, 'IP_TRACKNUMBER')
reaper.TrackFX_SetPreset( tracknumber, 3, "DummyPreset")


Wondering why my var 'tracknumber' returns bad argument (MediaTrack Expected)?

value of tracknumber prints as 2.0 (i have only trk 2 selected)
AudioBabble is offline   Reply With Quote
Old 05-19-2023, 07:55 PM   #1069
cfillion
Human being with feelings
 
cfillion's Avatar
 
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
Default

TrackFX_SetPreset expects its first argument to be a MediaTrack, not a number. GetSelectedTrack returns a MediaTrack so 'selected_trk' is already what it needs.

Code:
local selected_trk = reaper.GetSelectedTrack(nil, 0)
if selected_trk then -- don't error out if no tracks are selected
  reaper.TrackFX_SetPreset(selected_trk, 3, "DummyPreset")
end
cfillion is offline   Reply With Quote
Old 05-19-2023, 08:19 PM   #1070
AudioBabble
Human being with feelings
 
AudioBabble's Avatar
 
Join Date: Dec 2021
Location: Jupiter Island
Posts: 924
Default

Quote:
Originally Posted by cfillion View Post
TrackFX_SetPreset expects its first argument to be a MediaTrack, not a number. GetSelectedTrack returns a MediaTrack so 'selected_trk' is already what it needs.

Code:
local selected_trk = reaper.GetSelectedTrack(nil, 0)
if selected_trk then -- don't error out if no tracks are selected
  reaper.TrackFX_SetPreset(selected_trk, 3, "DummyPreset")
end
Great -- thanks for clearing that up... simpler than I expected!
AudioBabble is offline   Reply With Quote
Old 06-05-2023, 11:21 PM   #1071
the19thbear
Human being with feelings
 
Join Date: Jan 2008
Posts: 281
Default

Is there a way to select a timeline and select all items on selected tracks, under the timeline selection?

Thanks

EDIT: Found it:
Item: Select all items in curre time selection.


Close enough
the19thbear is offline   Reply With Quote
Old 07-02-2023, 04:27 PM   #1072
Sid
Human being with feelings
 
Join Date: Apr 2018
Posts: 515
Default

Is there a way to get the name of the toolbar button that called the script?
__________________
Reaper v6.81 Windows 10
Sid is online now   Reply With Quote
Old 07-03-2023, 09:14 AM   #1073
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Quote:
Originally Posted by Sid View Post
Is there a way to get the name of the toolbar button that called the script?
No, there isn't.
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 07-03-2023, 10:19 AM   #1074
AZpercussion
Human being with feelings
 
Join Date: Oct 2019
Location: Moscow / Tbilisi
Posts: 909
Default

Quote:
Originally Posted by Meo-Ada Mespotine View Post
No, there isn't.
Maybe it's possible via detecting what placed under mouse?
AZpercussion is offline   Reply With Quote
Old 07-03-2023, 10:39 AM   #1075
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Quote:
Originally Posted by AZpercussion View Post
Maybe it's possible via detecting what placed under mouse?
Still no, as there's no Api to get it. The position of toolbar-buttons isn't accessible in any way.
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 07-03-2023, 09:59 PM   #1076
Sid
Human being with feelings
 
Join Date: Apr 2018
Posts: 515
Default

Quote:
Originally Posted by Meo-Ada Mespotine View Post
Still no, as there's no Api to get it. The position of toolbar-buttons isn't accessible in any way.
I see. Thank you.
__________________
Reaper v6.81 Windows 10
Sid is online now   Reply With Quote
Old 08-11-2023, 05:01 AM   #1077
thoricane
Human being with feelings
 
Join Date: Feb 2016
Posts: 1
Default Add pan to "more_me" web interface

Hi, wondering if anyone can help me add pan functionality to the more_me.html interface? I use this interface to control my bands IEM mixes (works really well!) and having pan as well as volume controls would be amazing. I think this is a big question so happy to be directed if this has been answered before, or to pointers how to code this - I am not great at it but will give it a shot
thoricane is offline   Reply With Quote
Old 09-17-2023, 01:44 AM   #1078
80icio
Human being with feelings
 
Join Date: Mar 2016
Location: Italy
Posts: 322
Default browse for directory dialog box

Is there a way to create a 'browse for directory dialog box' ?
I'd like to add it on a LUA script I'm working on for choosing the directory where to export a file from the script
80icio is offline   Reply With Quote
Old 09-17-2023, 01:49 AM   #1079
80icio
Human being with feelings
 
Join Date: Mar 2016
Location: Italy
Posts: 322
Default

Quote:
Originally Posted by thoricane View Post
Hi, wondering if anyone can help me add pan functionality to the more_me.html interface? I use this interface to control my bands IEM mixes (works really well!) and having pan as well as volume controls would be amazing. I think this is a big question so happy to be directed if this has been answered before, or to pointers how to code this - I am not great at it but will give it a shot
MikeKravets solved it right here
https://forum.cockos.com/showpost.ph...49&postcount=6
80icio is offline   Reply With Quote
Old 09-17-2023, 03:43 AM   #1080
AudioBabble
Human being with feelings
 
AudioBabble's Avatar
 
Join Date: Dec 2021
Location: Jupiter Island
Posts: 924
Default

Quote:
Originally Posted by 80icio View Post
Is there a way to create a 'browse for directory dialog box' ?
I'd like to add it on a LUA script I'm working on for choosing the directory where to export a file from the script
From reascript API:

Lua: integer retval, string folder = reaper.JS_Dialog_BrowseForFolder(string caption, string initialFolder)

There's also JS_Dialog_BrowseForOpenFiles

and

JS_Dialog_BrowseForSaveFile

EDIT, sorry just re-read your question -- JS_Dialog_BrowseForSaveFile is the one you want
__________________
{Read This} | {FR - FX inserts on sends} | {latest drivel}

Last edited by AudioBabble; 09-17-2023 at 03:50 AM.
AudioBabble 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 08:05 AM.


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