<commit_before>'use strict';

/* Directives */
var dragOps = {
    addClass: false,
    cursorAt: { left: 17, top: 17 },
    revert: 'invalid',
    zIndex: 900,
    start: function(event, ui) {
        var self = $(this);
        //console.log('drag-start', self);
        self.addClass('ui-state-disabled');
    },
    stop: function(event, ui) {
        var self = $(this);
        //console.log('drag-stop', self);
        if (!self.data('dropped')) {
            self.draggable({ disabled: false });
            self.removeClass('ui-state-disabled');
        }
    }
},
dropOps = {
        addClasses: false,
        tolerance: 'intersect',
        over: function(event, ui) {
            var self = $(this);
            //console.log('drop-over', self);
            self.add(self.siblings()).addClass('ui-state-hover');
        },
        out: function(event, ui) {
            var self = $(this);
            //console.log('drop-out', self);
            self.add(self.siblings()).removeClass('ui-state-hover');
        },
        drop: function(event, ui) {
            var self = $(this),
            selfGroup = self.add(self.siblings()),
            listPart = ui.draggable,
            letter = listPart.find('.part-letter').text();
            //console.log('drop-drop', self);
            if (selfGroup.hasClass('ui-state-hover')) {
                selfGroup.removeClass('ui-state-hover');
            }
            
            listPart.data('dropped', true).draggable({ disabled: true });
            selfGroup.addClass('ui-state-highlight').text(letter).each(function(){ $(this).data('part-id', listPart.data('part-id')); });
            //console.log(self.data());
        }
    };
    
app.directive('draggable', function() {
    return {
        restrict: 'A',
        link: function(scope, elem, attrs) {
            var vars = scope.$eval(attrs.draggable),
            options = dragOps;
            
            //console.log(vars);
            options.scope = vars.scope;
            options.helper = function(event) {
                return $('<div></div>').text(vars.helper.letter);
            };
            
            elem.draggable(options);
            //console.log('drAGGable:', options);
        }
    };
}).directive('droppable', function() {
    return {
        restrict: 'A',
        link: function(scope, elem, attrs) {
            var vars = scope.$eval(attrs.droppable),
                options = dropOps;
                
                options.scope = vars.scope;
                
            elem.droppable(options);
            //console.log('drOPPable:', options);
        }
    };
}).directive('addPartId', function() {
    return {
        restrict: 'A',
        link: function(scope, elem, attrs) {
            elem.data('part-id', scope.partId);
            //console.log(elem.data('part-id'));
        }
    };<commit_msg>added a rearange directive for the .part-drop items. Also updated the other directives to make the rearranging possible<commit_after>'use strict';

var dragOps = {
    addClass: false,
    cursorAt: { left: 17, top: 17 },
    revert: 'invalid',
    zIndex: 900,
    start: function(event, ui) {
        var self = $(this);
        //console.log('drag-start', self);
        self.addClass('ui-state-disabled');
    },
    stop: function(event, ui) {
        var self = $(this);
        //console.log('drag-stop', self);
        if (!self.data('dropped')) {
            self.draggable('enable');
            self.removeClass('ui-state-disabled');
        }
    }
},
dropOps = {
    addClasses: false,
    tolerance: 'intersect',
    over: function(event, ui) {
        var self = $(this);
        //console.log('drop-over', self);
        self.add(self.siblings()).addClass('ui-state-hover');
    },
    out: function(event, ui) {
        var self = $(this);
        //console.log('drop-out', self);
        self.add(self.siblings()).removeClass('ui-state-hover');
    },
    drop: function(event, ui) {
        $('.alert-error').remove();
        
        var self = $(this),
        selfGroup = self.add(self.siblings()),
        prevPart = ui.draggable,
        prevGroup = prevPart.add(prevPart.siblings()),
        letter = prevPart.data('part-id').replace(/[a-z]/g, ''), // remove lowercase letters to leave the single uppercase part letter
        oldID = self.data('part-id');
        //console.log('drop-drop', self);
        
        if (selfGroup.hasClass('ui-state-hover')) { selfGroup.removeClass('ui-state-hover'); }
        
        // Dragged from the list to a spot...
        if (!prevPart.hasClass('part-drop')) {
            // that is empty
            if (self.data('part-id') === undefined) {
                //console.log('list to empty');
                prevPart.data('dropped', true).draggable('disable');
            }
            // that is already occupied
            else {
                //console.log('list to occupied');
                //console.log(self.clone());
                
                prevPart.data('dropped', true).draggable('disable');
                prevPart.siblings().each(function(){
                    var self = $(this);
                    
                    if (self.data('part-id') === oldID) {
                        self.data('dropped', false).draggable('enable').removeClass('ui-state-disabled');
                        
                        return false;
                    }
                });
            }
            
            selfGroup.addClass('ui-state-highlight').text(letter).data('part-id', prevPart.data('part-id'));
        }
        // Rearrange...
        else {
            // to a different part...
            if (self.data('part-id') !== prevPart.data('part-id')) {
                // that is empty
                if (self.data('part-id') === undefined) {
                    //console.log('rearrange to empty');
                    prevGroup.removeClass('ui-state-highlight').text('');
                }
                // that is already occupied
                else {
                    //console.log('rearrange to occupied', prevPart.data('part-id'), '>', self.data('part-id'));
                    
                    selfGroup.data('part-id', prevPart.data('part-id'));
                   //console.log(self.data('part-id'));
                    selfGroup.text(prevPart.text());
                    
                    prevGroup.data('part-id', oldID);
                    prevGroup.text(oldID.replace(/[a-z]/g, ''));
                    
                    return;
                }
            }
            // to a spot that is of the same part
            else if (self.data('part-id') === prevPart.data('part-id')) {
                //console.log('canceled drop b/c part was the same', self.data('part-id'), prevPart.data('part-id'))
                return false;
            }
            
            selfGroup.addClass('ui-state-highlight').text(letter).data('part-id', prevPart.data('part-id'));
            prevGroup.removeData('part-id');
        }
        
        //console.log(self.data());
    }
},
rearrangeOps = {
    addClass: false,
    cursorAt: { left: 17, top: 17 },
    revert: 'invalid',
    zIndex: 900,
    start: function(event, ui) {
        var self = $(this);
        //console.log('rearrange-start', self);
        
        if (!self.data('part-id')) {
            //console.log('canceled rearrange b/c it has no partID');
            return false;
        } else { 
            self.add(self.siblings()).addClass('ui-draggable-disabled');
        }
    },
    stop: function(event, ui) {
        var self = $(this);
        //console.log('rearrange-stop', self);
        
        self.add(self.siblings()).removeClass('ui-draggable-disabled');
    }
};

/* Directives */

app.directive('uiDraggable', function() {
    return {
        restrict: 'A',
        link: function(scope, elem, attrs) {
            var vars = scope.$eval(attrs.uiDraggable),
            options = dragOps;
            
            //console.log(vars);
            options.scope = vars.scope;
            options.helper = function(event) {
                return $('<div></div>').text(vars.helper.letter);
            };
            
            elem.draggable(options);
            //console.log('drAGGable:', options);
        }
    };
}).directive('uiDroppable', function() {
    return {
        restrict: 'A',
        link: function(scope, elem, attrs) {
            var vars = scope.$eval(attrs.uiDroppable),
                options = dropOps;
                
                options.scope = vars.scope;
                
            elem.droppable(options);
            //console.log('drOPPable:', options);
        }
    };
}).directive('uiRearrange', function() {
    return {
        restrict: 'A',
        link: function(scope, elem, attrs) {
            var vars = scope.$eval(attrs.uiRearrange),
            options = rearrangeOps;
            
            //console.log(vars);
            options.scope = vars.scope;
            
            options.helper = function(event) {
                return $('<div></div>').text(elem.data('part-id') ? elem.data('part-id').replace(/[a-z]/g, '') : '');
            };
            
            elem.draggable(options);
            //console.log('rearrange:', options);
        }
    };
}).directive('addPartId', function() {
    return {
        restrict: 'A',
        link: function(scope, elem, attrs) {
            elem.data('part-id', scope.partId);
            //console.log(elem.data('part-id'));
        }
    };
{'fraction_non_alphanumeric': 0.16274448279468676, 'fraction_numerical': 0.0021964229683087543, 'mean_word_length': 1.5704301075268816, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5127181', 'n_tokens_mistral': 2744, 'n_tokens_neox': 2691, 'n_words': 482}