<commit_before>using System;
using System.Collections.Generic;
using Avalonia.Platform;
using Avalonia.Rendering.SceneGraph;
using Avalonia.Threading;
using Avalonia.Utilities;
using Avalonia.Visuals.Media.Imaging;

namespace Avalonia.Media
{
    public sealed class DrawingContext : IDisposable
    {
        private readonly bool _ownsImpl;
        private int _currentLevel;


        private static ThreadSafeObjectPool<Stack<PushedState>> StateStackPool { get; } =
            ThreadSafeObjectPool<Stack<PushedState>>.Default;

        private static ThreadSafeObjectPool<Stack<TransformContainer>> TransformStackPool { get; } =
            ThreadSafeObjectPool<Stack<TransformContainer>>.Default;

        private Stack<PushedState>? _states = StateStackPool.Get();

        private Stack<TransformContainer>? _transformContainers = TransformStackPool.Get();

        readonly struct TransformContainer
        {
            public readonly Matrix LocalTransform;
            public readonly Matrix ContainerTransform;

            public TransformContainer(Matrix localTransform, Matrix containerTransform)
            {
                LocalTransform = localTransform;
                ContainerTransform = containerTransform;
            }
        }

        public DrawingContext(IDrawingContextImpl impl)
        {
            PlatformImpl = impl;
            _ownsImpl = true;
        }
        
        public DrawingContext(IDrawingContextImpl impl, bool ownsImpl)
        {
            _ownsImpl = ownsImpl;
            PlatformImpl = impl;
        }

        public IDrawingContextImpl PlatformImpl { get; }

        private Matrix _currentTransform = Matrix.Identity;

        private Matrix _currentContainerTransform = Matrix.Identity;

        /// <summary>
        /// Gets the current transform of the drawing context.
        /// </summary>
        public Matrix CurrentTransform
        {
            get { return _currentTransform; }
            private set
            {
                _currentTransform = value;
                var transform = _currentTransform * _currentContainerTransform;
                PlatformImpl.Transform = transform;
            }
        }

        //HACK: This is a temporary hack that is used in the render loop 
        //to update TransformedBounds property
        [Obsolete("HACK for render loop, don't use")]
        public Matrix CurrentContainerTransform => _currentContainerTransform;

        /// <summary>
        /// Draws an image.
        /// </summary>
        /// <param name="source">The image.</param>
        /// <param name="rect">The rect in the output to draw to.</param>
        public void DrawImage(IImage source, Rect rect)
        {
            _ = source ?? throw new ArgumentNullException(nameof(source));

            DrawImage(source, new Rect(source.Size), rect);
        }

        /// <summary>
        /// Draws an image.
        /// </summary>
        /// <param name="source">The image.</param>
        /// <param name="sourceRect">The rect in the image to draw.</param>
        /// <param name="destRect">The rect in the output to draw to.</param>
        /// <param name="bitmapInterpolationMode">The bitmap interpolation mode.</param>
        public void DrawImage(IImage source, Rect sourceRect, Rect destRect, BitmapInterpolationMode bitmapInterpolationMode = default)
        {
            _ = source ?? throw new ArgumentNullException(nameof(source));

            source.Draw(this, sourceRect, destRect, bitmapInterpolationMode);
        }

        /// <summary>
        /// Draws a line.
        /// </summary>
        /// <param name="pen">The stroke pen.</param>
        /// <param name="p1">The first point of the line.</param>
        /// <param name="p2">The second point of the line.</param>
        public void DrawLine(IPen pen, Point p1, Point p2)
        {
            if (PenIsVisible(pen))
            {
                PlatformImpl.DrawLine(pen, p1, p2);
            }
        }

        /// <summary>
        /// Draws a geometry.
        /// </summary>
        /// <param name="brush">The fill brush.</param>
        /// <param name="pen">The stroke pen.</param>
        /// <param name="geometry">The geometry.</param>
        public void DrawGeometry(IBrush brush, IPen pen, Geometry geometry)
        {
            if (geometry.PlatformImpl is not null)
                DrawGeometry(brush, pen, geometry.PlatformImpl);
        }

        /// <summary>
        /// Draws a geometry.
        /// </summary>
        /// <param name="brush">The fill brush.</param>
        /// <param name="pen">The stroke pen.</param>
        /// <param name="geometry">The geometry.</param>
        public void DrawGeometry(IBrush brush, IPen pen, IGeometryImpl geometry)
        {
            _ = geometry ?? throw new ArgumentNullException(nameof(geometry));

            if (brush != null || PenIsVisible(pen))
            {
                PlatformImpl.DrawGeometry(brush, pen, geometry);
            }
        }

        /// <summary>
        /// Draws a rectangle with the specified Brush and Pen.
        /// </summary>
        /// <param name="brush">The brush used to fill the rectangle, or <c>null</c> for no fill.</param>
        /// <param name="pen">The pen used to stroke the rectangle, or <c>null</c> for no stroke.</param>
        /// <param name="rect">The rectangle bounds.</param>
        /// <param name="radiusX">The radius in the X dimension of the rounded corners.
        ///     This value will be clamped to the range of 0 to Width/2
        /// </param>
        /// <param name="radiusY">The radius in the Y dimension of the rounded corners.
        ///     This value will be clamped to the range of 0 to Height/2
        /// </param>
        /// <param name="boxShadows">Box shadow effect parameters</param>
        /// <remarks>
        /// The brush and the pen can both be null. If the brush is null, then no fill is performed.
        /// If the pen is null, then no stoke is performed. If both the pen and the brush are null, then the drawing is not visible.
        /// </remarks>
        public void DrawRectangle(IBrush? brush, IPen? pen, Rect rect, double radiusX = 0, double radiusY = 0,
            BoxShadows boxShadows = default)
        {
            if (brush == null && !PenIsVisible(pen))
            {
                return;
            }

            if (!MathUtilities.IsZero(radiusX))
            {
                radiusX = Math.Min(radiusX, rect.Width / 2);
            }

            if (!MathUtilities.IsZero(radiusY))
            {
                radiusY = Math.Min(radiusY, rect.Height / 2);
            }

            PlatformImpl.DrawRectangle(brush, pen, new RoundedRect(rect, radiusX, radiusY), boxShadows);
        }

        /// <summary>
        /// Draws the outline of a rectangle.
        /// </summary>
        /// <param name="pen">The pen.</param>
        /// <param name="rect">The rectangle bounds.</param>
        /// <param name="cornerRadius">The corner radius.</param>
        public void DrawRectangle(IPen pen, Rect rect, float cornerRadius = 0.0f)
        {
            DrawRectangle(null, pen, rect, cornerRadius, cornerRadius);
        }

        /// <summary>
        /// Draws an ellipse with the specified Brush and Pen.
        /// </summary>
        /// <param name="brush">The brush used to fill the ellipse, or <c>null</c> for no fill.</param>
        /// <param name="pen">The pen used to stroke the ellipse, or <c>null</c> for no stroke.</param>
        /// <param name="center">The location of the center of the ellipse.</param>
        /// <param name="radiusX">The horizontal radius of the ellipse.</param>
        /// <param name="radiusY">The vertical radius of the ellipse.</param>
        /// <remarks>
        /// The brush and the pen can both be null. If the brush is null, then no fill is performed.
        /// If the pen is null, then no stoke is performed. If both the pen and the brush are null, then the drawing is not visible.
        /// </remarks>
        public void DrawEllipse(IBrush brush, IPen pen, Point center, double radiusX, double radiusY)
        {
            if (brush == null && !PenIsVisible(pen))
            {
                return;
            }

            var originX = center.X - radiusX;
            var originY = center.Y - radiusY;
            var width = radiusX * 2;
            var height = radiusY * 2;

            PlatformImpl.DrawEllipse(brush, pen, new Rect(originX, originY, width, height));
        }

        /// <summary>
        /// Draws a custom drawing operation
        /// </summary>
        /// <param name="custom">custom operation</param>
        public void Custom(ICustomDrawOperation custom) => PlatformImpl.Custom(custom);

        /// <summary>
        /// Draws text.
        /// </summary>
        /// <param name="foreground">The foreground brush.</param>
        /// <param name="origin">The upper-left corner of the text.</param>
        /// <param name="text">The text.</param>
        public void DrawText(IBrush foreground, Point origin, FormattedText text)
        {
            _ = text ?? throw new ArgumentNullException(nameof(text));

            if (foreground != null)
            {
                PlatformImpl.DrawText(foreground, origin, text.PlatformImpl);
            }
        }

        /// <summary>
        /// Draws a glyph run.
        /// </summary>
        /// <param name="foreground">The foreground brush.</param>
        /// <param name="glyphRun">The glyph run.</param>
        public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun)
        {
            _ = glyphRun ?? throw new ArgumentNullException(nameof(glyphRun));

            if (foreground != null)
            {
                PlatformImpl.DrawGlyphRun(foreground, glyphRun);
            }
        }

        /// <summary>
        /// Draws a filled rectangle.
        /// </summary>
        /// <param name="brush">The brush.</param>
        /// <param name="rect">The rectangle bounds.</param>
        /// <param name="cornerRadius">The corner radius.</param>
        public void FillRectangle(IBrush brush, Rect rect, float cornerRadius = 0.0f)
        {
            DrawRectangle(brush, null, rect, cornerRadius, cornerRadius);
        }

        public readonly struct PushedState : IDisposable
        {
            private readonly int _level;
            private readonly DrawingContext _context;
            private readonly Matrix _matrix;
            private readonly PushedStateType _type;

            public enum PushedStateType
            {
                None,
                Matrix,
                Opacity,
                Clip,
                MatrixContainer,
                GeometryClip,
                OpacityMask,
            }

            public PushedState(DrawingContext context, PushedStateType type, Matrix matrix = default(Matrix))
            {
                if (context._states is null)
                    throw new ObjectDisposedException(nameof(DrawingContext));

                _context = context;
                _type = type;
                _matrix = matrix;
                _level = context._currentLevel += 1;
                context._states.Push(this);
            }

            public void Dispose()
            {
                if (_context._states is null || _context._transformContainers is null)
                    throw new ObjectDisposedException(nameof(DrawingContext));
                if (_type == PushedStateType.None)
                    return;
                if (_context._currentLevel != _level)
                    throw new InvalidOperationException("Wrong Push/Pop state order");
                _context._currentLevel--;
                _context._states.Pop();
                if (_type == PushedStateType.Matrix)
                    _context.CurrentTransform = _matrix;
                else if (_type == PushedStateType.Clip)
                    _context.PlatformImpl.PopClip();
                else if (_type == PushedStateType.Opacity)
                    _context.PlatformImpl.PopOpacity();
                else if (_type == PushedStateType.GeometryClip)
                    _context.PlatformImpl.PopGeometryClip();
                else if (_type == PushedStateType.OpacityMask)
                    _context.PlatformImpl.PopOpacityMask();
                else if (_type == PushedStateType.MatrixContainer)
                {
                    var cont = _context._transformContainers.Pop();
                    _context._currentContainerTransform = cont.ContainerTransform;
                    _context.CurrentTransform = cont.LocalTransform;
                }
            }
        }


        public PushedState PushClip(RoundedRect clip)
        {
            PlatformImpl.PushClip(clip);
            return new PushedState(this, PushedState.PushedStateType.Clip);
        }

        /// <summary>
        /// Pushes a clip rectangle.
        /// </summary>
        /// <param name="clip">The clip rectangle.</param>
        /// <returns>A disposable used to undo the clip rectangle.</returns>
        public PushedState PushClip(Rect clip)
        {
            PlatformImpl.PushClip(clip);
            return new PushedState(this, PushedState.PushedStateType.Clip);
        }

        /// <summary>
        /// Pushes a clip geometry.
        /// </summary>
        /// <param name="clip">The clip geometry.</param>
        /// <returns>A disposable used to undo the clip geometry.</returns>
        public PushedState PushGeometryClip(Geometry clip)
        {
            _ = clip ?? throw new ArgumentNullException(nameof(clip));

            PlatformImpl.PushGeometryClip(clip.PlatformImpl);
            return new PushedState(this, PushedState.PushedStateType.GeometryClip);
        }

        /// <summary>
        /// Pushes an opacity value.<commit_msg>Add a hacky exception for existing potential problem.<commit_after>using System;
using System.Collections.Generic;
using Avalonia.Platform;
using Avalonia.Rendering.SceneGraph;
using Avalonia.Threading;
using Avalonia.Utilities;
using Avalonia.Visuals.Media.Imaging;

namespace Avalonia.Media
{
    public sealed class DrawingContext : IDisposable
    {
        private readonly bool _ownsImpl;
        private int _currentLevel;


        private static ThreadSafeObjectPool<Stack<PushedState>> StateStackPool { get; } =
            ThreadSafeObjectPool<Stack<PushedState>>.Default;

        private static ThreadSafeObjectPool<Stack<TransformContainer>> TransformStackPool { get; } =
            ThreadSafeObjectPool<Stack<TransformContainer>>.Default;

        private Stack<PushedState>? _states = StateStackPool.Get();

        private Stack<TransformContainer>? _transformContainers = TransformStackPool.Get();

        readonly struct TransformContainer
        {
            public readonly Matrix LocalTransform;
            public readonly Matrix ContainerTransform;

            public TransformContainer(Matrix localTransform, Matrix containerTransform)
            {
                LocalTransform = localTransform;
                ContainerTransform = containerTransform;
            }
        }

        public DrawingContext(IDrawingContextImpl impl)
        {
            PlatformImpl = impl;
            _ownsImpl = true;
        }
        
        public DrawingContext(IDrawingContextImpl impl, bool ownsImpl)
        {
            _ownsImpl = ownsImpl;
            PlatformImpl = impl;
        }

        public IDrawingContextImpl PlatformImpl { get; }

        private Matrix _currentTransform = Matrix.Identity;

        private Matrix _currentContainerTransform = Matrix.Identity;

        /// <summary>
        /// Gets the current transform of the drawing context.
        /// </summary>
        public Matrix CurrentTransform
        {
            get { return _currentTransform; }
            private set
            {
                _currentTransform = value;
                var transform = _currentTransform * _currentContainerTransform;
                PlatformImpl.Transform = transform;
            }
        }

        //HACK: This is a temporary hack that is used in the render loop 
        //to update TransformedBounds property
        [Obsolete("HACK for render loop, don't use")]
        public Matrix CurrentContainerTransform => _currentContainerTransform;

        /// <summary>
        /// Draws an image.
        /// </summary>
        /// <param name="source">The image.</param>
        /// <param name="rect">The rect in the output to draw to.</param>
        public void DrawImage(IImage source, Rect rect)
        {
            _ = source ?? throw new ArgumentNullException(nameof(source));

            DrawImage(source, new Rect(source.Size), rect);
        }

        /// <summary>
        /// Draws an image.
        /// </summary>
        /// <param name="source">The image.</param>
        /// <param name="sourceRect">The rect in the image to draw.</param>
        /// <param name="destRect">The rect in the output to draw to.</param>
        /// <param name="bitmapInterpolationMode">The bitmap interpolation mode.</param>
        public void DrawImage(IImage source, Rect sourceRect, Rect destRect, BitmapInterpolationMode bitmapInterpolationMode = default)
        {
            _ = source ?? throw new ArgumentNullException(nameof(source));

            source.Draw(this, sourceRect, destRect, bitmapInterpolationMode);
        }

        /// <summary>
        /// Draws a line.
        /// </summary>
        /// <param name="pen">The stroke pen.</param>
        /// <param name="p1">The first point of the line.</param>
        /// <param name="p2">The second point of the line.</param>
        public void DrawLine(IPen pen, Point p1, Point p2)
        {
            if (PenIsVisible(pen))
            {
                PlatformImpl.DrawLine(pen, p1, p2);
            }
        }

        /// <summary>
        /// Draws a geometry.
        /// </summary>
        /// <param name="brush">The fill brush.</param>
        /// <param name="pen">The stroke pen.</param>
        /// <param name="geometry">The geometry.</param>
        public void DrawGeometry(IBrush brush, IPen pen, Geometry geometry)
        {
            if (geometry.PlatformImpl is not null)
                DrawGeometry(brush, pen, geometry.PlatformImpl);
        }

        /// <summary>
        /// Draws a geometry.
        /// </summary>
        /// <param name="brush">The fill brush.</param>
        /// <param name="pen">The stroke pen.</param>
        /// <param name="geometry">The geometry.</param>
        public void DrawGeometry(IBrush brush, IPen pen, IGeometryImpl geometry)
        {
            _ = geometry ?? throw new ArgumentNullException(nameof(geometry));

            if (brush != null || PenIsVisible(pen))
            {
                PlatformImpl.DrawGeometry(brush, pen, geometry);
            }
        }

        /// <summary>
        /// Draws a rectangle with the specified Brush and Pen.
        /// </summary>
        /// <param name="brush">The brush used to fill the rectangle, or <c>null</c> for no fill.</param>
        /// <param name="pen">The pen used to stroke the rectangle, or <c>null</c> for no stroke.</param>
        /// <param name="rect">The rectangle bounds.</param>
        /// <param name="radiusX">The radius in the X dimension of the rounded corners.
        ///     This value will be clamped to the range of 0 to Width/2
        /// </param>
        /// <param name="radiusY">The radius in the Y dimension of the rounded corners.
        ///     This value will be clamped to the range of 0 to Height/2
        /// </param>
        /// <param name="boxShadows">Box shadow effect parameters</param>
        /// <remarks>
        /// The brush and the pen can both be null. If the brush is null, then no fill is performed.
        /// If the pen is null, then no stoke is performed. If both the pen and the brush are null, then the drawing is not visible.
        /// </remarks>
        public void DrawRectangle(IBrush? brush, IPen? pen, Rect rect, double radiusX = 0, double radiusY = 0,
            BoxShadows boxShadows = default)
        {
            if (brush == null && !PenIsVisible(pen))
            {
                return;
            }

            if (!MathUtilities.IsZero(radiusX))
            {
                radiusX = Math.Min(radiusX, rect.Width / 2);
            }

            if (!MathUtilities.IsZero(radiusY))
            {
                radiusY = Math.Min(radiusY, rect.Height / 2);
            }

            PlatformImpl.DrawRectangle(brush, pen, new RoundedRect(rect, radiusX, radiusY), boxShadows);
        }

        /// <summary>
        /// Draws the outline of a rectangle.
        /// </summary>
        /// <param name="pen">The pen.</param>
        /// <param name="rect">The rectangle bounds.</param>
        /// <param name="cornerRadius">The corner radius.</param>
        public void DrawRectangle(IPen pen, Rect rect, float cornerRadius = 0.0f)
        {
            DrawRectangle(null, pen, rect, cornerRadius, cornerRadius);
        }

        /// <summary>
        /// Draws an ellipse with the specified Brush and Pen.
        /// </summary>
        /// <param name="brush">The brush used to fill the ellipse, or <c>null</c> for no fill.</param>
        /// <param name="pen">The pen used to stroke the ellipse, or <c>null</c> for no stroke.</param>
        /// <param name="center">The location of the center of the ellipse.</param>
        /// <param name="radiusX">The horizontal radius of the ellipse.</param>
        /// <param name="radiusY">The vertical radius of the ellipse.</param>
        /// <remarks>
        /// The brush and the pen can both be null. If the brush is null, then no fill is performed.
        /// If the pen is null, then no stoke is performed. If both the pen and the brush are null, then the drawing is not visible.
        /// </remarks>
        public void DrawEllipse(IBrush brush, IPen pen, Point center, double radiusX, double radiusY)
        {
            if (brush == null && !PenIsVisible(pen))
            {
                return;
            }

            var originX = center.X - radiusX;
            var originY = center.Y - radiusY;
            var width = radiusX * 2;
            var height = radiusY * 2;

            PlatformImpl.DrawEllipse(brush, pen, new Rect(originX, originY, width, height));
        }

        /// <summary>
        /// Draws a custom drawing operation
        /// </summary>
        /// <param name="custom">custom operation</param>
        public void Custom(ICustomDrawOperation custom) => PlatformImpl.Custom(custom);

        /// <summary>
        /// Draws text.
        /// </summary>
        /// <param name="foreground">The foreground brush.</param>
        /// <param name="origin">The upper-left corner of the text.</param>
        /// <param name="text">The text.</param>
        public void DrawText(IBrush foreground, Point origin, FormattedText text)
        {
            _ = text ?? throw new ArgumentNullException(nameof(text));

            if (foreground != null)
            {
                PlatformImpl.DrawText(foreground, origin, text.PlatformImpl);
            }
        }

        /// <summary>
        /// Draws a glyph run.
        /// </summary>
        /// <param name="foreground">The foreground brush.</param>
        /// <param name="glyphRun">The glyph run.</param>
        public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun)
        {
            _ = glyphRun ?? throw new ArgumentNullException(nameof(glyphRun));

            if (foreground != null)
            {
                PlatformImpl.DrawGlyphRun(foreground, glyphRun);
            }
        }

        /// <summary>
        /// Draws a filled rectangle.
        /// </summary>
        /// <param name="brush">The brush.</param>
        /// <param name="rect">The rectangle bounds.</param>
        /// <param name="cornerRadius">The corner radius.</param>
        public void FillRectangle(IBrush brush, Rect rect, float cornerRadius = 0.0f)
        {
            DrawRectangle(brush, null, rect, cornerRadius, cornerRadius);
        }

        public readonly struct PushedState : IDisposable
        {
            private readonly int _level;
            private readonly DrawingContext _context;
            private readonly Matrix _matrix;
            private readonly PushedStateType _type;

            public enum PushedStateType
            {
                None,
                Matrix,
                Opacity,
                Clip,
                MatrixContainer,
                GeometryClip,
                OpacityMask,
            }

            public PushedState(DrawingContext context, PushedStateType type, Matrix matrix = default(Matrix))
            {
                if (context._states is null)
                    throw new ObjectDisposedException(nameof(DrawingContext));

                _context = context;
                _type = type;
                _matrix = matrix;
                _level = context._currentLevel += 1;
                context._states.Push(this);
            }

            public void Dispose()
            {
                if (_context._states is null || _context._transformContainers is null)
                    throw new ObjectDisposedException(nameof(DrawingContext));
                if (_type == PushedStateType.None)
                    return;
                if (_context._currentLevel != _level)
                    throw new InvalidOperationException("Wrong Push/Pop state order");
                _context._currentLevel--;
                _context._states.Pop();
                if (_type == PushedStateType.Matrix)
                    _context.CurrentTransform = _matrix;
                else if (_type == PushedStateType.Clip)
                    _context.PlatformImpl.PopClip();
                else if (_type == PushedStateType.Opacity)
                    _context.PlatformImpl.PopOpacity();
                else if (_type == PushedStateType.GeometryClip)
                    _context.PlatformImpl.PopGeometryClip();
                else if (_type == PushedStateType.OpacityMask)
                    _context.PlatformImpl.PopOpacityMask();
                else if (_type == PushedStateType.MatrixContainer)
                {
                    var cont = _context._transformContainers.Pop();
                    _context._currentContainerTransform = cont.ContainerTransform;
                    _context.CurrentTransform = cont.LocalTransform;
                }
            }
        }


        public PushedState PushClip(RoundedRect clip)
        {
            PlatformImpl.PushClip(clip);
            return new PushedState(this, PushedState.PushedStateType.Clip);
        }

        /// <summary>
        /// Pushes a clip rectangle.
        /// </summary>
        /// <param name="clip">The clip rectangle.</param>
        /// <returns>A disposable used to undo the clip rectangle.</returns>
        public PushedState PushClip(Rect clip)
        {
            PlatformImpl.PushClip(clip);
            return new PushedState(this, PushedState.PushedStateType.Clip);
        }

        /// <summary>
        /// Pushes a clip geometry.
        /// </summary>
        /// <param name="clip">The clip geometry.</param>
        /// <returns>A disposable used to undo the clip geometry.</returns>
        public PushedState PushGeometryClip(Geometry clip)
        {
            _ = clip ?? throw new ArgumentNullException(nameof(clip));

            // HACK: This check was added when nullable annotations pointed out that we're potentially
            // pushing a null value for the clip here. Ideally we'd return an empty PushedState here but
            // I don't want to make that change as part of adding nullable annotations.
            if (clip.PlatformImpl is null)
                throw new InvalidOperationException("Cannot push empty geometry clip.");

            PlatformImpl.PushGeometryClip(clip.PlatformImpl);
            return new PushedState(this, PushedState.PushedStateType.GeometryClip);
        }

        /// <summary>
        /// Pushes an opacity value.
{'fraction_non_alphanumeric': 0.10514406929467916, 'fraction_numerical': 0.0014848859819692416, 'mean_word_length': 1.7785854616895875, 'pattern_counts': {'":': 0, '<': 277, '<?xml version=': 0, '>': 281, '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': '4929615', 'n_tokens_mistral': 7205, 'n_tokens_neox': 6892, 'n_words': 2049}