Spaces:
Running
Running
| import gradio as gr | |
| import pandas as pd | |
| from datetime import datetime | |
| import re | |
| from gtts import gTTS | |
| import io | |
| import base64 | |
| # ============================================================================ | |
| # LITIGATION INFILTRATION - BOOK PASSAGES | |
| # ============================================================================ | |
| BOOK_PASSAGES = { | |
| "intro": """From Litigation Infiltration by Dwayne Anthony Brian Galloway: | |
| Standing in the Sun | |
| If you are one hundred percent honest, and your evidence is one hundred percent clear, the shadows where institutions hide their lies will disappear. | |
| This is the fundamental principle. You do not fight institutions with emotion or anger. You fight them with their own documented lies, dragged into the sunlight through Subject Access Requests and presented in a Fact-Lie-Law-Consequence Matrix. | |
| The system relies on you being too intimidated, too poor, or too confused to challenge it. When you remove those barriers through knowledge and method, the system has no defense. | |
| This is Black Polished Chrome: BLACK, the unmovable weight of Acts of Parliament. POLISHED, clinical writing, free from emotional scratches. CHROME, the mirror that reflects their own words back at them.""", | |
| "cra_burden_flip": """From Litigation Infiltration - Consumer Rights Act 2015 Section 19(14): | |
| The Statutory Burden Flip | |
| The most powerful weapon in consumer law that almost nobody knows about. | |
| Consumer Rights Act 2015, Section 19, subsection 14 states: If the goods do not conform to the contract at any time within the period of six months beginning with the day on which they were delivered, they must be taken not to have conformed to the contract when they were delivered. | |
| What this means in plain English: If a fault appears in the first six months, the law ASSUMES the fault existed when the product was sold. The burden of proof FLIPS to the seller. They must prove it WASN'T faulty when sold. You do NOT need an independent expert report. | |
| This was confirmed in Clegg versus Andersson, 2003, Court of Appeal. When a seller tells you to get an independent inspection, they are attempting unlawful burden reversal. You cite section 19(14) and Clegg versus Andersson, and you watch them fold.""", | |
| "equality_act": """From Litigation Infiltration - Equality Act 2010 Section 20: | |
| The Mandatory Duty to Make Reasonable Adjustments | |
| This is not optional. This is not discretionary. This is MANDATORY. | |
| Section 20 of the Equality Act 2010 imposes three requirements on service providers. The duty is ANTICIPATORY. They must think ahead. The duty is PROACTIVE. They must take positive steps. "We treat everyone the same" is NOT a defense. It is an admission of breach. | |
| This was confirmed in Archibald versus Fife Council, 2004, House of Lords, where the court held that the duty to make adjustments may require preferential treatment, even giving the disabled person an advantage over non-disabled persons. | |
| When a bank or service provider tells you "we treat everyone the same," you cite Section 20 and Archibald, and you tell them that treating you the same when you disclosed your disability is a breach of their mandatory statutory duty.""", | |
| "sar_weapon": """From Litigation Infiltration - Data Protection Act 2018 Section 15: | |
| The Subject Access Request as a Weapon | |
| Every institution keeps two sets of records. The PUBLIC record: what they tell you. The PRIVATE record: what they say internally. "Mark account for closure. Apply fraud marker. Customer is difficult." | |
| The Subject Access Request under Data Protection Act 2018 Section 15 forces them to hand over the private record. This is the CHROME layer. You will quote their own words back to them in court. | |
| If they claim "legal privilege," you cite Gurieva versus CSD, 2020, Court of Appeal. The court held that blanket claims of privilege are insufficient. They must identify specific documents and prove actual prejudice.""", | |
| "matrix": """From Litigation Infiltration - The Fact-Lie-Law-Consequence Matrix: | |
| The Litigation Spine | |
| The Matrix is not a tool. It is the skeleton of your lawsuit. | |
| Four columns: FACT, what provably happened. LIE or DEFENSE, what they said that contradicts the fact. LAW, which statute their lie violates. CONSEQUENCE, what they legally owe as a result. | |
| Build one row for each fact-lie pair. When you are done, you have built your Particulars of Claim. The judge can see instantly what happened, what they said, what law they broke, and what they owe. | |
| The Matrix is the weapon. Everything else is decoration.""" | |
| } | |
| # ============================================================================ | |
| # DOCUMENT EXTRACTION (RELIABLE) | |
| # ============================================================================ | |
| def extract_text_from_file(file): | |
| """Extract text from uploaded file (PDF, DOCX, TXT)""" | |
| name = file.name.lower() | |
| try: | |
| if name.endswith('.pdf'): | |
| import PyPDF2 | |
| pdf_reader = PyPDF2.PdfReader(file) | |
| return "\n".join([page.extract_text() or "" for page in pdf_reader.pages]) | |
| elif name.endswith('.docx'): | |
| import docx | |
| doc = docx.Document(file) | |
| return "\n".join([p.text for p in doc.paragraphs]) | |
| else: # .txt or fallback | |
| return file.read().decode('utf-8', errors='ignore') | |
| except Exception as e: | |
| return f"Error reading {file.name}: {str(e)}" | |
| # ============================================================================ | |
| # SMART MATRIX BUILDER (ENHANCED) | |
| # ============================================================================ | |
| def extract_dates(text): | |
| """Extract all dates from text""" | |
| patterns = [ | |
| r'\b(\d{1,2}[/-]\d{1,2}[/-]\d{2,4})\b', | |
| r'\b(\d{1,2}\s+(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z]*\s+\d{4})\b', | |
| r'\b(\d{4}-\d{1,2}-\d{1,2})\b' | |
| ] | |
| for pattern in patterns: | |
| matches = re.findall(pattern, text, re.I) | |
| if matches: | |
| return matches | |
| return [] | |
| def extract_amounts(text): | |
| """Extract monetary amounts""" | |
| amounts = re.findall(r'£(\d{1,3}(?:,\d{3})*(?:\.\d{2})?)', text) | |
| if not amounts: | |
| amounts = re.findall(r'(\d{1,3}(?:,\d{3})*(?:\.\d{2})?)\s*(?:pounds?|gbp)', text, re.I) | |
| return [float(a.replace(',', '')) for a in amounts if a] | |
| def build_smart_matrix(text): | |
| """Build matrix from text using pattern matching + keywords""" | |
| rows = [] | |
| text_lower = text.lower() | |
| # 1. Consumer Rights Act - product defect | |
| if re.search(r'(faulty|defective|broke|damaged|unsafe|not working|failed)', text_lower): | |
| date = extract_dates(text) | |
| date_str = date[0] if date else "[date]" | |
| amount = extract_amounts(text) | |
| amount_str = f"£{amount[0]:,.2f}" if amount else "£[amount]" | |
| # Check for seller's lie | |
| lie = None | |
| if 'standard' in text_lower and 'brake' in text_lower: | |
| lie = '"Standard configuration for e-bikes sold in the UK"' | |
| elif 'warranty void' in text_lower or 'crash damage voids warranty' in text_lower: | |
| lie = '"Crash damage voids warranty"' | |
| elif 'unauthorised modifications' in text_lower or 'modified the bike' in text_lower: | |
| lie = '"You made unauthorised modifications"' | |
| else: | |
| lie = '"Goods were as described and fit for purpose"' | |
| row = { | |
| "FACT": f"On {date_str}, product delivered defective/unsafe (value {amount_str})", | |
| "LIE/DEFENSE": lie, | |
| "LAW": "Consumer Rights Act 2015 s.9 (satisfactory quality), s.10 (fit for purpose), s.19(14) (burden on seller)", | |
| "CONSEQUENCE": f"Full refund {amount_str} + consequential losses + damages for distress" | |
| } | |
| rows.append(row) | |
| # 2. Disability discrimination | |
| disability_keywords = ['disab', 'pip', 'personal independence', 'spinal', 'c4', 'metal plate', 'depression', 'anxiety', 'vulnerable'] | |
| if any(k in text_lower for k in disability_keywords): | |
| date = extract_dates(text) | |
| date_str = date[0] if date else "[date]" | |
| # Detect specific lies | |
| if 'treat everyone the same' in text_lower or 'treated like every other customer' in text_lower: | |
| lie = '"We treat everyone the same"' | |
| elif 'any disability you say you have' in text_lower: | |
| lie = '"Any disability you say you have"' | |
| else: | |
| lie = '"No reasonable adjustments required"' | |
| row = { | |
| "FACT": f"Disabled person (PIP/medical evidence) disclosed disability on {date_str}. Requested reasonable adjustments.", | |
| "LIE/DEFENSE": lie, | |
| "LAW": "Equality Act 2010 s.20 (duty to make reasonable adjustments); Archibald v Fife Council [2004] UKHL 32", | |
| "CONSEQUENCE": "Damages for injury to feelings (Vento middle band £11,700-£35,200) + adjustments implemented + aggravated damages" | |
| } | |
| rows.append(row) | |
| # 3. Refund reversal / account freeze | |
| if re.search(r'refund.*revers|chargeback.*deny|temporary refund.*withdraw|account.*block', text_lower): | |
| date = extract_dates(text) | |
| date_str = date[0] if date else "[date]" | |
| amount = extract_amounts(text) | |
| amount_str = f"£{amount[0]:,.2f}" if amount else "£[amount]" | |
| row = { | |
| "FACT": f"On {date_str}, temporary refund of {amount_str} reversed. Account frozen/blocked.", | |
| "LIE/DEFENSE": '"Merchant provided evidence goods were as described" / "Crash damage voids warranty"', | |
| "LAW": "Consumer Rights Act 2015 s.19(14); Payment Services Regulations 2017; FCA PRIN 6 (treat customers fairly)", | |
| "CONSEQUENCE": f"Reinstate refund {amount_str} + compensation for financial deprivation + aggravated damages" | |
| } | |
| rows.append(row) | |
| # 4. SAR / data breach | |
| if re.search(r'subject access|SAR|data protection|GDPR', text_lower): | |
| date = extract_dates(text) | |
| date_str = date[0] if date else "[date]" | |
| row = { | |
| "FACT": f"Subject Access Request filed on {date_str}. Response incomplete or withheld.", | |
| "LIE/DEFENSE": '"All data provided" / "Legal privilege / crime prevention exemption"', | |
| "LAW": "Data Protection Act 2018 s.15; UK GDPR Art 15; Gurieva v CSD [2020] (no blanket privilege)", | |
| "CONSEQUENCE": "Adverse inference in litigation + ICO complaint + damages for distress" | |
| } | |
| rows.append(row) | |
| # 5. Fraud markers / defamation | |
| if re.search(r'fraud (marker|allegation)|credit file', text_lower): | |
| date = extract_dates(text) | |
| date_str = date[0] if date else "[date]" | |
| row = { | |
| "FACT": f"On {date_str}, defendant placed fraud marker or made defamatory statement.", | |
| "LIE/DEFENSE": '"Investigation found evidence of fraud" / "Reasonable grounds to suspect"', | |
| "LAW": "Defamation Act 2013; Data Protection Act 2018 s.35 (unlawful processing)", | |
| "CONSEQUENCE": "Remove fraud marker + damages for defamation + credit file restoration" | |
| } | |
| rows.append(row) | |
| # 6. Hardship / financial crisis caused by defendant | |
| if re.search(r'no food|no electric|eviction|homeless|hunger|sugar water', text_lower): | |
| date = extract_dates(text) | |
| date_str = date[0] if date else "[date]" | |
| row = { | |
| "FACT": f"From {date_str}, defendant's actions caused severe hardship (no food, electricity, housing risk).", | |
| "LIE/DEFENSE": '"Customer responsible for own finances" / "No duty of care owed"', | |
| "LAW": "FCA PRIN 6 (treat customers fairly); Equality Act 2010 s.15 (discrimination arising from disability); Hadley v Baxendale (foreseeable loss)", | |
| "CONSEQUENCE": "Consequential loss + aggravated damages + exemplary damages for reckless disregard" | |
| } | |
| rows.append(row) | |
| # If no rows detected, add a default instructional row | |
| if not rows: | |
| rows.append({ | |
| "FACT": "Upload documents containing facts (emails, letters, statements)", | |
| "LIE/DEFENSE": "The AI will detect contradictions", | |
| "LAW": "Statutes will be cited automatically", | |
| "CONSEQUENCE": "Remedies will be calculated" | |
| }) | |
| return rows | |
| # ============================================================================ | |
| # AUDIO GENERATION (GTTS - RELIABLE) | |
| # ============================================================================ | |
| def generate_audio_gtts(passage_key): | |
| """Generate audio using gTTS (synchronous, no asyncio issues)""" | |
| text = BOOK_PASSAGES.get(passage_key, BOOK_PASSAGES["intro"]) | |
| try: | |
| tts = gTTS(text=text, lang='en', slow=False) | |
| with io.BytesIO() as output: | |
| tts.write_to_fp(output) | |
| output.seek(0) | |
| b64 = base64.b64encode(output.read()).decode() | |
| return f"data:audio/mp3;base64,{b64}", text | |
| except Exception as e: | |
| print(f"TTS error: {e}") | |
| return None, text | |
| # ============================================================================ | |
| # MAIN PROCESSING FUNCTION | |
| # ============================================================================ | |
| def process_uploaded_files(files): | |
| if not files: | |
| return "No files uploaded.", None, "", gr.DataFrame(value=pd.DataFrame()) | |
| all_text = "" | |
| file_list = [] | |
| for file in files: | |
| file_list.append(file.name) | |
| all_text += f"\n\n=== {file.name} ===\n\n{extract_text_from_file(file)}" | |
| # Build matrix | |
| matrix_rows = build_smart_matrix(all_text) | |
| df = pd.DataFrame(matrix_rows) | |
| # Create analysis summary | |
| analysis = f"""## Analysis Complete | |
| **Files uploaded:** {', '.join(file_list)} | |
| **Detected breach types:** | |
| {chr(10).join(['- ' + row['LAW'].split(';')[0] for row in matrix_rows[:3]]) if matrix_rows else '- None detected'} | |
| **Key smoking guns found:** | |
| """ | |
| # Find smoking guns | |
| guns = [] | |
| if any(x in all_text.lower() for x in ['treat everyone the same', 'treated like every other customer']): | |
| guns.append('"Treated like every other customer" (Eversheds letter)') | |
| if 'any disability you say you have' in all_text.lower(): | |
| guns.append('"Any disability you say you have" (direct discrimination admission)') | |
| if 'warranty void' in all_text.lower(): | |
| guns.append('Crash damage voiding warranty (circular liability)') | |
| if 'expert report' in all_text.lower(): | |
| guns.append('Demand for independent expert report (unlawful burden shift)') | |
| analysis += chr(10).join(['- ' + g for g in guns]) if guns else '- None explicitly found' | |
| analysis += """ | |
| **Your matrix is ready.** Edit any cell below if needed. Then use the tabs to generate documents or calculate damages. | |
| """ | |
| # Determine which audio passage is most relevant | |
| passage = "intro" | |
| if any(x in all_text.lower() for x in ['faulty', 'defective', 'refund']): | |
| passage = "cra_burden_flip" | |
| elif any(x in all_text.lower() for x in ['disab', 'pip', 'reasonable adjustment']): | |
| passage = "equality_act" | |
| elif 'subject access' in all_text.lower(): | |
| passage = "sar_weapon" | |
| audio_b64, passage_text = generate_audio_gtts(passage) | |
| return analysis, audio_b64, passage_text, df | |
| # ============================================================================ | |
| # DOCUMENT GENERATORS | |
| # ============================================================================ | |
| def generate_lbc(name, address, defendant, defendant_addr, matrix_df): | |
| if matrix_df is None or matrix_df.empty: | |
| matrix_summary = "Matrix not available. Please upload documents first." | |
| else: | |
| rows = [] | |
| for _, row in matrix_df.iterrows(): | |
| rows.append(f"• {row['FACT']} – {row['LIE/DEFENSE']} – breach of {row['LAW'].split(';')[0]}") | |
| matrix_summary = "\n".join(rows) | |
| return f"""LETTER BEFORE CLAIM | |
| PRE-ACTION PROTOCOL | |
| {name} | |
| {address} | |
| {datetime.now().strftime("%d %B %Y")} | |
| {defendant} | |
| {defendant_addr} | |
| Dear Sir/Madam, | |
| RE: FORMAL NOTICE OF STATUTORY BREACHES AND INTENDED PROCEEDINGS | |
| I write in accordance with the Civil Procedure Rules Pre-Action Protocol to provide formal notice of your statutory breaches and my intention to commence proceedings without further notice if not resolved within 30 days. | |
| **Summary of breaches:** | |
| {matrix_summary} | |
| **Remedy sought:** | |
| - Full refund / account reinstatement | |
| - Compensation for distress, discrimination, and consequential losses | |
| - Removal of any adverse credit or fraud markers | |
| - Formal written apology | |
| I require a written response within 30 days stating: | |
| 1. Which breaches you admit or deny | |
| 2. Your proposed remedy | |
| 3. A timeline for implementation | |
| If I do not receive a satisfactory response, I will issue proceedings in the County Court / High Court without further notice. This letter will be relied upon for adverse costs. | |
| Yours faithfully, | |
| {name} | |
| """ | |
| def generate_sar(name, address, defendant): | |
| return f"""SUBJECT ACCESS REQUEST | |
| Data Protection Act 2018 s.15 & UK GDPR Article 15 | |
| {name} | |
| {address} | |
| {datetime.now().strftime("%d %B %Y")} | |
| Data Protection Officer | |
| {defendant} | |
| Dear Data Controller, | |
| I hereby make a formal Subject Access Request under Section 15 of the Data Protection Act 2018 and Article 15 of the UK General Data Protection Regulation. | |
| I request that you provide me with ALL personal data you hold about me, including but not limited to: | |
| 1. All internal and external emails, letters, and memos that refer to me or my account | |
| 2. All customer relationship management (CRM) notes, case notes, and call logs | |
| 3. All audio recordings of telephone conversations and their transcripts | |
| 4. All fraud markers, risk assessments, credit file notes, and CIFAS markers | |
| 5. All information shared with third parties (including credit reference agencies) | |
| 6. All information used to make any automated decision affecting me | |
| Under Gurieva v Community Safety Development (CSD) [2020], you cannot make blanket claims of legal privilege or crime prevention exemption. You must identify specific documents and prove actual prejudice. | |
| I understand that you must respond within one month (30 days) of receiving this request. Please provide the data in electronic format. | |
| Yours faithfully, | |
| {name} | |
| """ | |
| def calculate_damages(direct, injury, consequential, aggravated): | |
| total = (direct or 0) + (injury or 0) + (consequential or 0) + (aggravated or 0) | |
| if total <= 10000: | |
| court = "County Court – Small Claims Track" | |
| fee = 455 if total > 5000 else 205 | |
| elif total <= 100000: | |
| court = "County Court – Fast Track" | |
| fee = min(10000, total * 0.05) | |
| else: | |
| court = "High Court – Multi Track" | |
| fee = min(10000, total * 0.05) | |
| return f"""## Total Claim Value: £{total:,.2f} | |
| **Breakdown:** | |
| - Direct loss: £{direct or 0:,.2f} | |
| - Injury to feelings: £{injury or 0:,.2f} | |
| - Consequential loss: £{consequential or 0:,.2f} | |
| - Aggravated/exemplary damages: £{aggravated or 0:,.2f} | |
| **Court track:** {court} | |
| **Estimated filing fee:** £{fee:,.2f} | |
| **Help with fees:** Apply using EX160 if you receive benefits or have low income. | |
| """ | |
| # ============================================================================ | |
| # GRADIO INTERFACE | |
| # ============================================================================ | |
| with gr.Blocks(title="Black Polished Chrome - Litigation Infiltration", theme=gr.themes.Soft()) as demo: | |
| gr.Markdown(""" | |
| # ⚖️ BLACK POLISHED CHROME | |
| ## Litigation Infiltration - AI Auto-Builder | |
| ### By Dwayne Anthony Brian Galloway | |
| **Upload your documents – AI builds your case matrix automatically.** | |
| """) | |
| with gr.Tab("📄 Upload & Build"): | |
| gr.Markdown("Upload emails, letters, bank statements, medical reports – any evidence.") | |
| files_input = gr.Files(file_types=[".pdf", ".docx", ".txt"], file_count="multiple", label="Upload documents") | |
| build_btn = gr.Button("🚀 Build Matrix", variant="primary", size="lg") | |
| analysis_output = gr.Markdown() | |
| audio_output = gr.Audio(label="Listen to relevant passage (optional)", type="numpy") | |
| passage_output = gr.Textbox(label="Audio transcript", lines=8) | |
| gr.Markdown("### Your Fact-Lie-Law-Consequence Matrix (editable)") | |
| matrix_df = gr.Dataframe(label="Matrix - edit cells directly", interactive=True, wrap=True) | |
| build_btn.click( | |
| fn=process_uploaded_files, | |
| inputs=[files_input], | |
| outputs=[analysis_output, audio_output, passage_output, matrix_df] | |
| ) | |
| with gr.Tab("📝 Generate Documents"): | |
| gr.Markdown("### Your details") | |
| your_name = gr.Textbox(label="Your full name") | |
| your_address = gr.Textbox(label="Your address", lines=2) | |
| def_name = gr.Textbox(label="Defendant name (e.g., Bank of Scotland plc)") | |
| def_addr = gr.Textbox(label="Defendant address", lines=2) | |
| gr.Markdown("### Letter Before Claim") | |
| lbc_btn = gr.Button("Generate LBC", variant="secondary") | |
| lbc_out = gr.Textbox(label="Copy and paste into Word", lines=20) | |
| gr.Markdown("### Subject Access Request (SAR)") | |
| sar_btn = gr.Button("Generate SAR", variant="secondary") | |
| sar_out = gr.Textbox(label="Copy and paste", lines=20) | |
| lbc_btn.click( | |
| fn=generate_lbc, | |
| inputs=[your_name, your_address, def_name, def_addr, matrix_df], | |
| outputs=[lbc_out] | |
| ) | |
| sar_btn.click( | |
| fn=generate_sar, | |
| inputs=[your_name, your_address, def_name], | |
| outputs=[sar_out] | |
| ) | |
| with gr.Tab("💰 Calculate Damages"): | |
| gr.Markdown("### Vento bands (discrimination)") | |
| gr.Markdown("- Lower: £1,200 – £11,700 \n- Middle: £11,700 – £35,200 \n- Upper: £35,200 – £58,700") | |
| direct_input = gr.Number(label="Direct loss (£)", value=0) | |
| injury_input = gr.Number(label="Injury to feelings (£)", value=15000) | |
| cons_input = gr.Number(label="Consequential loss (£)", value=0) | |
| agg_input = gr.Number(label="Aggravated/exemplary (£)", value=5000) | |
| calc_btn = gr.Button("Calculate total", variant="primary") | |
| total_out = gr.Markdown() | |
| calc_btn.click( | |
| fn=calculate_damages, | |
| inputs=[direct_input, injury_input, cons_input, agg_input], | |
| outputs=[total_out] | |
| ) | |
| with gr.Tab("ℹ️ Help"): | |
| gr.Markdown(""" | |
| ## How to use Black Polished Chrome | |
| 1. **Upload** your evidence files (PDF, Word, TXT) | |
| 2. **Click** "Build Matrix" | |
| 3. **Edit** any matrix cells directly (dates, amounts, law, consequence) | |
| 4. **Generate** Letter Before Claim and SAR | |
| 5. **Calculate** your damages | |
| ### The Matrix is your weapon | |
| Each row is a separate legal breach. The judge will see: | |
| - What happened | |
| - What they lied about | |
| - Which law they broke | |
| - What they owe you | |
| ### Need help? | |
| The audio passages explain key legal concepts. Listen to the one that matches your case. | |
| ### Disclaimer | |
| This is an educational tool. Not legal advice. Consult a solicitor for complex claims. | |
| """) | |
| demo.launch() |