     }
     
     public func replacingCharacters(in range: Range<Int>, with replacement: AttributedString) -> AttributedString {
-        guard range.clamped(to: 0..<string.count) == range else { fatalError("Index out of range.") }
+        
+        precondition(range.clamped(to: 0..<string.count) == range, "Index out of range.")
+        
         var result = self.attributedSubstring(from: 0..<range.lowerBound)
         result.append(replacement)
         result.append(self.attributedSubstring(from: range.upperBound..<string.count))

    
    public func attributedSubstring(from range: Range<Int>) -> AttributedString {
        
        guard range.clamped(to: 0..<string.count) == range else { fatalError("Index out of range.") }
        
        let startIndex = string.index(string.startIndex, offsetBy: range.lowerBound)
        let endIndex = string.index(string.startIndex, offsetBy: range.upperBound)

extension AttributedString {
    
    public func replacingCharacters(in range: Range<Int>, with replacement: String) -> AttributedString {
        
        precondition(range.clamped(to: 0..<string.count) == range, "Index out of range.")
        
        var result = self.attributedSubstring(from: 0..<range.lowerBound)
        result.append(replacement)
        result.append(self.attributedSubstring(from: range.upperBound..<string.count))
