<commit_before>import MapKit

extension MCreateSave
{
    //MARK: private
    
    private class func snapshots(
        directory:URL,
        renders:[MCreateSaveRender],
        completion:@escaping(([URL]) -> ()))
    {
        var urls:[URL] = []
        let dispatchGroup:DispatchGroup = MCreateSave.factoryDispatchGroup()
        
        for render:MCreateSaveRender in renders
        {
            snapshots(
                dispatchGroup:dispatchGroup,
                directory:directory,
                render:render)
            { (url:URL?) in
                
                if let url:URL = url
                {
                    urls.append(url)
                }
                
                dispatchGroup.leave()
            }
        }
        
        print("save 2 4")
        
        dispatchGroup.notify(
            queue:DispatchQueue.global(
                qos:DispatchQoS.QoSClass.background))
        {
            print("save 2 5")
            
            completion(urls)
        }
    }
    
    private class func snapshots(
        dispatchGroup:DispatchGroup,
        directory:URL,
        render:MCreateSaveRender,
        completion:@escaping((URL?) -> ()))
    {
        for tile:MCreateSaveRenderTile in render.tiles
        {
            dispatchGroup.enter()
            
            print("enter dispatch \(dispatchGroup)")
            
            snapshot(
                directory:directory,
                tile:tile,
                completion:completion)
        }
    }
    
    private class func snapshot(
        directory:URL,
        tile:MCreateSaveRenderTile,
        completion:@escaping((URL?) -> ()))
    {
        let snapshotter:MKMapSnapshotter = MKMapSnapshotter(
            options:tile.options)
        
        snapshotter.start
        { (snapshot:MKMapSnapshot?, error:Error?) in
            
            guard
            
                error == nil,
                let image:UIImage = snapshot?.image,
                let url:URL = fileSave(
                    directory:directory,
                    name:tile.name,
                    image:image)
            
            else
            {
                completion(nil)
                
                return
            }
            
            completion(url)
        }
    }
    
    //MARK: internal
    
    class func snapshots(
        plan:DPlan,
        mapRange:MCreateSaveMapRange,
        settings:DSettings,
        completion:@escaping(([URL]) -> ()))
    {
        print("save 2 2")
        
        guard
            
            let directory:URL = factoryDirectory(<commit_msg>Use dispatch wait instead of notify<commit_after>import MapKit

extension MCreateSave
{
    private static let kSnapshotTimeout:TimeInterval = 300
    
    //MARK: private
    
    private class func snapshots(
        directory:URL,
        renders:[MCreateSaveRender],
        completion:@escaping(([URL]) -> ()))
    {
        var urls:[URL] = []
        let dispatchGroup:DispatchGroup = MCreateSave.factoryDispatchGroup()
        
        for render:MCreateSaveRender in renders
        {
            snapshots(
                dispatchGroup:dispatchGroup,
                directory:directory,
                render:render)
            { (url:URL?) in
                
                if let url:URL = url
                {
                    urls.append(url)
                }
                
                dispatchGroup.leave()
            }
        }
        
        print("save 2 4")
        
        let timeout:DispatchTime = DispatchTime.now() + kSnapshotTimeout
        let _:DispatchTimeoutResult = dispatchGroup.wait(
            timeout:timeout)
        
        print("save 2 5")
        completion(urls)
    }
    
    private class func snapshots(
        dispatchGroup:DispatchGroup,
        directory:URL,
        render:MCreateSaveRender,
        completion:@escaping((URL?) -> ()))
    {
        for tile:MCreateSaveRenderTile in render.tiles
        {
            dispatchGroup.enter()
            
            print("enter dispatch \(dispatchGroup)")
            
            snapshot(
                directory:directory,
                tile:tile,
                completion:completion)
        }
    }
    
    private class func snapshot(
        directory:URL,
        tile:MCreateSaveRenderTile,
        completion:@escaping((URL?) -> ()))
    {
        let snapshotter:MKMapSnapshotter = MKMapSnapshotter(
            options:tile.options)

        snapshotter.start
        { (snapshot:MKMapSnapshot?, error:Error?) in
            
            guard
            
                error == nil,
                let image:UIImage = snapshot?.image,
                let url:URL = fileSave(
                    directory:directory,
                    name:tile.name,
                    image:image)
            
            else
            {
                print("save 2 7")
                
                completion(nil)
                
                return
            }
            
            print("save 2 6")
            
            completion(url)
        }
    }
    
    //MARK: internal
    
    class func snapshots(
        plan:DPlan,
        mapRange:MCreateSaveMapRange,
        settings:DSettings,
        completion:@escaping(([URL]) -> ()))
    {
        print("save 2 2")
        
        guard
            
            let directory:URL = factoryDirectory(
{'fraction_non_alphanumeric': 0.08232711306256861, 'fraction_numerical': 0.0034760336626417855, 'mean_word_length': 1.177220230983672, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, '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': '3131603', 'n_tokens_mistral': 1392, 'n_tokens_neox': 1314, 'n_words': 242}