1 2 Previous Next 57 Replies Latest reply on Mar 12, 2018 1:52 PM by JJMack

    Photoshop CC 2015 changes to scripting

    matias.kiviniemi Level 3

      It's again the time of year that Adobe releases a new version with some new "features" so I was thinking we should share issues to minimize time on debugger

       

      • Greatly improved Javascript performance, I'd say at least 2-3x improvement in my scripts, Kudos Adobe
      • Dialogs are much more responsive and change updates immediatelly. However in my end loop (waiting for user to click OK) dialog became unresponsive and hanged Photoshop. Needed to add app.refresh() in the loop (but don't use in script as it has great performance impact).

       

      So far looking looking good, but please share if you discover some changes

        • 1. Re: Photoshop CC 2015 changes to scripting
          xbytor2 Level 4

          Notes on PS2015/JS:

          - The underlying UI engine has changed which is the reason for all that is new and/or different.

          - ScriptUI is very much faster. Not sure about the actual DOM side.

          - Some script's UIs will break. I have some serious issues RadioButtons. [Reported]

          - UI widgets have been 'adjusted' which means layout will be off a bit or a lot depending on what you are doing. Auto-layout may or may not be affected.

          - Centering palette windows with multiple monitors centers relative to the bounding box of the monitors, not to the active/current monitor. [Reported]

          - I have a version of Image Processor Pro in development that will crash PS after running the script and simply hitting the Cancel button.

            This appears to be happening as the window is being deconstructed. This only happens on Win7. [Reported]

           

          - There may still be JS syntax or runtime errors that are not recognized. By this, I mean the script just terminates without an error dialog. [Reported]

          Ex:

          if (|| true) {
            alert('true');
          }
          
          

           

          will (occasionally) run without incident but throw an error on CC2014 and CS6.

           

          I've filed bugs for all of these and the good people at Adobe are aware of them.

           

          If anybody finds additional bugs, please post them in this thread and report them here: Adobe - Feature Request/Bug Report Form

           

          Edited for clarity.

          • 2. Re: Photoshop CC 2015 changes to scripting
            Chuck Uebele Adobe Community Professional & MVP

            I was having issue with radio buttons too. They would not work unless they were in a group. I got a note that said that it was fixed, but haven't checked yet. the new UI size does mess up some of my scripts. Would love to have a scroll bar on the UI.

            • 3. Re: Photoshop CC 2015 changes to scripting
              DBarranca Level 4

              Don't forget the new Mondo rendering engine for Scripts!!

              ---

              (Ops, had the message window open for a long time and posted this not noticing it's been already mentioned in the thread. I'll be collecting Mondo discrepancies vs the previous ScriptUI engine and report here!)

               

              Davide Barranca

              • 4. Re: Photoshop CC 2015 changes to scripting
                DBarranca Level 4

                Speaking of Mondo, JPGs can't be loaded anymore in ScriptUI dialogs:

                 

                var w = new Window ("dialog", "Bouquet");
                var flowers = w.add ("image", undefined, File ("~/Desktop/Fiore.jpg"));
                w.show ();
                

                 

                Invalid Image Data error - only PNGs - hopefully this is going to be fixed.

                 

                Davide

                • 5. Re: Photoshop CC 2015 changes to scripting
                  Chuck Uebele Adobe Community Professional & MVP

                  Umm, I've always used pngs, just for the transparency.

                  • 6. Re: Photoshop CC 2015 changes to scripting
                    JJMack Most Valuable Participant

                    Adobe documented something in what new on that.

                    Photoshop Help | Photoshop UI toolkit for plug-ins and scripts

                     

                    UI Layout

                     

                    There are no changes in the scripting APIs for creating user interfaces. However, there is a difference in the way the grouping widget works.

                    In Flex, the “group” widget used to act as layout mechanism for grouping widgets and used to be completely invisible itself. Now, “group” is itself a widget with its own background and can’t overlap with other widgets.

                    For instance, if we have two groups arranged one over the other with widgets in each group such that widgets from one group do not overlap with widgets in the other group, all widgets are visible in Flex.

                     

                    Group widget - Flex

                     


                    However, in the new framework, in the same scenario, the group at the top hides the group at the bottom.

                     

                    Group widget - New framework

                     


                     

                    Note:

                    Some users may find that their existing scripts have incorrect UI layout in the new framework because of this same reason. All such scripts should be modified by removing overlaps in the “group” widgets. Scripts created afresh in the new framework or modified to run in it work fine in Flex as well.

                    • 7. Re: Photoshop CC 2015 changes to scripting
                      matias.kiviniemi Level 3

                      Does anyone know if it's possible to change Eclipse to install for CC2015 (and not the default CC2012 32bit)? I face personal development process issue with AEM no longer working with CC2015 (CEP folder missing). I.e. normally I use the Eclipse Ctrl+F11 to update .html/.js/.jsx for quick iterations and then build a zxp when ready for more version testing. But if I'm to develop CC2015-only stuff can't use Eclipse and with no AEM I'd need to upload a test build to Add-ons.I guess there's always manual copying the stuff (any good links exactly what needs to go where)?

                      • 8. Re: Photoshop CC 2015 changes to scripting
                        DBarranca Level 4

                        Hi Matias,

                        you should be able to change the Eclipse preferences > Adobe Extension Builder 3 > CC Launching Paths > Service Manager

                        (put /Library/Application Support/Adobe/CEP/).

                        For Extensions, I've put together a CC2015 Survival Guide that might be of some help.

                        Regards,

                         

                        Davide

                        • 9. Re: Photoshop CC 2015 changes to scripting
                          Rune L-H Level 1

                          So far I've run into these issues:

                           

                          - Photoshop CC2015 on Win7 crashes instantly when an extension runs a jsx to draw a window or palette using script UI. The same script works perfect when being run from ExtendScript instead of from the extension. Also, if I just briefly run any script that draws a script UI window (either from ExtendScript or from File->Scripts) then the extension works without any crashes... until next time PS is restarted. Vote for the support ticket here: PS CC2015 (win7) crashes instantly when extension uses script UI

                           

                          - Seems there is a change in what kind of error dialogs are shown. Stdlib.convertToSmartLayer() now results in an error saying "The object 'layer 394 of document 5932' is not currently available". This is caused in Stdlib.wrapLCLayer() when it tries to reselect the layer and it's not available. It can be avoided by using app.displayDialogs = DialogModes.NO

                           

                          / Rune

                          • 10. Re: Photoshop CC 2015 changes to scripting
                            xbytor2 Level 4

                            A similar problem popped up a few versions ago which was solved by adding an app.refresh() or Stdlib.waitForRedraw(). I'll add an exception handler in and put your DialogModes.NO work-around in wrapLCLayer.

                             

                            I'll do a push of xtools to the CVS tree on SourceForge later this week and a full release after the dust settles on the PS/CC2015 release. I've already dropped in changes for CC2015 elsewhere in xtools that will be included in that refresh.

                            • 11. Re: Photoshop CC 2015 changes to scripting
                              xbytor2 Level 4

                              I pushed my current xtools environment out to SourceForge that includes the wrapLCLayer() fix and all of my CC2015 and other mods. I'll packaged up a beta zip later in the week.

                              • 12. Re: Photoshop CC 2015 changes to scripting
                                Silver Back Gorilla Level 1

                                Only tested on Win 7.....

                                 

                                window.location doesn't work for any of my dialogs.   It centers the window regardless of the coordinates.

                                 

                                window.location still works on palettes though

                                • 13. Re: Photoshop CC 2015 changes to scripting
                                  Silver Back Gorilla Level 1

                                  Again, only tested on Win 7....

                                   

                                  graphics.font = ScriptUI.newFont  isn't working.  The font will display default size and font style.

                                  • 14. Re: Photoshop CC 2015 changes to scripting
                                    Chuck Uebele Adobe Community Professional & MVP

                                    graphics.font = ScriptUI.newFont  isn't working.  The font will display default size and font style.

                                     

                                    That's a bummer! i was thinking of using that due to the new UI size.

                                    • 15. Re: Photoshop CC 2015 changes to scripting
                                      y.fujisawa Level 1

                                      Window.find('xxxx').close() doesn't work on my code.

                                      • 16. Re: Photoshop CC 2015 changes to scripting
                                        Andreas Jansson Level 2

                                        Photoshop object model disappeared from the Object Model Viewer ( OMV) for me, when installing Photoshop 2015. Is that the case for other scripters? Please open ExtendScript ToolKit CC and check for Photoshop in the list.

                                        Also see: Photoshop missing in Object Model Viewer (ExtendScript ToolKit CC) after installing 2015 CC for a screen shot.

                                        • 17. Re: Photoshop CC 2015 changes to scripting
                                          Rune L-H Level 1

                                          CC2015 also seems to have broken ScriptUI.environment.keyboardState.

                                          Reported here: Photoshop CC2015 has broken Script UI Keyboard state object

                                          • 18. Re: Photoshop CC 2015 changes to scripting
                                            Chuck Uebele Adobe Community Professional & MVP

                                            Were eventlisteners mentioned? I've got one attached to a tabbed panel that controls all the enable features of the the various checkboxes etc. That's not working.

                                            • 19. Re: Photoshop CC 2015 changes to scripting
                                              JSinha

                                              Hi Rune,

                                              I am facing the same issue of Photoshop crashing when we try to create a palette from within an extension. Did you hear back from Adobe on the fix for this issue?

                                               

                                              Thanks.

                                              • 20. Re: Photoshop CC 2015 changes to scripting
                                                JJMack Most Valuable Participant

                                                In my PastImageRoll script I used code I took from Mike Hale web post for handling keyboard events.   The code does not seemed to be triggered in CC 2015.

                                                 

                                                It was like the handlers that are in the Fit Image plug-in sctipt that have been commented out since CS6.   They work for me in PasteImageRoll up to CC 2015 but not in CC 2015.

                                                 

                                                // do not allow anything except for numbers 0-9

                                                RollPaperDialog.PrintResPnl.docResEdt.addEventListener ('keydown', NumericEditKeyboardHandler);

                                                RollPaperDialog.PrintResPnl.imgCpysEdt.addEventListener ('keydown', NumericEditKeyboardHandler);

                                                RollPaperDialog.PaperSizePnl.aspectWidthEdt.addEventListener ('keydown', DesmalEditKeyboardHandler);

                                                RollPaperDialog.PaperSizePnl.aspectHeightEdt.addEventListener ('keydown', DesmalEditKeyboardHandler);

                                                RollPaperDialog.CellSizePnl.aspectWidthEdt.addEventListener ('keydown', DesmalEditKeyboardHandler);

                                                RollPaperDialog.CellSizePnl.aspectHeightEdt.addEventListener ('keydown', DesmalEditKeyboardHandler);

                                                RollPaperDialog.GroutSizePnl.aspectWidthEdt.addEventListener ('keydown', DesmalEditKeyboardHandler);

                                                RollPaperDialog.GroutSizePnl.aspectHeightEdt.addEventListener ('keydown', DesmalEditKeyboardHandler);

                                                 

                                                Seems there are many things like this commented out in Adobe scripts supplied with Photoshop.  In contactsheetII   I see X now use code like this make me almost want to learn scripting

                                                 

                                                //

                                                // Function: addNumericFilter

                                                // Description: Adds a numeric keystroke filter to a widget

                                                // Input:  obj - UI widget

                                                // Return: <none>

                                                //

                                                ContactSheetUI.addNumericFilter = function(obj) {

                                                  obj.keyFilter = /\d/;

                                                  obj.addEventListener('keydown', ContactSheetUI.filterKey);

                                                };

                                                 

                                                 

                                                //

                                                // Function: addNumberFilter

                                                // Description: Adds a number/localized-decimal-point keystroke filter

                                                // Input:  obj - UI widget

                                                // Return: <none>

                                                //

                                                ContactSheetUI.addNumberFilter = function(obj) {

                                                  obj.keyFilter = RegExp("[\\-" + psxui.dpREStr + "\\d]");

                                                  obj.addEventListener('keydown', ContactSheetUI.filterKey);

                                                };

                                                //

                                                // Function: addPositiveNumberFilter

                                                // Description: Adds a positive number/localized-decimal-point keystroke filter

                                                // Input:  obj - UI widget

                                                // Return: <none>

                                                //

                                                ContactSheetUI.addPositiveNumberFilter = function(obj) {

                                                  obj.keyFilter = RegExp("[" + psxui.dpREStr + "\\d]");

                                                  obj.addEventListener('keydown', ContactSheetUI.filterKey);

                                                };

                                                • 21. Re: Photoshop CC 2015 changes to scripting
                                                  xbytor2 Level 4

                                                  When I was writing the ContactSheetII.jsx, the Quality Control people at Adobe were very, very specific about keystroke filters so I learned a lot about them writing up the code.

                                                  • 22. Re: Photoshop CC 2015 changes to scripting
                                                    Chuck Uebele Adobe Community Professional & MVP

                                                    Seems to be a bug with dialogs not closing if a second dialog is opened.

                                                     

                                                    How to close parent window immediately at Photoshop CC2015?

                                                    • 23. Re: Photoshop CC 2015 changes to scripting
                                                      Rune L-H Level 1

                                                      JSinha, last I heard was that the engineers would take a look at it. But you should give the support ticket a vote here: Photoshop CC 2015: (win7) Crashes instantly when extension uses script UI

                                                       

                                                      I did come up with a hackish workaround to this issue though. If you make a script that briefly shows an (invisible) dialog and closes it again, and run that from Photoshop's File->Script menu before using the extension, then Photoshop will not crash. This means that you can distribute that script together with your extension and run it as part of the extension initialization, and everything will work out the box for the end user. Here's my code:

                                                       

                                                      // Copy this script to Photoshop/Presets/Scripts folder

                                                      var dlgWindow = new Window("palette", "");

                                                      dlgWindow.opacity = 0;

                                                      dlgWindow.show();

                                                      dlgWindow.close();

                                                       

                                                      // In your panel initialization

                                                      try{

                                                          if ($.os.match(/windows/i)) {

                                                              var idAdobeScriptAutomationScripts = stringIDToTypeID( "AdobeScriptAutomation Scripts" );

                                                                  var desc1 = new ActionDescriptor();

                                                                  var idjsNm = charIDToTypeID( "jsNm" );

                                                                  desc1.putString( idjsNm, """YOUR SCRIPT NAME""" );

                                                                  var idjsMs = charIDToTypeID( "jsMs" );

                                                                  desc1.putString( idjsMs, """undefined""" );

                                                              executeAction( idAdobeScriptAutomationScripts, desc1, DialogModes.NO );

                                                          }

                                                      }catch(e){};

                                                       

                                                      Crazy, eh.

                                                      • 24. Re: Photoshop CC 2015 changes to scripting
                                                        JJMack Most Valuable Participant

                                                        X there seems to be a big difference as to how ContactSheetII  UI works in CC 2015 and CC 2014 with some of the input fields it that because of the eventlistener code? The change seem to be in the panel. The CC 2014 version run in cc 2015 still seem to filter some of the numeric input fields not allow character be entered..

                                                         

                                                        I use Mike Hale code for handling numeric input fields in several script and now that way does not work in CC 2015.   Your CC 2014 version of contacsheetII handles in CC 2015 some of your dialogs fields the way I want to.  However I do not know JavaScript only hack at it and I do not understand how your CC 2014 code works.

                                                         

                                                        Could you please do me a favor a post a simple dialog that only allows numeric data to be entered into its input field that will work in CC 2015 and CC 2014.

                                                         

                                                        I like the immediate feedback and not having to check if is not numeric and then have to putout a message and then re-display the dialog.  For that way I need to restructure my poor hacks.

                                                         

                                                        Here the code Mike posted that no longer works in CC 2015  the keydown event handler is never triggered

                                                         

                                                        function NumericEditKeyboardHandler (event) {

                                                            try {

                                                                var keyIsOK = KeyIsNumeric (event) || 

                                                                              KeyIsDelete (event) || 

                                                                              KeyIsLRArrow (event) ||

                                                                              KeyIsTabEnterEscape (event);

                                                                              

                                                                if (! keyIsOK) {

                                                                    //    Bad input: tell ScriptUI not to accept the keydown event

                                                                    event.preventDefault();

                                                                    /*    Notify user of invalid input: make sure NOT

                                                                        to put up an alert dialog or do anything which

                                                                        requires user interaction, because that

                                                                        interferes with preventing the 'default'

                                                                        action for the keydown event */

                                                                    app.beep();

                                                                }

                                                            }

                                                            catch (e) {

                                                                ; // alert ("Ack! bug in NumericEditKeyboardHandler: " + e);

                                                            }

                                                        }

                                                        //    key identifier functions

                                                        function KeyIsNumeric ( event ) {

                                                            return  ( event.keyName >= '0' ) && ( event.keyName <= '9' ) && ! KeyHasModifier ( event );

                                                        }

                                                        function KeyHasModifier ( event ) {

                                                            return event.shiftKey || event.ctrlKey || event.altKey || event.metaKey;

                                                        }

                                                        function KeyIsDelete (event) {

                                                            //    Shift-delete is ok

                                                            return (event.keyName == 'Backspace') && ! (event.ctrlKey);

                                                        }

                                                         

                                                        function KeyIsLRArrow (event) {

                                                            return ((event.keyName == 'Left') || (event.keyName == 'Right')) && ! (event.altKey || event.metaKey);

                                                        }

                                                         

                                                        function KeyIsTabEnterEscape (event) {

                                                            return event.keyName == 'Tab' || event.keyName == 'Enter' || event.keyName == 'Escape';

                                                        }

                                                        function createDialog( ) {

                                                            var dlg = new Window( 'dialog', 'Example Dialog' );

                                                            dlg.maskSt = dlg.add( 'edittext', undefined, '' );

                                                            dlg.maskSt.preferredSize.width = 40;

                                                            dlg.maskSt.addEventListener ('keydown', NumericEditKeyboardHandler );

                                                           dlg.btnPnl = dlg.add( 'panel', undefined, 'Process' );

                                                           dlg.btnPnl.orientation = "row";

                                                           dlg.btnPnl.alignment = "right";

                                                           dlg.btnPnl.okBtn = dlg.btnPnl.add( 'button', undefined, 'Ok', { name:'ok' });

                                                           dlg.btnPnl.cancelBtn = dlg.btnPnl.add( 'button', undefined, 'Cancel', { name:'cancel' });

                                                           return dlg;

                                                        };

                                                        function initializeDialog( w ) {

                                                            w.maskSt.addEventListener ('keydown', NumericEditKeyboardHandler );

                                                            w.maskSt.onChanging = function() {

                                                                                            // range check if needed

                                                                                                if( Number(this.text) < 0 || Number(this.text) > 100 ){

                                                                                                    alert('Out of range');

                                                                                                    // handle however you like

                                                                                                    this.text = '';

                                                                                                }

                                                                                            }

                                                            w.btnPnl.okBtn.onClick = function ( ) { this.parent.parent.close( 1 ); };

                                                            w.btnPnl.cancelBtn.onClick = function ( ) { this.parent.parent.close( 2 ); };

                                                        };

                                                        runDialog = function( w ) {

                                                           return w.show( );

                                                        };

                                                        var win = createDialog();

                                                        initializeDialog( win );

                                                        runDialog( win );

                                                        • 25. Re: Photoshop CC 2015 changes to scripting
                                                          JSinha Level 1

                                                          Hey Rune,

                                                          Already voted for the support ticket.

                                                          Thanks much for your suggestion..will try it out. I guess we can only wait for Adobe to come up with a fix

                                                          • 26. Re: Photoshop CC 2015 changes to scripting
                                                            xbytor2 Level 4

                                                            X there seems to be a big difference as to how ContactSheetII  UI works in CC 2015 and CC 2014 with some of the input fields it that because of the eventlistener code? The change seem to be in the panel. The CC 2014 version run in cc 2015 still seem to filter some of the numeric input fields not allow character be entered..

                                                             

                                                             

                                                            CSII is Adobe's baby, now. I haven't been keeping up with it at all. But since you have brought this up, I'll take a look at this. We will probably have to file a bug report but I would like to have a solution ready before then.

                                                             

                                                            My main focus these days is CSX, xtools, and Image Processor  Pro.

                                                             

                                                            Could you please do me a favor a post a simple dialog that only allows numeric data to be entered into its input field that will work in CC 2015 and CC 2014.

                                                             

                                                            If/when I figure out what's going on here, I'll post an example that works for CS5 to CC2015 which is what I try to support in my scripts.

                                                            • 27. Re: Photoshop CC 2015 changes to scripting
                                                              gimblll

                                                              Listbox columns seem to be broken when going from 2014 -> 2015, at least for me:

                                                               

                                                              Posted a thread here: Listbox columns not working in Photoshop CC 2015

                                                              Opened an issue/ticket here: Photoshop CC 2015: Listbox columns do not work anymore

                                                              • 30. Re: Photoshop CC 2015 changes to scripting
                                                                JJMack Most Valuable Participant

                                                                The link take you to a page that has ad download like for CC 2015 SCK wihich take tou to an agreement page tha has tah actual doload links for Windows and Mac  both get a html 404 not found error

                                                                Adobe Photoshop CC 2015 SDK

                                                                • 31. Re: Photoshop CC 2015 changes to scripting
                                                                  Rei_Martins Level 1

                                                                  For me the links show: "was not found on this server"

                                                                  Thanks.

                                                                  • 32. Re: Photoshop CC 2015 changes to scripting
                                                                    Rei_Martins Level 1

                                                                    Links is working now...

                                                                    • 33. Re: Photoshop CC 2015 changes to scripting
                                                                      xbytor2 Level 4

                                                                      I looked in to this for a bit. It turns out that there were a fields where the numeric filter is not working even in CS6. It's a copy/paste bug where I was adding the filters to the widgets. But even with those fixed, the filters aren't working at all in CC2015 as has been observed. The 'keydown' event listener is not getting called at all. This looks like a hard bug. I'll see if I can find a work-around.

                                                                       

                                                                      I've also been able to get it into a state where the tab key is ignored. Very weird.

                                                                      • 34. Re: Photoshop CC 2015 changes to scripting
                                                                        JJMack Most Valuable Participant

                                                                        I submitted a bug report about the keydown event on Adobe feedback site.  Its has been acknowledged Photoshop CC 2015 scripting addEventListener keydown event not working

                                                                         

                                                                        Many script are now broken....

                                                                        • 35. Re: Photoshop CC 2015 changes to scripting
                                                                          y0ta Level 1

                                                                          regarding the list bug: Listbox columns seem to be broken when going from 2014 -> 2015, at least for me

                                                                           

                                                                          Any news on this or how should I develop the UI differently ?

                                                                          Thx you to flag it, I was looking why I can't display the column correctly, except to have the "anuj" result.

                                                                           

                                                                           

                                                                          Do you know what anuj mean ?

                                                                          Cheers

                                                                          • 36. Re: Photoshop CC 2015 changes to scripting
                                                                            gimblll Level 1

                                                                            I found no workaround for it, sorry. The listbox columns just don't seem to work in 2015, so I use 2014 for now.

                                                                            • 37. Re: Photoshop CC 2015 changes to scripting
                                                                              ymmtny

                                                                              addEventListener to static text stopped working in CC 2015

                                                                              ----------------------------------------------

                                                                              var win = new Window("dialog", "Test Window"); 

                                                                              win.g = win.add("Group{ orientation: 'row', alignment:'right',  cb: Button {text:'Cancel'}, pb: StaticText {text:'Create'}}");

                                                                              win.g.pb.addEventListener ("click", function(e){

                                                                                  alert("test")

                                                                                  });

                                                                              • 38. Re: Photoshop CC 2015 changes to scripting
                                                                                JJMack Most Valuable Participant

                                                                                Please report the problem  on Adobe feedback site Photoshop Family Customer Community

                                                                                • 39. Re: Photoshop CC 2015 changes to scripting
                                                                                  DBarranca Level 4

                                                                                  There is another (reported) issue halfway between scripting and HTML Panels.

                                                                                   

                                                                                  In Photoshop you can't apparently use #include statements in the JSX of an HTML Panel - it won't work (InDesign for instance is different).

                                                                                   

                                                                                  To load multiple JSX files at runtime, you are forced to:

                                                                                  - pass from the JS to the JSX the Extension's root path: csInterface.getSystemPath(SystemPath.EXTENSION)

                                                                                  - in the JSX use the path to $.evalFile()

                                                                                   

                                                                                  So far so good, apparently (even if it's not clear who has access to the ExtendScript context first, the main script or the extra ones loaded at document.ready), but the problem is that functions declared in the extra JSX don't stick to the ExtendScript context - that is, if you call them they're undefined - even if the $.evalFile() files are parsed correctly (e.g. if you put alerts in there, they fire).

                                                                                   

                                                                                  As a result, to my experience it's not possible to successfully modularize JSX files.

                                                                                  See a demo extension here: https://dl.dropboxusercontent.com/u/23243188/com.example.evalJSX.zip

                                                                                   

                                                                                  Davide

                                                                                  1 2 Previous Next