Giter Club home page Giter Club logo

stirling-pdf's Introduction

Stirling-PDF

Docker Pulls Discord Docker Image Version (tag latest semver) GitHub Repo stars Paypal Donate Github Sponsor

Deploy to DO

This is a robust, locally hosted web-based PDF manipulation tool using Docker. It enables you to carry out various operations on PDF files, including splitting, merging, converting, reorganizing, adding images, rotating, compressing, and more. Originally developed entirely by ChatGPT, this locally hosted web application has evolved to encompass a comprehensive set of features, addressing all your PDF requirements.

Stirling PDF does not initiate any outbound calls for record-keeping or tracking purposes.

All files and PDFs exist either exclusively on the client side, reside in server memory only during task execution, or temporarily reside in a file solely for the execution of the task. Any file downloaded by the user will have been deleted from the server by that point.

stirling-home

Features

  • Dark mode support.
  • Custom download options (see here for example)
  • Parallel file processing and downloads
  • API for integration with external scripts
  • Optional Login and Authentication support (see here for documentation)

PDF Features

Page Operations

  • View and modify PDFs - View multi page PDFs with custom viewing sorting and searching. Plus on page edit features like annotate, draw and adding text and images. (Using PDF.js with Joxit and Liberation.Liberation fonts)
  • Full interactive GUI for merging/splitting/rotating/moving PDFs and their pages.
  • Merge multiple PDFs together into a single resultant file.
  • Split PDFs into multiple files at specified page numbers or extract all pages as individual files.
  • Reorganize PDF pages into different orders.
  • Rotate PDFs in 90-degree increments.
  • Remove pages.
  • Multi-page layout (Format PDFs into a multi-paged page).
  • Scale page contents size by set %.
  • Adjust Contrast.
  • Crop PDF.
  • Auto Split PDF (With physically scanned page dividers).
  • Extract page(s).
  • Convert PDF to a single page.

Conversion Operations

  • Convert PDFs to and from images.
  • Convert any common file to PDF (using LibreOffice).
  • Convert PDF to Word/Powerpoint/Others (using LibreOffice).
  • Convert HTML to PDF.
  • URL to PDF.
  • Markdown to PDF.

Security & Permissions

  • Add and remove passwords.
  • Change/set PDF Permissions.
  • Add watermark(s).
  • Certify/sign PDFs.
  • Sanitize PDFs.
  • Auto-redact text.

Other Operations

  • Add/Generate/Write signatures.
  • Repair PDFs.
  • Detect and remove blank pages.
  • Compare 2 PDFs and show differences in text.
  • Add images to PDFs.
  • Compress PDFs to decrease their filesize (Using OCRMyPDF).
  • Extract images from PDF.
  • Extract images from Scans.
  • Add page numbers.
  • Auto rename file by detecting PDF header text.
  • OCR on PDF (Using OCRMyPDF).
  • PDF/A conversion (Using OCRMyPDF).
  • Edit metadata.
  • Flatten PDFs.
  • Get all information on a PDF to view or export as JSON.

For a overview of the tasks and the technology each uses please view Endpoint-groups.md Demo of the app is available here. username: demo, password: demo

Technologies used

How to use

Locally

Please view https://github.com/Stirling-Tools/Stirling-PDF/blob/main/LocalRunGuide.md

Docker / Podman

https://hub.docker.com/r/frooodle/s-pdf

Stirling PDF has 2 different versions, a Full version and ultra-Lite version. Depending on the types of features you use you may want a smaller image to save on space. To see what the different versions offer please look at our version mapping For people that don't mind about space optimization just use the latest tag. Docker Image Size (tag) Docker Image Size (tag)

Docker Run

docker run -d \
  -p 8080:8080 \
  -v /location/of/trainingData:/usr/share/tessdata \
  -v /location/of/extraConfigs:/configs \
  -v /location/of/logs:/logs \
  -e DOCKER_ENABLE_SECURITY=false \
  -e INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false \
  -e LANGS=en_GB \
  --name stirling-pdf \
  frooodle/s-pdf:latest


  Can also add these for customisation but are not required

  -v /location/of/customFiles:/customFiles \

Docker Compose

version: '3.3'
services:
  stirling-pdf:
    image: frooodle/s-pdf:latest
    ports:
      - '8080:8080'
    volumes:
      - /location/of/trainingData:/usr/share/tessdata #Required for extra OCR languages
      - /location/of/extraConfigs:/configs
#      - /location/of/customFiles:/customFiles/
#      - /location/of/logs:/logs/
    environment:
      - DOCKER_ENABLE_SECURITY=false
      - INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false
      - LANGS=en_GB

Note: Podman is CLI-compatible with Docker, so simply replace "docker" with "podman".

Enable OCR/Compression feature

Please view https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToUseOCR.md

Supported Languages

Stirling PDF currently supports 27!

Language Progress
English (English) (en_GB) 100%
English (US) (en_US) 100%
Arabic (العربية) (ar_AR) 58%
German (Deutsch) (de_DE) 98%
French (Français) (fr_FR) 93%
Spanish (Español) (es_ES) 99%
Simplified Chinese (简体中文) (zh_CN) 98%
Traditional Chinese (繁體中文) (zh_TW) 98%
Catalan (Català) (ca_CA) 64%
Italian (Italiano) (it_IT) 98%
Swedish (Svenska) (sv_SE) 58%
Polish (Polski) (pl_PL) 59%
Romanian (Română) (ro_RO) 57%
Korean (한국어) (ko_KR) 93%
Portuguese Brazilian (Português) (pt_BR) 73%
Russian (Русский) (ru_RU) 93%
Basque (Euskara) (eu_ES) 75%
Japanese (日本語) (ja_JP) 93%
Dutch (Nederlands) (nl_NL) 91%
Greek (Ελληνικά) (el_GR) 91%
Turkish (Türkçe) (tr_TR) 99%
Indonesia (Bahasa Indonesia) (id_ID) 86%
Hindi (हिंदी) (hi_IN) 87%
Hungarian (Magyar) (hu_HU) 86%
Bulgarian (Български) (bg_BG) 81%
Sebian Latin alphabet (Srpski) (sr_LATN_RS) 88%
Ukrainian (Українська) (uk_UA) 93%

Contributing (creating issues, translations, fixing bugs, etc.)

Please see our Contributing Guide!

Customisation

Stirling PDF allows easy customization of the app. Includes things like

  • Custom application name
  • Custom slogans, icons, images, and even custom HTML (via file overrides)

There are two options for this, either using the generated settings file settings.yml This file is located in the /configs directory and follows standard YAML formatting

Environment variables are also supported and would override the settings file For example in the settings.yml you have

system:
  defaultLocale: 'en-US'

To have this via an environment variable you would have SYSTEM_DEFAULTLOCALE

The Current list of settings is

security:
  enableLogin: false # set to 'true' to enable login
  csrfDisabled: true

system:
  defaultLocale: 'en-US' # Set the default language (e.g. 'de-DE', 'fr-FR', etc)
  googlevisibility: false # 'true' to allow Google visibility (via robots.txt), 'false' to disallow
  customStaticFilePath: '/customFiles/static/' # Directory path for custom static files
  showUpdate: true # see when a new update is available
  showUpdateOnlyAdmin: false # Only admins can see when a new update is available, depending on showUpdate it must be set to 'true'

#ui:
#  appName: exampleAppName # Application's visible name
#  homeDescription: I am a description # Short description or tagline shown on homepage.
#  appNameNavbar: navbarName # Name displayed on the navigation bar

endpoints:
  toRemove: [] # List endpoints to disable (e.g. ['img-to-pdf', 'remove-pages'])
  groupsToRemove: [] # List groups to disable (e.g. ['LibreOffice'])

metrics:
  enabled: true # 'true' to enable Info APIs endpoints (view http://localhost:8080/swagger-ui/index.html#/API to learn more), 'false' to disable

Extra notes

  • Endpoints. Currently, the endpoints ENDPOINTS_TO_REMOVE and GROUPS_TO_REMOVE can include comma separate lists of endpoints and groups to disable as example ENDPOINTS_TO_REMOVE=img-to-pdf,remove-pages would disable both image-to-pdf and remove pages, GROUPS_TO_REMOVE=LibreOffice Would disable all things that use LibreOffice. You can see a list of all endpoints and groups here
  • customStaticFilePath. Customise static files such as the app logo by placing files in the /customFiles/static/ directory. An example of customising app logo is placing a /customFiles/static/favicon.svg to override current SVG. This can be used to change any images/icons/css/fonts/js etc in Stirling-PDF

Environment only parameters

  • SYSTEM_ROOTURIPATH ie set to /pdf-app to Set the application's root URI to localhost:8080/pdf-app
  • SYSTEM_CONNECTIONTIMEOUTMINUTES to set custom connection timeout values
  • DOCKER_ENABLE_SECURITY to tell docker to download security jar (required as true for auth login)
  • INSTALL_BOOK_AND_ADVANCED_HTML_OPS to download calibre onto stirling-pdf enabling pdf to/from book and advanced html conversion
  • LANGS to define custom font libraries to install for use for document conversions

API

For those wanting to use Stirling-PDFs backend API to link with their own custom scripting to edit PDFs you can view all existing API documentation here or navigate to /swagger-ui/index.html of your stirling-pdf instance for your versions documentation (Or by following the API button in your settings of Stirling-PDF)

Login authentication

stirling-login

Prerequisites:

  • User must have the folder ./configs volumed within docker so that it is retained during updates.
  • Docker uses must download the security jar version by setting DOCKER_ENABLE_SECURITY to true in environment variables.
  • Then either enable login via the settings.yml file or via setting SECURITY_ENABLE_LOGIN to true
  • Now the initial user will be generated with username admin and password stirling. On login you will be forced to change the password to a new one. You can also use the environment variables SECURITY_INITIALLOGIN_USERNAME and SECURITY_INITIALLOGIN_PASSWORD to set your own straight away (Recommended to remove them after user creation).

Once the above has been done, on restart, a new stirling-pdf-DB.mv.db will show if everything worked.

When you login to Stirling PDF you will be redirected to /login page to login with those default credentials. After login everything should function as normal

To access your account settings go to Account settings in the settings cog menu (top right in navbar) This Account settings menu is also where you find your API key.

To add new users go to the bottom of Account settings and hit 'Admin Settings', here you can add new users. The different roles mentioned within this are for rate limiting. This is a Work in progress which will be expanding on more in future

For API usage you must provide a header with 'X-API-Key' and the associated API key for that user.

FAQ

Q1: What are your planned features?

  • Progress bar/Tracking
  • Full custom logic pipelines to combine multiple operations together.
  • Folder support with auto scanning to perform operations on
  • Redact text (Via UI not just automated way)
  • Add Forms
  • Multi page layout (Stich PDF pages together) support x rows y columns and custom page sizing
  • Fill forms manually or automatically

Q2: Why is my application downloading .htm files?

This is an issue caused commonly by your NGINX configuration. The default file upload size for NGINX is 1MB, you need to add the following in your Nginx sites-available file. client_max_body_size SIZE; Where "SIZE" is 50M for example for 50MB files.

Q3: Why is my download timing out

NGINX has timeout values by default so if you are running Stirling-PDF behind NGINX you may need to set a timeout value such as adding the config proxy_read_timeout 3600;

stirling-pdf's People

Contributors

92mn avatar aancw avatar adrielcarmoufms avatar albanobattistella avatar boredsquirrel avatar c-jaenicke avatar cloud-erik avatar cocomastergo avatar dependabot[bot] avatar dimk10 avatar frooodle avatar github-actions[bot] avatar ilern avatar inazkue avatar jordyjordy avatar ludy87 avatar mannam11 avatar manuelkamp avatar marco-79 avatar michelheusschen avatar neiljared avatar nicolasfr avatar omerbustun avatar peterdavehello avatar pixeebot avatar pl4nty avatar sbplat avatar sf298 avatar tkymmm avatar zoey2936 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stirling-pdf's Issues

Compress PDF page is broken

image

Command error output:
Using Tesseract OpenMP thread limit 2
Start processing 21 pages concurrently
PriorOcrFoundError: page already has text! - aborting (use --force-ocr to force OCR;  see also help for the arguments --skip-text and --redo-ocr
2023-03-22T13:42:03.393-04:00 ERROR 1 --- [nio-8080-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception

java.io.IOException: Command process failed with exit code 6. Error message: Using Tesseract OpenMP thread limit 2
Start processing 21 pages concurrently
PriorOcrFoundError: page already has text! - aborting (use --force-ocr to force OCR;  see also help for the arguments --skip-text and --redo-ocr
        at stirling.software.SPDF.utils.ProcessExecutor.runCommandWithOutputHandling(ProcessExecutor.java:61) ~[classes!/:0.4.0]
        at stirling.software.SPDF.controller.CompressController.optimizePdf(CompressController.java:100) ~[classes!/:0.4.0]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207) ~[spring-web-6.0.5.jar!/:6.0.5]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152) ~[spring-web-6.0.5.jar!/:6.0.5]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-6.0.5.jar!/:6.0.5]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) ~[spring-webmvc-6.0.5.jar!/:6.0.5]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-6.0.5.jar!/:6.0.5]
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.0.5.jar!/:6.0.5]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081) ~[spring-webmvc-6.0.5.jar!/:6.0.5]
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974) ~[spring-webmvc-6.0.5.jar!/:6.0.5]
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) ~[spring-webmvc-6.0.5.jar!/:6.0.5]
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.0.5.jar!/:6.0.5]
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:731) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.0.5.jar!/:6.0.5]
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:814) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:223) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.0.5.jar!/:6.0.5]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.5.jar!/:6.0.5]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.0.5.jar!/:6.0.5]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.5.jar!/:6.0.5]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.0.5.jar!/:6.0.5]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.5.jar!/:6.0.5]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:119) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:741) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:400) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:859) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1734) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

Is there support for aarch64?

I'm running Ubuntu-20.04-aarch64 on Oracle Free Tier and when trying to start the container I get "exec /bin/sh: exec format error".
Am I doing something wrong or is it just not supported?

Feature request: Multitool - Bookmark Passthrough

Some PDFs (mostly documents) have embedded bookmarks that let users jump to a specific location. Currently if parsing a document, any existing bookmarks are lost.

I don't think the existing pdf writer (Hopding /pdf-lib supports retaining chapters, as it was in the roadmap SEP-2021 Hopding/pdf-lib#998, but the maintainers last contribution on github was NOV-2021.

I found this, Don't know if it's going to be of any use
https://github.com/xianghuzhao/pdf-bookmark

Feature request: OCR

Firstly - thanks for this neat project, I was looking for exactly something like this few days ago.

Would it possible to add OCR as one of the tools? There's a good working CLI tool called OCRmyPDF so maybe it wouldn't be too hard to implement.

There is a typo in the new image to pdf implementation

The field for selecting images has a wrong label/placeholder

Expected behaviour:
The field says "Select Image(s)"

Actual behaviour:
The field says "Select PDF(s)"

How to reproduce:
Visit the page for the image converter, read the label.

Error when compressing PDF

Stack Trace:
com.spire.pdf.packages.sprlBc: Neutral cultures cannot be used in formatting and parsing and therefore cannot be set as the thread's current culture at com.spire.pdf.packages.sprxuB.spr� (klf:255) at com.spire.pdf.PdfPageBase.spr (Unknown Source) at com.spire.pdf.PdfPageBase.getImagesInfo(Unknown Source) at stirling.software.SPDF.controller.CompressController.compressPDF(CompressController.java:51) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1080) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:973) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:731) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:814) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:223) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:119) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:741) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:400) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:859) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1734) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:833)
image

Complete Log:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.0.2)

2023-03-06T03:03:10.164-05:00  INFO 1 --- [           main] stirling.software.SPDF.SPdfApplication   : Starting SPdfApplication using Java 17.0.2 with PID 1 (/app.jar started by root in /)
2023-03-06T03:03:10.168-05:00  INFO 1 --- [           main] stirling.software.SPDF.SPdfApplication   : No active profile set, falling back to 1 default profile: "default"
2023-03-06T03:03:11.466-05:00  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2023-03-06T03:03:11.480-05:00  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-03-06T03:03:11.480-05:00  INFO 1 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.5]
2023-03-06T03:03:11.601-05:00  INFO 1 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-03-06T03:03:11.604-05:00  INFO 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1362 ms
2023-03-06T03:03:12.159-05:00  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2023-03-06T03:03:12.179-05:00  INFO 1 --- [           main] stirling.software.SPDF.SPdfApplication   : Started SPdfApplication in 2.612 seconds (process running for 3.303)
2023-03-08T10:02:49.268-05:00  INFO 1 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-03-08T10:02:49.268-05:00  INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2023-03-08T10:02:49.270-05:00  INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
2023-03-08T10:03:39.773-05:00 ERROR 1 --- [nio-8080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: com.spire.pdf.packages.sprlBc: Neutral cultures cannot be used in formatting and parsing and therefore cannot be set as the thread's current culture] with root cause

com.spire.pdf.packages.sprlBc: Neutral cultures cannot be used in formatting and parsing and therefore cannot be set as the thread's current culture
        at com.spire.pdf.packages.sprxuB.spr (klf:255) ~[spire.pdf.free-5.1.0.jar!/:5.1.0]
        at com.spire.pdf.PdfPageBase.spr  (Unknown Source) ~[spire.pdf.free-5.1.0.jar!/:5.1.0]
        at com.spire.pdf.PdfPageBase.getImagesInfo(Unknown Source) ~[spire.pdf.free-5.1.0.jar!/:5.1.0]
        at stirling.software.SPDF.controller.CompressController.compressPDF(CompressController.java:51) ~[classes!/:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207) ~[spring-web-6.0.4.jar!/:6.0.4]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152) ~[spring-web-6.0.4.jar!/:6.0.4]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-6.0.4.jar!/:6.0.4]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) ~[spring-webmvc-6.0.4.jar!/:6.0.4]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-6.0.4.jar!/:6.0.4]
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.0.4.jar!/:6.0.4]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1080) ~[spring-webmvc-6.0.4.jar!/:6.0.4]
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:973) ~[spring-webmvc-6.0.4.jar!/:6.0.4]
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) ~[spring-webmvc-6.0.4.jar!/:6.0.4]
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.0.4.jar!/:6.0.4]
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:731) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.0.4.jar!/:6.0.4]
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:814) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:223) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.0.4.jar!/:6.0.4]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.4.jar!/:6.0.4]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.0.4.jar!/:6.0.4]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.4.jar!/:6.0.4]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.0.4.jar!/:6.0.4]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.4.jar!/:6.0.4]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:119) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:741) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:400) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:859) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1734) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.0.2)

2023-03-08T10:20:21.295-05:00  INFO 1 --- [           main] stirling.software.SPDF.SPdfApplication   : Starting SPdfApplication using Java 17.0.2 with PID 1 (/app.jar started by root in /)
2023-03-08T10:20:21.299-05:00  INFO 1 --- [           main] stirling.software.SPDF.SPdfApplication   : No active profile set, falling back to 1 default profile: "default"
2023-03-08T10:20:22.460-05:00  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2023-03-08T10:20:22.471-05:00  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-03-08T10:20:22.471-05:00  INFO 1 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.5]
2023-03-08T10:20:22.582-05:00  INFO 1 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-03-08T10:20:22.584-05:00  INFO 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1217 ms
2023-03-08T10:20:23.060-05:00  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2023-03-08T10:20:23.080-05:00  INFO 1 --- [           main] stirling.software.SPDF.SPdfApplication   : Started SPdfApplication in 2.343 seconds (process running for 2.985)
2023-03-08T10:20:32.241-05:00  INFO 1 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-03-08T10:20:32.241-05:00  INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2023-03-08T10:20:32.242-05:00  INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
2023-03-08T10:20:46.678-05:00 ERROR 1 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: com.spire.pdf.packages.sprlBc: Neutral cultures cannot be used in formatting and parsing and therefore cannot be set as the thread's current culture] with root cause

com.spire.pdf.packages.sprlBc: Neutral cultures cannot be used in formatting and parsing and therefore cannot be set as the thread's current culture
        at com.spire.pdf.packages.sprxuB.spr (klf:255) ~[spire.pdf.free-5.1.0.jar!/:5.1.0]
        at com.spire.pdf.PdfPageBase.spr  (Unknown Source) ~[spire.pdf.free-5.1.0.jar!/:5.1.0]
        at com.spire.pdf.PdfPageBase.getImagesInfo(Unknown Source) ~[spire.pdf.free-5.1.0.jar!/:5.1.0]
        at stirling.software.SPDF.controller.CompressController.compressPDF(CompressController.java:51) ~[classes!/:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207) ~[spring-web-6.0.4.jar!/:6.0.4]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152) ~[spring-web-6.0.4.jar!/:6.0.4]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-6.0.4.jar!/:6.0.4]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) ~[spring-webmvc-6.0.4.jar!/:6.0.4]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-6.0.4.jar!/:6.0.4]
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.0.4.jar!/:6.0.4]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1080) ~[spring-webmvc-6.0.4.jar!/:6.0.4]
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:973) ~[spring-webmvc-6.0.4.jar!/:6.0.4]
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) ~[spring-webmvc-6.0.4.jar!/:6.0.4]
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.0.4.jar!/:6.0.4]
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:731) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.0.4.jar!/:6.0.4]
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:814) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:223) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.0.4.jar!/:6.0.4]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.4.jar!/:6.0.4]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.0.4.jar!/:6.0.4]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.4.jar!/:6.0.4]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.0.4.jar!/:6.0.4]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.4.jar!/:6.0.4]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:119) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:741) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:400) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:859) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1734) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

Support for Reverse proxies

I would really appreciate if you could add support for reverse proxies like Apache, Caddy, Traefik and others.

To support reverse proxies in spring boot according to the docs what you have to do is simple.
Add this line to the application.properties:
server.forward-headers-strategy=NATIVE

[Feature Request] - Rest API

Hi,

I was just wondering if there were any plans to provide an API interface, where I can e.g. post a pdf and ask it to remove pages 2, 4 and 7 etc.

Remove Pages - URL incorrect on Home page

Remove Pages on home page redirects to /remove-pages which throws error
image

It works from top navigation as it redirects to /delete-pages

I believe it should be remove-pages and top nav should match that to be consistent with naming conventions

Cheers!

Compression does not always reduce the size of files??

I think that the pdf compression to reduce the size does not work correctly or not always with all types of pdf, possibly it is not able to reduce the quality of the images to 150dpi or similar. Is this failure possible or is it a limitation? I tried to compress to reduce the size of 3mb using any of the 3 options and all exports left the file size practically the same. But using PDF4me (API mode with app or automation) has been able to reduce it to 800kbs (web mode) and 1.5mbs (print mode). I include the pdf that you can try to try the compression. Thanks anyway, your project is very good, very useful and I love it!
ATHLET_ES_low.pdf

Struggling with Rest API

Hello there, first of all, congrats for such a nice work.

Since I can do a curl to rest api im testing if I can remove password from there; it works well from web ui but as I have lots of files with password I would like to use the API and make a script to remove passwords from all files.
Im not going deep in the script here, but I post the api call:

curl -X 'POST' \
  'http://192.168.2.43:8087/remove-password?password=actualpdfpassword' \
  -H 'accept: */*' \
  -H 'Content-Type: multipart/form-data' \
  -F 'fileInput=/share/Container/pdf/07.pdf;type=application/pdf' \
  -o '/share/Container/pdf/NO_PASS.pdf'

it creates a 0Kb NO_PASS.pdf file

here the command from my actual instance: http://192.168.2.43:8087/swagger-ui/index.html

curl -X 'POST' \
  'http://192.168.2.43:8087/remove-password?password=actualpdfpassword' \
  -H 'accept: */*' \
  -H 'Content-Type: multipart/form-data' \
  -F '[email protected];type=application/pdf'

what Im doing wrong here? any suggestion?
Running Stirling-PDF from docker BTW

Thanks so much in advance!

Missing Output Types

Missing JPG, GIF formats for PDF To Image. Was in previous version. Running Latest Update.
S-PDF

Idea: PDF document preview

It would be great to have some form of preview for PDF. Now when I want to ie: rearrange PDF i need to check locally what pages I need to rearrange and than provide that in StirlingPDF. It would be great to do this interactively.

Remove Password doesn't work

As the title says, Remove Password doesn't work. It just gives me a smaller file, albeit still being password-locked.

Application Logo

Hey

I like your project a lot and I want to add it to the service list in Kubero. This will allow users an easy installation on a Kubernetes cluster. But I need a (more or less) square icon/logo .

image

Change contrast option on existing PDF

Great project first and foremost!

I had been looking for a replacement for the aging zpex/web-pdf-toolbox (https://hub.docker.com/r/zpex/web-pdf-toolbox) - since it has not been updated since 10/07/2021 - An as of recently I've had to re-pull or restart it to get things working again.

So Stirling-PDF was perfect timing.

One of the options that the Zpex project has is the ability to adjust the contrast on existing PDF. Might this be a feature/function that could be added at some point in the future.

Again great project and thank you for your time and consideration.

Translations

I would like to translate Stirling to Polish. Earlier in other systems I use Weblate. Maybe You would consider to make Your app multilanguage and set new projest in weblate

Error 400 adding Watermark

Hi,
when adding watermark I am getting following error:

2023-02-06 07_28_46-Mozilla Firefox

I have standard Docker installation.
I am getting following error in logs:
06.02.2023 07:27:36 2023-02-06T06:27:36.381Z WARN 1 --- [nio-8080-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.multipart.support.MissingServletRequestPartException: Required part 'pdfFile' is not present.] 06.02.2023 07:28:40 2023-02-06T06:28:40.862Z WARN 1 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.multipart.support.MissingServletRequestPartException: Required part 'pdfFile' is not present.] 06.02.2023 07:30:30 2023-02-06T06:30:30.525Z WARN 1 --- [nio-8080-exec-9] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.multipart.support.MissingServletRequestPartException: Required part 'pdfFile' is not present.]

Seems like PDF file is not linked properly in form?

[Bug] Detect/Split Scanned photos needs scripts under root /scripts

"Detect/Split Scanned photos" searches for the script "split_photos.py" under root /scripts/ and not under the Stirling-PDF install folder ./scripts/. This may work in docker installations but needs to copy or symlink the scripts folder to / in standard installations.

Feature request: Image extraction from PDFs

First of all, thanks for your work on this excellent project.

For my workflow a feature to extract the pictures embedded in a pdf would be really helpful. Because I need this feature somewhat often I still have to use a desktop pdf editor.

Thanks in advance

OCR Doesn't seem to make the PDF searchable

After using OCR on a PDF with a scanned image, the resulting pdf also has just a image, no searchable or text I can copy.
If I select the option to Produce a text file along with OCR, I can see that the OCR process does run, it just seems the output PDF does not contain this information.

If I use the option to forceOCR on all pages, then even pages that were searchable are now not.

I am running Stirling-PDF on docker, lastest tag as of 27/04/2023.
App Version 0.6.0
Tesseract Model - tessdata eng (the bigger one, not fast)

Error when filename contains non-English characters

Hi, when I try to merge or rotate pdf files with Chinese name, the site returns error 'contentType is null'
Here is the log:

2023-04-24T10:32:15.988Z  WARN 7 --- [nio-8080-exec-6] o.apache.coyote.http11.Http11Processor   : The HTTP response header [Content-Disposition] with value [form-data; name="attachment"; filename="AIGC大时代,光模块产业迎风启航-浙商证券-2023.4.14-41页_merged.pdf"] has been removed from the response because it is invalid

java.lang.IllegalArgumentException: The Unicode character [大] at code point [22,823] cannot be encoded as it is outside the permitted range of 0 to 255
        at org.apache.tomcat.util.buf.MessageBytes.toBytesSimple(MessageBytes.java:290) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.tomcat.util.buf.MessageBytes.toBytes(MessageBytes.java:261) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.coyote.http11.Http11OutputBuffer.write(Http11OutputBuffer.java:389) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.coyote.http11.Http11OutputBuffer.sendHeader(Http11OutputBuffer.java:368) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.coyote.http11.Http11Processor.prepareResponse(Http11Processor.java:1049) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.coyote.AbstractProcessor.action(AbstractProcessor.java:376) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.coyote.Response.action(Response.java:208) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.coyote.http11.Http11OutputBuffer.doWrite(Http11OutputBuffer.java:187) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.coyote.Response.doWrite(Response.java:613) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:334) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.connector.OutputBuffer.appendByteArray(OutputBuffer.java:750) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:677) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:382) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:360) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:89) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.springframework.util.StreamUtils.copy(StreamUtils.java:119) ~[spring-core-6.0.7.jar!/:6.0.7]
        at org.springframework.http.converter.ByteArrayHttpMessageConverter.writeInternal(ByteArrayHttpMessageConverter.java:67) ~[spring-web-6.0.7.jar!/:6.0.7]
        at org.springframework.http.converter.ByteArrayHttpMessageConverter.writeInternal(ByteArrayHttpMessageConverter.java:38) ~[spring-web-6.0.7.jar!/:6.0.7]
        at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:226) ~[spring-web-6.0.7.jar!/:6.0.7]
        at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:300) ~[spring-webmvc-6.0.7.jar!/:6.0.7]
        at org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:245) ~[spring-webmvc-6.0.7.jar!/:6.0.7]
        at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:78) ~[spring-web-6.0.7.jar!/:6.0.7]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:136) ~[spring-webmvc-6.0.7.jar!/:6.0.7]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) ~[spring-webmvc-6.0.7.jar!/:6.0.7]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-6.0.7.jar!/:6.0.7]
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.0.7.jar!/:6.0.7]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081) ~[spring-webmvc-6.0.7.jar!/:6.0.7]
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974) ~[spring-webmvc-6.0.7.jar!/:6.0.7]
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) ~[spring-webmvc-6.0.7.jar!/:6.0.7]
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.0.7.jar!/:6.0.7]
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:563) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.0.7.jar!/:6.0.7]
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:631) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-10.1.7.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.0.7.jar!/:6.0.7]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.7.jar!/:6.0.7]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.0.7.jar!/:6.0.7]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.7.jar!/:6.0.7]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.0.7.jar!/:6.0.7]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.7.jar!/:6.0.7]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:738) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:894) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.7.jar!/:na]
        at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.