No internet connection
  1. Home
  2. How to

Create New Track from Send Menu on Selected Tracks Script Help

By Philip weinrobe @Philip_weinrobe
    2021-09-11 17:15:13.592Z

    hi everyone
    i'm new here and trying to do something i see lots of people poking at, but no one has posted a script that i can find that can do exactly what i'm looking for. i'm sure this would be helpful for a lot of people. here's what i'd love the script to do:

    From the MIX WINDOW

    1. i will select select multiple tracks then run a script that will....
    2. identify first open send across all selected tracks
    3. "new track" option from send output selection on the open send, selected from last track in selection so that the new aux track will be to the right of all selected tracks
    4. pop-up dialog to name the new aux track
    5. make the new aux track stereo
    6. insert plugin on insert B of new aux track, bring up search dialog to instantiate plug-in
    7. solo safe the new aux track
    8. expand the send on the selected tracks so i can quickly access the send faders
    9. return me to mix window with the original selected tracks selected and the newly created plugin window on top

    i think this is possible because i see lots of scripts that get really close. i am just so new to this platform i can't figure out how to write this myself yet. i've tried editing other scripts but keep getting stuck...anyone available to help? wouldn't this be cool! hahaaha.

    thank you!
    philip weinrobe
    brooklyn ny

    • 26 replies

    There are 26 replies. Estimated reading time: 35 minutes

    1. samuel henriques @samuel_henriques
        2021-09-11 23:25:03.506Z2021-09-15 09:39:22.190Z

        Hello @Philip_weinrobe,

        Try this, I didn't have the change to test it a lot, so let me know how it goes.
        I looked like you wanted to use a selected send, but it made more cense to create it and you can name it when you name the track ( the send gets the same name). It identifies the first free that is the same on all selected tracks and creates the send on that one. If you want it different let me know.
        When the new track win opens, the script will wait until you name the new aux and press Ok.
        When the search plugin opens, the script will wait until a new insert opens on the insert B.
        It works on edit or mix windows.

        Hope it helps

        Code updated Here:
        Create New Track from Send Menu on Selected Tracks Script Help #post-6

        1. P
          In reply toPhilip_weinrobe:
          Philip weinrobe @Philip_weinrobe
            2021-09-12 17:58:10.606Z

            this seems to work perfect! thank you so much
            i'm gonna use it on an actual mix now and see hot it goes....will report back!

            1. P
              In reply toPhilip_weinrobe:
              Philip weinrobe @Philip_weinrobe
                2021-09-14 02:56:55.614Z

                i was going crazy cause i couldn't figure out why this sometimes wouldn't work but now i figured it out:

                the script fails to run (no error pops up) if any of my sends are expanded AND that send is assigned.

                can you figure out why this is happening?

                1. P
                  In reply toPhilip_weinrobe:
                  Philip weinrobe @Philip_weinrobe
                    2021-09-14 03:05:47.782Z

                    another bug i just discovered:
                    though you can run the script from the mix window, the selected tracks must be visible on screen in the edit window for the script to run. is this correct? any way to make it work no matter what is visible in the edit window when targeted?

                    1. samuel henriques @samuel_henriques
                        2021-09-14 19:35:54.914Z2024-02-20 11:31:34.576Z

                        Here's a new version, I changed it a bit and fixed the failing when inserts were expanded.

                        The thing I'm still figuring, and need your help is the behaviour of the closing inserts and sends in the end.
                        If you always have the same inserts and sends view on both edit and mix windows, the script should be fine. But if you have different views, please explain how you use them so I can think of a solution.

                        About the moving to edit to do its thing, and going back to mix. It seams to be possible to do how you are asking, but because the edit and mix windows return completely different locations of the elements and have a fairly different behaviour, it would mean a complete and much more complex script just for the mix and this one just for the edit. And it could be much more unstable.

                        try this and let me know how it works.

                        
                        /**
                        * @param {string} sendAssignment
                        */
                        function assignToNewTrack(sendAssignment) {
                            const selectedTracks = sf.ui.proTools.selectedTrackNames
                            sf.ui.proTools.trackGetByName({ name: selectedTracks[selectedTracks.length - 1] }).track.groups.whoseTitle.is(getGroup("Sends", sendAssignment)).first.buttons.whoseTitle.is(`Send Assignment ${sendAssignment}`).first.popupMenuSelect({
                                isShift: true,
                                isOption: true,
                                menuPath: ["new track..."],
                            });
                        }
                        
                        function moveSendWinOutOfSlots() {
                            sf.ui.proTools.invalidate()
                        
                            const sendWin = sf.ui.proTools.mainTrackOutputWindow.elementWaitFor().element
                            const sendWinPos = sendWin.position.x
                            const sendSlots = sf.ui.proTools.selectedTrack.groups.whoseTitle.is("Inserts A-E").first
                            const sendSlotsPos = sendSlots.position.x
                        
                            if (sendWinPos - sendSlotsPos < 450 && sendSlotsPos - sendWinPos < 170) {
                                sendWin.windowMove({
                                    position: {
                                        y: sendWin.position.y,
                                        x: sendSlotsPos + 450
                                    }
                                })
                            }
                        }
                        
                        function getFirstFreeSend() {
                            const selectedTracks = sf.ui.proTools.selectedTrackHeaders
                            const sendLetters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
                            let sendAssignmentList = []
                            for (let i = 0; i < selectedTracks.length; i++) {
                                let trackInfo = sf.ui.proTools.trackGetByName({ name: selectedTracks[i].normalizedTrackName })
                                    .track.sendButtons.filter(x => x.value.invalidate().value != "unassigned").map(x => x.title.invalidate().value.split(" ")[2])
                                sendAssignmentList.push(...trackInfo)
                            }
                        
                            const firstFreeSend = sendLetters.filter(letter => sendAssignmentList.indexOf(letter) === -1)[0]
                        
                            if (firstFreeSend) {
                                return firstFreeSend
                            } else {
                                alert("Must have at least one free send, that is the same for all tracks.")
                                throw 0
                            };
                        };
                        
                        
                        /**
                        * @param {'Insert'|'Send'} slotType
                        * @param {array} [defaultUsedSlots] = [] - If parameter is not used, default is []
                        */
                        function getFirstFreeInsertOrSend(slotType, defaultUsedSlots) {
                        
                            let buttons
                            slotType == "Insert" ? buttons = "insertButtons" : buttons = "sendButtons"
                        
                            const selectedTracks = sf.ui.proTools.selectedTrackHeaders
                            const sendLetters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
                            let sendAssignmentList = defaultUsedSlots || []
                            try {
                                for (let i = 0; i < selectedTracks.length; i++) {
                                    let trackInfo = sf.ui.proTools.trackGetByName({ name: selectedTracks[i].normalizedTrackName })
                                        // .insertButtons or .sendButtons
                                        .track[buttons].filter(x => x.value.invalidate().value != "unassigned").map(x => x.title.invalidate().value.split(" ")[2])
                                    sendAssignmentList.push(...trackInfo)
                                }
                            } catch (err) { }
                            const firstFreeSend = sendLetters.filter(letter => sendAssignmentList.indexOf(letter) === -1)[0]
                        
                            if (firstFreeSend) {
                                return firstFreeSend
                            } else {
                                if (slotType == "Insert") { alert(`Must have at least one free ${slotType} slot.`) }
                                else if (slotType == "Send") { alert(`Must have at least one free ${slotType} slot, that is the same for selected tracks.`) }
                                throw 0
                            };
                        };
                        
                        
                        /**
                        * @param {string} sendLetter
                        * @param {'Inserts'|'Sends'} slotType
                        */
                        function getGroup(slotType, sendLetter) {
                            let group
                            sendLetter.toLowerCase().charCodeAt(0) - 97 <= 4 ? group = `${slotType} A-E` : group = `${slotType} F-J`
                            return group
                        }
                        
                        
                        
                        function newTrackSettings() {
                            const newTrackWin = sf.ui.proTools.windows.whoseTitle.is("New Track").first.elementWaitFor().element
                        
                            const format = newTrackWin.popupButtons.whoseTitle.is("Stereo").first
                            const type = newTrackWin.popupButtons.whoseTitle.is("Aux Input").first
                            const timeBase = newTrackWin.popupButtons.whoseTitle.is("Samples").first
                        
                            if (format.value.invalidate().value != "Stereo") { format.popupMenuSelect({ menuPath: ["Stereo"] }); }
                            if (type.value.invalidate().value != "Aux Input") { type.popupMenuSelect({ menuPath: ["Aux Input"] }); }
                            if (timeBase.value.invalidate().value != "Samples") { timeBase.popupMenuSelect({ menuPath: ["Samples"] }); }
                        
                            newTrackWin.checkBoxes.whoseTitle.is("Create next to current track").first.checkboxSet({ targetValue: "Enable" });
                        
                            //  Wait to name track and press ok
                            newTrackWin.elementWaitFor({ waitType: "Disappear", timeout: -1 })
                            sf.ui.proTools.invalidate()
                        }
                        
                        /**
                         * @param {'Enable'|'Disable'} targetValue
                         * @param {array} [viewsNames] = [] - If parameter is not used, default is set inside
                         */
                        function setWindowViews(targetValue, viewsNames) {
                            let views = viewsNames || ["Inserts A-E", "Inserts F-J", "Sends A-E", "Sends F-J"]
                        
                            views.forEach(view => {
                                sf.ui.proTools.menuClick({ menuPath: ["View", "Edit Window Views", view], targetValue: targetValue })
                                // sf.ui.proTools.menuClick({ menuPath: ["View", "Mix Window Views", view], targetValue: targetValue })
                            })
                        }
                        
                        
                        const getSelectedTrackOut = (trackName) => sf.ui.proTools.trackGetByName({ name: trackName }).track.outputPathButton.title.invalidate().value.split('\n')[1].trim();
                        
                        
                        
                        let insertSlot
                        let firstFreeSend
                        function actions() {
                        
                            const originalSelectedTracks = sf.ui.proTools.selectedTrackNames
                        
                            // Save first selected track output on variable
                            const firstSelectedOut = getSelectedTrackOut(originalSelectedTracks[0])
                        
                            //  Get free sends
                            firstFreeSend = getFirstFreeInsertOrSend("Send")
                        
                            // Assign new send to new track
                            assignToNewTrack(firstFreeSend)
                        
                            // New track setting and wait for track name
                            newTrackSettings()
                        
                            // If new send win is blocking the inserts or sends, move win away
                            moveSendWinOutOfSlots()
                        
                            // Expand created send
                            sf.ui.proTools.menuClick({ menuPath: ["View", "Expanded Sends", `Send ${firstFreeSend}`], targetValue: "Enable" })
                        
                            // Solo safe new Aux
                            const selectedTracks = sf.ui.proTools.selectedTrackNames
                            const auxTrack = sf.ui.proTools.trackGetByName({ name: selectedTracks[selectedTracks.length - 1] }).track
                            auxTrack.trackSelect()
                            auxTrack.trackScrollToView()
                            auxTrack.buttons.whoseTitle.is("Solo").first.mouseClickElement({ isCommand: true })
                        
                            // set new aux output
                            if (getSelectedTrackOut(auxTrack.normalizedTrackName) != firstSelectedOut) {
                                auxTrack.trackOutputSelect({ outputSelector: items => items.filter(item => item.element.title.value.includes(firstSelectedOut))[0] })
                            }
                        
                            // Get free insert slot after A
                            insertSlot = getFirstFreeInsertOrSend("Insert", ["A"])
                        
                        
                            // Open search...
                            auxTrack.groups.whoseTitle.is(getGroup("Inserts", insertSlot)).first
                                .buttons.whoseTitle.is(`Insert Assignment ${insertSlot}`)
                                .first.popupMenuSelect({
                                    menuPath: ["search..."],
                                });
                        
                        
                            // Wait to open new plug
                            while (true) {
                                const plugIsOpen = auxTrack.groups.whoseTitle.is(getGroup("Inserts", insertSlot)).first
                                    .buttons.whoseTitle.is(`Insert Assignment ${insertSlot}`).first
                                    .value.invalidate().value != "unassigned"
                        
                                if (!plugIsOpen) {
                                    sf.wait({ intervalMs: 1000 })
                                } else {
                                    break;
                                }
                            }
                            sf.ui.proTools.trackSelectByName({ names: originalSelectedTracks })
                        }
                        
                        
                        
                        
                        function main() {
                        
                            sf.ui.proTools.appActivateMainWindow();
                            sf.ui.proTools.invalidate();
                        
                            // const isActiveInsGroupFMix = sf.ui.proTools.getMenuItem("View", "Mix Window Views", "Inserts F-J").isMenuChecked
                            const isActiveInsGroupFEdit = sf.ui.proTools.getMenuItem("View", "Edit Window Views", "Inserts F-J").isMenuChecked
                        
                            // const isActiveSendGroupFMix = sf.ui.proTools.getMenuItem("View", "Mix Window Views", "Sends F-J").isMenuChecked
                            const isActiveSendGroupFEdit = sf.ui.proTools.getMenuItem("View", "Edit Window Views", "Sends F-J").isMenuChecked
                        
                        
                            const isEditWin = sf.ui.proTools.focusedWindow.title.value.startsWith("Edit")
                            if (!isEditWin) { sf.ui.proTools.menuClick({ menuPath: ["Window", "Edit"] }) }
                        
                            // Close expand created sends
                            sf.ui.proTools.menuClick({ menuPath: ["View", "Expanded Sends", "None"], targetValue: "Enable" })
                        
                            setWindowViews("Enable")
                        
                            try {
                                actions()
                            } catch (err) { throw err }
                            finally {
                        
                                //  Go to mix if needed
                                if (!isEditWin) { sf.ui.proTools.menuClick({ menuPath: ["Window", "Mix"] }) }
                        
                                // Close Inserts Views if not needed
                                if (insertSlot.toLowerCase().charCodeAt(0) - 97 <= 4 && (/* !isActiveInsGroupFMix || */ !isActiveInsGroupFEdit)) {
                                    // if (!isActiveInsGroupFMix) { setWindowViews("Disable", ["Inserts F-J"]) }
                                    if (!isActiveInsGroupFEdit) { setWindowViews("Disable", ["Inserts F-J"]) }
                                }
                        
                        
                                // Close Sends F-J if not needed
                                if (firstFreeSend.toLowerCase().charCodeAt(0) - 97 <= 4 && (/* !isActiveSendGroupFMix || */ !isActiveSendGroupFEdit)) {
                                    //  if (!isActiveSendGroupFMix) { setWindowViews("Disable", ["Sends F-J"]) }
                                    if (!isActiveSendGroupFEdit) { setWindowViews("Disable", ["Sends F-J"]) }
                                }
                        
                            }
                        }
                        
                        main()
                        
                        
                        
                        
                        1. samuel henriques @samuel_henriques
                            2021-10-03 23:30:56.509Z

                            UPDATED above,

                            Fixed an error, if the first selected track had mono output, it wouldn't find the correct out on the new Aux and fail.

                            Cleaned it a bit but left the parts to change view on mix window, if someone needs it in the future.

                            1. JJordan Oorebeek @Jordan_Oorebeek
                                2024-02-04 04:18:43.446Z

                                Hey!

                                I've just discovered this script and was wondering how one would modify it so it doesn't include the "open plugin" on the new aux. So the script would be complete as soon as the new aux was created and routing matched the the sending track's output. Also the only other question would be how would you make the new aux bypass the solo (solo safe)?

                                Sorry to dig up an old thread but this is an incredibly useful script. I've seen another one in a package but it only does mono sends.

                                1. samuel henriques @samuel_henriques
                                    2024-02-20 11:41:50.199Z

                                    Hello Jordan,

                                    Sure,
                                    Make sure the line numbers on the posted script line up with the lines on you pasted script.
                                    You can comment out lines of code by typing // at the start of the lines.
                                    To remove the solo safe comment line 162
                                    To remove the open plugin part comment from line 174 to 194

                                    Hope this is it.

                            2. P
                              In reply toPhilip_weinrobe:
                              Philip weinrobe @Philip_weinrobe
                                2021-09-14 21:12:12.737Z

                                ok, this is working amazing!!
                                the last thing i'd want to do is:

                                • newly created aux track to inherit the same output path as the first track in the originally selected tracks

                                possible?
                                this is really amazing. thank you

                                1. P
                                  In reply toPhilip_weinrobe:
                                  Philip weinrobe @Philip_weinrobe
                                    2021-09-15 00:12:52.716Z

                                    i generally only have A-E open on both mix and edit, since i try to keep myself to 5 plugins and 5 sends per track. sometimes i need to go over and when i do will generally have the same inserts/sends open on both mix and edit

                                    1. samuel henriques @samuel_henriques
                                        2021-09-15 10:59:32.529Z

                                        UPDATED ABOVE: now it will set the new aux out, the same as the first selected track.

                                        As for the views, as it is now, it will open all sends and inserts and close them if they are not needed, or not close them if they were opened on edit or mix.

                                      • P
                                        In reply toPhilip_weinrobe:
                                        Philip weinrobe @Philip_weinrobe
                                          2021-09-20 14:59:32.922Z

                                          this is amazing. thank you deeply

                                          1. P
                                            In reply toPhilip_weinrobe:
                                            Philip weinrobe @Philip_weinrobe
                                              2021-09-21 17:29:04.422Z

                                              ah, found one more bug:
                                              if there is a send in slot A, the process fails. can we make it just use the first available send slot?
                                              thank you!

                                              1. P
                                                In reply toPhilip_weinrobe:
                                                Philip weinrobe @Philip_weinrobe
                                                  2021-09-21 18:05:20.743Z

                                                  it still seems to leave f-j open on both sends and inserts...hmmm.
                                                  maybe this is not possible to close?

                                                  1. samuel henriques @samuel_henriques
                                                      2021-09-21 20:19:59.097Z

                                                      Hey Philip,

                                                      Not getting the error if slot A is used. But noticed that the send window, when it opens can get on top of the inserts, and in that case, it will fail. I'll try to find a solution.
                                                      Send me the error with the line so I try to find it.

                                                      About the F-J, if they are open before you start the script, they wont close. They only close if they were not open and the send or insert didn't use any F-J. Are you getting a different behaviour?

                                                    • P
                                                      In reply toPhilip_weinrobe:
                                                      Philip weinrobe @Philip_weinrobe
                                                        2021-09-21 20:24:24.748Z

                                                        F-J: yes, it's just opening and staying open even if they weren't open at start of script run.
                                                        roger that on the first error, couldn't repeat it just now. will let you know when/if happens again!

                                                        1. samuel henriques @samuel_henriques
                                                            2021-09-21 21:20:19.492Z

                                                            Updated above,

                                                            Now, If the new send window opens and covers the track header, inserts, sends or i/o, the window will be moved away.

                                                            Removed code for opening and closing the sends and inserts on the mix window. Only the edit widow will change now, with the same rules (I hope).

                                                            There are a few commented bits on the code, just so you test it, I'll clean it later.

                                                            Let me know how it goes.

                                                          • P
                                                            In reply toPhilip_weinrobe:
                                                            Philip weinrobe @Philip_weinrobe
                                                              2021-09-22 14:46:15.406Z

                                                              initial testing is positive! will let you know if anything pops up. thank you!

                                                              1. J
                                                                In reply toPhilip_weinrobe:
                                                                JP Ruggieri @JP_Ruggieri
                                                                  2021-09-28 03:48:37.639Z

                                                                  Is there anyway to edit this script so instead of the audio tracks having sends in them, their output was routed to the new aux track?

                                                                  1. PPhilip weinrobe @Philip_weinrobe
                                                                      2021-09-28 12:10:49.532Z

                                                                      i requested this and a few people were helping with one but i haven't seen one that works as solidly as this script yet...

                                                                      1. JJP Ruggieri @JP_Ruggieri
                                                                          2021-09-28 13:04:16.429Z

                                                                          Keep me in the loop! That would be a great one

                                                                          1. samuel henriques @samuel_henriques
                                                                              2021-10-03 23:43:50.911Z

                                                                              Hey JP, are you looking to

                                                                              • route selected tracks to new track...
                                                                              • select aux stereo and wait for operator input and press ok
                                                                              • open search on insert 1 of new aux
                                                                              • and working from edit or mix?

                                                                              Could you make a new thread, please, this is fairly different.
                                                                              I think I'll have a bit tomorrow to have a go at it.

                                                                              1. JJP Ruggieri @JP_Ruggieri
                                                                                  2021-10-05 00:52:43.449Z

                                                                                  Sure thing will do!

                                                                          2. E
                                                                            In reply toPhilip_weinrobe:
                                                                            Eli Crews @Eli_Crews
                                                                              2025-02-25 15:12:39.708Z

                                                                              Hello all, I'm trying to modify this script for my own purposes, which really just entails changing the slot for both the send on the initial track, and the insert on the created aux. Can you tell me how to make this send from slot F instead of A, and have the insert show up in slot H instead of A? I treid changing line 169 to H for the second one of those, but that didn't worek. Here's the exact script I'm working with, thanks!:

                                                                              /**

                                                                              • @param {string} sendAssignment
                                                                                */
                                                                                function assignToNewTrack(sendAssignment) {
                                                                                const selectedTracks = sf.ui.proTools.selectedTrackNames
                                                                                sf.ui.proTools.trackGetByName({ name: selectedTracks[selectedTracks.length - 1] }).track.groups.whoseTitle.is(getGroup("Sends", sendAssignment)).first.buttons.whoseTitle.is(Send Assignment ${sendAssignment}).first.popupMenuSelect({
                                                                                isShift: true,
                                                                                isOption: true,
                                                                                menuPath: ["new track..."],
                                                                                });
                                                                                }

                                                                              function moveSendWinOutOfSlots() {
                                                                              sf.ui.proTools.invalidate()

                                                                              const sendWin = sf.ui.proTools.mainTrackOutputWindow.elementWaitFor().element
                                                                              const sendWinPos = sendWin.position.x
                                                                              const sendSlots = sf.ui.proTools.selectedTrack.groups.whoseTitle.is("Inserts A-E").first
                                                                              const sendSlotsPos = sendSlots.position.x
                                                                              
                                                                              if (sendWinPos - sendSlotsPos < 450 && sendSlotsPos - sendWinPos < 170) {
                                                                                  sendWin.windowMove({
                                                                                      position: {
                                                                                          y: sendWin.position.y,
                                                                                          x: sendSlotsPos + 450
                                                                                      }
                                                                                  })
                                                                              }
                                                                              

                                                                              }

                                                                              function getFirstFreeSend() {
                                                                              const selectedTracks = sf.ui.proTools.selectedTrackHeaders
                                                                              const sendLetters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
                                                                              let sendAssignmentList = []
                                                                              for (let i = 5; i < selectedTracks.length; i++) {
                                                                              let trackInfo = sf.ui.proTools.trackGetByName({ name: selectedTracks[i].normalizedTrackName })
                                                                              .track.sendButtons.filter(x => x.value.invalidate().value != "unassigned").map(x => x.title.invalidate().value.split(" ")[2])
                                                                              sendAssignmentList.push(...trackInfo)
                                                                              }

                                                                              const firstFreeSend = sendLetters.filter(letter => sendAssignmentList.indexOf(letter) === -1)[0]
                                                                              
                                                                              if (firstFreeSend) {
                                                                                  return firstFreeSend
                                                                              } else {
                                                                                  alert("Must have at least one free send, that is the same for all tracks.")
                                                                                  throw 0
                                                                              };
                                                                              

                                                                              };

                                                                              /**

                                                                              • @param {'Insert'|'Send'} slotType

                                                                              • @param {array} [defaultUsedSlots] = [] - If parameter is not used, default is []
                                                                                */
                                                                                function getFirstFreeInsertOrSend(slotType, defaultUsedSlots) {

                                                                                let buttons
                                                                                slotType == "Insert" ? buttons = "insertButtons" : buttons = "sendButtons"

                                                                                const selectedTracks = sf.ui.proTools.selectedTrackHeaders
                                                                                const sendLetters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
                                                                                let sendAssignmentList = defaultUsedSlots || []
                                                                                try {
                                                                                for (let i = 0; i < selectedTracks.length; i++) {
                                                                                let trackInfo = sf.ui.proTools.trackGetByName({ name: selectedTracks[i].normalizedTrackName })
                                                                                // .insertButtons or .sendButtons
                                                                                .track[buttons].filter(x => x.value.invalidate().value != "unassigned").map(x => x.title.invalidate().value.split(" ")[2])
                                                                                sendAssignmentList.push(...trackInfo)
                                                                                }
                                                                                } catch (err) { }
                                                                                const firstFreeSend = sendLetters.filter(letter => sendAssignmentList.indexOf(letter) === -1)[0]

                                                                                if (firstFreeSend) {
                                                                                return firstFreeSend
                                                                                } else {
                                                                                if (slotType == "Insert") { alert(Must have at least one free ${slotType} slot.) }
                                                                                else if (slotType == "Send") { alert(Must have at least one free ${slotType} slot, that is the same for selected tracks.) }
                                                                                throw 0
                                                                                };
                                                                                };

                                                                              /**

                                                                              • @param {string} sendLetter
                                                                              • @param {'Inserts'|'Sends'} slotType
                                                                                */
                                                                                function getGroup(slotType, sendLetter) {
                                                                                let group
                                                                                sendLetter.toLowerCase().charCodeAt(0) - 97 <= 4 ? group = ${slotType} A-E : group = ${slotType} F-J
                                                                                return group
                                                                                }

                                                                              function newTrackSettings() {

                                                                              const newTrackWin = sf.ui.proTools.windows.whoseTitle.is("New Track").first.elementWaitFor().element
                                                                              
                                                                              ///  Popup butons to variables
                                                                              const [type, timeBase, format] = newTrackWin.popupButtons.map(x => x)
                                                                              
                                                                              if (format.title.invalidate().value != "Stereo") { format.popupMenuSelect({ menuPath: ["Stereo"] }); }
                                                                              if (type.title.invalidate().value != "Aux Input") { type.popupMenuSelect({ menuPath: ["Aux Input"] }); }
                                                                              if (timeBase.title.invalidate().value != "Samples") { timeBase.popupMenuSelect({ menuPath: ["Samples"] }); }
                                                                              
                                                                              newTrackWin.checkBoxes.whoseTitle.is("Create next to current track").first.checkboxSet({ targetValue: "Enable" });
                                                                              
                                                                              //  Wait to name track and press ok
                                                                              newTrackWin.elementWaitFor({ waitType: "Disappear", timeout: -1 })
                                                                              sf.ui.proTools.invalidate()
                                                                              

                                                                              }

                                                                              /**

                                                                              • @param {'Enable'|'Disable'} targetValue

                                                                              • @param {array} [viewsNames] = [] - If parameter is not used, default is set inside
                                                                                */
                                                                                function setWindowViews(targetValue, viewsNames) {
                                                                                let views = viewsNames || ["Inserts A-E", "Inserts F-J", "Sends A-E", "Sends F-J"]

                                                                                views.forEach(view => {
                                                                                sf.ui.proTools.menuClick({ menuPath: ["View", "Edit Window Views", view], targetValue: targetValue })
                                                                                // sf.ui.proTools.menuClick({ menuPath: ["View", "Mix Window Views", view], targetValue: targetValue })
                                                                                })
                                                                                }

                                                                              const getSelectedTrackOut = (trackName) => sf.ui.proTools.trackGetByName({ name: trackName }).track.outputPathButton.title.invalidate().value.split('\n')[1].trim();

                                                                              let insertSlot
                                                                              let firstFreeSend
                                                                              function actions() {

                                                                              const originalSelectedTracks = sf.ui.proTools.selectedTrackNames
                                                                              
                                                                              // Save first selected track output on variable
                                                                              const firstSelectedOut = getSelectedTrackOut(originalSelectedTracks[0])
                                                                              
                                                                              //  Get free sends
                                                                              firstFreeSend = getFirstFreeInsertOrSend("Send")
                                                                              
                                                                              // Assign new send to new track
                                                                              assignToNewTrack(firstFreeSend)
                                                                              
                                                                              // New track setting and wait for track name
                                                                              newTrackSettings()
                                                                              
                                                                              // If new send win is blocking the inserts or sends, move win away
                                                                              moveSendWinOutOfSlots()
                                                                              
                                                                              // Expand created send
                                                                              sf.ui.proTools.menuClick({ menuPath: ["View", "Expanded Sends", `Send ${firstFreeSend}`], targetValue: "Enable" })
                                                                              
                                                                              // Solo safe new Aux
                                                                              const selectedTracks = sf.ui.proTools.selectedTrackNames
                                                                              const auxTrack = sf.ui.proTools.trackGetByName({ name: selectedTracks[selectedTracks.length - 1] }).track
                                                                              auxTrack.trackSelect()
                                                                              auxTrack.trackScrollToView()
                                                                              auxTrack.buttons.whoseTitle.is("Solo").first.mouseClickElement({ isCommand: true })
                                                                              
                                                                              // set new aux output
                                                                              if (getSelectedTrackOut(auxTrack.normalizedTrackName) != firstSelectedOut) {
                                                                                  auxTrack.trackOutputSelect({ outputSelector: items => items.filter(item => item.element.title.value.includes(firstSelectedOut))[0] })
                                                                              }
                                                                              
                                                                              // Get free insert slot after H
                                                                              insertSlot = getFirstFreeInsertOrSend("Insert", ["H"])
                                                                              
                                                                              
                                                                              // Open search...
                                                                              auxTrack.groups.whoseTitle.is(getGroup("Inserts", insertSlot)).first
                                                                                  .buttons.whoseTitle.is(`Insert Assignment ${insertSlot}`)
                                                                                  .first.popupMenuSelect({
                                                                                      menuPath: ["search..."],
                                                                                  });
                                                                              
                                                                              
                                                                              // Wait to open new plug
                                                                              while (true) {
                                                                                  const plugIsOpen = auxTrack.groups.whoseTitle.is(getGroup("Inserts", insertSlot)).first
                                                                                      .buttons.whoseTitle.is(`Insert Assignment ${insertSlot}`).first
                                                                                      .value.invalidate().value != "unassigned"
                                                                              
                                                                                  if (!plugIsOpen) {
                                                                                      sf.wait({ intervalMs: 1000 })
                                                                                  } else {
                                                                                      break;
                                                                                  }
                                                                              }
                                                                              sf.ui.proTools.trackSelectByName({ names: originalSelectedTracks })
                                                                              

                                                                              }

                                                                              function main() {

                                                                              sf.ui.proTools.appActivateMainWindow();
                                                                              sf.ui.proTools.invalidate();
                                                                              
                                                                              const isActiveInsGroupFEdit = sf.ui.proTools.getMenuItem("View", "Edit Window Views", "Inserts F-J").isMenuChecked
                                                                              
                                                                              const isActiveSendGroupFEdit = sf.ui.proTools.getMenuItem("View", "Edit Window Views", "Sends F-J").isMenuChecked
                                                                              
                                                                              
                                                                              const isEditWin = sf.ui.proTools.focusedWindow.title.value.startsWith("Edit")
                                                                              if (!isEditWin) { sf.ui.proTools.menuClick({ menuPath: ["Window", "Edit"] }) }
                                                                              
                                                                              // Close expand created sends
                                                                              sf.ui.proTools.menuClick({ menuPath: ["View", "Expanded Sends", "None"], targetValue: "Enable" })
                                                                              
                                                                              setWindowViews("Enable")
                                                                              
                                                                              try {
                                                                                  actions()
                                                                              } catch (err) { }
                                                                              finally {
                                                                              
                                                                                  //  Go to mix if needed
                                                                                  if (!isEditWin) { sf.ui.proTools.menuClick({ menuPath: ["Window", "Mix"] }) }
                                                                              
                                                                                  if (insertSlot) {
                                                                                      // Close Inserts Views if not needed
                                                                                      if (insertSlot.toLowerCase().charCodeAt(0) - 97 <= 4 && (!isActiveInsGroupFEdit)) {
                                                                                          if (!isActiveInsGroupFEdit) { setWindowViews("Disable", ["Inserts F-J"]) }
                                                                                      }
                                                                                  }
                                                                              
                                                                                  if (firstFreeSend) {
                                                                                      // Close Sends F-J if not needed
                                                                                      if (firstFreeSend.toLowerCase().charCodeAt(0) - 97 <= 4 && (!isActiveSendGroupFEdit)) {
                                                                                          if (!isActiveSendGroupFEdit) { setWindowViews("Disable", ["Sends F-J"]) }
                                                                                      }
                                                                                  }
                                                                              }
                                                                              

                                                                              }

                                                                              main()

                                                                              1. EEli Crews @Eli_Crews
                                                                                  2025-02-25 15:13:19.659Z

                                                                                  Oops that formatting got messed up so you can't see my line numbers, maybe it's readable anyhow?

                                                                                  1. EEli Crews @Eli_Crews
                                                                                      2025-02-25 15:13:51.831Z

                                                                                      Is there a better way to post long scripts that I don't know about?