Showing preview only (2,823K chars total). Download the full file or copy to clipboard to get everything.
Repository: ldidry/lufi
Branch: master
Commit: 8f97fcc2f497
Files: 142
Total size: 2.6 MB
Directory structure:
gitextract_s0gul96a/
├── .gitignore
├── .gitlab-ci.yml
├── .provision/
│ ├── README.md
│ ├── ansible-role-lufi/
│ │ ├── README.md
│ │ ├── defaults/
│ │ │ └── main.yml
│ │ ├── files/
│ │ │ ├── cronjob
│ │ │ └── robots.txt
│ │ ├── handlers/
│ │ │ └── main.yml
│ │ ├── tasks/
│ │ │ ├── apprun.yml
│ │ │ ├── cron.yml
│ │ │ ├── dependencies.yml
│ │ │ ├── gitclone.yml
│ │ │ └── main.yml
│ │ ├── templates/
│ │ │ ├── lufi.conf.j2
│ │ │ └── update.sh
│ │ └── vars/
│ │ └── main.yml
│ └── terraform-aws-lufi/
│ ├── README.md
│ ├── lufi_startup.sh
│ ├── main.tf
│ ├── output.tf
│ ├── provider.tf
│ └── vars.tf
├── AUTHORS.md
├── CHANGELOG
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── cpanfile
├── cpanfile.snapshot
├── lib/
│ ├── Date/
│ │ └── Language/
│ │ └── Occitan.pm
│ ├── Lufi/
│ │ ├── Command/
│ │ │ ├── copyFilesToSwift.pm
│ │ │ ├── cron/
│ │ │ │ ├── cleanbdd.pm
│ │ │ │ ├── cleanfiles.pm
│ │ │ │ └── watch.pm
│ │ │ ├── cron.pm
│ │ │ ├── sqliteToOtherDB.pm
│ │ │ └── theme.pm
│ │ ├── Controller/
│ │ │ ├── Auth.pm
│ │ │ ├── Files.pm
│ │ │ ├── Invitation.pm
│ │ │ ├── Mail.pm
│ │ │ └── Misc.pm
│ │ ├── DB/
│ │ │ ├── File/
│ │ │ │ ├── Mysql.pm
│ │ │ │ ├── Pg.pm
│ │ │ │ └── SQLite.pm
│ │ │ ├── File.pm
│ │ │ ├── Invitation/
│ │ │ │ ├── Mysql.pm
│ │ │ │ ├── Pg.pm
│ │ │ │ └── SQLite.pm
│ │ │ ├── Invitation.pm
│ │ │ ├── Slice/
│ │ │ │ ├── Mysql.pm
│ │ │ │ ├── Pg.pm
│ │ │ │ └── SQLite.pm
│ │ │ └── Slice.pm
│ │ ├── DefaultConfig.pm
│ │ └── Plugin/
│ │ ├── Headers.pm
│ │ └── Helpers.pm
│ ├── Lufi.pm
│ └── Mounter.pm
├── lufi.conf.template
├── script/
│ ├── application
│ └── lufi
├── t/
│ ├── lufi.passwd
│ └── test.t
├── themes/
│ └── default/
│ ├── lib/
│ │ └── Lufi/
│ │ ├── I18N/
│ │ │ ├── ar.po
│ │ │ ├── br.po
│ │ │ ├── ca.po
│ │ │ ├── co.po
│ │ │ ├── de.po
│ │ │ ├── el.po
│ │ │ ├── en.po
│ │ │ ├── es.po
│ │ │ ├── fa.po
│ │ │ ├── fr.po
│ │ │ ├── fr_FR.po
│ │ │ ├── hr.po
│ │ │ ├── it.po
│ │ │ ├── ja_JP.po
│ │ │ ├── lufi.pot
│ │ │ ├── nl.po
│ │ │ ├── oc.po
│ │ │ ├── pl.po
│ │ │ ├── pt.po
│ │ │ ├── ru.po
│ │ │ ├── sk.po
│ │ │ ├── sv.po
│ │ │ ├── zh_Hans.po
│ │ │ └── zh_Hant.po
│ │ └── I18N.pm
│ ├── public/
│ │ ├── MATERIALIZE_LICENSE
│ │ ├── css/
│ │ │ ├── cover.css
│ │ │ ├── lufi.css
│ │ │ ├── materialize.css
│ │ │ └── materialize.min.css
│ │ ├── font/
│ │ │ └── material-design-icons/
│ │ │ └── LICENSE.txt
│ │ ├── img/
│ │ │ └── lufi.xcf
│ │ └── js/
│ │ ├── filesize.min.js
│ │ ├── filesize.min.js.map
│ │ ├── ie-detection.js
│ │ ├── jquery-3.7.1.min.js
│ │ ├── jquery-3.7.1.min.map
│ │ ├── jszip.js
│ │ ├── jszip.min.js
│ │ ├── lufi-common.js
│ │ ├── lufi-down.js
│ │ ├── lufi-files.js
│ │ ├── lufi-list-invitations.js
│ │ ├── lufi-notifications.js
│ │ ├── lufi-up.js
│ │ ├── materialize.js
│ │ ├── materialize.min.js
│ │ ├── sidenav.js
│ │ └── sjcl.js
│ └── templates/
│ ├── about.html.ep
│ ├── delays.html.ep
│ ├── delete_file.html.ep
│ ├── files.html.ep
│ ├── index.html.ep
│ ├── invitations/
│ │ ├── exception.html.ep
│ │ ├── invite.html.ep
│ │ ├── invite.mail.ep
│ │ ├── my_invitations.html.ep
│ │ └── notification_files_sent.mail.ep
│ ├── layouts/
│ │ └── default.html.ep
│ ├── login.html.ep
│ ├── logout.html.ep
│ ├── mail.html.ep
│ ├── msg.html.ep
│ ├── partial/
│ │ ├── files.js.ep
│ │ ├── index.js.ep
│ │ ├── invitations.js.ep
│ │ ├── layout.js.ep
│ │ ├── mail.js.ep
│ │ └── render.js.ep
│ └── render.html.ep
└── utilities/
├── lufi.default
├── lufi.init
├── lufi.service
└── migrations/
├── mysql.sql
├── pg.sql
└── sqlite.sql
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
local/*
files/*
cover_db/*
*.conf
*.db
*.db-shm
*.db-wal
*.bak
*.swp
script/*.pid
stop-upload
.zanata-cache/
themes/*
!themes/default
!themes/default/*
================================================
FILE: .gitlab-ci.yml
================================================
image: hatsoftwares/lufi-test-ci:bullseye
stages:
- create_release
- publish_changelog
- pouet_it
- carton
- carton_bdd
- tests
variables:
POSTGRES_DB: lufi_db
POSTGRES_USER: lufi
POSTGRES_PASSWORD: lufi_pwd
MYSQL_DATABASE: lufi_db
MYSQL_USER: lufi
MYSQL_PASSWORD: lufi_pwd
MYSQL_ROOT_PASSWORD: root
### Jobs templates
##
#
.retry: &retry
retry: 2
except:
- tags
.carton_bdd_template: &carton_bdd_definition
<<: *retry
stage: carton_bdd
cache:
key: "$CI_COMMIT_REF_NAME"
paths:
- local/
policy: pull
artifacts:
paths:
- local.tar
expire_in: 3 hours
needs:
- carton
after_script:
- tar cf local.tar local/
.tests_template: &tests_template
<<: *retry
stage: tests
coverage: '/Total.* (\d+\.\d+)$/'
before_script:
- tar xf local.tar && rm local.tar
- which mariadb_config && cd $(dirname $(which mariadb_config)) && ln -s mariadb_config mysql_config
- cd $CI_PROJECT_DIR
- pwd
script:
- MOJO_CONFIG="t/${CI_JOB_NAME}.conf" make test
- MOJO_CONFIG="t/${CI_JOB_NAME}.conf" make cover
.sqlite_template: &sqlite_definition
<<: *tests_template
needs:
- carton_sqlite
services:
- name: rroemhild/test-openldap
alias: rroemhild-test-openldap
# - name: openstackswift/saio
# alias: swiftstack-picoswiftstack
.pg_template: &pg_definition
<<: *tests_template
needs:
- carton_postgresql
services:
- name: postgres:11
alias: postgres
- name: rroemhild/test-openldap
alias: rroemhild-test-openldap
# - name: openstackswift/saio
# alias: swiftstack-picoswiftstack
.mysql_template: &mysql_definition
<<: *tests_template
needs:
- carton_mysql
services:
- name: mariadb:10.3
alias: mariadb
- name: rroemhild/test-openldap
alias: rroemhild-test-openldap
# - name: openstackswift/saio
# alias: swiftstack-picoswiftstack
### Publish tag changelog and create a toot
##
#
include:
- 'https://framagit.org/fiat-tux/gitlabci-snippets/-/raw/2aac6c1f3dd725d9aed57549da67a92759f9f9ec/create-release-from-ci.gitlab-ci.yml'
- 'https://framagit.org/fiat-tux/gitlabci-snippets/-/raw/4e4e03322e95e9b0124c714456ebf1bdc02ad43f/pouet-it-from-ci.gitlab-ci.yml'
### Podcheck
##
#
podcheck:
stage: carton
script:
- make podcheck
except:
- tags
### Cpanfile.snapshot
## Used to get a cpanfile.snapshot from a fresh server (not like my dev VM)
#
#cpanfile_snapshot:
# stage: carton
# script:
# - rm cpanfile.snapshot
# - which mariadb_config && cd $(dirname $(which mariadb_config)) && ln -s mariadb_config mysql_config
# - carton install
# - cat cpanfile.snapshot
# except:
# - tags
### Install common dependencies
##
#
carton:
<<: *retry
stage: carton
cache:
key: "$CI_COMMIT_REF_NAME"
paths:
- local/
script:
- carton install --deployment --without=sqlite --without=postgresql --without=mysql
### Install DB related dependencies
##
#
carton_sqlite:
<<: *carton_bdd_definition
script:
- carton install --deployment --without=postgresql --without=mysql
carton_postgresql:
<<: *carton_bdd_definition
script:
- carton install --deployment --without=sqlite --without=mysql
carton_mysql:
<<: *carton_bdd_definition
before_script:
- which mariadb_config && cd $(dirname $(which mariadb_config)) && ln -s mariadb_config mysql_config
- cd $CI_PROJECT_DIR
script:
- carton install --deployment --without=sqlite --without=postgresql
### Tests
##
#
sqlite:
<<: *sqlite_definition
postgresql:
<<: *pg_definition
mysql:
<<: *mysql_definition
================================================
FILE: .provision/README.md
================================================
## ansible-role-lufi
An ansible role deploy the application on host machine(Ubuntu 20.04)
## terraform-aws-lufi
A terraform plan creates necessary AWS infrastructure and deploy the lufi. This terraform plan uses the `lufi_startup.sh` script to deploy application on AWS and also uses above ansible roles `ansible-role-lufi` to configure the application on AWS.
================================================
FILE: .provision/ansible-role-lufi/README.md
================================================
Ansible-Role-Lufi
=========
This role installs the and configures Lufi on Debian/Ubuntu servers with nginx web server configuration.
Role Variables
--------------
| Variable name | Value | Description |
| ------------- | ----- | ----------- |
| `app_dir` | /var/www/lufi | Set the application directory for the best practice |
| `lufi_owner` | www-data | Set the application user for the best practice |
| `lufi_group` | www-data | Set the application group for the best practice |
| `_contact` | contact.example.com | Contact option (mandatory), where you have to put some way for the users to contact you. |
| `_report` | report@example.com | report option (mandatory) Put an email address or an URL to let people report illegal files |
| `_project_version` | master | We can chose the project version either Master branch, Dev branch or tag based |
| `_server_name` | IP address (or) CNAME/FQDN | Mention the Server Name for the Nginx configurations |
Sample example of use in a playbook
--------------
The following code has been tested with Ubuntu 20.04
```yaml
- name: "install lufi"
hosts: enter your hosts file
become: yes
role:
- ansible-role-lufi
vars:
lufi_owner: "www-data"
lufi_group: "www-data"
contact: "contact.example.com"
report: "report@example.com"
app_dir: "/var/www/lufi"
project_version: "master"
servername: "IP address (or) CNAME/FQDN"
```
Contributing
------------
Don’t hesitate to create a pull request
================================================
FILE: .provision/ansible-role-lufi/defaults/main.yml
================================================
---
# defaults file for roles/servers
robots_text: /var/www/html/
================================================
FILE: .provision/ansible-role-lufi/files/cronjob
================================================
#Path of the script
PATH=/var/www/lufi
carton exec script/lufi cron cleanbdd --mode production
carton exec script/lufi cron cleanfiles --mode production
carton exec script/lufi cron watch --mode production
================================================
FILE: .provision/ansible-role-lufi/files/robots.txt
================================================
User-agent: *
Allow: /$
Allow: /js/
Allow: /css/
Allow: /font/
Allow: /img/
Disallow: /r/
================================================
FILE: .provision/ansible-role-lufi/handlers/main.yml
================================================
---
# handlers file for roles/servers
- name: restart nginx
service: name=nginx state=restarted
================================================
FILE: .provision/ansible-role-lufi/tasks/apprun.yml
================================================
#apprun.yml
---
- name: This command will install the postgress module
ansible.builtin.shell:
cmd: carton install --deployment --without=test --without=sqlite --without=mysql
chdir: "{{ app_dir }}"
- name: Upload application file
ansible.builtin.template:
src: ../templates/lufi.conf.j2
dest: "{{ app_dir }}/lufi.conf"
- name: Run the command for app_executes
ansible.builtin.shell:
cmd: carton exec hypnotoad script/lufi
chdir: "{{ app_dir }}"
- name: Nginx configuration file add
ansible.builtin.template:
src: ../templates/app.conf
dest: /etc/nginx/conf.d/
mode: '0644'
notify: restart nginx
================================================
FILE: .provision/ansible-role-lufi/tasks/cron.yml
================================================
#cron.yml
---
- name: Copy the cronjob file
ansible.builtin.copy:
src: ../files/cronjob
dest: /etc/cron.d/
owner: www-data
group: www-data
- name: "example cronjob"
ansible.builtin.cron:
name: "cronjob"
state: present
user: www-data
minute: "0"
hour: "0"
day: "*"
month: "*"
weekday: "*"
job: |
carton exec script/lufi cron cleanbdd --mode production; carton exec script/lufi cron cleanfiles --mode production; carton exec script/lufi cron watch --mode production
#- name: Crontab file exists
# cron:
# name: Add date and time to a file.
# minute: "*/2"
# hour: 9-16
# weekday: 1-5
# user: devops
# job: df >> /home/devops/disk_usage
# cron_file: disk_usage
# state: present
================================================
FILE: .provision/ansible-role-lufi/tasks/dependencies.yml
================================================
#dependencies.yml
---
- name: Install Dependencies
ansible.builtin.apt:
name:
- nginx
- build-essential
- libssl-dev
- libio-socket-ssl-perl
- liblwp-protocol-https-perl
- zlib1g-dev
- libmojo-sqlite-perl
- carton
state: present
- name: Install Postgress Dev Packages
ansible.builtin.apt:
name:
- libpq-dev
================================================
FILE: .provision/ansible-role-lufi/tasks/gitclone.yml
================================================
#gitclone
---
- name: clone the repository
ansible.builtin.git:
repo: 'https://framagit.org/fiat-tux/hat-softwares/lufi.git'
dest: "{{ app_dir }}"
clone: yes
update: yes
version: "{{ project_version }}"
- name: Change the owner
ansible.builtin.file:
path: "{{ app_dir }}"
owner: "{{ lufi_owner }}"
group: "{{ lufi_group }}"
state: directory
recurse: yes
- name: Add the robots.txt file
ansible.builtin.copy:
src: ../files/robots.txt
dest: "{{ robots_text }}"
================================================
FILE: .provision/ansible-role-lufi/tasks/main.yml
================================================
---
# tasks file for roles/servers
- include: dependencies.yml
- include: gitclone.yml
- include: apprun.yml
- include: cron.yml
================================================
FILE: .provision/ansible-role-lufi/templates/lufi.conf.j2
================================================
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
{
####################
# Hypnotoad settings
####################
# see http://mojolicio.us/perldoc/Mojo/Server/Hypnotoad for a full list of settings
hypnotoad => {
# array of IP addresses and ports you want to listen to
# you can specify a unix socket too, like 'http+unix://%2Ftmp%2Flufi.sock'
listen => ['http://0.0.0.0:8081'],
# if you use Lufi behind a reverse proxy like Nginx, you want to set proxy to 1
# if you use Lufi directly, let it commented
#proxy => 1,
# Please read http://mojolicious.org/perldoc/Mojo/Server/Hypnotoad#workers
# to adjust this to your server
workers => 30,
clients => 1,
},
# Put a way to contact you here and uncomment it
# You can put some HTML in it
# MANDATORY
contact => '<a href="https://{{ _contact }}">Contact page</a>',
# Put an URL or an email address to receive file reports and uncomment it
# It's for make reporting illegal files easy for users
# MANDATORY
report => '{{ _report }}',
# Array of random strings used to encrypt cookies
# optional, default is ['fdjsofjoihrei'], PLEASE, CHANGE IT
#secrets => ['fdjsofjoihrei'],
# Name of the instance, displayed next to the logo
# optional, default is Lufi
#instance_name => 'Lufi',
# Choose a theme. See the available themes in `themes` directory
# Optional, default is 'default'
#theme => 'default',
# Length of the random URL
# optional, default is 8
#length => 8,
# How many URLs will be provisioned in a batch ?
# optional, default is 5
#provis_step => 5,
# Max number of URLs to be provisioned
# optional, default is 100
#provisioning => 100,
# Length of the modify/delete token
# optional, default is 32
#token_length => 32,
# Max file size, in octets
# You can write it 100*1024*1024
# optional, no default
#max_file_size => 104857600,
# If you want to have piwik statistics, provide a piwik image tracker
# Only the image tracker is allowed, no javascript
# optional, no default
#piwik_img => 'https://piwik.example.org/piwik.php?idsite=1&rec=1',
# Broadcast_message which will displayed on the index page
# optional, no default
#broadcast_message => 'Maintenance',
# Default time limit for files
# Valid values are 0, 1, 7, 30 and 365
# optional, default is 0 (no limit)
#default_delay => 0,
# Number of days after which the files will be deleted, even if they were uploaded with "no delay" (or value superior to max_delay)
# A warning message will be displayed on homepage
# optional, default is 0 (no limit)
#max_delay => 0,
# Size thresholds: if you want to define max delays for different sizes of file
# The keys are size in Bytes, you can't have 10*1000*10000 as key
# If a file is smaller than the smallest configured size, it will have a expiration delay of max_delay (see above)
# optional, default is using max_delay (see above) for all sizes
#delay_for_size => {
# 10000000 => 90, # between 10MB and 50MB => max is 90 days, less than 10MB => max is max_delay (see above)
# 50000000 => 60, # between 50MB ans 1GB => max is 60 days
# 1000000000 => 2, # more than 1GB => max is 2 days
#},
# URL sub-directory in which you want Lufi to be accessible
# example: you want to have Lufi under https://example.org/lufi/
# => set prefix to '/lufi' or to '/lufi/', it doesn't matter
# optional, defaut is /
#prefix => '/',
# Array of authorized domains for API calls.
# If you want to authorize everyone to use the API: ['*']
# optional, no domains allowed by default
#allowed_domains => ['http://1.example.com', 'http://2.example.com'],
# String of the URL to be redirected to when accessing /logout
# optional, default is no redirection after logging out
#logout_custom => 'https://sso.example.com/logout?redirect_uri=https%3A%2F%2Fexample.com',
# Define a path to the upload directory, where the uploaded files will be stored
# You can define it relative to lufi directory or set an absolute path
# Remember that it has to be in a directory writable by Lufi user
# optional, default is 'files'
#upload_dir => 'files',
#!!!!!!!!!!!!!!!
# EXPERIMENTAL !
#!!!!!!!!!!!!!!!
# You can store files on Swift object storage (https://en.wikipedia.org/wiki/OpenStack#Swift) instead of filesystem
# Please read https://metacpan.org/pod/Net::OpenStack::Swift#SYNOPSIS to know how to configure this setting
# IMPORTANT: add a `container` key in it, to let Lufi know which container to use. This is not a regular Net::OpenStack::Swift setting, but Lufi need it.
# EXPERIMENTAL: if the upload or download of files are stucked, reload Lufi and create a cron task to reload Lufi once a day
# You can copy Lufi files to Swift object storage by launching the command `carton exec script/lufi copyFilesToSwift` (can take a long time)
# optional, no default
#swift => {
# auth_url => 'https://auth-endpoint-url/v2.0',
# user => 'userid',
# password => 'password',
# tenant_name => 'project_id',
# container => 'lufi'
#},
# Allow to add a password on files, asked before allowing to download files
# optional, default is 0
#allow_pwd_on_files => 0,
# Force all files to be in "Burn after reading mode"
# optional, default is 0
#force_burn_after_reading => 0,
# If set, the files' URLs will always use this domain
# optional, no default
#fixed_domain => 'example.org',
# Abuse reasons
# Set an integer in the abuse field of a file in the database and it will not be downloadable anymore
# The reason will be displayed to the downloader, according to the reasons you will configure here.
# optional, no default
#abuse => {
# 0 => 'Copyright infringment',
# 1 => 'Illegal content',
#},
###############
# Mail settings
###############
# Mail configuration
# See https://metacpan.org/pod/Mojolicious::Plugin::Mail#EXAMPLES
# optional, default to sendmail method with no arguments
#mail => {
# # Valid values are 'sendmail' and 'smtp'
# how => 'smtp',
# howargs => ['smtp.example.org']
#},
# Email sender address
# optional, default to no-reply@lufi.io
#mail_sender => 'no-reply@lufi.io',
# Disable sending mail through the server
# optional, default is false
#disable_mail_sending => 0,
#############
# DB settings
#############
# Choose what database you want to use
# Valid choices are sqlite, postgresql and mysql (all lowercase)
# optional, default is sqlite
# dbtype => 'sqlite',
# SQLite ONLY - only used if dbtype is set to sqlite
# Define a path to the SQLite database
# You can define it relative to lufi directory or set an absolute path
# Remember that it has to be in a directory writable by Lufi user
# optional, default is lufi.db
# db_path => 'lufi.db',
# PostgreSQL ONLY - only used if dbtype is set to postgresql
# These are the credentials to access the PostgreSQL database
# mandatory if you choosed postgresql as dbtype
pgdb => {
database => 'lufi',
host => 'localhost',
# optional, default is 5432
port => 5432,
user => 'DBUSER',
pwd => 'DBPASSWORD',
# https://mojolicious.org/perldoc/Mojo/Pg#max_connections
# optional, default is 1
#max_connections => 1,
},
# MySQL ONLY - only used if dbtype is set to mysql
# These are the credentials to access the MySQL database
# mandatory if you choosed mysql as dbtype
#mysqldb => {
# database => 'lufi',
# host => 'localhost',
# # optional, default is 3306
# #port => 3306,
# user => 'DBUSER',
# pwd => 'DBPASSWORD',
# # https://metacpan.org/pod/Mojo::mysql#max_connections
# # optional, default is 5 (set to 0 to disable persistent connections)
# #max_connections => 5,
#},
#############################################
# LDAP settings (authentication and features)
#############################################
# Set `ldap` if you want that only authenticated users can upload files
# Please note that everybody can still download files
# optional, no default
#ldap => {
# uri => 'ldaps://ldap.example.org', # server URI
# user_tree => 'ou=users,dc=example,dc=org', # search base DN
# bind_dn => 'uid=ldap_user,ou=users,dc=example,dc=org', # search bind DN
# bind_pwd => 'secr3t', # search bind password
# user_attr => 'uid', # user attribute (uid, mail, sAMAccountName, etc.)
# user_filter => '(!(uid=ldap_user))', # user filter (to exclude some users, etc.)
# # optional start_tls configuration. See https://metacpan.org/pod/distribution/perl-ldap/lib/Net/LDAP.pod#start_tls
# # don't set or uncomment if you don't want to configure it
# start_tls => {
# verify => 'optional',
# clientcert => '/etc/ssl/certs/ca-bundle.pem'
# }
#},
# If you've set ldap above, the session will last `session_duration` seconds before
# the user needs to reauthenticate
# optional, default is 3600
#session_duration => 3600,
# If you use `ldap` for authentication, you can map some attributes from LDAP to be able to access them in Lufi
# Those attributes will be accessible with:
# $c->current_user->{lufi_attribute_name} in Lufi backend files (all that is in `lib` directory)
# <%= $self->current_user->{lufi_attribute_name} %> in templates files (in `themes` directory)
#
# Define the attributes like this: `lufi_attribute_name => 'LDAP_attribute_name'`
# Note that you can’t use `username` as a Lufi attribute name: this name is reserved and will contain the login of the user
# optional, no default
#ldap_map_attr => {
# displayname => 'cn',
# mail => 'mail'
#},
# When using LDAP authentication, LDAP users can invite people (by mail) to use Lufi to send them files without
# being authenticated.
# This is where you configure the behavior of the invitations.
# You may need to fetch some attributes from LDAP to use some invitations settings. See `ldap_map_attr` above.
# optional, no default
#invitations => {
# # The name of the key set in `ldap_map_attr` (above) that corresponds to the mail of the LDAP user
# # optional, default is `mail`
# mail_attr => 'mail',
# # The `From` header of invitation mail can be the mail of the LDAP user
# # Be sure to have a mail system that will correctly send the mail from your users! (DKIM, SPF…)
# # To enable this feature, set it to 1
# # optional, disabled by default
# send_invitation_with_ldap_user_mail => 1,
# # The user is able to set an expiration delay for the invitation.
# # This expiration delay can’t be more than this setting (in days).
# # optional, default is 30 days
# max_invitation_expiration_delay => 30,
# # Once the guest has submitted his files, he has an additional period of time to submit forgotten files.
# # You can set that additional period of time in minutes here.
# # To disable that feature, set it to 0 or less
# # optional, default is 10 minutes
# max_additional_period => 10,
# # Lufi follows privacy-by-design, so, by default, no files URLs (with the decode secret) are stored in database.
# # However, the concern is different for this case. Storing files URLs makes users able to retrieve the guests’ sent files
# # from their `invitations` page.
# # Set to 1 to store guests’ files URLs in database
# # optional, default is 0 (disabled)
# save_files_url_in_db => 0,
# # Users can resend the invitation to their guest. This does not extend the invitation’s expiration delay unless you
# # set this option to 1.
# # optional, default is 0 (disabled)
# extend_invitation_expiration_on_resend => 0,
#},
#########################
# Htpasswd authentication
#########################
# Set `htpasswd` if you want to use an htpasswd file instead of ldap
# See 'man htpasswd' to know how to create such file
#htpasswd => 'lufi.passwd',
#######################
# HTTP Headers settings
#######################
# Content-Security-Policy header that will be sent by Lufi
# Set to '' to disable CSP header
# https://content-security-policy.com/ provides a good documentation about CSP.
# https://report-uri.com/home/generate provides a tool to generate a CSP header.
# optional, default is "base-uri 'self'; connect-src 'self' ws://YOUR_HOST; default-src 'none'; font-src 'self'; form-action 'self'; frame-ancestors 'none'; img-src 'self' blob:; media-src blob:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'"
#csp => "",
# X-Frame-Options header that will be sent by Lufi
# Valid values are: 'DENY', 'SAMEORIGIN', 'ALLOW-FROM https://example.com/'
# Set to '' to disable X-Frame-Options header
# See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
# Please note that this will add a "frame-ancestors" directive to the CSP header (see above) accordingly
# to the chosen setting (See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)
# optional, default is 'DENY'
#x_frame_options => 'DENY',
# X-Content-Type-Options that will be sent by Lufi
# See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
# Set to '' to disable X-Content-Type-Options header
# optional, default is 'nosniff'
#x_content_type_options => 'nosniff',
# X-XSS-Protection that will be sent by Lufi
# See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection
# Set to '' to disable X-XSS-Protection header
# optional, default is '1; mode=block'
#x_xss_protection => '1; mode=block',
#########################
# Lufi cron jobs settings
#########################
# Expired files will be kept for 2 additional days after the expiration time has passed!
# The reasoning behind this is to allow downloads to complete and avoid deleting them while
# they are still being tranfered.
# Number of days senders' IP addresses are kept in database
# After that delay, they will be deleted from database (used with script/lufi cron cleanbdd)
# optional, default is 365
keep_ip_during => 1,
# Max size of the files directory, in octets
# Used by script/lufi cron watch to trigger an action
# optional, no default
max_total_size => 10*1024*1024*1024,
# Default action when files directory is over max_total_size (used with script/lufi cron watch)
# Valid values are 'warn', 'stop-upload' and 'delete'
# Please, see README.md
# optional, default is 'warn'
policy_when_full => 'warn',
# Files which are not viewed since delete_no_longer_viewed_files days will be deleted by the cron cleanfiles task
# If delete_no_longer_viewed_files is not set, the no longer viewed files will NOT be deleted
# optional, no default
delete_no_longer_viewed_files => 1,
};
================================================
FILE: .provision/ansible-role-lufi/templates/update.sh
================================================
# install perl dependencies
apt install liblwp-protocol-https-perl carton
sleep 5
git pull
sleep 5
carton install --deployment --without=test --without=sqlite --without=mysql
sleep5
carton exec hypnotoad script/lufi
================================================
FILE: .provision/ansible-role-lufi/vars/main.yml
================================================
---
# vars file for roles/servers
lufi_owner: "www-data"
lufi_group: "www-data"
app_dir: ""
_contact: "contact.example.com"
_report: "report@example.com"
_project_version: ""
_servername: ""
================================================
FILE: .provision/terraform-aws-lufi/README.md
================================================
# Terraform-AWS-Lufi
This terraform plan create the resourcess of EC2 instance
## Terraform Variables
Edit the `vars.tf` file to add the variables as per your need.
| Variable name | Value | Description |
| ------------- | ----- | ----------- |
| `aws_region` | us-east-1 | Set the region |
| `vpc_cidr` | 10.0.0.0/16 | Set the cidr value for the vpc |
| `public_subnet_cidr` | 10.0.2.0/24 | Set the cidr value for the public subnet |
| `user` | ubuntu | Set the EC2 instance user name |
| `public_key` | /home/user_name/.ssh/id_rsa_pub | Set the publickey value for the ec2 instance from the host machine |
| `private_key` | /home/user_name/.ssh/id_rsa | Set the private key value for the ec2 instance from the hostmachine |
| `aws_access_key` | AWSACCESSKEY | Enter your aws access key |
| `aws_secrete_key` | AWSSECRETEKEY | Enter your aws secrete key |
| `instance_name` | Lufi_app_instance | Set the name for instance |
| `app_dir` | /var/www/ | Set the application directory for the best practice |
| `lufi_owner` | www-data | Set the application user for the best practice |
| `lufi_group` | www-data | Set the application group for the best practice |
| `contact` | contact.example.com | Contact option (mandatory), where you have to put some way for the users to contact you. |
| `report` | report@example.com | report option (mandatory) Put an email address or an URL to let people report illegal files |
## Usage of terraform plan with lufi deploy script
```sh
git clone https://framagit.org/fiat-tux/hat-softwares/lufi.git
cd lufi/.provision/terraform-aws-lufi
terraform init
terraform plan
terraform apply
```
## Usage of terraform plan with ansible role
- Comment out the below `data template` and `user_data` source in __main.tf__ file
```hcl
locals {
user_data_vars = {
user = var.lufi_owner
group = var.lufi_group
directory = var.app_dir
git_branch = var.project_version
contact_lufi = var.contact
report_lufi = var.report
}
}
```
```hcl
user_data = templatefile("${path.module}/lufi_startup.sh", local.user_data_vars)
```
- Add the below provisioner data in __main.tf__ file at the `aws_instance` resource
```sh
connection {
agent = false
type = "ssh"
host = aws_instance.ec2_instance.public_dns
private_key = "${file(var.private_key)}"
user = "${var.user}"
}
provisioner "remote-exec" {
inline = [
"sudo apt update -y",
"sudo apt install python3.9 -y",
]
}
provisioner "local-exec" {
command = <<EOT
sleep 120 && \
> hosts && \
echo "[Lufi]" | tee -a hosts && \
echo "${aws_instance.ec2_instance.public_ip} ansible_user=${var.user} ansible_ssh_private_key_file=${var.private_key}" | tee -a hosts && \
export ANSIBLE_HOST_KEY_CHECKING=False && \
ansible-playbook -u ${var.user} --private-key ${var.private_key} -i hosts site.yml
EOT
}
```
================================================
FILE: .provision/terraform-aws-lufi/lufi_startup.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
echo "**********************************************************************"
echo " *"
echo "Install dependencies *"
echo " *"
echo "**********************************************************************"
SUDO=sudo
$SUDO apt update
$SUDO apt install jq wget unzip carton build-essential nginx libssl-dev libio-socket-ssl-perl liblwp-protocol-https-perl zlib1g-dev libmojo-sqlite-perl libpq-dev -y
echo "**********************************************************************"
echo " *"
echo "Configuring the Application *"
echo " *"
echo "**********************************************************************"
sleep 10;
version=$(curl -s https://framagit.org/api/v4/projects/1998/releases | jq '.[]' | jq -r '.name' | head -1)
echo $version
pushd ${directory}
$SUDO wget https://framagit.org/fiat-tux/hat-softwares/lufi/-/archive/$version/lufi-$version.zip
$SUDO unzip lufi-$version.zip
$SUDO chown ${user} lufi-$version
$SUDO chgrp ${group} lufi-$version
pushd lufi-$version
echo "**********************************************************************"
echo " *"
echo "Install Carton Packages *"
echo " *"
echo "**********************************************************************"
$SUDO carton install --deployment --without=test --without=sqlite --without=mysql
sleep 10;
$SUDO cp lufi.conf.template lufi.conf
sed -i 's/127.0.0.1/0.0.0.0/' lufi.conf
sed -i 's/#contact/contact/g' lufi.conf
sed -i "s/contact.example.com/${contact_lufi}/g" lufi.conf
sed -i 's/#report/report/' -i lufi.conf
sed -i "s/report@example.com/${report_lufi}/g" lufi.conf
sed -i "192 , 194 s/#/ /g" lufi.conf && \
sed -i "195 s/# / /g" lufi.conf && \
sed -i "196 , 198 s/#/ /g" lufi.conf && \
sed -i "199 , 201 s/# / /g" lufi.conf && \
sed -i "202 s/#/ /g" lufi.conf
echo "**********************************************************************"
echo " *"
echo "Run the Application *"
echo " *"
echo "**********************************************************************"
$SUDO carton exec hypnotoad script/lufi
================================================
FILE: .provision/terraform-aws-lufi/main.tf
================================================
locals {
user_data_vars = {
user = var.lufi_owner
group = var.lufi_group
directory = var.app_dir
contact_lufi = var.contact
report_lufi = var.report
}
}
#Create the VPC
resource "aws_vpc" "vpc" {
cidr_block = "${var.vpc_cidr}"
enable_dns_hostnames = true
enable_dns_support = true
instance_tenancy = "default"
tags = {
Name = "lufi-master-vpc"
}
}
# Create InternetGateWay and attach to VPC
resource "aws_internet_gateway" "IGW" {
vpc_id = "${aws_vpc.vpc.id}"
tags = {
"Name" = "lufi-master-igw"
}
}
# Create a public subnet
resource "aws_subnet" "publicsubnet" {
vpc_id = "${aws_vpc.vpc.id}"
cidr_block = "${var.public_subnet_cidr}"
map_public_ip_on_launch = true
tags = {
Name = "lufi-master-us-east-1-public"
}
}
# Create routeTable
resource "aws_route_table" "public" {
vpc_id = "${aws_vpc.vpc.id}"
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.IGW.id}"
}
tags = {
Name = "lufi-master-us-east-1-public-rt"
}
}
resource "aws_main_route_table_association" "mainRTB" {
vpc_id = "${aws_vpc.vpc.id}"
route_table_id = "${aws_route_table.public.id}"
}
## Create security group
resource "aws_security_group" "security" {
name = "lufi-master-sg"
description = "allow all traffic"
vpc_id = "${aws_vpc.vpc.id}"
ingress {
description = "allow all traffic"
from_port = "0"
to_port = "65535"
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "allow port SSH"
from_port = "22"
to_port = "22"
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
#Create key_pair for the instance
resource "aws_key_pair" "genkey" {
key_name = "lufi.webapp"
public_key = "${file(var.public_key)}"
}
# Add ubuntu AMI
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"]
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
}
# Craete ec2 instance
resource "aws_instance" "ec2_instance" {
ami = "${data.aws_ami.ubuntu.id}"
instance_type = "t2.medium"
associate_public_ip_address = "true"
subnet_id = "${aws_subnet.publicsubnet.id}"
vpc_security_group_ids = ["${aws_security_group.security.id}"]
user_data = templatefile("${path.module}/lufi_startup.sh", local.user_data_vars)
key_name = "lufi.webapp"
tags = {
Name = "${var.instance_name}"
}
}
================================================
FILE: .provision/terraform-aws-lufi/output.tf
================================================
output "public_ip" {
value = "${aws_instance.ec2_instance.public_ip}"
}
output "App_running_at" {
value = "http://${aws_instance.ec2_instance.public_ip}:8081"
}
================================================
FILE: .provision/terraform-aws-lufi/provider.tf
================================================
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
provider "aws" {
access_key = "${var.aws_access_key}"
secret_key = "${var.aws_secret_key}"
region = "${var.aws_region}"
}
================================================
FILE: .provision/terraform-aws-lufi/vars.tf
================================================
variable "aws_region" {
default = "aws_region"
}
variable "vpc_cidr" {
default = "cidr_value"
}
variable "public_subnet_cidr" {
default = "cidr_value"
}
variable "public_subnet1_cidr" {
default = "cidr_value"
}
variable "user" {
default = "user_of_instance"
}
variable "public_key" {
default = "$PWD_publickey"
}
variable "private_key" {
default = "$PWD_privatekey"
}
variable "aws_access_key" {
default = "aws_access_key"
}
variable "aws_secret_key" {
default = "aws_secrete_key"
}
variable "instance_name" {
default = "instance_name"
}
variable "lufi_owner" {
default = ""
}
variable "lufi_group" {
default = ""
}
variable "app_dir" {
default = ""
}
variable "contact" {
default = ""
}
variable "report" {
default = ""
}
================================================
FILE: AUTHORS.md
================================================
# Lufi's authors
## Main developer 🤪
- Luc Didry, aka Sky (<https://fiat-tux.fr>), core developer, [@framasky@framapiaf.org](https://framapiaf.org/@framasky/) on Mastodon
## Contributors
### Translations 🌐
- Nikos Filopoulos (italian translation)
- Framartin (fix french translation)
- Sébastien Duthil (fix english translation)
- Armando Lüscher, https://noplanman.ch/ (german translation)
- Quentin Pagès (occitan translation)
- Jéssica Da Cunha (portuguese translation)
- Ilker Kulgu (dutch translation)
- Butterfly of Fire (arabic translation)
- Frju365 (german translation)
- pi2 (german translation)
### Code ⌨️
- Armando Lüscher, https://noplanman.ch/ (fix css)
- Yann Le Brech (htpasswd file support)
- Ilker Kulgu (fix IE11 compatibility)
- Stéphane Baron (bugfix)
- alexandre.LG, http://inios.fr/
- Mildis (bugfix)
- TECH'advantage, https://www.tech-advantage.com/ (paid for LDAP invitations feature)
- pi2 (typo)
- Rain (bugfix)
- Nicolas Constant (notifications)
## Vulnerabilities / bug hunters 🐛
Lufi participated to a [Hackpéro](https://hackpero.com/) (sort of a bug bounty hackathon), thanks to [Bounty factory](https://hackpero.com/).
Many thanks to those who found bugs and vulnerabilities:
- joker2a
- March
- Nicknam3
- SaxX
- tfairane
================================================
FILE: CHANGELOG
================================================
Revision history for Lufi
0.08.0 ????-??-??
0.07.3 2025-11-15
- 🔖 — Fix 0.07.2 release (tag on wrong commit)
0.07.2 2025-07-29
- 🐛 — Fix bug in POST file deletion (#319)
0.07.1 2025-07-16
- 🚚 — Use POST to delete a file instead of GET
0.07.0 2023-12-25
- ⬆️ — Update jQuery
- 🩹 — Fix a format query parameter
- 🎨 — Use template literals in js
- ➖ — Replace moment.js with Date().toLocaleDateString(…)
- 🩹 — Fix Roboto font warnings in js console
- ♿️ — Add autofocus on login input field
- ✨ — Add a `lockfile_dir` setting (fix #242)
- 👷 — Update the create-release snippet’s URL
0.06.00 2023-12-18
- ⬆️ — Update deps
- 🌐 Update translations
0.05.21 2023-02-21
- ⬆️ — Update deps (still #284)
0.05.20 2023-02-21
- ⬆️ — Update deps (#284)
0.05.19 2023-01-11
- 🌐 Update translations
- 👷 — Deactivate Swift tests in CI
- Terraform and Ansible provisioning (@arunodhayamsam)
- Support for header authentication (@mildis)
0.05.18 2022-03-19
- ✨ Add support for header authentication, thanks to @mildis (!69)
- 🌐 Update translations
0.05.17 2022-03-02
- 🌐 Update translations
0.05.16 2021-11-08
- 👷🐛 Create release in CI before publishing changelog
- 🌐 Update translations
0.05.15 2021-11-03
- 🐛 Fix mail signature separator
- 💄 Disable signature when using LDAP (#249)
- 🌐 Update translations
- 🔒 Fix XSS where using zip feature (#254)
- 🔒 Fix unauthorized manipulations of invitations (#254)
- 🔒 Detect schemeless URL in mail (#254)
0.05.14 2021-06-16
- 🔧 Set default morbo port to 3000 (as it should have stay)
- 🐛 Fix `Notification not defined` in Duckduckgo browser (Fix #224 again)
- ✨ Add `disable_mail_sending` config parameter
- 🌐 Update translations
0.05.13 2021-01-28
- 🐛 Fix latest git tag improperly fetched
0.05.12 2021-01-13
- 🌐 Update translations
- 🐛 Fix `Notification not defined`
0.05.11 2020-12-07
- 🌐 Update translations
- 🐛 Try to avoid clients constantly hitting /download/XXX
0.05.10 2020-11-28
- 🌐 Update translations
0.05.9 2020-11-25
- 🐛 Invitation, error 500 when guest send file with special character (#229)
- 🌐 Update translations
0.05.8 2020-11-18
- 🌐 Update translations
0.05.7 2020-10-06
- 🐛 Remove breakingchanges migration from sqliteToOtherDB (no need for now)
0.05.6 2020-09-28
- 🌐 Update translations
- 📝 Document file deletion behavior
0.05.5 2020-08-20
- 🐛 Change lufi-provisioning.lock handling process to avoid error messages (#210)
0.05.4 2020-08-17
- 🐛 Fix incorrect HTML in delays.html.ep (#207)
0.05.3 2020-08-17
- 🐛 Check if provisioning lockfile mod time exists before using it (#208)
0.05.2 2020-07-25
- 🔥 Remove code from abandonned feature
- Fix regression introduced in 0.05.1 (#201)
0.05.1 2020-06-30
- Update german translation
- Fix possible high load due to concurrent provisioning
0.05.0 2020-06-02
- Notifications when uploading and downloading files (#181)
- Use Weblate instead of Zanata for translations (https://weblate.framasoft.org/projects/lufi/development/)
- Add config API endpoint (#183)
- Show latest tag and commit of the instance in about page and config API endpoint (#174)
- Add support for Swift object storage (EXPERIMENTAL)
0.04.6 2019-11-07
- Now can send large files (>2Gio) while using a DB other than SQLite (#165)
- Use customized instance name in <title>
0.04.5 2019-10-14
- Update german language
- Smoother progress of progress bar (use smaller chunks)
0.04.4 2019-10-11
- Fix invitations sorting order (#163)
- Same behavior on files and invitations tables (striped, invert selection
button) (#166)
- Change row color on hover
- Fix typo that leads to error in Safari (#164)
- Fix (for good, I hope) the problem with badly detected URLs in mail
sending (#159)
- Fix unstranslated string (#167)
0.04.3 2019-09 29
- Translate dates in invitations (#161)
- Ignore all .conf files in .gitignore
- Remove redundant fixed_domain setting in conf template
0.04.2 2019-08-14
- Update german language
- Fix logout button color on mobile view (#157)
0.04.1 2019-08-12
- LocalStorage key is now prefix-dependant (#154)
This allow to not mix up files in localStorage for two instances if they
are on the same domain
- Fix bug on cookie-based language choice when using two instances on same
domain, with one’s path is the beginning of the other instance’s path.
WARNING! You need to do a `carton install --deployment …` to have the fix.
- Fix navbar bug (there can be too much items in it, depending on Lufi
settings (LDAP, invitations…), trouble beginning at screens < 1800px)
- Add setting to customize the instance name (#156)
0.04.0 2019-08-04
- Allow to zip the files before upload
- Allow to see what’s in zip file on download page
- Allow to individually download files from zip file (only if zip created by Lufi)
- Allow to invite people to send you files on Lufi when using LDAP auth (#150).
Feature paid for by TECH’advantage (https://www.tech-advantage.com/)
0.03.7 2019-08-01
- Fix missing default values for some settings (mildis)
0.03.6 2019-07-30
- Update german translation
- Use configured url prefix when using mail sending interface
- Avoid collision between startup and recurring provisionings
- Avoid files password autocomplete by browsers (tested with Firefox and
Chromium) (#138)
0.03.5 2018-12-06
- Fix CI
0.03.4 2018-12-06
- Update arabic, german and italian translations
0.03.3 2018-11-02
- Update deps, seems to fix install on Debian Jessie
0.03.2 2018-11-02
- Fix dependences in Lufi.pm
0.03.1 2018-10-29
- Fix default CSP Header
0.03 2018-10-28
- Use Mojo::SQLite instead of ORLite
- Use FiatTux plugins
- Option to force "Burn after reading" for each uploaded file
- Use GzipStatic and StaticCache plugins for speed
- Allow to block files by setting an abuse field in DB
- Display file size when uploading
- Add Content-Security-Policy header
- Update sjcl.js
- Mitigate genRandomKey exception risk
- Add report file link in the navbar
- Allow to choose your language
- Use a recurrent task to provision shorts
- Add a command to migrate data from SQLite to an other database
- Add a test suite
- MySQL support
- Display max size on upload page
- Add CSRF token challenge on login
- Add CSRF token challenge on logout
- Add constraints on mail sending to prevent spam sending (not perfect, but
should be good enough)
- Add Code of Conduct
- Add arabic translation
- Add german translation
0.02.2 2017-09-18
- Fix cron tasks bug
0.02.1 2017-09-14
- Fix DB abstraction layer bug
0.02 2017-09-13
- Database abstraction layer
- PostgreSQL support
- IE 11 and Edge support
- Fix encoding error (#83)
- Htpassword authentication support
- Ability to add a password to a file
- Portuguese translation
- Catalan translation
- Dutch translation
- Deleting files from "My files" is now done with Ajax (#23)
- Allow bulk files deletion from "My files" (#24)
- Bugfixes
0.01 2017-01-09
- Upload files
- Download files
- Preview files in browser depending on mimetype (images and videos)
- LDAP authentication support
================================================
FILE: CONTRIBUTING.md
================================================
# CONTRIBUTING
Please, read about contributing at <https://framagit.org/luc/lufi/wikis/contribute>
================================================
FILE: LICENSE
================================================
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<http://www.gnu.org/licenses/>.
================================================
FILE: Makefile
================================================
EXTRACTDIR ?= -D lib -D themes/default/templates
POT ?= themes/default/lib/Lufi/I18N/lufi.pot
ENPO ?= themes/default/lib/Lufi/I18N/en.po
XGETTEXT ?= carton exec local/bin/xgettext.pl -u
CARTON ?= carton exec
REAL_LUFI ?= script/application
LUFI ?= script/lufi
LDAP_CONTAINER_IMAGE ?= docker.io/rroemhild/test-openldap:latest
LOCAL_LDAP_PORT ?= 10389
LOCAL_SWIFT_PORT ?= 8080
SWIFT_CONTAINER_IMAGE ?= docker.io/openstackswift/saio:latest
MORBO_HOST ?= 0.0.0.0
MORBO_PORT ?= 3000
locales:
$(XGETTEXT) $(EXTRACTDIR) -o $(POT) 2>/dev/null
$(XGETTEXT) $(EXTRACTDIR) -o $(ENPO) 2>/dev/null
podcheck:
podchecker lib/Lufi/DB/File.pm lib/Lufi/DB/Slice.pm lib/Lufi/DB/Invitation.pm
cover:
PERL5OPT='-Ilib/' HARNESS_PERL_SWITCHES='-MDevel::Cover' $(CARTON) cover --ignore_re '^local'
test:
@PERL5OPT='-Ilib/' HARNESS_PERL_SWITCHES='-MDevel::Cover' $(CARTON) prove -l -f -o t/test.t
clean:
rm -rf lufi.db files/
dev: clean
$(CARTON) morbo $(LUFI) --listen http://$(MORBO_HOST):$(MORBO_PORT) --watch lib/ --watch script/ --watch themes/ --watch lufi.conf
ldap:
podman run -d -p $(LOCAL_LDAP_PORT):10389 $(LDAP_CONTAINER_IMAGE); exit 0
ldapdev: ldap dev
swift:
podman run -d --rm -p $(LOCAL_SWIFT_PORT):8080 --hostname="picoswiftstack" --name="picoswiftstack" $(SWIFT_CONTAINER_IMAGE); exit 0
@echo "Sleeping 20 seconds to let picoswiftstack start"
@sleep 20
podman exec picoswiftstack get_auth
swiftdev: swift dev
devlog:
multitail log/development.log
prod:
$(CARTON) hypnotoad -f $(LUFI)
================================================
FILE: README.md
================================================
# Lufi
## What does Lufi mean?
Lufi means Let's Upload that FIle. It's a E2E encrypted file sharing software.
## Which browsers are compatible?
Lufi is tested and working on the following browsers / devices :
- Firefox
- Chrome
- Internet Explorer 11
- Microsoft Edge
- Safari
- iOS devices (ipad, iphone)
- Android devices (Galaxy tab, Galaxy S8)
## What does it do?
It stores files and allows you to download them.
Is that all? No. All the files are encrypted **by the browser**! It means that your files **never** leave your computer unencrypted.
The administrator of the Lufi instance you use will not be able to see what is in your file, neither will your network administrator, or your ISP.
The encryption key part of the URL is a anchor (Cf. [Fragment Identifier](https://en.wikipedia.org/wiki/Fragment_identifier)), that means this part is only processed client-side and does not reach the server. :-)
## License
Lufi is licensed under the terms of the AGPL. See the [LICENSE](LICENSE) file.
## Official instance
There is a demonstration site, available at <https://lufi.fiat-tux.fr>, with strong limitations on time and file size.
## Logo
Because Lufi is quite similar to Luffy, like in "[Monkey D. Luffy](https://en.wikipedia.org/wiki/Monkey_D._Luffy)" from [One Piece](https://en.wikipedia.org/wiki/One_Piece) manga, the logo is a straw hat, made with pain, love and [Inkscape](https://inkscape.org/).
## Wiki (work in progress)
The official wiki will contain all you need to know about Lufi (installation, configuration, etc.). Go to <https://framagit.org/fiat-tux/hat-softwares/lufi/wikis/home> or clone it:
```
git clone https://framagit.org/fiat-tux/hat-softwares/lufi.wiki.git
```
## Encryption
All the encryption/decryption processes take place in your browser. The encryption key is never sent over the network.
However please note that some metadata are sent unencrypted:
* the file name
* its size
* its mimetype
## Client
There is the web interface, but you can use a CLI client too! Have a look at [lufi-cli](https://framagit.org/fiat-tux/hat-softwares/lufi-cli) or install it directly with `sudo npm install -g lufi-cli`.
There is another client in Python too: <https://framagit.org/setop/pylufic>.
## Internationalization
Lufi comes with several languages.
Please, see [this wiki page](https://framagit.org/fiat-tux/hat-softwares/lufi/wikis/contribute#internationalization) to know how to contribute to internationalization.
## Authors
See [AUTHORS.md](AUTHORS.md) file.
## Contribute!
Please consider contributing, either by [reporting issues](https://framagit.org/fiat-tux/hat-softwares/lufi/issues) or by helping the internationalization. And of course, code contributions are welcome!
The details on how to contribute are on the [wiki](https://framagit.org/fiat-tux/hat-softwares/lufi/wikis/contribute).
This software uses [Fiat Tux Code of conduct](https://framagit.org/fiat-tux/code-of-conduct/blob/master/README.md).
## Make a donation
You can make a donation to the author on [Tipeee](https://www.tipeee.com/fiat-tux) or on [Liberapay](https://liberapay.com/sky/).
## Other dependencies
Lufi is written in Perl with the [Mojolicious](http://mojolicio.us) framework.
It uses:
* [Materialize](http://materializecss.com/) framework to look not too ugly
* [jQuery](https://jquery.com)
* [Stanford Javascript Crypto Library](http://bitwiseshiftleft.github.com/sjcl/)
* [Moment.js](http://momentjs.com/) for displaying real dates instead of unix timestamps.
* [Filesize.js](http://filesizejs.com/) for displaying file sizes
## Deploy Lufi
An ansible role and a terraform plan reside under the `.provision` directory. An user could utilize the terraform plan if they chose to deploy lufi on AWS, if that's not the goal, they could simply execute the ansible role in part. Usage docs for both are present in their respective directories.
You can use Docker by using the recipe on <https://github.com/megalis-bretagne/lufi-docker>.
================================================
FILE: cpanfile
================================================
requires 'inc::Module::Install';
requires 'Mojolicious', '>= 8.05';
requires 'Mojolicious::Plugin::DebugDumperHelper';
requires 'Mojolicious::Plugin::I18N';
requires 'Mojolicious::Plugin::Mail';
requires 'Mojolicious::Plugin::GzipStatic';
requires 'Mojolicious::Plugin::StaticCache';
requires 'Mojolicious::Plugin::CSPHeader', '>= 0.06';
requires 'Mojolicious::Plugin::FiatTux::Helpers', '== 0.12', url => 'https://framagit.org/fiat-tux/mojolicious/fiat-tux/mojolicious-plugin-fiattux-helpers/-/archive/0.12/mojolicious-plugin-fiattux-helpers-0.12.tar.gz';
requires 'Mojolicious::Plugin::FiatTux::GrantAccess', '== 0.10', url => 'https://framagit.org/fiat-tux/mojolicious/fiat-tux/mojolicious-plugin-fiattux-grantaccess/-/archive/0.10/mojolicious-plugin-fiattux-grantaccess-0.10.tar.gz';
requires 'Mojolicious::Plugin::FiatTux::Themes', '== 0.02', url => 'https://framagit.org/fiat-tux/mojolicious/fiat-tux/mojolicious-plugin-fiattux-themes/-/archive/0.02/mojolicious-plugin-fiattux-themes-0.02.tar.gz';
requires 'Filesys::DiskUsage';
requires 'Switch';
requires 'Locale::Maketext';
requires 'Locale::Maketext::Extract';
requires 'Net::DNS';
requires 'Email::Valid';
requires 'Number::Bytes::Human';
requires 'Filesys::DfPortable';
requires 'Data::Entropy';
requires 'Crypt::SaltedHash';
requires 'Data::Validate::URI';
requires 'Term::ProgressBar';
requires 'URI::Find';
# Mojolicious optional deps
feature 'optional_deps' => sub {
requires 'Cpanel::JSON::XS';
requires 'EV';
requires 'IO::Socket::Socks';
requires 'Role::Tiny';
};
feature 'test' => sub {
requires 'Devel::Cover';
requires 'B::Debug';
};
feature 'ldap', 'LDAP authentication support' => sub {
requires 'Net::LDAP';
requires 'Mojolicious::Plugin::Authentication';
requires 'Date::Language';
};
feature 'htpasswd', 'Htpasswd authentication support' => sub {
requires 'Apache::Htpasswd';
requires 'Mojolicious::Plugin::Authentication';
};
feature 'auth_headers', 'Header authentication support' => sub {
requires 'Mojolicious::Plugin::Authentication';
};
feature 'postgresql', 'PostgreSQL support' => sub {
requires 'Mojo::Pg';
requires 'Mojolicious::Plugin::PgURLHelper';
};
feature 'sqlite', 'SQLite support' => sub {
requires 'Mojo::SQLite', '>= 3.000';
};
feature 'mysql', 'MySQL support' => sub {
requires 'DBD::mysql', '== 4.050';
requires 'Mojo::mysql';
requires 'Mojolicious::Plugin::PgURLHelper';
};
feature 'swift-storage', 'Openstack Swift object storage support' => sub {
requires 'Net::OpenStack::Swift';
};
================================================
FILE: cpanfile.snapshot
================================================
# carton snapshot format: version 1.0
DISTRIBUTIONS
Apache-Htpasswd-1.9
pathname: K/KM/KMELTZ/Apache-Htpasswd-1.9.tar.gz
provides:
Apache::Htpasswd 1.9
requirements:
Crypt::PasswdMD5 0
Digest::SHA 2
ExtUtils::MakeMaker 0
MIME::Base64 0
App-Rad-1.05
pathname: G/GA/GARU/App-Rad-1.05.tar.gz
provides:
App::Rad 1.05
App::Rad::Config undef
App::Rad::Exclude 0.01
App::Rad::Help 0.03
App::Rad::Include 0.01
requirements:
Attribute::Handlers 0
B::Deparse 0
Carp 0
ExtUtils::MakeMaker 0
File::Temp 0
FindBin 0
Getopt::Long 2.36
Test::More 0
Authen-SASL-2.1700
pathname: E/EH/EHUELS/Authen-SASL-2.1700.tar.gz
provides:
Authen::SASL 2.1700
Authen::SASL::CRAM_MD5 2.1700
Authen::SASL::EXTERNAL 2.1700
Authen::SASL::Perl 2.1700
Authen::SASL::Perl::ANONYMOUS 2.1700
Authen::SASL::Perl::CRAM_MD5 2.1700
Authen::SASL::Perl::DIGEST_MD5 2.1700
Authen::SASL::Perl::EXTERNAL 2.1700
Authen::SASL::Perl::GSSAPI 2.1700
Authen::SASL::Perl::LOGIN 2.1700
Authen::SASL::Perl::PLAIN 2.1700
requirements:
Digest::HMAC_MD5 0
Digest::MD5 0
ExtUtils::MakeMaker 0
perl 5.006000
B-Debug-1.26
pathname: R/RU/RURBAN/B-Debug-1.26.tar.gz
provides:
B::Debug 1.26
requirements:
B 0
ExtUtils::MakeMaker 0
Test::More 0
deprecate 0.03
B-Hooks-EndOfScope-0.26
pathname: E/ET/ETHER/B-Hooks-EndOfScope-0.26.tar.gz
provides:
B::Hooks::EndOfScope 0.26
B::Hooks::EndOfScope::PP 0.26
B::Hooks::EndOfScope::XS 0.26
requirements:
ExtUtils::MakeMaker 0
Hash::Util::FieldHash 0
Module::Implementation 0.05
Scalar::Util 0
Sub::Exporter::Progressive 0.001006
Text::ParseWords 0
Tie::Hash 0
Variable::Magic 0.48
perl 5.006001
strict 0
warnings 0
Canary-Stability-2013
pathname: M/ML/MLEHMANN/Canary-Stability-2013.tar.gz
provides:
Canary::Stability 2013
requirements:
ExtUtils::MakeMaker 0
Capture-Tiny-0.48
pathname: D/DA/DAGOLDEN/Capture-Tiny-0.48.tar.gz
provides:
Capture::Tiny 0.48
requirements:
Carp 0
Exporter 0
ExtUtils::MakeMaker 6.17
File::Spec 0
File::Temp 0
IO::Handle 0
Scalar::Util 0
perl 5.006
strict 0
warnings 0
Class-Accessor-Lite-0.08
pathname: K/KA/KAZUHO/Class-Accessor-Lite-0.08.tar.gz
provides:
Class::Accessor::Lite 0.08
requirements:
ExtUtils::MakeMaker 6.36
Class-Method-Modifiers-2.15
pathname: E/ET/ETHER/Class-Method-Modifiers-2.15.tar.gz
provides:
Class::Method::Modifiers 2.15
requirements:
B 0
Carp 0
Exporter 0
ExtUtils::MakeMaker 0
base 0
perl 5.006
strict 0
warnings 0
Class-MethodMaker-2.24
pathname: S/SC/SCHWIGON/class-methodmaker/Class-MethodMaker-2.24.tar.gz
provides:
Class::MethodMaker 2.24
Class::MethodMaker::Constants undef
Class::MethodMaker::Engine 2.24
Class::MethodMaker::OptExt undef
Class::MethodMaker::V1Compat undef
Generate undef
requirements:
ExtUtils::MakeMaker 0
perl 5.006
Clone-0.46
pathname: G/GA/GARU/Clone-0.46.tar.gz
provides:
Clone 0.46
requirements:
ExtUtils::MakeMaker 0
Clone-Choose-0.010
pathname: H/HE/HERMES/Clone-Choose-0.010.tar.gz
provides:
Clone::Choose 0.010
requirements:
ExtUtils::MakeMaker 0
Storable 0
perl 5.008001
Convert-ASN1-0.34
pathname: T/TI/TIMLEGGE/Convert-ASN1-0.34.tar.gz
provides:
Convert::ASN1 0.34
requirements:
ExtUtils::MakeMaker 0
Cpanel-JSON-XS-4.37
pathname: R/RU/RURBAN/Cpanel-JSON-XS-4.37.tar.gz
provides:
Cpanel::JSON::XS 4.37
Cpanel::JSON::XS::Type undef
requirements:
Carp 0
Config 0
Encode 1.9801
Exporter 0
ExtUtils::MakeMaker 0
Pod::Text 2.08
XSLoader 0
overload 0
strict 0
warnings 0
Crypt-PasswdMD5-1.42
pathname: R/RS/RSAVAGE/Crypt-PasswdMD5-1.42.tgz
provides:
Crypt::PasswdMD5 1.42
requirements:
Digest::MD5 2.53
ExtUtils::MakeMaker 0
strict 0
warnings 0
Crypt-Rijndael-1.16
pathname: L/LE/LEONT/Crypt-Rijndael-1.16.tar.gz
provides:
Crypt::Rijndael 1.16
requirements:
ExtUtils::MakeMaker 0
perl 5.006
Crypt-SaltedHash-0.09
pathname: G/GS/GSHANK/Crypt-SaltedHash-0.09.tar.gz
provides:
Crypt::SaltedHash 0.09
requirements:
Digest 0
ExtUtils::MakeMaker 6.30
Test::Fatal 0
Test::More 0
DBD-MariaDB-1.23
pathname: P/PA/PALI/DBD-MariaDB-1.23.tar.gz
provides:
DBD::MariaDB 1.23
requirements:
Config 0
DBI 1.608
Data::Dumper 0
Devel::CheckLib 1.12
DynaLoader 0
ExtUtils::MakeMaker 0
File::Spec 0
Getopt::Long 0
perl 5.008001
strict 0
utf8 0
warnings 0
DBD-Pg-3.18.0
pathname: T/TU/TURNSTEP/DBD-Pg-3.18.0.tar.gz
provides:
Bundle::DBD::Pg v3.18.0
DBD::Pg v3.18.0
requirements:
DBI 1.614
ExtUtils::MakeMaker 6.58
File::Temp 0
Test::More 0.88
Time::HiRes 0
version 0
DBD-SQLite-1.74
pathname: I/IS/ISHIGAKI/DBD-SQLite-1.74.tar.gz
provides:
DBD::SQLite 1.74
DBD::SQLite::Constants undef
DBD::SQLite::GetInfo undef
DBD::SQLite::VirtualTable 1.74
DBD::SQLite::VirtualTable::Cursor 1.74
DBD::SQLite::VirtualTable::FileContent undef
DBD::SQLite::VirtualTable::FileContent::Cursor undef
DBD::SQLite::VirtualTable::PerlData undef
DBD::SQLite::VirtualTable::PerlData::Cursor undef
requirements:
DBI 1.57
ExtUtils::MakeMaker 0
File::Spec 0.82
Test::More 0.88
Tie::Hash 0
perl 5.006
DBD-mysql-4.050
pathname: D/DV/DVEEDEN/DBD-mysql-4.050.tar.gz
provides:
Bundle::DBD::mysql 4.050
DBD::mysql 4.050
DBD::mysql::GetInfo undef
DBD::mysql::db 4.050
DBD::mysql::dr 4.050
DBD::mysql::st 4.050
requirements:
DBI 1.609
Data::Dumper 0
Devel::CheckLib 1.09
ExtUtils::MakeMaker 0
perl 5.008001
DBI-1.643
pathname: T/TI/TIMB/DBI-1.643.tar.gz
provides:
Bundle::DBI 12.008696
DBD::DBM 0.08
DBD::DBM::Statement 0.08
DBD::DBM::Table 0.08
DBD::DBM::db 0.08
DBD::DBM::dr 0.08
DBD::DBM::st 0.08
DBD::ExampleP 12.014311
DBD::ExampleP::db 12.014311
DBD::ExampleP::dr 12.014311
DBD::ExampleP::st 12.014311
DBD::File 0.44
DBD::File::DataSource::File 0.44
DBD::File::DataSource::Stream 0.44
DBD::File::Statement 0.44
DBD::File::Table 0.44
DBD::File::TableSource::FileSystem 0.44
DBD::File::db 0.44
DBD::File::dr 0.44
DBD::File::st 0.44
DBD::Gofer 0.015327
DBD::Gofer::Policy::Base 0.010088
DBD::Gofer::Policy::classic 0.010088
DBD::Gofer::Policy::pedantic 0.010088
DBD::Gofer::Policy::rush 0.010088
DBD::Gofer::Transport::Base 0.014121
DBD::Gofer::Transport::corostream undef
DBD::Gofer::Transport::null 0.010088
DBD::Gofer::Transport::pipeone 0.010088
DBD::Gofer::Transport::stream 0.014599
DBD::Gofer::db 0.015327
DBD::Gofer::dr 0.015327
DBD::Gofer::st 0.015327
DBD::Mem 0.001
DBD::Mem::DataSource 0.001
DBD::Mem::Statement 0.001
DBD::Mem::Table 0.001
DBD::Mem::db 0.001
DBD::Mem::dr 0.001
DBD::Mem::st 0.001
DBD::NullP 12.014715
DBD::NullP::db 12.014715
DBD::NullP::dr 12.014715
DBD::NullP::st 12.014715
DBD::Proxy 0.2004
DBD::Proxy::RPC::PlClient 0.2004
DBD::Proxy::db 0.2004
DBD::Proxy::dr 0.2004
DBD::Proxy::st 0.2004
DBD::Sponge 12.010003
DBD::Sponge::db 12.010003
DBD::Sponge::dr 12.010003
DBD::Sponge::st 12.010003
DBDI 12.015129
DBI 1.643
DBI::Const::GetInfo::ANSI 2.008697
DBI::Const::GetInfo::ODBC 2.011374
DBI::Const::GetInfoReturn 2.008697
DBI::Const::GetInfoType 2.008697
DBI::DBD 12.015129
DBI::DBD::Metadata 2.014214
DBI::DBD::SqlEngine 0.06
DBI::DBD::SqlEngine::DataSource 0.06
DBI::DBD::SqlEngine::Statement 0.06
DBI::DBD::SqlEngine::Table 0.06
DBI::DBD::SqlEngine::TableSource 0.06
DBI::DBD::SqlEngine::TieMeta 0.06
DBI::DBD::SqlEngine::TieTables 0.06
DBI::DBD::SqlEngine::db 0.06
DBI::DBD::SqlEngine::dr 0.06
DBI::DBD::SqlEngine::st 0.06
DBI::Gofer::Execute 0.014283
DBI::Gofer::Request 0.012537
DBI::Gofer::Response 0.011566
DBI::Gofer::Serializer::Base 0.009950
DBI::Gofer::Serializer::DataDumper 0.009950
DBI::Gofer::Serializer::Storable 0.015586
DBI::Gofer::Transport::Base 0.012537
DBI::Gofer::Transport::pipeone 0.012537
DBI::Gofer::Transport::stream 0.012537
DBI::Profile 2.015065
DBI::ProfileData 2.010008
DBI::ProfileDumper 2.015325
DBI::ProfileDumper::Apache 2.014121
DBI::ProfileSubs 0.009396
DBI::ProxyServer 0.3005
DBI::ProxyServer::db 0.3005
DBI::ProxyServer::dr 0.3005
DBI::ProxyServer::st 0.3005
DBI::SQL::Nano 1.015544
DBI::SQL::Nano::Statement_ 1.015544
DBI::SQL::Nano::Table_ 1.015544
DBI::Util::CacheMemory 0.010315
DBI::Util::_accessor 0.009479
DBI::common 1.643
requirements:
ExtUtils::MakeMaker 6.48
Test::Simple 0.90
perl 5.008001
Data-Entropy-0.007
pathname: Z/ZE/ZEFRAM/Data-Entropy-0.007.tar.gz
provides:
Data::Entropy 0.007
Data::Entropy::Algorithms 0.007
Data::Entropy::RawSource::CryptCounter 0.007
Data::Entropy::RawSource::Local 0.007
Data::Entropy::RawSource::RandomOrg 0.007
Data::Entropy::RawSource::RandomnumbersInfo 0.007
Data::Entropy::Source 0.007
requirements:
Carp 0
Crypt::Rijndael 0
Data::Float 0.008
Errno 1.00
Exporter 0
HTTP::Lite 2.2
IO::File 1.03
Module::Build 0
Params::Classify 0
Test::More 0
constant 0
integer 0
parent 0
perl 5.006
strict 0
warnings 0
Data-Float-0.013
pathname: Z/ZE/ZEFRAM/Data-Float-0.013.tar.gz
provides:
Data::Float 0.013
requirements:
Carp 0
Exporter 0
Module::Build 0
Test::More 0
constant 0
integer 0
parent 0
perl 5.006
strict 0
warnings 0
Data-Validate-Domain-0.15
pathname: D/DR/DROLSKY/Data-Validate-Domain-0.15.tar.gz
provides:
Data::Validate::Domain 0.15
requirements:
Exporter 0
ExtUtils::MakeMaker 0
Net::Domain::TLD 1.74
strict 0
warnings 0
Data-Validate-IP-0.31
pathname: D/DR/DROLSKY/Data-Validate-IP-0.31.tar.gz
provides:
Data::Validate::IP 0.31
requirements:
Exporter 0
ExtUtils::MakeMaker 0
NetAddr::IP 4
Scalar::Util 0
base 0
perl 5.008
strict 0
warnings 0
Data-Validate-URI-0.07
pathname: S/SO/SONNEN/Data-Validate-URI-0.07.tar.gz
provides:
Data::Validate::URI 0.07
requirements:
Data::Validate::Domain 0
Data::Validate::IP 0
ExtUtils::MakeMaker 0
Data-Validator-1.07
pathname: G/GF/GFUJI/Data-Validator-1.07.tar.gz
provides:
Data::Validator 1.07
Data::Validator::Role::AllowExtra undef
Data::Validator::Role::Croak undef
Data::Validator::Role::Method undef
Data::Validator::Role::NoRestricted undef
Data::Validator::Role::NoThrow undef
Data::Validator::Role::Sequenced undef
Data::Validator::Role::SmartSequenced undef
Data::Validator::Role::StrictSequenced undef
requirements:
ExtUtils::MakeMaker 6.59
Module::Build 0.38
Mouse 0.93
perl 5.008001
Devel-CheckCompiler-0.07
pathname: S/SY/SYOHEX/Devel-CheckCompiler-0.07.tar.gz
provides:
Devel::AssertC99 undef
Devel::CheckCompiler 0.07
requirements:
Exporter 0
ExtUtils::CBuilder 0
File::Temp 0
Module::Build::Tiny 0.035
Test::More 0.98
parent 0
perl 5.008001
Devel-CheckLib-1.16
pathname: M/MA/MATTN/Devel-CheckLib-1.16.tar.gz
provides:
Devel::CheckLib 1.16
requirements:
Exporter 0
ExtUtils::MakeMaker 0
File::Spec 0
File::Temp 0.16
perl 5.004050
Devel-Cover-1.40
pathname: P/PJ/PJCJ/Devel-Cover-1.40.tar.gz
provides:
Devel::Cover 1.40
Devel::Cover::Annotation::Git 1.40
Devel::Cover::Annotation::Random 1.40
Devel::Cover::Annotation::Svk 1.40
Devel::Cover::Branch 1.40
Devel::Cover::Collection 1.40
Devel::Cover::Collection::Template::Provider 1.40
Devel::Cover::Condition 1.40
Devel::Cover::Condition_and_2 1.40
Devel::Cover::Condition_and_3 1.40
Devel::Cover::Condition_or_2 1.40
Devel::Cover::Condition_or_3 1.40
Devel::Cover::Condition_xor_4 1.40
Devel::Cover::Criterion 1.40
Devel::Cover::DB 1.40
Devel::Cover::DB::Criterion 1.40
Devel::Cover::DB::Digests 1.40
Devel::Cover::DB::File 1.40
Devel::Cover::DB::IO 1.40
Devel::Cover::DB::IO::Base 1.40
Devel::Cover::DB::IO::JSON 1.40
Devel::Cover::DB::IO::Sereal 1.40
Devel::Cover::DB::IO::Storable 1.40
Devel::Cover::DB::Run 1.40
Devel::Cover::DB::Structure 1.40
Devel::Cover::Html_Common 1.40
Devel::Cover::Op 1.40
Devel::Cover::Pod 1.40
Devel::Cover::Report::Compilation 1.40
Devel::Cover::Report::Html 1.40
Devel::Cover::Report::Html_basic 1.40
Devel::Cover::Report::Html_basic::Template::Provider 1.40
Devel::Cover::Report::Html_minimal 1.40
Devel::Cover::Report::Html_subtle 1.40
Devel::Cover::Report::Html_subtle::Template::Provider 1.40
Devel::Cover::Report::Json 1.40
Devel::Cover::Report::Sort 1.40
Devel::Cover::Report::Text 1.40
Devel::Cover::Report::Text2 1.40
Devel::Cover::Report::Vim 1.40
Devel::Cover::Report::Vim::Template::Provider 1.40
Devel::Cover::Statement 1.40
Devel::Cover::Subroutine 1.40
Devel::Cover::Test 1.40
Devel::Cover::Time 1.40
Devel::Cover::Truth_Table 1.40
Devel::Cover::Truth_Table::Row 1.40
Devel::Cover::Util 1.40
Devel::Cover::Web 1.40
requirements:
Digest::MD5 0
ExtUtils::MakeMaker 0
HTML::Entities 3.69
Storable 0
Test::More 0
Digest-HMAC-1.04
pathname: A/AR/ARODLAND/Digest-HMAC-1.04.tar.gz
provides:
Digest::HMAC 1.04
Digest::HMAC_MD5 1.04
Digest::HMAC_SHA1 1.04
requirements:
Digest::MD5 2
Digest::SHA 1
ExtUtils::MakeMaker 0
perl 5.004
Dist-CheckConflicts-0.11
pathname: D/DO/DOY/Dist-CheckConflicts-0.11.tar.gz
provides:
Dist::CheckConflicts 0.11
requirements:
Carp 0
Exporter 0
ExtUtils::MakeMaker 6.30
Module::Runtime 0.009
base 0
strict 0
warnings 0
EV-4.34
pathname: M/ML/MLEHMANN/EV-4.34.tar.gz
provides:
EV 4.34
EV::MakeMaker undef
requirements:
Canary::Stability 0
ExtUtils::MakeMaker 6.52
common::sense 0
Email-Date-Format-1.008
pathname: R/RJ/RJBS/Email-Date-Format-1.008.tar.gz
provides:
Email::Date::Format 1.008
requirements:
Exporter 5.57
ExtUtils::MakeMaker 6.78
Time::Local 1.27
perl 5.012
warnings 0
Email-Valid-1.203
pathname: R/RJ/RJBS/Email-Valid-1.203.tar.gz
provides:
Email::Valid 1.203
requirements:
ExtUtils::MakeMaker 0
Mail::Address 0
Scalar::Util 0
Test::More 0
perl 5.006
Encode-Locale-1.05
pathname: G/GA/GAAS/Encode-Locale-1.05.tar.gz
provides:
Encode::Locale 1.05
requirements:
Encode 2
Encode::Alias 0
ExtUtils::MakeMaker 0
perl 5.008
ExtUtils-Config-0.008
pathname: L/LE/LEONT/ExtUtils-Config-0.008.tar.gz
provides:
ExtUtils::Config 0.008
requirements:
Data::Dumper 0
ExtUtils::MakeMaker 6.30
strict 0
warnings 0
ExtUtils-Helpers-0.026
pathname: L/LE/LEONT/ExtUtils-Helpers-0.026.tar.gz
provides:
ExtUtils::Helpers 0.026
ExtUtils::Helpers::Unix 0.026
ExtUtils::Helpers::VMS 0.026
ExtUtils::Helpers::Windows 0.026
requirements:
Carp 0
Exporter 5.57
ExtUtils::MakeMaker 0
File::Basename 0
File::Copy 0
File::Spec::Functions 0
Text::ParseWords 3.24
perl 5.006
strict 0
warnings 0
ExtUtils-InstallPaths-0.012
pathname: L/LE/LEONT/ExtUtils-InstallPaths-0.012.tar.gz
provides:
ExtUtils::InstallPaths 0.012
requirements:
Carp 0
ExtUtils::Config 0.002
ExtUtils::MakeMaker 0
File::Spec 0
perl 5.006
strict 0
warnings 0
File-Listing-6.16
pathname: P/PL/PLICEASE/File-Listing-6.16.tar.gz
provides:
File::Listing 6.16
File::Listing::apache 6.16
File::Listing::dosftp 6.16
File::Listing::netware 6.16
File::Listing::unix 6.16
File::Listing::vms 6.16
requirements:
Exporter 5.57
ExtUtils::MakeMaker 0
HTTP::Date 0
perl 5.006
File-Remove-1.61
pathname: S/SH/SHLOMIF/File-Remove-1.61.tar.gz
provides:
File::Remove 1.61
requirements:
Cwd 3.29
ExtUtils::MakeMaker 0
File::Glob 0
File::Path 0
File::Spec 3.29
Module::Build 0.28
constant 0
perl 5.008
strict 0
vars 0
warnings 0
Filesys-DfPortable-0.85
pathname: I/IG/IGUTHRIE/Filesys-DfPortable-0.85.tar.gz
provides:
Filesys::DfPortable 0.85
requirements:
ExtUtils::MakeMaker 0
Filesys-DiskUsage-0.13
pathname: M/MA/MANWAR/Filesys-DiskUsage-0.13.tar.gz
provides:
Filesys::DiskUsage 0.13
requirements:
ExtUtils::MakeMaker 0
File::Basename 0
File::Find 0
File::Temp 0
Test::More 0
Test::Warn 0
perl 5.006
Furl-3.14
pathname: S/SY/SYOHEX/Furl-3.14.tar.gz
provides:
Furl 3.14
Furl::ConnectionCache undef
Furl::HTTP 3.14
Furl::Headers undef
Furl::Request undef
Furl::Response undef
Furl::ZlibStream undef
requirements:
Class::Accessor::Lite 0
Encode 0
HTTP::Parser::XS 0.11
MIME::Base64 0
Module::Build::Tiny 0.035
Mozilla::CA 0
Scalar::Util 0
Socket 0
Time::HiRes 0
perl 5.008001
HTML-Parser-3.81
pathname: O/OA/OALDERS/HTML-Parser-3.81.tar.gz
provides:
HTML::Entities 3.81
HTML::Filter 3.81
HTML::HeadParser 3.81
HTML::LinkExtor 3.81
HTML::Parser 3.81
HTML::PullParser 3.81
HTML::TokeParser 3.81
requirements:
Carp 0
Exporter 0
ExtUtils::MakeMaker 6.52
HTML::Tagset 0
HTTP::Headers 0
IO::File 0
URI 0
URI::URL 0
XSLoader 0
strict 0
HTML-Tagset-3.20
pathname: P/PE/PETDANCE/HTML-Tagset-3.20.tar.gz
provides:
HTML::Tagset 3.20
requirements:
ExtUtils::MakeMaker 0
HTTP-CookieJar-0.014
pathname: D/DA/DAGOLDEN/HTTP-CookieJar-0.014.tar.gz
provides:
HTTP::CookieJar 0.014
HTTP::CookieJar::LWP 0.014
requirements:
Carp 0
ExtUtils::MakeMaker 6.17
HTTP::Date 0
Time::Local 1.1901
parent 0
perl 5.008001
strict 0
warnings 0
HTTP-Cookies-6.11
pathname: O/OA/OALDERS/HTTP-Cookies-6.11.tar.gz
provides:
HTTP::Cookies 6.11
HTTP::Cookies::Microsoft 6.11
HTTP::Cookies::Netscape 6.11
requirements:
Carp 0
ExtUtils::MakeMaker 0
HTTP::Date 6
HTTP::Headers::Util 6
HTTP::Request 0
locale 0
perl 5.008001
strict 0
HTTP-Date-6.06
pathname: O/OA/OALDERS/HTTP-Date-6.06.tar.gz
provides:
HTTP::Date 6.06
requirements:
Exporter 0
ExtUtils::MakeMaker 0
Time::Local 1.28
Time::Zone 0
perl 5.006002
strict 0
HTTP-Lite-2.44
pathname: N/NE/NEILB/HTTP-Lite-2.44.tar.gz
provides:
HTTP::Lite 2.44
requirements:
ExtUtils::MakeMaker 0
Fcntl 0
Socket 1.3
perl 5.005
strict 0
warnings 0
HTTP-Message-6.45
pathname: O/OA/OALDERS/HTTP-Message-6.45.tar.gz
provides:
HTTP::Config 6.45
HTTP::Headers 6.45
HTTP::Headers::Auth 6.45
HTTP::Headers::ETag 6.45
HTTP::Headers::Util 6.45
HTTP::Message 6.45
HTTP::Request 6.45
HTTP::Request::Common 6.45
HTTP::Response 6.45
HTTP::Status 6.45
requirements:
Carp 0
Clone 0.46
Compress::Raw::Bzip2 0
Compress::Raw::Zlib 2.062
Encode 3.01
Encode::Locale 1
Exporter 5.57
ExtUtils::MakeMaker 0
File::Spec 0
HTTP::Date 6
IO::Compress::Bzip2 2.021
IO::Compress::Deflate 0
IO::Compress::Gzip 0
IO::HTML 0
IO::Uncompress::Inflate 0
IO::Uncompress::RawInflate 0
LWP::MediaTypes 6
MIME::Base64 2.1
MIME::QuotedPrint 0
URI 1.10
parent 0
perl 5.008001
strict 0
warnings 0
HTTP-Negotiate-6.01
pathname: G/GA/GAAS/HTTP-Negotiate-6.01.tar.gz
provides:
HTTP::Negotiate 6.01
requirements:
ExtUtils::MakeMaker 0
HTTP::Headers 6
perl 5.008001
HTTP-Parser-XS-0.17
pathname: K/KA/KAZUHO/HTTP-Parser-XS-0.17.tar.gz
provides:
HTTP::Parser::XS 0.17
HTTP::Parser::XS::PP undef
requirements:
ExtUtils::MakeMaker 6.36
Test::More 0.96
Hash-Merge-0.302
pathname: H/HE/HERMES/Hash-Merge-0.302.tar.gz
provides:
Hash::Merge 0.302
requirements:
Clone::Choose 0.008
ExtUtils::MakeMaker 6.64
Scalar::Util 0
perl 5.008001
IO-HTML-1.004
pathname: C/CJ/CJM/IO-HTML-1.004.tar.gz
provides:
IO::HTML 1.004
requirements:
Carp 0
Encode 2.10
Exporter 5.57
ExtUtils::MakeMaker 0
perl 5.008
IO-Socket-SSL-2.084
pathname: S/SU/SULLR/IO-Socket-SSL-2.084.tar.gz
provides:
IO::Socket::SSL 2.084
IO::Socket::SSL::Intercept 2.056
IO::Socket::SSL::OCSP_Cache 2.084
IO::Socket::SSL::OCSP_Resolver 2.084
IO::Socket::SSL::PublicSuffix undef
IO::Socket::SSL::SSL_Context 2.084
IO::Socket::SSL::SSL_HANDLE 2.084
IO::Socket::SSL::Session_Cache 2.084
IO::Socket::SSL::Trace 2.084
IO::Socket::SSL::Utils 2.015
requirements:
ExtUtils::MakeMaker 0
Mozilla::CA 0
Net::SSLeay 1.46
Scalar::Util 0
IO-Socket-Socks-0.74
pathname: O/OL/OLEG/IO-Socket-Socks-0.74.tar.gz
provides:
IO::Socket::Socks 0.74
IO::Socket::Socks::Debug 0.74
IO::Socket::Socks::Error 0.74
IO::Socket::Socks::ReadOnlyVar 0.74
IO::Socket::Socks::SocketClassVar 0.74
requirements:
ExtUtils::MakeMaker 6.52
IO::Select 0
Socket 1.94
Test::More 0.88
constant 1.03
ISO-639_1-0.04
pathname: L/LD/LDIDRY/ISO-639_1-0.04.tar.gz
provides:
ISO::639_1 0.04
requirements:
Module::Build::Tiny 0.035
perl 5.008001
JSON-4.10
pathname: I/IS/ISHIGAKI/JSON-4.10.tar.gz
provides:
JSON 4.10
JSON::Backend::PP 4.10
requirements:
ExtUtils::MakeMaker 0
Test::More 0
LWP-MediaTypes-6.04
pathname: O/OA/OALDERS/LWP-MediaTypes-6.04.tar.gz
provides:
LWP::MediaTypes 6.04
requirements:
Carp 0
Exporter 0
ExtUtils::MakeMaker 0
File::Basename 0
Scalar::Util 0
perl 5.006002
strict 0
Locale-Maketext-Lexicon-1.00
pathname: D/DR/DRTECH/Locale-Maketext-Lexicon-1.00.tar.gz
provides:
Locale::Maketext::Extract 1.00
Locale::Maketext::Extract::Plugin::Base 1.00
Locale::Maketext::Extract::Plugin::FormFu 1.00
Locale::Maketext::Extract::Plugin::FormFu::Extractor 1.00
Locale::Maketext::Extract::Plugin::Generic 1.00
Locale::Maketext::Extract::Plugin::Haml 1.00
Locale::Maketext::Extract::Plugin::Mason 1.00
Locale::Maketext::Extract::Plugin::PPI 1.00
Locale::Maketext::Extract::Plugin::Perl 1.00
Locale::Maketext::Extract::Plugin::TT2 1.00
Locale::Maketext::Extract::Plugin::TT2::Directive 1.00
Locale::Maketext::Extract::Plugin::TT2::Parser 1.00
Locale::Maketext::Extract::Plugin::TextTemplate 1.00
Locale::Maketext::Extract::Plugin::TextTemplate::Parser 1.00
Locale::Maketext::Extract::Plugin::YAML 1.00
Locale::Maketext::Extract::Plugin::YAML::Extractor 1.00
Locale::Maketext::Extract::Run 1.00
Locale::Maketext::Lexicon 1.00
Locale::Maketext::Lexicon::Auto 1.00
Locale::Maketext::Lexicon::Gettext 1.00
Locale::Maketext::Lexicon::Msgcat 1.00
Locale::Maketext::Lexicon::Tie 1.00
requirements:
ExtUtils::MakeMaker 6.30
Locale::Maketext 1.17
Log-Minimal-0.19
pathname: K/KA/KAZEBURO/Log-Minimal-0.19.tar.gz
provides:
Log::Minimal 0.19
requirements:
CPAN::Meta 0
CPAN::Meta::Prereqs 0
Data::Dumper 0
Module::Build 0.38
Scalar::Util 0
Term::ANSIColor 0
MIME-Charset-1.013.1
pathname: N/NE/NEZUMI/MIME-Charset-1.013.1.tar.gz
provides:
MIME::Charset v1.13.1
requirements:
CPAN 0
Encode 1.98
ExtUtils::MakeMaker 6.42
Test::More 0
perl 5.005
MIME-EncWords-1.014.3
pathname: N/NE/NEZUMI/MIME-EncWords-1.014.3.tar.gz
provides:
Encode::MIME::EncWords 0.03
MIME::EncWords 1.014003
requirements:
Encode 1.98
ExtUtils::MakeMaker 0
MIME::Base64 2.13
MIME::Charset v1.10.1
Test::More 0
MIME-Lite-3.033
pathname: R/RJ/RJBS/MIME-Lite-3.033.tar.gz
provides:
MIME::Lite 3.033
MIME::Lite::IO_Handle 3.033
MIME::Lite::IO_Scalar 3.033
MIME::Lite::IO_ScalarArray 3.033
MIME::Lite::SMTP 3.033
MailTool undef
requirements:
Email::Date::Format 1.000
ExtUtils::MakeMaker 0
File::Basename 0
File::Spec 0
MIME::Base64 0
MIME::QuotedPrint 0
MIME::Types 1.28
Mail::Address 1.62
MIME-Types-2.24
pathname: M/MA/MARKOV/MIME-Types-2.24.tar.gz
provides:
MIME::Type 2.24
MIME::Types 2.24
MojoX::MIME::Types 2.24
requirements:
ExtUtils::MakeMaker 0
File::Basename 0
File::Spec 0
List::Util 0
Test::More 0.47
MRO-Compat-0.15
pathname: H/HA/HAARG/MRO-Compat-0.15.tar.gz
provides:
MRO::Compat 0.15
requirements:
ExtUtils::MakeMaker 0
perl 5.006
MailTools-2.21
pathname: M/MA/MARKOV/MailTools-2.21.tar.gz
provides:
Mail::Address 2.21
Mail::Cap 2.21
Mail::Field 2.21
Mail::Field::AddrList 2.21
Mail::Field::Date 2.21
Mail::Field::Generic 2.21
Mail::Filter 2.21
Mail::Header 2.21
Mail::Internet 2.21
Mail::Mailer 2.21
Mail::Mailer::qmail 2.21
Mail::Mailer::rfc822 2.21
Mail::Mailer::sendmail 2.21
Mail::Mailer::smtp 2.21
Mail::Mailer::smtp::pipe 2.21
Mail::Mailer::smtps 2.21
Mail::Mailer::smtps::pipe 2.21
Mail::Mailer::testfile 2.21
Mail::Mailer::testfile::pipe 2.21
Mail::Send 2.21
Mail::Util 2.21
MailTools 2.21
requirements:
Date::Format 0
Date::Parse 0
ExtUtils::MakeMaker 0
IO::Handle 0
Net::Domain 1.05
Net::SMTP 1.03
Test::More 0
Module-Build-0.4234
pathname: L/LE/LEONT/Module-Build-0.4234.tar.gz
provides:
Module::Build 0.4234
Module::Build::Base 0.4234
Module::Build::Compat 0.4234
Module::Build::Config 0.4234
Module::Build::Cookbook 0.4234
Module::Build::Dumper 0.4234
Module::Build::Notes 0.4234
Module::Build::PPMMaker 0.4234
Module::Build::Platform::Default 0.4234
Module::Build::Platform::MacOS 0.4234
Module::Build::Platform::Unix 0.4234
Module::Build::Platform::VMS 0.4234
Module::Build::Platform::VOS 0.4234
Module::Build::Platform::Windows 0.4234
Module::Build::Platform::aix 0.4234
Module::Build::Platform::cygwin 0.4234
Module::Build::Platform::darwin 0.4234
Module::Build::Platform::os2 0.4234
Module::Build::PodParser 0.4234
requirements:
CPAN::Meta 2.142060
Cwd 0
Data::Dumper 0
ExtUtils::CBuilder 0.27
ExtUtils::Install 0
ExtUtils::Manifest 0
ExtUtils::Mkbootstrap 0
ExtUtils::ParseXS 2.21
File::Basename 0
File::Compare 0
File::Copy 0
File::Find 0
File::Path 0
File::Spec 0.82
Getopt::Long 0
Module::Metadata 1.000002
Perl::OSType 1
TAP::Harness 3.29
Text::Abbrev 0
Text::ParseWords 0
perl 5.006001
version 0.87
Module-Build-Tiny-0.047
pathname: L/LE/LEONT/Module-Build-Tiny-0.047.tar.gz
provides:
Module::Build::Tiny 0.047
requirements:
CPAN::Meta 0
DynaLoader 0
Exporter 5.57
ExtUtils::CBuilder 0
ExtUtils::Config 0.003
ExtUtils::Helpers 0.020
ExtUtils::Install 0
ExtUtils::InstallPaths 0.002
ExtUtils::ParseXS 0
File::Basename 0
File::Find 0
File::Path 0
File::Spec::Functions 0
Getopt::Long 2.36
JSON::PP 2
Pod::Man 0
TAP::Harness::Env 0
perl 5.006
strict 0
warnings 0
Module-Build-XSUtil-0.19
pathname: H/HI/HIDEAKIO/Module-Build-XSUtil-0.19.tar.gz
provides:
Module::Build::XSUtil 0.19
requirements:
Devel::CheckCompiler 0
Devel::PPPort 0
Exporter 0
ExtUtils::CBuilder 0
File::Basename 0
File::Path 0
Module::Build 0.4005
XSLoader 0
parent 0
perl 5.008001
Module-Implementation-0.09
pathname: D/DR/DROLSKY/Module-Implementation-0.09.tar.gz
provides:
Module::Implementation 0.09
requirements:
Carp 0
ExtUtils::MakeMaker 0
Module::Runtime 0.012
Try::Tiny 0
strict 0
warnings 0
Module-Install-1.21
pathname: E/ET/ETHER/Module-Install-1.21.tar.gz
provides:
Module::AutoInstall 1.21
Module::Install 1.21
Module::Install::Admin 1.21
Module::Install::Admin::Bundle 1.21
Module::Install::Admin::Compiler 1.21
Module::Install::Admin::Find 1.21
Module::Install::Admin::Include 1.21
Module::Install::Admin::Makefile 1.21
Module::Install::Admin::Manifest 1.21
Module::Install::Admin::Metadata 1.21
Module::Install::Admin::ScanDeps 1.21
Module::Install::Admin::WriteAll 1.21
Module::Install::AutoInstall 1.21
Module::Install::Base 1.21
Module::Install::Base::FakeAdmin 1.21
Module::Install::Bundle 1.21
Module::Install::Can 1.21
Module::Install::Compiler 1.21
Module::Install::Deprecated 1.21
Module::Install::External 1.21
Module::Install::Fetch 1.21
Module::Install::Include 1.21
Module::Install::Inline 1.21
Module::Install::MakeMaker 1.21
Module::Install::Makefile 1.21
Module::Install::Metadata 1.21
Module::Install::PAR 1.21
Module::Install::Run 1.21
Module::Install::Scripts 1.21
Module::Install::Share 1.21
Module::Install::Win32 1.21
Module::Install::With 1.21
Module::Install::WriteAll 1.21
inc::Module::Install 1.21
requirements:
Devel::PPPort 3.16
ExtUtils::Install 1.52
ExtUtils::MakeMaker 6.59
ExtUtils::ParseXS 2.19
File::Path 0
File::Remove 1.42
File::Spec 3.28
Module::Build 0.29
Module::CoreList 2.17
Module::ScanDeps 1.09
Parse::CPAN::Meta 1.4413
Test::Harness 3.13
Test::More 0.86
YAML::Tiny 1.38
autodie 0
perl 5.006
Module-Runtime-0.016
pathname: Z/ZE/ZEFRAM/Module-Runtime-0.016.tar.gz
provides:
Module::Runtime 0.016
requirements:
Module::Build 0
Test::More 0.41
perl 5.006
strict 0
warnings 0
Module-ScanDeps-1.35
pathname: R/RS/RSCHUPP/Module-ScanDeps-1.35.tar.gz
provides:
Module::ScanDeps 1.35
requirements:
ExtUtils::MakeMaker 0
File::Spec 0
File::Temp 0
Getopt::Long 0
List::Util 1.33
Module::Metadata 0
Text::ParseWords 0
perl 5.008009
version 0
Mojo-Pg-4.27
pathname: S/SR/SRI/Mojo-Pg-4.27.tar.gz
provides:
Mojo::Pg 4.27
Mojo::Pg::Database undef
Mojo::Pg::Migrations undef
Mojo::Pg::PubSub undef
Mojo::Pg::Results undef
Mojo::Pg::Transaction undef
requirements:
DBD::Pg 3.007004
ExtUtils::MakeMaker 0
Mojolicious 8.50
SQL::Abstract::Pg 1.0
perl 5.016
Mojo-SQLite-3.009
pathname: D/DB/DBOOK/Mojo-SQLite-3.009.tar.gz
provides:
Mojo::SQLite 3.009
Mojo::SQLite::Database 3.009
Mojo::SQLite::Migrations 3.009
Mojo::SQLite::PubSub 3.009
Mojo::SQLite::Results 3.009
Mojo::SQLite::Transaction 3.009
requirements:
Carp 0
DBD::SQLite 1.68
DBI 1.627
File::Spec::Functions 0
File::Temp 0
Module::Build::Tiny 0.034
Mojolicious 8.03
SQL::Abstract::Pg 1.0
Scalar::Util 0
URI 1.69
URI::db 0.15
URI::file 4.21
perl 5.010001
Mojo-mysql-1.27
pathname: J/JH/JHTHORSEN/Mojo-mysql-1.27.tar.gz
provides:
Mojo::mysql 1.27
Mojo::mysql::Database undef
Mojo::mysql::Migrations undef
Mojo::mysql::PubSub undef
Mojo::mysql::Results undef
Mojo::mysql::Transaction undef
SQL::Abstract::mysql undef
requirements:
DBD::MariaDB 1.21
DBI 1.643
ExtUtils::MakeMaker 0
Mojolicious 8.03
SQL::Abstract 1.86
perl 5.016
Mojolicious-9.35
pathname: S/SR/SRI/Mojolicious-9.35.tar.gz
provides:
Mojo undef
Mojo::Asset undef
Mojo::Asset::File undef
Mojo::Asset::Memory undef
Mojo::Base undef
Mojo::ByteStream undef
Mojo::Cache undef
Mojo::Collection undef
Mojo::Content undef
Mojo::Content::MultiPart undef
Mojo::Content::Single undef
Mojo::Cookie undef
Mojo::Cookie::Request undef
Mojo::Cookie::Response undef
Mojo::DOM undef
Mojo::DOM::CSS undef
Mojo::DOM::HTML undef
Mojo::Date undef
Mojo::DynamicMethods undef
Mojo::EventEmitter undef
Mojo::Exception undef
Mojo::File undef
Mojo::Headers undef
Mojo::HelloWorld undef
Mojo::Home undef
Mojo::IOLoop undef
Mojo::IOLoop::Client undef
Mojo::IOLoop::Server undef
Mojo::IOLoop::Stream undef
Mojo::IOLoop::Subprocess undef
Mojo::IOLoop::TLS undef
Mojo::JSON undef
Mojo::JSON::Pointer undef
Mojo::Loader undef
Mojo::Log undef
Mojo::Message undef
Mojo::Message::Request undef
Mojo::Message::Response undef
Mojo::Parameters undef
Mojo::Path undef
Mojo::Promise undef
Mojo::Reactor undef
Mojo::Reactor::EV undef
Mojo::Reactor::Poll undef
Mojo::Server undef
Mojo::Server::CGI undef
Mojo::Server::Daemon undef
Mojo::Server::Hypnotoad undef
Mojo::Server::Morbo undef
Mojo::Server::Morbo::Backend undef
Mojo::Server::Morbo::Backend::Poll undef
Mojo::Server::PSGI undef
Mojo::Server::Prefork undef
Mojo::Template undef
Mojo::Transaction undef
Mojo::Transaction::HTTP undef
Mojo::Transaction::WebSocket undef
Mojo::URL undef
Mojo::Upload undef
Mojo::UserAgent undef
Mojo::UserAgent::CookieJar undef
Mojo::UserAgent::Proxy undef
Mojo::UserAgent::Server undef
Mojo::UserAgent::Transactor undef
Mojo::Util undef
Mojo::WebSocket undef
Mojolicious 9.35
Mojolicious::Command undef
Mojolicious::Command::Author::cpanify undef
Mojolicious::Command::Author::generate undef
Mojolicious::Command::Author::generate::app undef
Mojolicious::Command::Author::generate::dockerfile undef
Mojolicious::Command::Author::generate::lite_app undef
Mojolicious::Command::Author::generate::makefile undef
Mojolicious::Command::Author::generate::plugin undef
Mojolicious::Command::Author::inflate undef
Mojolicious::Command::cgi undef
Mojolicious::Command::daemon undef
Mojolicious::Command::eval undef
Mojolicious::Command::get undef
Mojolicious::Command::prefork undef
Mojolicious::Command::psgi undef
Mojolicious::Command::routes undef
Mojolicious::Command::version undef
Mojolicious::Commands undef
Mojolicious::Controller undef
Mojolicious::Lite undef
Mojolicious::Plugin undef
Mojolicious::Plugin::Config undef
Mojolicious::Plugin::DefaultHelpers undef
Mojolicious::Plugin::EPLRenderer undef
Mojolicious::Plugin::EPRenderer undef
Mojolicious::Plugin::HeaderCondition undef
Mojolicious::Plugin::JSONConfig undef
Mojolicious::Plugin::Mount undef
Mojolicious::Plugin::NotYAMLConfig undef
Mojolicious::Plugin::TagHelpers undef
Mojolicious::Plugins undef
Mojolicious::Renderer undef
Mojolicious::Routes undef
Mojolicious::Routes::Match undef
Mojolicious::Routes::Pattern undef
Mojolicious::Routes::Route undef
Mojolicious::Sessions undef
Mojolicious::Static undef
Mojolicious::Types undef
Mojolicious::Validator undef
Mojolicious::Validator::Validation undef
Test::Mojo undef
ojo undef
requirements:
ExtUtils::MakeMaker 0
IO::Socket::IP 0.37
Sub::Util 1.41
perl 5.016
Mojolicious-Plugin-Authentication-1.39
pathname: J/JJ/JJATRIA/Mojolicious-Plugin-Authentication-1.39.tar.gz
provides:
Mojolicious::Plugin::Authentication 1.39
requirements:
Exporter 0
ExtUtils::MakeMaker 0
Mojolicious 8.0
perl 5.016
Mojolicious-Plugin-CSPHeader-0.06
pathname: L/LD/LDIDRY/Mojolicious-Plugin-CSPHeader-0.06.tar.gz
provides:
Mojolicious::Plugin::CSPHeader 0.06
requirements:
ExtUtils::MakeMaker 0
Mojolicious 7.75
Mojolicious-Plugin-DebugDumperHelper-0.03
pathname: L/LD/LDIDRY/Mojolicious-Plugin-DebugDumperHelper-0.03.tar.gz
provides:
Mojolicious::Plugin::DebugDumperHelper 0.03
requirements:
ExtUtils::MakeMaker 0
Mojolicious 6.11
Mojolicious-Plugin-GzipStatic-0.04
pathname: L/LD/LDIDRY/Mojolicious-Plugin-GzipStatic-0.04.tar.gz
provides:
Mojolicious::Plugin::GzipStatic 0.04
requirements:
ExtUtils::MakeMaker 0
IO::Compress::Gzip 0
Mojolicious 7.75
Mojolicious-Plugin-I18N-1.6
pathname: S/SH/SHARIFULN/Mojolicious-Plugin-I18N-1.6.tar.gz
provides:
Mojolicious::Plugin::I18N 1.6
requirements:
I18N::LangTags 0.35
Module::Build 0.42
Mojolicious 5
Test::More 0
perl 5.010001
Mojolicious-Plugin-Mail-1.5
pathname: S/SH/SHARIFULN/Mojolicious-Plugin-Mail-1.5.tar.gz
provides:
Mojolicious::Plugin::Mail 1.5
requirements:
Encode 0
MIME::EncWords 0
MIME::Lite 3.027
Mojolicious 5
Test::More 0
perl 5.001001
Mojolicious-Plugin-PgURLHelper-0.03
pathname: L/LD/LDIDRY/Mojolicious-Plugin-PgURLHelper-0.03.tar.gz
provides:
Mojolicious::Plugin::PgURLHelper 0.03
requirements:
ExtUtils::MakeMaker 0
Mojolicious 7.23
Mojolicious-Plugin-StaticCache-0.02
pathname: L/LD/LDIDRY/Mojolicious-Plugin-StaticCache-0.02.tar.gz
provides:
Mojolicious::Plugin::StaticCache 0.02
requirements:
ExtUtils::MakeMaker 0
Mojolicious 7.33
Moo-2.005005
pathname: H/HA/HAARG/Moo-2.005005.tar.gz
provides:
Method::Generate::Accessor undef
Method::Generate::BuildAll undef
Method::Generate::Constructor undef
Method::Generate::DemolishAll undef
Moo 2.005005
Moo::HandleMoose undef
Moo::HandleMoose::FakeConstructor undef
Moo::HandleMoose::FakeMetaClass undef
Moo::HandleMoose::_TypeMap undef
Moo::Object undef
Moo::Role 2.005005
Moo::_Utils undef
Moo::sification undef
oo undef
requirements:
Carp 0
Class::Method::Modifiers 1.10
Exporter 0
ExtUtils::MakeMaker 0
Role::Tiny 2.002003
Scalar::Util 1.00
Sub::Defer 2.006006
Sub::Quote 2.006006
perl 5.006
Mouse-v2.5.10
pathname: S/SK/SKAJI/Mouse-v2.5.10.tar.gz
provides:
Mouse v2.5.10
Mouse::Exporter undef
Mouse::Meta::Attribute undef
Mouse::Meta::Class undef
Mouse::Meta::Method undef
Mouse::Meta::Method::Accessor undef
Mouse::Meta::Method::Constructor undef
Mouse::Meta::Method::Delegation undef
Mouse::Meta::Method::Destructor undef
Mouse::Meta::Module undef
Mouse::Meta::Role undef
Mouse::Meta::Role::Application undef
Mouse::Meta::Role::Application::RoleSummation undef
Mouse::Meta::Role::Composite undef
Mouse::Meta::Role::Method undef
Mouse::Meta::TypeConstraint undef
Mouse::Object undef
Mouse::PurePerl undef
Mouse::Role v2.5.10
Mouse::Spec v2.5.10
Mouse::TypeRegistry undef
Mouse::Util v2.5.10
Mouse::Util::MetaRole undef
Mouse::Util::TypeConstraints undef
Squirrel undef
Squirrel::Role undef
Test::Mouse undef
ouse undef
requirements:
ExtUtils::CBuilder 0
Module::Build 0.4005
Module::Build::XSUtil 0.19
Scalar::Util 1.14
XSLoader 0.02
perl 5.008005
Mozilla-CA-20231213
pathname: L/LW/LWP/Mozilla-CA-20231213.tar.gz
provides:
Mozilla::CA 20231213
requirements:
ExtUtils::MakeMaker 0
Net-DNS-1.41
pathname: N/NL/NLNETLABS/Net-DNS-1.41.tar.gz
provides:
Net::DNS 1.41
Net::DNS::Domain 1913
Net::DNS::DomainName 1898
Net::DNS::DomainName1035 1898
Net::DNS::DomainName2535 1898
Net::DNS::Header 1910
Net::DNS::Mailbox 1910
Net::DNS::Mailbox1035 1910
Net::DNS::Mailbox2535 1910
Net::DNS::Nameserver 1949
Net::DNS::Packet 1947
Net::DNS::Parameters 1945
Net::DNS::Question 1895
Net::DNS::RR 1910
Net::DNS::RR::A 1896
Net::DNS::RR::AAAA 1896
Net::DNS::RR::AFSDB 1945
Net::DNS::RR::AMTRELAY 1896
Net::DNS::RR::APL 1896
Net::DNS::RR::APL::Item 1896
Net::DNS::RR::CAA 1910
Net::DNS::RR::CDNSKEY 1909
Net::DNS::RR::CDS 1909
Net::DNS::RR::CERT 1896
Net::DNS::RR::CNAME 1896
Net::DNS::RR::CSYNC 1910
Net::DNS::RR::DHCID 1896
Net::DNS::RR::DNAME 1896
Net::DNS::RR::DNSKEY 1910
Net::DNS::RR::DS 1909
Net::DNS::RR::EUI48 1896
Net::DNS::RR::EUI64 1896
Net::DNS::RR::GPOS 1910
Net::DNS::RR::HINFO 1896
Net::DNS::RR::HIP 1896
Net::DNS::RR::HTTPS 1945
Net::DNS::RR::IPSECKEY 1909
Net::DNS::RR::ISDN 1896
Net::DNS::RR::KEY 1896
Net::DNS::RR::KX 1945
Net::DNS::RR::L32 1896
Net::DNS::RR::L64 1896
Net::DNS::RR::LOC 1896
Net::DNS::RR::LP 1896
Net::DNS::RR::MB 1910
Net::DNS::RR::MG 1910
Net::DNS::RR::MINFO 1896
Net::DNS::RR::MR 1910
Net::DNS::RR::MX 1945
Net::DNS::RR::NAPTR 1898
Net::DNS::RR::NID 1896
Net::DNS::RR::NS 1896
Net::DNS::RR::NSEC 1945
Net::DNS::RR::NSEC3 1910
Net::DNS::RR::NSEC3PARAM 1896
Net::DNS::RR::NULL 1896
Net::DNS::RR::OPENPGPKEY 1896
Net::DNS::RR::OPT 1934
Net::DNS::RR::OPT::CHAIN 1934
Net::DNS::RR::OPT::CLIENT_SUBNET 1934
Net::DNS::RR::OPT::COOKIE 1934
Net::DNS::RR::OPT::DAU 1934
Net::DNS::RR::OPT::DHU 1934
Net::DNS::RR::OPT::EXPIRE 1934
Net::DNS::RR::OPT::EXTENDED_ERROR 1934
Net::DNS::RR::OPT::KEY_TAG 1934
Net::DNS::RR::OPT::N3U 1934
Net::DNS::RR::OPT::NSID 1934
Net::DNS::RR::OPT::PADDING 1934
Net::DNS::RR::OPT::REPORT_CHANNEL 1934
Net::DNS::RR::OPT::TCP_KEEPALIVE 1934
Net::DNS::RR::PTR 1896
Net::DNS::RR::PX 1945
Net::DNS::RR::RP 1945
Net::DNS::RR::RRSIG 1896
Net::DNS::RR::RT 1945
Net::DNS::RR::SIG 1908
Net::DNS::RR::SMIMEA 1896
Net::DNS::RR::SOA 1945
Net::DNS::RR::SPF 1896
Net::DNS::RR::SRV 1945
Net::DNS::RR::SSHFP 1896
Net::DNS::RR::SVCB 1945
Net::DNS::RR::TKEY 1908
Net::DNS::RR::TLSA 1896
Net::DNS::RR::TSIG 1909
Net::DNS::RR::TXT 1911
Net::DNS::RR::URI 1896
Net::DNS::RR::X25 1896
Net::DNS::RR::ZONEMD 1896
Net::DNS::Resolver 1895
Net::DNS::Resolver::Base 1947
Net::DNS::Resolver::MSWin32 1856
Net::DNS::Resolver::Recurse 1930
Net::DNS::Resolver::UNIX 1856
Net::DNS::Resolver::android 1856
Net::DNS::Resolver::cygwin 1856
Net::DNS::Resolver::os2 1856
Net::DNS::Resolver::os390 1856
Net::DNS::Text 1894
Net::DNS::Update 1895
Net::DNS::ZoneFile 1910
Net::DNS::ZoneFile::Generator 1910
Net::DNS::ZoneFile::Text 1910
requirements:
Carp 1.1
Digest::HMAC 1.03
Digest::MD5 2.13
Digest::SHA 5.23
Encode 2.26
Exporter 5.63
ExtUtils::MakeMaker 6.48
File::Spec 3.29
Getopt::Long 2.43
IO::File 1.14
IO::Select 1.17
IO::Socket 1.3
IO::Socket::IP 0.38
MIME::Base64 2.13
PerlIO 1.05
Scalar::Util 1.19
Time::Local 1.19
perl 5.008009
Net-Domain-TLD-1.75
pathname: A/AL/ALEXP/Net-Domain-TLD-1.75.tar.gz
provides:
Net::Domain::TLD 1.75
requirements:
Carp 0
ExtUtils::MakeMaker 0
Storable 0
Net-HTTP-6.23
pathname: O/OA/OALDERS/Net-HTTP-6.23.tar.gz
provides:
Net::HTTP 6.23
Net::HTTP::Methods 6.23
Net::HTTP::NB 6.23
Net::HTTPS 6.23
requirements:
Carp 0
Compress::Raw::Zlib 0
ExtUtils::MakeMaker 0
IO::Socket::INET 0
IO::Uncompress::Gunzip 0
URI 0
base 0
perl 5.006002
strict 0
warnings 0
Net-OpenStack-Swift-0.15
pathname: M/MA/MASAKYST/Net-OpenStack-Swift-0.15.tar.gz
provides:
Net::OpenStack::Swift 0.15
Net::OpenStack::Swift::InnerKeystone::Base undef
Net::OpenStack::Swift::InnerKeystone::V1_0 undef
Net::OpenStack::Swift::InnerKeystone::V2_0 undef
Net::OpenStack::Swift::InnerKeystone::V3_0 undef
Net::OpenStack::Swift::Util undef
requirements:
App::Rad 0
Data::Validator 0
Furl 0
IO::Socket::SSL 0
JSON 0
Log::Minimal 0
Module::Build::Tiny 0.035
Mouse 0
Parallel::Fork::BossWorkerAsync 0
Path::Tiny 0
Sys::CPU 0
Text::ASCIITable 0
URI::Escape 0
namespace::clean 0
perl 5.010_001
Net-SSLeay-1.92
pathname: C/CH/CHRISN/Net-SSLeay-1.92.tar.gz
provides:
Net::SSLeay 1.92
Net::SSLeay::Handle 1.92
requirements:
English 0
ExtUtils::MakeMaker 0
File::Spec::Functions 0
MIME::Base64 0
Text::Wrap 0
constant 0
perl 5.008001
NetAddr-IP-4.079
pathname: M/MI/MIKER/NetAddr-IP-4.079.tar.gz
provides:
NetAddr::IP 4.079
NetAddr::IP::InetBase 0.08
NetAddr::IP::Lite 1.57
NetAddr::IP::Util 1.53
NetAddr::IP::UtilPP 1.09
NetAddr::IP::UtilPolluted 1.53
NetAddr::IP::Util_IS 1
requirements:
ExtUtils::MakeMaker 0
Test::More 0
Number-Bytes-Human-0.11
pathname: F/FE/FERREIRA/Number-Bytes-Human-0.11.tar.gz
provides:
Number::Bytes::Human 0.11
requirements:
Carp 0
ExtUtils::MakeMaker 0
POSIX 0
Test::More 0
Package-Stash-0.40
pathname: E/ET/ETHER/Package-Stash-0.40.tar.gz
provides:
Package::Stash 0.40
Package::Stash::PP 0.40
requirements:
B 0
Carp 0
Dist::CheckConflicts 0.02
ExtUtils::MakeMaker 0
Getopt::Long 0
Module::Implementation 0.06
Package::Stash::XS 0.26
Scalar::Util 0
Symbol 0
Text::ParseWords 0
constant 0
perl 5.008001
strict 0
warnings 0
Package-Stash-XS-0.30
pathname: E/ET/ETHER/Package-Stash-XS-0.30.tar.gz
provides:
Package::Stash::XS 0.30
requirements:
ExtUtils::MakeMaker 0
XSLoader 0
perl 5.008001
strict 0
warnings 0
Parallel-Fork-BossWorkerAsync-0.09
pathname: J/JV/JVANNUCCI/Parallel-Fork-BossWorkerAsync-0.09.tar.gz
provides:
Parallel::Fork::BossWorkerAsync 0.09
requirements:
ExtUtils::MakeMaker 0
Params-Classify-0.015
pathname: Z/ZE/ZEFRAM/Params-Classify-0.015.tar.gz
provides:
Params::Classify 0.015
requirements:
Exporter 0
Module::Build 0
Scalar::Util 1.01
Test::More 0
parent 0
perl 5.006001
strict 0
warnings 0
Path-Tiny-0.144
pathname: D/DA/DAGOLDEN/Path-Tiny-0.144.tar.gz
provides:
Path::Tiny 0.144
Path::Tiny::Error 0.144
requirements:
Carp 0
Cwd 0
Digest 1.03
Digest::SHA 5.45
Encode 0
Exporter 5.57
ExtUtils::MakeMaker 6.17
Fcntl 0
File::Compare 0
File::Copy 0
File::Glob 0
File::Path 2.07
File::Spec 0.86
File::Temp 0.19
File::stat 0
constant 0
overload 0
perl 5.008001
strict 0
warnings 0
warnings::register 0
Role-Tiny-2.002004
pathname: H/HA/HAARG/Role-Tiny-2.002004.tar.gz
provides:
Role::Tiny 2.002004
Role::Tiny::With 2.002004
requirements:
Exporter 5.57
perl 5.006
SQL-Abstract-2.000001
pathname: M/MS/MSTROUT/SQL-Abstract-2.000001.tar.gz
provides:
Chunkstrumenter undef
DBIx::Class::SQLMaker::Role::SQLA2Passthrough undef
SQL::Abstract 2.000001
SQL::Abstract::Formatter undef
SQL::Abstract::Parts undef
SQL::Abstract::Plugin::BangOverrides undef
SQL::Abstract::Plugin::ExtraClauses undef
SQL::Abstract::Reference undef
SQL::Abstract::Role::Plugin undef
SQL::Abstract::Test undef
SQL::Abstract::Tree undef
requirements:
Exporter 5.57
ExtUtils::MakeMaker 0
Hash::Merge 0.12
List::Util 0
MRO::Compat 0.12
Moo 2.000001
Scalar::Util 0
Sub::Quote 2.000001
Test::Builder::Module 0.84
Test::Deep 0.101
Text::Balanced 2.00
perl 5.006
SQL-Abstract-Pg-1.0
pathname: S/SR/SRI/SQL-Abstract-Pg-1.0.tar.gz
provides:
SQL::Abstract::Pg 1.0
requirements:
ExtUtils::MakeMaker 0
SQL::Abstract 2.0
perl 5.016
Sub-Exporter-Progressive-0.001013
pathname: F/FR/FREW/Sub-Exporter-Progressive-0.001013.tar.gz
provides:
Sub::Exporter::Progressive 0.001013
requirements:
ExtUtils::MakeMaker 0
Sub-Quote-2.006008
pathname: H/HA/HAARG/Sub-Quote-2.006008.tar.gz
provides:
Sub::Defer 2.006008
Sub::Quote 2.006008
requirements:
ExtUtils::MakeMaker 0
Scalar::Util 0
perl 5.006
Sub-Uplevel-0.2800
pathname: D/DA/DAGOLDEN/Sub-Uplevel-0.2800.tar.gz
provides:
Sub::Uplevel 0.2800
requirements:
Carp 0
ExtUtils::MakeMaker 6.17
constant 0
perl 5.006
strict 0
warnings 0
Switch-2.17
pathname: C/CH/CHORNY/Switch-2.17.tar.gz
provides:
Switch 2.17
requirements:
ExtUtils::MakeMaker 0
Filter::Util::Call 0
Text::Balanced 2
if 0
perl 5.005
Sys-CPU-0.52
pathname: M/MK/MKODERER/Sys-CPU-0.52.tar.gz
provides:
Sys::CPU 0.52
requirements:
ExtUtils::MakeMaker 0
Term-ProgressBar-2.23
pathname: M/MA/MANWAR/Term-ProgressBar-2.23.tar.gz
provides:
Term::ProgressBar 2.23
Term::ProgressBar::IO 2.23
requirements:
Capture::Tiny 0.13
Carp 0
Class::MethodMaker 1.02
ExtUtils::MakeMaker 0
Fatal 0
File::Temp 0
POSIX 0
Term::ReadKey 2.14
Test::Exception 0.31
Test::More 0.80
Test::Warnings 0
perl 5.006
TermReadKey-2.38
pathname: J/JS/JSTOWE/TermReadKey-2.38.tar.gz
provides:
Term::ReadKey 2.38
requirements:
ExtUtils::MakeMaker 6.58
Test-Deep-1.204
pathname: R/RJ/RJBS/Test-Deep-1.204.tar.gz
provides:
Test::Deep 1.204
Test::Deep::All 1.204
Test::Deep::Any 1.204
Test::Deep::Array 1.204
Test::Deep::ArrayEach 1.204
Test::Deep::ArrayElementsOnly 1.204
Test::Deep::ArrayLength 1.204
Test::Deep::ArrayLengthOnly 1.204
Test::Deep::Blessed 1.204
Test::Deep::Boolean 1.204
Test::Deep::Cache 1.204
Test::Deep::Cache::Simple 1.204
Test::Deep::Class 1.204
Test::Deep::Cmp 1.204
Test::Deep::Code 1.204
Test::Deep::Hash 1.204
Test::Deep::HashEach 1.204
Test::Deep::HashElements 1.204
Test::Deep::HashKeys 1.204
Test::Deep::HashKeysOnly 1.204
Test::Deep::Ignore 1.204
Test::Deep::Isa 1.204
Test::Deep::ListMethods 1.204
Test::Deep::MM 1.204
Test::Deep::Methods 1.204
Test::Deep::NoTest 1.204
Test::Deep::None 1.204
Test::Deep::Number 1.204
Test::Deep::Obj 1.204
Test::Deep::Ref 1.204
Test::Deep::RefType 1.204
Test::Deep::Regexp 1.204
Test::Deep::RegexpMatches 1.204
Test::Deep::RegexpOnly 1.204
Test::Deep::RegexpRef 1.204
Test::Deep::RegexpRefOnly 1.204
Test::Deep::RegexpVersion 1.204
Test::Deep::ScalarRef 1.204
Test::Deep::ScalarRefOnly 1.204
Test::Deep::Set 1.204
Test::Deep::Shallow 1.204
Test::Deep::Stack 1.204
Test::Deep::String 1.204
Test::Deep::SubHash 1.204
Test::Deep::SubHashElements 1.204
Test::Deep::SubHashKeys 1.204
Test::Deep::SubHashKeysOnly 1.204
Test::Deep::SuperHash 1.204
Test::Deep::SuperHashElements 1.204
Test::Deep::SuperHashKeys 1.204
Test::Deep::SuperHashKeysOnly 1.204
requirements:
ExtUtils::MakeMaker 6.78
List::Util 1.09
Scalar::Util 1.09
Test::Builder 0
Test::More 0.96
perl 5.012
Test-Exception-0.43
pathname: E/EX/EXODIST/Test-Exception-0.43.tar.gz
provides:
Test::Exception 0.43
requirements:
Carp 0
Exporter 0
ExtUtils::MakeMaker 0
Sub::Uplevel 0.18
Test::Builder 0.7
Test::Builder::Tester 1.07
Test::Harness 2.03
base 0
perl 5.006001
strict 0
warnings 0
Test-Fatal-0.017
pathname: R/RJ/RJBS/Test-Fatal-0.017.tar.gz
provides:
Test::Fatal 0.017
requirements:
Carp 0
Exporter 5.57
ExtUtils::MakeMaker 6.78
Test::Builder 0
Try::Tiny 0.07
strict 0
warnings 0
Test-Warn-0.37
pathname: B/BI/BIGJ/Test-Warn-0.37.tar.gz
provides:
Test::Warn 0.37
requirements:
Carp 1.22
ExtUtils::MakeMaker 0
Sub::Uplevel 0.12
Test::Builder 0.13
Test::Builder::Tester 1.02
perl 5.006
Test-Warnings-0.032
pathname: E/ET/ETHER/Test-Warnings-0.032.tar.gz
provides:
Test::Warnings 0.032
requirements:
Carp 0
Exporter 0
ExtUtils::MakeMaker 0
Test::Builder 0
parent 0
perl 5.006
strict 0
warnings 0
Text-ASCIITable-0.22
pathname: L/LU/LUNATIC/Text-ASCIITable-0.22.tar.gz
provides:
Text::ASCIITable 0.22
Text::ASCIITable::Wrap 0.2
requirements:
Carp 0
Encode 0
List::Util 0
perl v5.6.0
Text-Soundex-3.05
pathname: R/RJ/RJBS/Text-Soundex-3.05.tar.gz
provides:
Text::Soundex 3.05
requirements:
ExtUtils::MakeMaker 0
if 0
TimeDate-2.33
pathname: A/AT/ATOOMIC/TimeDate-2.33.tar.gz
provides:
Date::Format 2.24
Date::Format::Generic 2.24
Date::Language 1.10
Date::Language::Afar 0.99
Date::Language::Amharic 1.00
Date::Language::Austrian 1.01
Date::Language::Brazilian 1.01
Date::Language::Bulgarian 1.01
Date::Language::Chinese 1.00
Date::Language::Chinese_GB 1.01
Date::Language::Czech 1.01
Date::Language::Danish 1.01
Date::Language::Dutch 1.02
Date::Language::English 1.01
Date::Language::Finnish 1.01
Date::Language::French 1.04
Date::Language::Gedeo 0.99
Date::Language::German 1.02
Date::Language::Greek 1.00
Date::Language::Hungarian 1.01
Date::Language::Icelandic 1.01
Date::Language::Italian 1.01
Date::Language::Norwegian 1.01
Date::Language::Occitan 1.04
Date::Language::Oromo 0.99
Date::Language::Romanian 1.01
Date::Language::Russian 1.01
Date::Language::Russian_cp1251 1.01
Date::Language::Russian_koi8r 1.01
Date::Language::Sidama 0.99
Date::Language::Somali 0.99
Date::Language::Spanish 1.00
Date::Language::Swedish 1.01
Date::Language::Tigrinya 1.00
Date::Language::TigrinyaEritrean 1.00
Date::Language::TigrinyaEthiopian 1.00
Date::Language::Turkish 1.0
Date::Parse 2.33
Time::Zone 2.24
TimeDate 1.21
requirements:
ExtUtils::MakeMaker 0
Try-Tiny-0.31
pathname: E/ET/ETHER/Try-Tiny-0.31.tar.gz
provides:
Try::Tiny 0.31
requirements:
Carp 0
Exporter 5.57
ExtUtils::MakeMaker 0
constant 0
perl 5.006
strict 0
warnings 0
URI-5.21
pathname: O/OA/OALDERS/URI-5.21.tar.gz
provides:
URI 5.21
URI::Escape 5.21
URI::Heuristic 5.21
URI::IRI 5.21
URI::QueryParam 5.21
URI::Split 5.21
URI::URL 5.21
URI::WithBase 5.21
URI::data 5.21
URI::file 5.21
URI::file::Base 5.21
URI::file::FAT 5.21
URI::file::Mac 5.21
URI::file::OS2 5.21
URI::file::QNX 5.21
URI::file::Unix 5.21
URI::file::Win32 5.21
URI::ftp 5.21
URI::gopher 5.21
URI::http 5.21
URI::https 5.21
URI::icap 5.21
URI::icaps 5.21
URI::ldap 5.21
URI::ldapi 5.21
URI::ldaps 5.21
URI::mailto 5.21
URI::mms 5.21
URI::news 5.21
URI::nntp 5.21
URI::nntps 5.21
URI::pop 5.21
URI::rlogin 5.21
URI::rsync 5.21
URI::rtsp 5.21
URI::rtspu 5.21
URI::sftp 5.21
URI::sip 5.21
URI::sips 5.21
URI::snews 5.21
URI::ssh 5.21
URI::telnet 5.21
URI::tn3270 5.21
URI::urn 5.21
URI::urn::isbn 5.21
URI::urn::oid 5.21
requirements:
Carp 0
Cwd 0
Data::Dumper 0
Encode 0
Exporter 5.57
ExtUtils::MakeMaker 0
MIME::Base64 2
Net::Domain 0
Scalar::Util 0
constant 0
integer 0
overload 0
parent 0
perl 5.008001
strict 0
utf8 0
warnings 0
URI-Find-20160806
pathname: M/MS/MSCHWERN/URI-Find-20160806.tar.gz
provides:
URI::Find 20160806
URI::Find::Schemeless 20160806
requirements:
Module::Build 0.30
Test::More 0.88
URI 1.60
perl v5.8.8
URI-Nested-0.10
pathname: D/DW/DWHEELER/URI-Nested-0.10.tar.gz
provides:
URI::Nested 0.10
requirements:
Module::Build 0.30
Test::More 0.88
URI 1.40
perl 5.008001
URI-db-0.21
pathname: D/DW/DWHEELER/URI-db-0.21.tar.gz
provides:
URI::cassandra 0.21
URI::cockroach 0.21
URI::cockroachdb 0.21
URI::couch 0.21
URI::couchdb 0.21
URI::cubrid 0.21
URI::db 0.21
URI::db2 0.21
URI::derby 0.21
URI::exasol 0.21
URI::firebird 0.21
URI::hive 0.21
URI::impala 0.21
URI::informix 0.21
URI::ingres 0.21
URI::interbase 0.21
URI::ldapdb 0.21
URI::maria 0.21
URI::mariadb 0.21
URI::max 0.21
URI::maxdb 0.21
URI::monet 0.21
URI::monetdb 0.21
URI::mongo 0.21
URI::mongodb 0.21
URI::mssql 0.21
URI::mysql 0.21
URI::oracle 0.21
URI::pg 0.21
URI::pgsql 0.21
URI::pgxc 0.21
URI::postgres 0.21
URI::postgresql 0.21
URI::postgresxc 0.21
URI::redshift 0.21
URI::snowflake 0.21
URI::sqlite 0.21
URI::sqlite3 0.21
URI::sqlserver 0.21
URI::sybase 0.21
URI::teradata 0.21
URI::unify 0.21
URI::vertica 0.21
URI::yugabyte 0.21
URI::yugabytedb 0.21
requirements:
Module::Build 0.30
Test::More 0.88
URI 1.40
URI::Nested 0.10
perl 5.008001
Variable-Magic-0.63
pathname: V/VP/VPIT/Variable-Magic-0.63.tar.gz
provides:
Variable::Magic 0.63
requirements:
Carp 0
Config 0
Exporter 0
ExtUtils::MakeMaker 0
IO::Handle 0
IO::Select 0
IPC::Open3 0
POSIX 0
Socket 0
Test::More 0
XSLoader 0
base 0
lib 0
perl 5.008
WWW-RobotRules-6.02
pathname: G/GA/GAAS/WWW-RobotRules-6.02.tar.gz
provides:
WWW::RobotRules 6.02
WWW::RobotRules::AnyDBM_File 6.00
WWW::RobotRules::InCore 6.02
requirements:
AnyDBM_File 0
ExtUtils::MakeMaker 0
Fcntl 0
URI 1.10
perl 5.008001
YAML-Tiny-1.74
pathname: E/ET/ETHER/YAML-Tiny-1.74.tar.gz
provides:
YAML::Tiny 1.74
requirements:
B 0
Carp 0
Exporter 0
ExtUtils::MakeMaker 0
Fcntl 0
Scalar::Util 0
perl 5.008001
strict 0
warnings 0
common-sense-3.75
pathname: M/ML/MLEHMANN/common-sense-3.75.tar.gz
provides:
common::sense 3.75
requirements:
ExtUtils::MakeMaker 0
libwww-perl-6.72
pathname: O/OA/OALDERS/libwww-perl-6.72.tar.gz
provides:
LWP 6.72
LWP::Authen::Basic 6.72
LWP::Authen::Digest 6.72
LWP::Authen::Ntlm 6.72
LWP::ConnCache 6.72
LWP::Debug 6.72
LWP::Debug::TraceHTTP 6.72
LWP::DebugFile 6.72
LWP::MemberMixin 6.72
LWP::Protocol 6.72
LWP::Protocol::cpan 6.72
LWP::Protocol::data 6.72
LWP::Protocol::file 6.72
LWP::Protocol::ftp 6.72
LWP::Protocol::gopher 6.72
LWP::Protocol::http 6.72
LWP::Protocol::loopback 6.72
LWP::Protocol::mailto 6.72
LWP::Protocol::nntp 6.72
LWP::Protocol::nogo 6.72
LWP::RobotUA 6.72
LWP::Simple 6.72
LWP::UserAgent 6.72
requirements:
Digest::MD5 0
Encode 2.12
Encode::Locale 0
ExtUtils::MakeMaker 0
File::Copy 0
File::Listing 6
File::Temp 0
Getopt::Long 0
HTML::Entities 0
HTML::HeadParser 3.71
HTTP::CookieJar::LWP 0
HTTP::Cookies 6
HTTP::Date 6
HTTP::Negotiate 6
HTTP::Request 6.18
HTTP::Request::Common 6.18
HTTP::Response 6.18
HTTP::Status 6.18
IO::Select 0
IO::Socket 0
LWP::MediaTypes 6
MIME::Base64 2.1
Module::Load 0
Net::FTP 2.58
Net::HTTP 6.18
Scalar::Util 0
Try::Tiny 0
URI 1.10
URI::Escape 0
WWW::RobotRules 6
parent 0.217
perl 5.008001
strict 0
warnings 0
namespace-clean-0.27
pathname: R/RI/RIBASUSHI/namespace-clean-0.27.tar.gz
provides:
namespace::clean 0.27
requirements:
B::Hooks::EndOfScope 0.12
ExtUtils::MakeMaker 0
Package::Stash 0.23
perl 5.008001
perl-ldap-0.68
pathname: M/MA/MARSCHAP/perl-ldap-0.68.tar.gz
provides:
Bundle::Net::LDAP 0.03
LWP::Protocol::ldap 1.25
LWP::Protocol::ldapi undef
LWP::Protocol::ldaps undef
Net::LDAP 0.68
Net::LDAP::ASN 0.13
Net::LDAP::Bind 1.05
Net::LDAP::Constant 0.24
Net::LDAP::Control 0.20
Net::LDAP::Control::Assertion 0.02
Net::LDAP::Control::DontUseCopy 0.02
Net::LDAP::Control::EntryChange 0.02
Net::LDAP::Control::ManageDsaIT 0.04
Net::LDAP::Control::MatchedValues 0.02
Net::LDAP::Control::NoOp 0.01
Net::LDAP::Control::Paged 0.05
Net::LDAP::Control::PasswordPolicy 0.04
Net::LDAP::Control::PersistentSearch 0.04
Net::LDAP::Control::PostRead 0.03
Net::LDAP::Control::PreRead 0.04
Net::LDAP::Control::ProxyAuth 1.09
Net::LDAP::Control::Relax 0.03
Net::LDAP::Control::Sort 0.04
Net::LDAP::Control::SortResult 0.03
Net::LDAP::Control::Subentries 0.01
Net::LDAP::Control::SyncDone 0.03
Net::LDAP::Control::SyncRequest 0.03
Net::LDAP::Control::SyncState 0.04
Net::LDAP::Control::TreeDelete 0.01
Net::LDAP::Control::VLV 0.07
Net::LDAP::Control::VLVResponse 0.04
Net::LDAP::DSML 0.17
Net::LDAP::DSML::output 0.17
Net::LDAP::DSML::pp 0.17
Net::LDAP::Entry 0.29
Net::LDAP::Extension 1.04
Net::LDAP::Extension::Cancel 0.02
Net::LDAP::Extension::Refresh 0.04
Net::LDAP::Extension::SetPassword 0.06
Net::LDAP::Extension::WhoAmI 0.02
Net::LDAP::Extra 0.02
Net::LDAP::Extra::AD 0.05
Net::LDAP::Extra::eDirectory 0.03
Net::LDAP::Filter 0.20
Net::LDAP::FilterList 0.02
Net::LDAP::FilterMatch 0.27
Net::LDAP::Intermediate 0.04
Net::LDAP::Intermediate::SyncInfo 0.03
Net::LDAP::LDIF 0.27
Net::LDAP::Message 1.12
Net::LDAP::Message::Dummy 1.12
Net::LDAP::Reference 0.14
Net::LDAP::RootDSE 0.02
Net::LDAP::Schema 0.9908
Net::LDAP::Search 0.14
Net::LDAP::Util 0.20
Net::LDAPI 0.04
Net::LDAPS 0.06
requirements:
Authen::SASL 2.00
Convert::ASN1 0.2
Digest::MD5 0
ExtUtils::MakeMaker 6.59
File::Basename 0
File::Compare 0
File::Path 0
HTTP::Negotiate 0
HTTP::Response 0
HTTP::Status 0
IO::File 0
IO::Socket::SSL 1.26
JSON 0
LWP 0
LWP::MediaTypes 0
LWP::Protocol 0
MIME::Base64 0
Test::More 0
Text::Soundex 0
Time::Local 0
URI::ldap 1.1
perl 5.008001
================================================
FILE: lib/Date/Language/Occitan.pm
================================================
##
## Occitan tables, contributed by Quentn PAGÈS
##
package Date::Language::Occitan;
use Date::Language ();
use vars qw(@ISA @DoW @DoWs @MoY @MoYs @AMPM @Dsuf %MoY %DoW $VERSION);
@ISA = qw(Date::Language);
$VERSION = "1.04";
@DoW = qw(dimenge diluns dimars dimècres dijòus divendres dissabte);
@MoY = qw(genièr febrièr març abrial mai junh
julhet agost octòbre novembre decembre);
@DoWs = map { substr($_,0,3) } @DoW;
@MoYs = map { substr($_,0,3) } @MoY;
$MoYs[6] = 'jul';
@AMPM = qw(AM PM);
@Dsuf = ((qw(er e e e e e e e e e)) x 3, 'er');
@MoY{@MoY} = (0 .. scalar(@MoY));
@MoY{@MoYs} = (0 .. scalar(@MoYs));
@DoW{@DoW} = (0 .. scalar(@DoW));
@DoW{@DoWs} = (0 .. scalar(@DoWs));
# Formatting routines
sub format_a { $DoWs[$_[0]->[6]] }
sub format_A { $DoW[$_[0]->[6]] }
sub format_b { $MoYs[$_[0]->[4]] }
sub format_B { $MoY[$_[0]->[4]] }
sub format_h { $MoYs[$_[0]->[4]] }
sub format_p { $_[0]->[2] >= 12 ? $AMPM[1] : $AMPM[0] }
1;
================================================
FILE: lib/Lufi/Command/copyFilesToSwift.pm
================================================
package Lufi::Command::copyFilesToSwift;
use Mojo::Base 'Mojolicious::Command';
use File::Spec;
use Term::ProgressBar;
has description => 'Copy files from filesystem to Swift object storage';
has usage => sub { shift->extract_usage };
sub run {
my $c = shift;
if ($c->app->config('swift')) {
$c->app->check_swift_container();
my @dirs = glob(File::Spec->catdir($c->app->config('upload_dir'), '*'));
unless (scalar(@dirs)) {
say sprintf('The configured upload_dir (%s) seems to be empty. Is `upload_dir` configured in lufi.conf?', $c->app->config('upload_dir'));
exit 1;
}
say sprintf('%d folders to upload to Swift (can\'t say how many files, or the total size, sorry). This can take some time.', scalar(@dirs));
print 'Do you want to continue? [Y/n] ';
my $confirm = <STDIN>;
if ($confirm =~ m/yes|y/i) {
my $progress = Term::ProgressBar->new({ count => scalar(@dirs), ETA => 'linear', name => 'Copying to Swift'});
for my $dir (@dirs) {
my @files = glob(File::Spec->catfile($dir, '*'));
for my $file (@files) {
my ($volume, $directories, $filename) = File::Spec->splitpath($file);
my @file_dirs = File::Spec->splitdir($directories);
my $short = ($file_dirs[-1] ne '') ? $file_dirs[-1] : $file_dirs[-2];
my $path = File::Spec->catfile($short, $filename);
open my $fh, '<', $file or die sprintf('Unable to open file %s: %s', $file, $!);
$c->app->swift->put_object(
container_name => $c->app->config('swift')->{container},
object_name => $path,
content_length => -s $file,
content => $fh
);
close $fh;
}
$progress->update();
}
say sprintf('The copy to Swift object storage has ended. You can test Lufi, then delete `%s` directory', $c->app->config('upload_dir'));
} else {
say 'You want to stop. No problem.';
}
} else {
say 'You didn\'t configure `swift` in your config file. Exiting.';
exit 1;
}
}
=encoding utf8
=head1 NAME
Lufi::Command::copyFilesToSwift Copy files from filesystem to Swift object storage
=head1 SYNOPSIS
Usage: script/lufi copyFilesToSwift
This command needs you to:
- set `upload_dir` in your config file (otherwise, it will use the default path, `files` to copy files from)
- configure `swift` with correct informations in your config file
=cut
1;
================================================
FILE: lib/Lufi/Command/cron/cleanbdd.pm
================================================
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lufi::Command::cron::cleanbdd;
use Mojo::Base 'Mojolicious::Command';
use Lufi::DB::File;
use FindBin qw($Bin);
use Lufi::DefaultConfig qw($default_config);
has description => 'Delete IP addresses from database after configured delay.';
has usage => sub { shift->extract_usage };
sub run {
my $c = shift;
my $cfile = Mojo::File->new($Bin, '..' , 'lufi.conf');
if (defined $ENV{MOJO_CONFIG}) {
$cfile = Mojo::File->new($ENV{MOJO_CONFIG});
unless (-e $cfile->to_abs) {
$cfile = Mojo::File->new($Bin, '..', $ENV{MOJO_CONFIG});
}
}
my $config = $c->app->plugin('Config', {
file => $cfile,
default => $default_config
});
my $separation = time() - $config->{keep_ip_during} * 86400;
Lufi::DB::File->new(app => $c->app)->delete_creator_before($separation);
}
=encoding utf8
=head1 NAME
Lufi::Command::cron::cleanbdd - Delete IP addresses from database after configured delay
=head1 SYNOPSIS
Usage: script/lufi cron cleanbdd
=cut
1;
================================================
FILE: lib/Lufi/Command/cron/cleanfiles.pm
================================================
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lufi::Command::cron::cleanfiles;
use Mojo::Base 'Mojolicious::Command';
use Lufi::DB::File;
use FindBin qw($Bin);
use Lufi::DefaultConfig qw($default_config);
has description => 'Delete expired files.';
has usage => sub { shift->extract_usage };
sub run {
my $c = shift;
my $cfile = Mojo::File->new($Bin, '..' , 'lufi.conf');
if (defined $ENV{MOJO_CONFIG}) {
$cfile = Mojo::File->new($ENV{MOJO_CONFIG});
unless (-e $cfile->to_abs) {
$cfile = Mojo::File->new($Bin, '..', $ENV{MOJO_CONFIG});
}
}
my $config = $c->app->plugin('Config', {
file => $cfile,
default => $default_config
});
my $time = time();
my $ldfile = Lufi::DB::File->new(app => $c->app);
$ldfile->get_expired($time)->each(
sub {
my ($f, $num) = @_;
$f->delete;
}
);
if (defined($config->{delete_no_longer_viewed_files}) && $config->{delete_no_longer_viewed_files} > 0) {
$time = time() - $config->{delete_no_longer_viewed_files} * 86400;
my $ldfile = Lufi::DB::File->new(app => $c->app);
$ldfile->get_no_longer_viewed($time)->each(
sub {
my ($f, $num) = @_;
$f->delete;
}
);
}
}
=encoding utf8
=head1 NAME
Lufi::Command::cron::cleanfiles - Delete expired files
=head1 SYNOPSIS
Usage: script/lufi cron cleanfiles
=cut
1;
================================================
FILE: lib/Lufi/Command/cron/watch.pm
================================================
package Lufi::Command::cron::watch;
use Mojo::Base 'Mojolicious::Command';
use Filesys::DiskUsage qw/du/;
use Lufi::DB::File;
use Switch;
use FindBin qw($Bin);
use Lufi::DefaultConfig qw($default_config);
has description => 'Watch the files directory and take action when over quota';
has usage => sub { shift->extract_usage };
sub run {
my $c = shift;
my $cfile = Mojo::File->new($Bin, '..' , 'lufi.conf');
if (defined $ENV{MOJO_CONFIG}) {
$cfile = Mojo::File->new($ENV{MOJO_CONFIG});
unless (-e $cfile->to_abs) {
$cfile = Mojo::File->new($Bin, '..', $ENV{MOJO_CONFIG});
}
}
my $config = $c->app->plugin('Config', {
file => $cfile,
default => $default_config
});
if (defined($config->{max_total_size})) {
my $total = du(($c->app->config('upload_dir')));
if ($total > $config->{max_total_size}) {
say "[Lufi cron job watch] Files directory is over quota ($total > ".$config->{max_total_size}.")";
switch ($config->{policy_when_full}) {
case 'warn' {
say "[Lufi cron job watch] Please, delete some files or increase quota (".$config->{max_total_size}.")";
}
case 'stop-upload' {
open (my $fh, '>', 'stop-upload') or die ("Couldn't open stop-upload: $!");
close($fh);
say '[Lufi cron job watch] Uploads are stopped. Delete some images and the stop-upload file to reallow uploads.';
}
case 'delete' {
say '[Lufi cron job watch] Older files are being deleted';
my $ldfile = Lufi::DB::File->new(app => $c->app);
do {
$ldfile->get_oldest_undeleted_files(50)->each(
sub {
my ($f, $num) = @_;
$f->delete;
}
);
} while (du(qw/files/) > $config->{max_total_size});
}
else {
say '[Lufi cron job watch] Unrecognized policy_when_full option: '.$config->{policy_when_full}.'. Aborting.';
}
}
} else {
unlink 'stop-upload' if (-f 'stop-upload');
}
} else {
say "[Lufi cron job watch] No max_total_size found in the configuration file. Aborting.";
}
}
=encoding utf8
=head1 NAME
Lufi::Command::cron::watch - Watch the files directory and take action when over quota
=head1 SYNOPSIS
Usage: script/lufi cron watch
=cut
1;
================================================
FILE: lib/Lufi/Command/cron.pm
================================================
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lufi::Command::cron;
use Mojo::Base 'Mojolicious::Commands';
has description => 'Execute tasks.';
has hint => <<EOF;
See 'script/lufi cron help TASK' for more information on a specific task.
EOF
has message => sub { shift->extract_usage . "\nCron tasks:\n" };
has namespaces => sub { ['Lufi::Command::cron'] };
sub help { shift->run(@_) }
1;
=encoding utf8
=head1 NAME
Lufi::Command::cron - Cron commands
=head1 SYNOPSIS
Usage: script/lufi cron TASK [OPTIONS]
=cut
================================================
FILE: lib/Lufi/Command/sqliteToOtherDB.pm
================================================
package Lufi::Command::sqliteToOtherDB;
use Mojo::Base 'Mojolicious::Command';
use Lufi::DB::File;
use Lufi::DB::Slice;
use Lufi::DB::Invitation;
use Mojo::SQLite;
use FindBin qw($Bin);
use Term::ProgressBar;
use Lufi::DefaultConfig qw($default_config);
has description => 'Migrate the records from a SQLite db to the currently configured database';
has usage => sub { shift->extract_usage };
sub run {
my $c = shift;
my $cfile = Mojo::File->new($Bin, '..' , 'lufi.conf');
if (defined $ENV{MOJO_CONFIG}) {
$cfile = Mojo::File->new($ENV{MOJO_CONFIG});
unless (-e $cfile->to_abs) {
$cfile = Mojo::File->new($Bin, '..', $ENV{MOJO_CONFIG});
}
}
my $config = $c->app->plugin('Config', {
file => $cfile,
default => $default_config
});
if ($config->{dbtype} eq 'sqlite') {
say 'Please configure `dbtype` to something else than `sqlite` to use this command.';
print $c->usage;
exit 1;
}
my $sqlite = Mojo::SQLite->new('sqlite:'.$config->{db_path});
my $files = $sqlite->db->select('files', undef)->hashes;
my $slices = $sqlite->db->select('slices', undef)->hashes;
my $invitations = $sqlite->db->select('invitations', undef)->hashes;
my $progress = Term::ProgressBar->new({count => $files->size + $slices->size + $invitations->size});
$files->each(sub {
my ($file, $num) = @_;
$progress->update();
Lufi::DB::File->new(app => $c->app)
->short($file->{short})
->deleted($file->{deleted})
->mediatype($file->{mediatype})
->filename($file->{filename})
->filesize($file->{filesize})
->counter($file->{counter})
->delete_at_first_view($file->{delete_at_first_view})
->delete_at_day($file->{delete_at_day})
->created_at($file->{created_at})
->created_by($file->{created_by})
->last_access_at($file->{last_access_at})
->mod_token($file->{mod_token})
->nbslices($file->{nbslices})
->complete($file->{complete})
->passwd($file->{passwd})
->abuse($file->{abuse})
->write();
});
$slices->each(sub {
my ($slice, $num) = @_;
Lufi::DB::Slice->new(app => $c->app)
->short($slice->{short})
->j($slice->{j})
->write();
$progress->update();
});
$invitations->each(sub {
my ($invitation, $num) = @_;
Lufi::DB::Invitation->new(app => $c->app)
->token($invitation->{token})
->ldap_user($invitation->{ldap_user})
->ldap_user_mail($invitation->{ldap_user_mail})
->guest_mail($invitation->{guest_mail})
->created_at($invitation->{created_at})
->expire_at($invitation->{expire_at})
->files_sent_at($invitation->{files_sent_at})
->expend_expire_at($invitation->{expend_expire_at})
->files($invitation->{files})
->show_in_list($invitation->{show_in_list})
->deleted($invitation->{deleted})
->write();
$progress->update();
});
}
=encoding utf8
=head1 NAME
Lufi::Command::sqliteToOtherDB Migrate the records from a SQLite db to the currently configured database
=head1 SYNOPSIS
Usage: script/lufi sqliteToOtherDB
This command needs you to:
- set `db_path` in your config file (otherwise, it will use the default path, `lufi.db` to migrate data from)
- set `dbtype` to an other database type in your config file
- configure the other database access in your config file
=cut
1;
================================================
FILE: lib/Lufi/Command/theme.pm
================================================
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lufi::Command::theme;
use Mojo::Base 'Mojolicious::Commands';
use FindBin qw($Bin);
use File::Spec qw(catfile catdir);
use File::Path qw(make_path);
has description => 'Create new theme skeleton.';
has usage => sub { shift->extract_usage };
has message => sub { shift->extract_usage . "\nCreate new theme skeleton:\n" };
has namespaces => sub { ['Lufi::Command::theme'] };
sub run {
my $c = shift;
my $name = shift;
unless (defined $name) {
say $c->extract_usage;
exit 1;
}
my $home = File::Spec->catdir($Bin, '..', 'themes', $name);
unless (-d $home) {
# Create skeleton
mkdir $home;
mkdir File::Spec->catdir($home, 'public');
make_path(File::Spec->catdir($home, 'templates', 'layouts'));
make_path(File::Spec->catdir($home, 'lib', 'Lufi', 'I18N'));
my $i18n = <<EOF;
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lufi::I18N;
use base 'Locale::Maketext';
use File::Basename qw/dirname/;
use Locale::Maketext::Lexicon {
_auto => 1,
_decode => 1,
_style => 'gettext',
'*' => [
Gettext => dirname(__FILE__) . '/I18N/*.po',
Gettext => dirname(__FILE__) . '/../../../default/lib/Lufi/I18N/*.po',
]
};
1;
EOF
open my $f, '>', File::Spec->catfile($home, 'lib', 'Lufi', 'I18N.pm') or die "Unable to open $home/lib/Lufi/I18N.pm: $!";
print $f $i18n;
close $f;
my $makefile = <<EOF;
EN=lib/Lufi/I18N/en.po
FR=lib/Lufi/I18N/fr.po
IT=lib/Lufi/I18N/it.po
OC=lib/Lufi/I18N/oc.po
SEDOPTS=-e "s\@SOME DESCRIPTIVE TITLE\@Lufi language file\@" \\
-e "s\@YEAR THE PACKAGE'S COPYRIGHT HOLDER\@2015 Luc Didry\@" \\
-e "s\@CHARSET\@utf8\@" \\
-e "s\@the PACKAGE package\@the Lufi package\@" \\
-e '/^\\#\\. (/{N;/\\n\\#\\. (/{N;/\\n.*\\.\\.\\/default\\//{s/\\#\\..*\\n.*\\#\\./\\#. (/g}}}' \\
-e '/^\\#\\. (/{N;/\\n.*\\.\\.\\/default\\//{s/\\n/ /}}'
SEDOPTS2=-e '/^\\#.*\\.\\.\\/default\\//,+3d'
XGETTEXT=carton exec ../../local/bin/xgettext.pl
CARTON=carton exec
locales:
\$(XGETTEXT) -D templates -D ../default/templates -o \$(EN) 2>/dev/null
\$(XGETTEXT) -D templates -D ../default/templates -o \$(FR) 2>/dev/null
\$(XGETTEXT) -D templates -D ../default/templates -o \$(IT) 2>/dev/null
\$(XGETTEXT) -D templates -D ../default/templates -o \$(OC) 2>/dev/null
sed \$(SEDOPTS) -i \$(EN)
sed \$(SEDOPTS2) -i \$(EN)
sed \$(SEDOPTS) -i \$(FR)
sed \$(SEDOPTS2) -i \$(FR)
sed \$(SEDOPTS) -i \$(IT)
sed \$(SEDOPTS2) -i \$(IT)
sed \$(SEDOPTS) -i \$(OC)
sed \$(SEDOPTS2) -i \$(OC)
EOF
open $f, '>', File::Spec->catfile($home, 'Makefile') or die "Unable to open $home/Makefile: $!";
print $f $makefile;
close $f;
} else {
say "$name theme already exists. Aborting.";
exit 1;
}
}
=encoding utf8
=head1 NAME
Lufi::Command::theme - Create new theme skeleton.
=head1 SYNOPSIS
Usage: script/lufi theme THEME_NAME
Your new theme will be available in the themes directory.
=cut
1;
================================================
FILE: lib/Lufi/Controller/Auth.pm
================================================
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lufi::Controller::Auth;
use Mojo::Base 'Mojolicious::Controller';
sub login_page {
my $c = shift;
my $redirect = $c->param('redirect') // '/';
if ($c->is_user_authenticated) {
$c->redirect_to('/');
} else {
if ($c->config('auth_headers')) {
if($c->authenticate('dummy', 'dummy')) {
if ($redirect eq 'invite') {
return $c->redirect_to('invite');
} elsif ($redirect eq 'my_invitations') {
return $c->redirect_to('invite_list');
}
return $c->redirect_to('/');
}
} else {
$c->render(
template => 'login',
redirect => $redirect
);
}
}
}
sub login {
my $c = shift;
my $login = $c->param('login');
my $pwd = $c->param('password');
my $redirect = $c->param('redirect') // '/';
if ($c->validation->csrf_protect->has_error('csrf_token')) {
$c->stash(msg => $c->l('Bad CSRF token.'));
$c->render(template => 'login');
} else {
if($c->authenticate($login, $pwd)) {
if ($redirect eq 'invite') {
return $c->redirect_to('invite');
} elsif ($redirect eq 'my_invitations') {
return $c->redirect_to('invite_list');
}
return $c->redirect_to('/');
} else {
$c->stash(msg => $c->l('Please, check your credentials or your right to access this service: unable to authenticate.'));
$c->render(template => 'login');
}
}
}
sub log_out {
my $c = shift;
if ($c->is_user_authenticated) {
if ($c->validation->csrf_protect->has_error('csrf_token')) {
$c->stash(msg => $c->l('Bad CSRF token.'));
} else {
$c->logout;
}
}
if ($c->config('logout_custom')) {
return $c->redirect_to($c->config('logout_custom'));
} else {
$c->render(template => 'logout');
}
}
1;
================================================
FILE: lib/Lufi/Controller/Files.pm
================================================
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lufi::Controller::Files;
use Mojo::Base 'Mojolicious::Controller';
use Mojo::JSON qw(encode_json decode_json to_json true false);
use Mojo::Util qw(encode decode);
use Mojo::File;
use Lufi::DB::File;
use Lufi::DB::Slice;
use File::Spec::Functions;
use Number::Bytes::Human qw(format_bytes);
use Filesys::DfPortable;
use Crypt::SaltedHash;
sub files {
my $c = shift;
if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd'))) || $c->is_user_authenticated) {
$c->render(template => 'files');
} else {
$c->redirect_to('login');
}
}
sub upload {
my $c = shift;
my $invitation;
my $token = $c->session->{guest_token};
$invitation = Lufi::DB::Invitation->new(app => $c->app)->from_token($token) if $token;
if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd')) && !defined($c->config('auth_headers'))) || $c->is_user_authenticated || $invitation) {
$c->inactivity_timeout(30000000);
$c->app->log->debug('Client connected');
$c->on(
message => sub {
my ($ws, $text) = @_;
my $invit = Lufi::DB::Invitation->new(app => $c->app)->from_token($token) if $token;
my $begin = time;
my ($json) = split('XXMOJOXX', $text, 2);
$json = encode 'UTF-8', $json;
$text =~ s/^.*?XXMOJOXX/${json}XXMOJOXX/;
$json = decode_json $json;
$c->app->log->debug('Got message');
if (defined($json->{cancel}) && $json->{cancel}) {
my $f = Lufi::DB::File->new(app => $c->app)->from_short($json->{id});
if ($f && $f->mod_token && $f->mod_token eq $json->{mod_token}) {
$f = $f->delete();
return $ws->send(to_json(
{
action => 'cancel',
success => $f->deleted ? true : false,
msg => $f->deleted ? 'Lufi::DB::File->delete() was successfull' : 'Lufi::DB::File->delete() failed',
i => $json->{i}
}
));
} else {
return $ws->send(to_json(
{
action => 'cancel',
success => false,
msg => 'Lufi::DB::File not found or invalid mod_token',
i => $json->{i}
}
));
}
}
my $stop = 0;
# Check if stop_upload file is present
if ($c->stop_upload) {
$stop = 1;
return $ws->send(decode('UTF-8', encode_json(
{
success => false,
msg => $c->l('Sorry, uploading is disabled.'),
sent_delay => $json->{delay},
i => $json->{i}
}
)));
}
# Check against max_size
if (defined $c->config('max_file_size')) {
if ($json->{size} > $c->config('max_file_size')) {
$stop = 1;
return $ws->send(decode('UTF-8', encode_json(
{
success => false,
msg => $c->l('Your file is too big: %1 (maximum size allowed: %2)', format_bytes($json->{size}), format_bytes($c->config('max_file_size'))),
sent_delay => $json->{delay},
i => $json->{i}
}
)));
}
}
# Check that we have enough space (multiplying by 2 since it's encrypted, it takes more place that the original file)
# Only check if using filesystem, not Swift storage
if (!defined($c->config('swift')) && $json->{part} == 0 && ($json->{size} * 2) >= dfportable($c->config('upload_dir'))->{bavail}) {
$stop = 1;
return $ws->send(decode('UTF-8', encode_json(
{
success => false,
msg => $c->l('No enough space available on the server for this file (size: %1).', format_bytes($json->{size})),
sent_delay => $json->{delay},
i => $json->{i}
}
)));
}
# Check that the invitation is still valid, but only if it's the first chunk
# (i.e. a new file, we don't want to stop a current uploading)
if ($json->{part} == 0 && $invit && !$invit->is_valid()) {
$stop = 1;
$c->app->log->info(sprintf('Someone (%s) tried to use an expired or deleted invitation.', $invit->guest_mail));
$ws->send(decode('UTF-8', encode_json(
{
success => false,
msg => $c->l('Sorry, your invitation has expired or has been deleted. Please contact %1 to have another invitation.', $invit->ldap_user_mail),
}
)));
}
unless ($stop) {
my $f;
if (defined($json->{id})) {
$f = Lufi::DB::File->new(app => $c->app)->from_short($json->{id});
} else {
my $delay;
unless (defined $json->{delay}) {
$json->{delay} = $c->max_delay;
}
if (defined $c->config('delay_for_size')) {
# Choose delay according to config
my $delays = $c->config('delay_for_size');
my @keys = sort {$b <=> $a} keys %{$delays};
for my $key (@keys) {
if ($json->{size} >= $key) {
$delay = ($json->{delay} < $delays->{$key}) ? $json->{delay} : $delays->{$key};
last;
}
}
}
# If the file size is lower than the lowest configured size or if there is no delay_for_size setting, we choose the configured max delay
unless (defined $delay) {
$delay = (($json->{delay} > 0 && $json->{delay} <= $c->max_delay) || $c->max_delay == 0) ? $json->{delay} : $c->max_delay;
}
# If we have a password
my $salted_pwd;
if ($c->config('allow_pwd_on_files') && defined($json->{file_pwd}) && $json->{file_pwd} ne '') {
my $csh = Crypt::SaltedHash->new(algorithm => 'SHA-256', salt_len => 8);
$csh->add($json->{file_pwd});
$salted_pwd = $csh->generate();
}
my $creator = $c->ip;
# Authenticated user logging
if ((defined($c->config('ldap')) || defined($c->config('htpasswd')) || defined($c->config('auth_headers'))) && !$invitation) {
$creator = sprintf('User: %s, IP: %s', $c->current_user->{username}, $creator);
}
# Guest user logging
if ($invitation) {
$creator = sprintf('User: %s, IP: %s', $invitation->guest_mail, $creator);
}
my $delete_at_first_view = ($json->{del_at_first_view}) ? 1 : 0;
$delete_at_first_view = 1 if $c->app->config('force_burn_after_reading');
$f = Lufi::DB::File->new(app => $c->app)->get_empty()
->created_by($creator)
->delete_at_first_view($delete_at_first_view)
->delete_at_day($delay)
->mediatype($json->{type})
->filename($json->{name})
->filesize($json->{size})
->nbslices($json->{total})
->mod_token($c->shortener($c->config('token_length')))
->passwd($salted_pwd)
->zipped($json->{zipped})
->write;
}
# This check is just in case we didn't succeed to find a corresponding record
# It normally can't happen
if (defined $f) {
# If we already have a part, it's a resend because the websocket has been broken
# In this case, we don't need to rewrite the file
unless ($f->slices->grep(sub { $_->j == $json->{part} })->size) {
# Create slice file
my $s = Lufi::DB::Slice->new(
app => $c->app,
short => $f->short,
j => $json->{part}
)->store($text);
push @{$f->slices}, $s;
$s->write;
if (($json->{part} + 1) == $json->{total}) {
$f->complete(1);
$f->created_at(time);
$f->write;
}
}
my $result = {
success => true,
i => $json->{i},
j => $json->{part},
parts => $json->{total},
short => $f->short,
name => $f->filename,
size => $f->filesize,
del_at_first_view => (($f->delete_at_first_view) ? true : false),
created_at => $f->created_at,
delay => $f->delete_at_day,
token => $f->mod_token,
sent_delay => $json->{delay},
duration => time - $begin
};
$ws->send(to_json($result));
} else {
$ws->send(decode('UTF-8', encode_json(
{
success => false,
msg => $c->l('The server was unable to find the file record to add your file part to. Please, contact the administrator.'),
sent_delay => $json->{delay},
i => $json->{i}
}
)));
}
}
}
);
$c->on(
finish => sub {
$c->app->log->debug('Client disconnected');
}
);
} else {
$c->on(
message => sub {
$c->app->log->info(sprintf('Someone unauthenticated tried to upload a file. IP: %s', $c->ip));
$c->finish;
}
);
}
}
sub download {
my $c = shift;
my $short = $c->param('short');
$c->inactivity_timeout(300000);
$c->app->log->debug('Client connected');
my $ldfile = Lufi::DB::File->new(app => $c->app)->from_short($short);
# Do we have a file?
if (defined $ldfile) {
# Is the file fully uploaded?
if ($ldfile->deleted
|| (
$ldfile->delete_at_day != 0
&& (
($ldfile->created_at + $ldfile->delete_at_day * 86400) < time()
)
)
) {
unless ($ldfile->deleted) {
$ldfile->delete;
}
$c->on(
message => sub {
my ($ws, $json) = @_;
$c->send(decode('UTF-8', encode_json(
{
success => false,
msg => $c->l('Error: the file existed but was deleted.')
}
)));
}
);
} elsif (defined($ldfile->abuse)) {
my $abuse_msg = $c->l('This file has been deactivated by the admins. Contact them to know why.');
$abuse_msg = $c->app->config('abuse')->{$ldfile->abuse} if ($c->app->config('abuse') && $c->app->config('abuse')->{$ldfile->abuse});
$c->on(
message => sub {
my ($ws, $json) = @_;
$c->send(decode('UTF-8', encode_json(
{
success => false,
msg => $abuse_msg
}
)));
}
);
} elsif ($ldfile->complete) {
my $f = $ldfile;
$c->on(
message => sub {
my ($ws, $json) = @_;
$json = decode_json $json;
# Do we need a password?
my $valid = 1;
if ($c->config('allow_pwd_on_files') && defined($f->{passwd})) {
my $pwd = $json->{file_pwd};
$valid = Crypt::SaltedHash->validate($f->{passwd}, $json->{file_pwd}, 8);
}
if ($valid) {
if (defined($json->{part})) {
# Make $num an integer instead of a string
my $num = $json->{part} + 0;
# Get the slice
my $e = $f->slices->[$num];
my $text = $e->retrieve();
my ($json2) = split('XXMOJOXX', $text, 2);
$json2 = decode 'UTF-8', $json2;
$text =~ s/^.*?XXMOJOXX/${json2}XXMOJOXX/;
# Send the slice
$c->send($text);
} elsif (defined($json->{ended}) && $json->{ended}) {
$f->counter($f->counter + 1);
$f->last_access_at(time);
if ($f->delete_at_first_view) {
$f->delete;
} else {
$f->write;
}
}
} else {
$c->send(decode('UTF-8', encode_json(
{
msg => $c->l('Your password is not valid. Please refresh the page to retry.')
}
)));
}
}
);
$c->on(
finish => sub {
$c->app->log->debug('Client disconnected');
}
);
} else {
$c->on(
message => sub {
my ($ws, $json) = @_;
$c->send(decode('UTF-8', encode_json(
{
success => false,
msg => $c->l('Error: the file has not been sent entirely.')
}
)));
}
);
}
} else {
$c->send(decode('UTF-8', encode_json(
{
success => false,
msg => $c->l('Error: unable to find the file. Are you sure of your URL?')
}
)));
}
}
sub r {
my $c = shift;
my $short = $c->param('short');
my $ldfile = Lufi::DB::File->new(app => $c->app)->from_short($short);
if (defined $ldfile) {
return $c->render(
template => 'render',
f => $ldfile,
file_pwd => ($c->config('allow_pwd_on_files') && defined($ldfile->passwd))
);
} else {
return $c->render(
template => 'render',
msg => $c->l('Could not find the file. Are you sure of the URL?')
);
}
}
sub get_counter {
my $c = shift;
my $short = $c->param('short');
my $token = $c->param('token');
if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd')) && !defined($c->config('auth_headers'))) || $c->is_user_authenticated) {
my $ldfile = Lufi::DB::File->new(app => $c->app)->from_short($short);
if (defined $ldfile) {
if ($ldfile->mod_token eq $token) {
return $c->render(
json => {
success => true,
short => $short,
counter => $ldfile->counter,
deleted => ($ldfile->deleted) ? true : false
}
);
} else {
return $c->render(
json => {
success => false,
missing => false,
short => $short,
msg => $c->l('Unable to get counter for %1. The token is invalid.', $short)
}
);
}
} else {
return $c->render(
json => {
success => false,
missing => true,
short => $short,
msg => $c->l('Unable to get counter for %1. The file does not exists. It will be removed from your localStorage.', $short)
}
);
}
} else {
return $c->render(
json => {
success => false,
missing => false,
short => $short,
msg => $c->l('Unable to get counter for %1. You are not authenticated.', $short)
}
);
}
}
sub delete_file_page {
my $c = shift;
if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd'))) || $c->is_user_authenticated) {
my $short = $c->param('short');
my $token = $c->param('token');
my $ldfile = Lufi::DB::File->new(app => $c->app)->from_short($short);
$c->render(
template => 'delete_file',
short => $short,
token => $token,
filename => $ldfile->{filename},
);
} else {
$c->redirect_to('login');
}
}
sub delete {
my $c = shift;
my $short = $c->param('short');
my $token = $c->param('token');
if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd')) && !defined($c->config('auth_headers'))) || $c->is_user_authenticated) {
if (!(defined($c->param('_format')) && $c->param('_format') eq 'json') && $c->validation->csrf_protect->has_error('csrf_token')) {
$c->flash(msg => $c->l('Bad CSRF token.'));
$c->redirect_to('delete', $short, $token);
} else {
my $ldfile = Lufi::DB::File->new(app => $c->app)->from_short($short);
$ldfile = undef unless (defined($ldfile) && $ldfile->mod_token eq $token);
if (defined $ldfile) {
my $msg;
if ($ldfile->deleted) {
$msg = $c->l('The file has already been deleted');
} else {
$ldfile->delete;
$msg = $c->l('File deleted');
}
return $c->respond_to(
json => {
json => {
success => true,
msg => $msg
}
},
any => sub {
$c->render(
template => 'msg',
f => $ldfile,
msg => $msg,
del_short_from_localstorage => $short
);
}
);
} else {
my $msg = $c->l('Could not find the file. Are you sure of the URL and the token?');
return $c->respond_to(
json => {
json => {
success => false,
msg => $msg
}
},
any => sub {
$c->render(
template => 'msg',
f => undef,
msg => $msg
);
}
);
}
}
} else {
my $msg = $c->l('Could not delete the file. You are not authenticated.');
return $c->respond_to(
json => {
json => {
success => false,
msg => $msg
}
},
any => sub {
$c->render(
template => 'msg',
f => undef,
msg => $msg
);
}
);
}
}
1;
================================================
FILE: lib/Lufi/Controller/Invitation.pm
================================================
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lufi::Controller::Invitation;
use Mojo::Base 'Mojolicious::Controller';
use Mojo::Collection 'c';
use Mojo::File;
use Mojo::JSON qw(true false decode_json encode_json);
use Mojo::URL;
use Mojo::Util qw(decode
gitextract_s0gul96a/
├── .gitignore
├── .gitlab-ci.yml
├── .provision/
│ ├── README.md
│ ├── ansible-role-lufi/
│ │ ├── README.md
│ │ ├── defaults/
│ │ │ └── main.yml
│ │ ├── files/
│ │ │ ├── cronjob
│ │ │ └── robots.txt
│ │ ├── handlers/
│ │ │ └── main.yml
│ │ ├── tasks/
│ │ │ ├── apprun.yml
│ │ │ ├── cron.yml
│ │ │ ├── dependencies.yml
│ │ │ ├── gitclone.yml
│ │ │ └── main.yml
│ │ ├── templates/
│ │ │ ├── lufi.conf.j2
│ │ │ └── update.sh
│ │ └── vars/
│ │ └── main.yml
│ └── terraform-aws-lufi/
│ ├── README.md
│ ├── lufi_startup.sh
│ ├── main.tf
│ ├── output.tf
│ ├── provider.tf
│ └── vars.tf
├── AUTHORS.md
├── CHANGELOG
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── cpanfile
├── cpanfile.snapshot
├── lib/
│ ├── Date/
│ │ └── Language/
│ │ └── Occitan.pm
│ ├── Lufi/
│ │ ├── Command/
│ │ │ ├── copyFilesToSwift.pm
│ │ │ ├── cron/
│ │ │ │ ├── cleanbdd.pm
│ │ │ │ ├── cleanfiles.pm
│ │ │ │ └── watch.pm
│ │ │ ├── cron.pm
│ │ │ ├── sqliteToOtherDB.pm
│ │ │ └── theme.pm
│ │ ├── Controller/
│ │ │ ├── Auth.pm
│ │ │ ├── Files.pm
│ │ │ ├── Invitation.pm
│ │ │ ├── Mail.pm
│ │ │ └── Misc.pm
│ │ ├── DB/
│ │ │ ├── File/
│ │ │ │ ├── Mysql.pm
│ │ │ │ ├── Pg.pm
│ │ │ │ └── SQLite.pm
│ │ │ ├── File.pm
│ │ │ ├── Invitation/
│ │ │ │ ├── Mysql.pm
│ │ │ │ ├── Pg.pm
│ │ │ │ └── SQLite.pm
│ │ │ ├── Invitation.pm
│ │ │ ├── Slice/
│ │ │ │ ├── Mysql.pm
│ │ │ │ ├── Pg.pm
│ │ │ │ └── SQLite.pm
│ │ │ └── Slice.pm
│ │ ├── DefaultConfig.pm
│ │ └── Plugin/
│ │ ├── Headers.pm
│ │ └── Helpers.pm
│ ├── Lufi.pm
│ └── Mounter.pm
├── lufi.conf.template
├── script/
│ ├── application
│ └── lufi
├── t/
│ ├── lufi.passwd
│ └── test.t
├── themes/
│ └── default/
│ ├── lib/
│ │ └── Lufi/
│ │ ├── I18N/
│ │ │ ├── ar.po
│ │ │ ├── br.po
│ │ │ ├── ca.po
│ │ │ ├── co.po
│ │ │ ├── de.po
│ │ │ ├── el.po
│ │ │ ├── en.po
│ │ │ ├── es.po
│ │ │ ├── fa.po
│ │ │ ├── fr.po
│ │ │ ├── fr_FR.po
│ │ │ ├── hr.po
│ │ │ ├── it.po
│ │ │ ├── ja_JP.po
│ │ │ ├── lufi.pot
│ │ │ ├── nl.po
│ │ │ ├── oc.po
│ │ │ ├── pl.po
│ │ │ ├── pt.po
│ │ │ ├── ru.po
│ │ │ ├── sk.po
│ │ │ ├── sv.po
│ │ │ ├── zh_Hans.po
│ │ │ └── zh_Hant.po
│ │ └── I18N.pm
│ ├── public/
│ │ ├── MATERIALIZE_LICENSE
│ │ ├── css/
│ │ │ ├── cover.css
│ │ │ ├── lufi.css
│ │ │ ├── materialize.css
│ │ │ └── materialize.min.css
│ │ ├── font/
│ │ │ └── material-design-icons/
│ │ │ └── LICENSE.txt
│ │ ├── img/
│ │ │ └── lufi.xcf
│ │ └── js/
│ │ ├── filesize.min.js
│ │ ├── filesize.min.js.map
│ │ ├── ie-detection.js
│ │ ├── jquery-3.7.1.min.js
│ │ ├── jquery-3.7.1.min.map
│ │ ├── jszip.js
│ │ ├── jszip.min.js
│ │ ├── lufi-common.js
│ │ ├── lufi-down.js
│ │ ├── lufi-files.js
│ │ ├── lufi-list-invitations.js
│ │ ├── lufi-notifications.js
│ │ ├── lufi-up.js
│ │ ├── materialize.js
│ │ ├── materialize.min.js
│ │ ├── sidenav.js
│ │ └── sjcl.js
│ └── templates/
│ ├── about.html.ep
│ ├── delays.html.ep
│ ├── delete_file.html.ep
│ ├── files.html.ep
│ ├── index.html.ep
│ ├── invitations/
│ │ ├── exception.html.ep
│ │ ├── invite.html.ep
│ │ ├── invite.mail.ep
│ │ ├── my_invitations.html.ep
│ │ └── notification_files_sent.mail.ep
│ ├── layouts/
│ │ └── default.html.ep
│ ├── login.html.ep
│ ├── logout.html.ep
│ ├── mail.html.ep
│ ├── msg.html.ep
│ ├── partial/
│ │ ├── files.js.ep
│ │ ├── index.js.ep
│ │ ├── invitations.js.ep
│ │ ├── layout.js.ep
│ │ ├── mail.js.ep
│ │ └── render.js.ep
│ └── render.html.ep
└── utilities/
├── lufi.default
├── lufi.init
├── lufi.service
└── migrations/
├── mysql.sql
├── pg.sql
└── sqlite.sql
SYMBOL INDEX (673 symbols across 17 files)
FILE: themes/default/public/js/filesize.min.js
function b (line 5) | function b(e){var b,n,r,a,s,f,d,u,l,B,c,p,y,g=arguments.length>1&&void 0...
FILE: themes/default/public/js/ie-detection.js
function confirmExit (line 1) | function confirmExit() {
FILE: themes/default/public/js/jquery-3.7.1.min.js
function m (line 2) | function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e...
function x (line 2) | function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof...
function c (line 2) | function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e...
function fe (line 2) | function fe(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLower...
function p (line 2) | function p(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCode...
function I (line 2) | function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeTyp...
function W (line 2) | function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cach...
function F (line 2) | function F(e){return e[S]=!0,e}
function $ (line 2) | function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e...
function B (line 2) | function B(t){return function(e){return fe(e,"input")&&e.type===t}}
function _ (line 2) | function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&...
function z (line 2) | function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.d...
function X (line 2) | function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a...
function U (line 2) | function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}
function V (line 2) | function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeTyp...
function G (line 2) | function G(){}
function Y (line 2) | function Y(e,t){var n,r,i,o,a,s,u,l=c[e+" "];if(l)return t?0:l.slice(0);...
function Q (line 2) | function Q(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}
function J (line 2) | function J(a,e,t){var s=e.dir,u=e.next,l=u||s,c=t&&"parentNode"===l,f=n+...
function K (line 2) | function K(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--...
function Z (line 2) | function Z(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o...
function ee (line 2) | function ee(d,h,g,v,y,e){return v&&!v[S]&&(v=ee(v)),y&&!y[S]&&(y=ee(y,e)...
function te (line 2) | function te(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.r...
function ne (line 2) | function ne(e,t){var n,v,y,m,x,r,i=[],o=[],a=u[e+" "];if(!a){t||(t=Y(e))...
function re (line 2) | function re(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&Y(e=l...
function T (line 2) | function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t...
function A (line 2) | function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}
function N (line 2) | function N(e){return e}
function q (line 2) | function q(e){throw e}
function L (line 2) | function L(e,t,n,r){var i;try{e&&v(i=e.promise)?i.call(e).done(t).fail(n...
function l (line 2) | function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(...
function P (line 2) | function P(){C.removeEventListener("DOMContentLoaded",P),ie.removeEventL...
function W (line 2) | function W(e,t){return t.toUpperCase()}
function F (line 2) | function F(e){return e.replace(R,"ms-").replace(I,W)}
function B (line 2) | function B(){this.expando=ce.expando+B.uid++}
function V (line 2) | function V(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.r...
function te (line 2) | function te(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:functio...
function re (line 2) | function re(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[...
function Se (line 2) | function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagNa...
function Ee (line 2) | function Ee(e,t){for(var n=0,r=e.length;n<r;n++)_.set(e[n],"globalEval",...
function Ae (line 2) | function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),...
function Ne (line 2) | function Ne(){return!0}
function qe (line 2) | function qe(){return!1}
function Le (line 2) | function Le(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"...
function He (line 2) | function He(e,r,t){t?(_.set(e,r,!1),ce.event.add(e,r,{namespace:!1,handl...
function o (line 2) | function o(e){if(C.documentMode){var t=_.get(this,"handle"),n=ce.event.f...
function Re (line 2) | function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild...
function Ie (line 2) | function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}
function We (line 2) | function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.sli...
function Fe (line 2) | function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=...
function $e (line 2) | function $e(n,r,i,o){r=g(r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],...
function Be (line 2) | function Be(e,t,n){for(var r,i=t?ce.filter(t,e):e,o=0;null!=(r=i[o]);o++...
function Ge (line 2) | function Ge(e,t,n){var r,i,o,a,s=ze.test(t),u=e.style;return(n=n||Xe(e))...
function Ye (line 2) | function Ye(e,t){return{get:function(){if(!e())return(this.get=t).apply(...
function e (line 2) | function e(){if(l){u.style.cssText="position:absolute;left:-11111px;widt...
function t (line 2) | function t(e){return Math.round(parseFloat(e))}
function Ze (line 2) | function Ze(e){var t=ce.cssProps[e]||Ke[e];return t||(e in Je?e:Ke[e]=fu...
function rt (line 2) | function rt(e,t,n){var r=Y.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3...
function it (line 2) | function it(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0,l=0;if(n===(r?"bo...
function ot (line 2) | function ot(e,t,n){var r=Xe(e),i=(!le.boxSizingReliable()||n)&&"border-b...
function at (line 2) | function at(e,t,n,r,i){return new at.prototype.init(e,t,n,r,i)}
function dt (line 2) | function dt(){ut&&(!1===C.hidden&&ie.requestAnimationFrame?ie.requestAni...
function ht (line 2) | function ht(){return ie.setTimeout(function(){st=void 0}),st=Date.now()}
function gt (line 2) | function gt(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin...
function vt (line 2) | function vt(e,t,n){for(var r,i=(yt.tweeners[t]||[]).concat(yt.tweeners["...
function yt (line 2) | function yt(o,e,t){var n,a,r=0,i=yt.prefilters.length,s=ce.Deferred().al...
function Tt (line 2) | function Tt(e){return(e.match(D)||[]).join(" ")}
function Ct (line 2) | function Ct(e){return e.getAttribute&&e.getAttribute("class")||""}
function kt (line 2) | function kt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(D)|...
function Pt (line 2) | function Pt(n,e,r,i){var t;if(Array.isArray(e))ce.each(e,function(e,t){r...
function Ut (line 2) | function Ut(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var ...
function Vt (line 2) | function Vt(t,i,o,a){var s={},u=t===_t;function l(e){var r;return s[e]=!...
function Gt (line 2) | function Gt(e,t){var n,r,i=ce.ajaxSettings.flatOptions||{};for(n in t)vo...
function l (line 2) | function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&ie.clearTimeout(d),c=v...
FILE: themes/default/public/js/jszip.js
function s (line 13) | function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&re...
function CompressedObject (line 139) | function CompressedObject(compressedSize, uncompressedSize, crc32, compr...
function makeTable (line 225) | function makeTable() {
function crc32 (line 243) | function crc32(crc, buf, len, pos) {
function crc32str (line 267) | function crc32str(crc, str, len, pos) {
function FlateWorker (line 345) | function FlateWorker(action, options) {
function ZipFileWorker (line 736) | function ZipFileWorker(streamFiles, comment, platform, encodeFileName) {
function JSZip (line 1022) | function JSZip() {
function checkEntryCRC32 (line 1084) | function checkEntryCRC32(zipEntry) {
function NodejsStreamInputAdapter (line 1165) | function NodejsStreamInputAdapter(filename, stream) {
function NodejsStreamOutputAdapter (line 1245) | function NodejsStreamOutputAdapter(helper, options, updateCb) {
function isRegExp (line 1492) | function isRegExp(object) {
function ArrayReader (line 1739) | function ArrayReader(data) {
function DataReader (line 1797) | function DataReader(data) {
function NodeBufferReader (line 1916) | function NodeBufferReader(data) {
function StringReader (line 1937) | function StringReader(data) {
function Uint8ArrayReader (line 1977) | function Uint8ArrayReader(data) {
function ConvertWorker (line 2046) | function ConvertWorker(destType) {
function Crc32Probe (line 2074) | function Crc32Probe() {
function DataLengthProbe (line 2100) | function DataLengthProbe(propName) {
function DataWorker (line 2135) | function DataWorker(dataP) {
function GenericWorker (line 2255) | function GenericWorker(name) {
function transformZipOutput (line 2529) | function transformZipOutput(type, content, mimeType) {
function concat (line 2547) | function concat (type, dataArray) {
function accumulate (line 2580) | function accumulate(helper, updateCallback) {
function StreamHelper (line 2617) | function StreamHelper(worker, outputType, mimeType) {
function Utf8DecodeWorker (line 2955) | function Utf8DecodeWorker() {
function Utf8EncodeWorker (line 3018) | function Utf8EncodeWorker() {
function string2binary (line 3051) | function string2binary(str) {
function identity (line 3106) | function identity(input) {
function stringToArrayLike (line 3116) | function stringToArrayLike(str, array) {
function arrayLikeToString (line 3198) | function arrayLikeToString(array) {
function arrayLikeToArrayLike (line 3242) | function arrayLikeToArrayLike(arrayFrom, arrayTo) {
function ZipEntries (line 3526) | function ZipEntries(loadOptions) {
function ZipEntry (line 3813) | function ZipEntry(options, loadOptions) {
function nextTick (line 4254) | function nextTick() {
function immediate (line 4271) | function immediate(task) {
function INTERNAL (line 4283) | function INTERNAL() {}
function Promise (line 4293) | function Promise(resolver) {
function resolve (line 4312) | function resolve(value) {
function reject (line 4318) | function reject(reason) {
function QueueItem (line 4343) | function QueueItem(promise, onFulfilled, onRejected) {
function unwrap (line 4367) | function unwrap(promise, func, value) {
function getThen (line 4414) | function getThen(obj) {
function safelyResolveThenable (line 4424) | function safelyResolveThenable(self, thenable) {
function tryCatch (line 4453) | function tryCatch(func, value) {
function resolve (line 4466) | function resolve(value) {
function reject (line 4474) | function reject(reason) {
function all (line 4480) | function all(iterable) {
function race (line 4519) | function race(iterable) {
function Deflate (line 4689) | function Deflate(options) {
function deflate (line 4924) | function deflate(input, options) {
function deflateRaw (line 4944) | function deflateRaw(input, options) {
function gzip (line 4959) | function gzip(input, options) {
function Inflate (line 5064) | function Inflate(options) {
function inflate (line 5349) | function inflate(input, options) {
function inflateRaw (line 5369) | function inflateRaw(input, options) {
function buf2binstring (line 5580) | function buf2binstring(buf, len) {
function adler32 (line 5708) | function adler32(adler, buf, len, pos) {
function makeTable (line 5832) | function makeTable() {
function crc32 (line 5850) | function crc32(crc, buf, len, pos) {
function err (line 5991) | function err(strm, errorCode) {
function rank (line 5996) | function rank(f) {
function zero (line 6000) | function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len]...
function flush_pending (line 6009) | function flush_pending(strm) {
function flush_block_only (line 6031) | function flush_block_only(s, last) {
function put_byte (line 6038) | function put_byte(s, b) {
function putShortMSB (line 6048) | function putShortMSB(s, b) {
function read_buf (line 6063) | function read_buf(strm, buf, start, size) {
function longest_match (line 6097) | function longest_match(s, cur_match) {
function fill_window (line 6210) | function fill_window(s) {
function deflate_stored (line 6366) | function deflate_stored(s, flush) {
function deflate_fast (line 6464) | function deflate_fast(s, flush) {
function deflate_slow (line 6592) | function deflate_slow(s, flush) {
function deflate_rle (line 6754) | function deflate_rle(s, flush) {
function deflate_huff (line 6849) | function deflate_huff(s, flush) {
function Config (line 6906) | function Config(good_length, max_lazy, nice_length, max_chain, func) {
function lm_init (line 6935) | function lm_init(s) {
function DeflateState (line 6958) | function DeflateState() {
function deflateResetKeep (line 7147) | function deflateResetKeep(strm) {
function deflateReset (line 7176) | function deflateReset(strm) {
function deflateSetHeader (line 7185) | function deflateSetHeader(strm, head) {
function deflateInit2 (line 7193) | function deflateInit2(strm, level, method, windowBits, memLevel, strateg...
function deflateInit (line 7271) | function deflateInit(strm, level) {
function deflate (line 7276) | function deflate(strm, flush) {
function deflateEnd (line 7610) | function deflateEnd(strm) {
function deflateSetDictionary (line 7639) | function deflateSetDictionary(strm, dictionary) {
function GZheader (line 7764) | function GZheader() {
function zswap32 (line 8262) | function zswap32(q) {
function InflateState (line 8270) | function InflateState() {
function inflateResetKeep (line 8328) | function inflateResetKeep(strm) {
function inflateReset (line 8355) | function inflateReset(strm) {
function inflateReset2 (line 8367) | function inflateReset2(strm, windowBits) {
function inflateInit2 (line 8401) | function inflateInit2(strm, windowBits) {
function inflateInit (line 8421) | function inflateInit(strm) {
function fixedtables (line 8440) | function fixedtables(state) {
function updatewindow (line 8488) | function updatewindow(strm, src, end, copy) {
function inflate (line 8530) | function inflate(strm, flush) {
function inflateEnd (line 9622) | function inflateEnd(strm) {
function inflateGetHeader (line 9636) | function inflateGetHeader(strm, head) {
function inflateSetDictionary (line 9650) | function inflateSetDictionary(strm, dictionary) {
function zero (line 10129) | function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len]...
function StaticTreeDesc (line 10252) | function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_...
function TreeDesc (line 10270) | function TreeDesc(dyn_tree, stat_desc) {
function d_code (line 10278) | function d_code(dist) {
function put_short (line 10287) | function put_short(s, w) {
function send_bits (line 10299) | function send_bits(s, value, length) {
function send_code (line 10312) | function send_code(s, c, tree) {
function bi_reverse (line 10322) | function bi_reverse(code, len) {
function bi_flush (line 10336) | function bi_flush(s) {
function gen_bitlen (line 10360) | function gen_bitlen(s, desc)
function gen_codes (line 10457) | function gen_codes(tree, max_code, bl_count)
function tr_static_init (line 10495) | function tr_static_init() {
function init_block (line 10599) | function init_block(s) {
function bi_windup (line 10616) | function bi_windup(s)
function copy_block (line 10632) | function copy_block(s, buf, len, header)
function smaller (line 10655) | function smaller(tree, n, m, depth) {
function pqdownheap (line 10668) | function pqdownheap(s, tree, k)
function compress_block (line 10701) | function compress_block(s, ltree, dtree)
function build_tree (line 10761) | function build_tree(s, desc)
function scan_tree (line 10857) | function scan_tree(s, tree, max_code)
function send_tree (line 10923) | function send_tree(s, tree, max_code)
function build_bl_tree (line 10994) | function build_bl_tree(s) {
function send_all_trees (line 11030) | function send_all_trees(s, lcodes, dcodes, blcodes)
function detect_data_type (line 11070) | function detect_data_type(s) {
function _tr_init (line 11108) | function _tr_init(s)
function _tr_stored_block (line 11131) | function _tr_stored_block(s, buf, stored_len, last)
function _tr_align (line 11146) | function _tr_align(s) {
function _tr_flush_block (line 11157) | function _tr_flush_block(s, buf, stored_len, last)
function _tr_tally (line 11244) | function _tr_tally(s, dist, lc)
function ZStream (line 11330) | function ZStream() {
FILE: themes/default/public/js/jszip.min.js
function e (line 12) | function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&re...
function d (line 12) | function d(a,b,c,d,e){this.compressedSize=a,this.uncompressedSize=b,this...
function d (line 12) | function d(){for(var a,b=[],c=0;c<256;c++){a=c;for(var d=0;d<8;d++)a=1&a...
function e (line 12) | function e(a,b,c,d){var e=h,f=d+c;a^=-1;for(var g=d;g<f;g++)a=a>>>8^e[25...
function f (line 12) | function f(a,b,c,d){var e=h,f=d+c;a^=-1;for(var g=d;g<f;g++)a=a>>>8^e[25...
function d (line 12) | function d(a,b){h.call(this,"FlateWorker/"+a),this._pako=null,this._pako...
function d (line 12) | function d(a,b,c,d){f.call(this,"ZipFileWorker"),this.bytesWritten=0,thi...
function d (line 12) | function d(){if(!(this instanceof d))return new d;if(arguments.length)th...
function d (line 12) | function d(a){return new f.Promise(function(b,c){var d=a.decompressed.ge...
function d (line 12) | function d(a,b){f.call(this,"Nodejs stream input adapter for "+a),this._...
function d (line 12) | function d(a,b,c){e.call(this,b),this._helper=a;var d=this;a.on("data",f...
function d (line 12) | function d(a){return"[object RegExp]"===Object.prototype.toString.call(a)}
function d (line 12) | function d(a){e.call(this,a);for(var b=0;b<this.data.length;b++)a[b]=255...
function d (line 12) | function d(a){this.data=a,this.length=a.length,this.index=0,this.zero=0}
function d (line 12) | function d(a){e.call(this,a)}
function d (line 12) | function d(a){e.call(this,a)}
function d (line 12) | function d(a){e.call(this,a)}
function d (line 12) | function d(a){e.call(this,"ConvertWorker to "+a),this.destType=a}
function d (line 12) | function d(){e.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0)}
function d (line 12) | function d(a){f.call(this,"DataLengthProbe for "+a),this.propName=a,this...
function d (line 12) | function d(a){f.call(this,"DataWorker");var b=this;this.dataIsReady=!1,t...
function d (line 12) | function d(a){this.name=a||"default",this.streamInfo={},this.generatedEr...
function d (line 12) | function d(a,b,c){switch(a){case"blob":return h.newBlob(h.transformTo("a...
function e (line 12) | function e(a,b){var c,d=0,e=null,f=0;for(c=0;c<b.length;c++)f+=b[c].leng...
function f (line 12) | function f(a,b){return new m.Promise(function(c,f){var g=[],h=a._interna...
function g (line 12) | function g(a,b,c){var d=b;switch(b){case"blob":case"arraybuffer":d="uint...
function d (line 12) | function d(){i.call(this,"utf-8 decode"),this.leftOver=null}
function e (line 12) | function e(){i.call(this,"utf-8 encode")}
function d (line 12) | function d(a){var b=null;return b=i.uint8array?new Uint8Array(a.length):...
function e (line 12) | function e(a){return a}
function f (line 12) | function f(a,b){for(var c=0;c<a.length;++c)b[c]=255&a.charCodeAt(c);retu...
function g (line 12) | function g(a){var b=65536,d=c.getTypeOf(a),e=!0;if("uint8array"===d?e=n....
function h (line 13) | function h(a,b){for(var c=0;c<a.length;c++)b[c]=a[c];return b}
function d (line 13) | function d(a){this.files=[],this.loadOptions=a}
function d (line 13) | function d(a,b){this.options=a,this.loadOptions=b}
function c (line 13) | function c(){k=!0;for(var a,b,c=l.length;c;){for(b=l,l=[],a=-1;++a<c;)b[...
function d (line 13) | function d(a){1!==l.push(a)||k||e()}
function d (line 13) | function d(){}
function e (line 13) | function e(a){if("function"!=typeof a)throw new TypeError("resolver must...
function f (line 13) | function f(a,b,c){this.promise=a,"function"==typeof b&&(this.onFulfilled...
function g (line 13) | function g(a,b,c){o(function(){var d;try{d=b(c)}catch(e){return p.reject...
function h (line 13) | function h(a){var b=a&&a.then;if(a&&("object"==typeof a||"function"==typ...
function i (line 13) | function i(a,b){function c(b){f||(f=!0,p.reject(a,b))}function d(b){f||(...
function j (line 13) | function j(a,b){var c={};try{c.value=a(b),c.status="success"}catch(d){c....
function k (line 13) | function k(a){return a instanceof this?a:p.resolve(new this(d),a)}
function l (line 13) | function l(a){var b=new this(d);return p.reject(b,a)}
function m (line 13) | function m(a){function b(a,b){function d(a){g[b]=a,++h!==e||f||(f=!0,p.r...
function n (line 13) | function n(a){function b(a){c.resolve(a).then(function(a){f||(f=!0,p.res...
function b (line 13) | function b(b){function c(){return b}return d.resolve(a()).then(c)}
function c (line 13) | function c(b){function c(){throw b}return d.resolve(a()).then(c)}
function d (line 13) | function d(a){if(!(this instanceof d))return new d(a);this.options=i.ass...
function e (line 13) | function e(a,b){var c=new d(b);if(c.push(a,!0),c.err)throw c.msg||k[c.er...
function f (line 13) | function f(a,b){return b=b||{},b.raw=!0,e(a,b)}
function g (line 13) | function g(a,b){return b=b||{},b.gzip=!0,e(a,b)}
function d (line 13) | function d(a){if(!(this instanceof d))return new d(a);this.options=h.ass...
function e (line 13) | function e(a,b){var c=new d(b);if(c.push(a,!0),c.err)throw c.msg||k[c.er...
function f (line 13) | function f(a,b){return b=b||{},b.raw=!0,e(a,b)}
function d (line 13) | function d(a,b){if(b<65537&&(a.subarray&&g||!a.subarray&&f))return Strin...
function d (line 13) | function d(a,b,c,d){for(var e=65535&a|0,f=a>>>16&65535|0,g=0;0!==c;){g=c...
function d (line 13) | function d(){for(var a,b=[],c=0;c<256;c++){a=c;for(var d=0;d<8;d++)a=1&a...
function e (line 13) | function e(a,b,c,d){var e=f,g=d+c;a^=-1;for(var h=d;h<g;h++)a=a>>>8^e[25...
function d (line 13) | function d(a,b){return a.msg=I[b],b}
function e (line 13) | function e(a){return(a<<1)-(a>4?9:0)}
function f (line 13) | function f(a){for(var b=a.length;--b>=0;)a[b]=0}
function g (line 13) | function g(a){var b=a.state,c=b.pending;c>a.avail_out&&(c=a.avail_out),0...
function h (line 13) | function h(a,b){F._tr_flush_block(a,a.block_start>=0?a.block_start:-1,a....
function i (line 13) | function i(a,b){a.pending_buf[a.pending++]=b}
function j (line 13) | function j(a,b){a.pending_buf[a.pending++]=b>>>8&255,a.pending_buf[a.pen...
function k (line 13) | function k(a,b,c,d){var e=a.avail_in;return e>d&&(e=d),0===e?0:(a.avail_...
function l (line 13) | function l(a,b){var c,d,e=a.max_chain_length,f=a.strstart,g=a.prev_lengt...
function m (line 13) | function m(a){var b,c,d,e,f,g=a.w_size;do{if(e=a.window_size-a.lookahead...
function n (line 13) | function n(a,b){var c=65535;for(c>a.pending_buf_size-5&&(c=a.pending_buf...
function o (line 13) | function o(a,b){for(var c,d;;){if(a.lookahead<la){if(m(a),a.lookahead<la...
function p (line 13) | function p(a,b){for(var c,d,e;;){if(a.lookahead<la){if(m(a),a.lookahead<...
function q (line 14) | function q(a,b){for(var c,d,e,f,g=a.window;;){if(a.lookahead<=ka){if(m(a...
function r (line 14) | function r(a,b){for(var c;;){if(0===a.lookahead&&(m(a),0===a.lookahead))...
function s (line 14) | function s(a,b,c,d,e){this.good_length=a,this.max_lazy=b,this.nice_lengt...
function t (line 14) | function t(a){a.window_size=2*a.w_size,f(a.head),a.max_lazy_match=D[a.le...
function u (line 14) | function u(){this.strm=null,this.status=0,this.pending_buf=null,this.pen...
function v (line 14) | function v(a){var b;return a&&a.state?(a.total_in=a.total_out=0,a.data_t...
function w (line 14) | function w(a){var b=v(a);return b===O&&t(a.state),b}
function x (line 14) | function x(a,b){return a&&a.state?2!==a.state.wrap?Q:(a.state.gzhead=b,O...
function y (line 14) | function y(a,b,c,e,f,g){if(!a)return Q;var h=1;if(b===T&&(b=6),e<0?(h=0,...
function z (line 14) | function z(a,b){return y(a,b,$,aa,ba,Y)}
function A (line 14) | function A(a,b){var c,h,k,l;if(!a||!a.state||b>N||b<0)return a?d(a,Q):Q;...
function B (line 14) | function B(a){var b;return a&&a.state?(b=a.state.status,b!==na&&b!==oa&&...
function C (line 14) | function C(a,b){var c,d,e,g,h,i,j,k,l=b.length;if(!a||!a.state)return Q;...
function d (line 14) | function d(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=...
function d (line 14) | function d(a){return(a>>>24&255)+(a>>>8&65280)+((65280&a)<<8)+((255&a)<<...
function e (line 14) | function e(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this....
function f (line 14) | function f(a){var b;return a&&a.state?(b=a.state,a.total_in=a.total_out=...
function g (line 14) | function g(a){var b;return a&&a.state?(b=a.state,b.wsize=0,b.whave=0,b.w...
function h (line 14) | function h(a,b){var c,d;return a&&a.state?(d=a.state,b<0?(c=0,b=-b):(c=(...
function i (line 14) | function i(a,b){var c,d;return a?(d=new e,a.state=d,d.window=null,c=h(a,...
function j (line 14) | function j(a){return i(a,sa)}
function k (line 14) | function k(a){if(ta){var b;for(q=new s.Buf32(512),r=new s.Buf32(32),b=0;...
function l (line 14) | function l(a,b,c,d){var e,f=a.state;return null===f.window&&(f.wsize=1<<...
function m (line 14) | function m(a,b){var c,e,f,g,h,i,j,m,n,o,p,q,r,pa,qa,ra,sa,ta,ua,va,wa,xa...
function n (line 14) | function n(a){if(!a||!a.state)return G;var b=a.state;return b.window&&(b...
function o (line 14) | function o(a,b){var c;return a&&a.state?(c=a.state,0===(2&c.wrap)?G:(c.h...
function p (line 14) | function p(a,b){var c,d,e,f=b.length;return a&&a.state?(c=a.state,0!==c....
function d (line 14) | function d(a){for(var b=a.length;--b>=0;)a[b]=0}
function e (line 14) | function e(a,b,c,d,e){this.static_tree=a,this.extra_bits=b,this.extra_ba...
function f (line 14) | function f(a,b){this.dyn_tree=a,this.max_code=0,this.stat_desc=b}
function g (line 14) | function g(a){return a<256?ia[a]:ia[256+(a>>>7)]}
function h (line 14) | function h(a,b){a.pending_buf[a.pending++]=255&b,a.pending_buf[a.pending...
function i (line 14) | function i(a,b,c){a.bi_valid>X-c?(a.bi_buf|=b<<a.bi_valid&65535,h(a,a.bi...
function j (line 14) | function j(a,b,c){i(a,c[2*b],c[2*b+1])}
function k (line 14) | function k(a,b){var c=0;do c|=1&a,a>>>=1,c<<=1;while(--b>0);return c>>>1}
function l (line 14) | function l(a){16===a.bi_valid?(h(a,a.bi_buf),a.bi_buf=0,a.bi_valid=0):a....
function m (line 14) | function m(a,b){var c,d,e,f,g,h,i=b.dyn_tree,j=b.max_code,k=b.stat_desc....
function n (line 14) | function n(a,b,c){var d,e,f=new Array(W+1),g=0;for(d=1;d<=W;d++)f[d]=g=g...
function o (line 14) | function o(){var a,b,c,d,f,g=new Array(W+1);for(c=0,d=0;d<Q-1;d++)for(ka...
function p (line 14) | function p(a){var b;for(b=0;b<S;b++)a.dyn_ltree[2*b]=0;for(b=0;b<T;b++)a...
function q (line 14) | function q(a){a.bi_valid>8?h(a,a.bi_buf):a.bi_valid>0&&(a.pending_buf[a....
function r (line 14) | function r(a,b,c,d){q(a),d&&(h(a,c),h(a,~c)),G.arraySet(a.pending_buf,a....
function s (line 14) | function s(a,b,c,d){var e=2*b,f=2*c;return a[e]<a[f]||a[e]===a[f]&&d[b]<...
function t (line 14) | function t(a,b,c){for(var d=a.heap[c],e=c<<1;e<=a.heap_len&&(e<a.heap_le...
function u (line 14) | function u(a,b,c){var d,e,f,h,k=0;if(0!==a.last_lit)do d=a.pending_buf[a...
function v (line 14) | function v(a,b){var c,d,e,f=b.dyn_tree,g=b.stat_desc.static_tree,h=b.sta...
function w (line 14) | function w(a,b,c){var d,e,f=-1,g=b[1],h=0,i=7,j=4;for(0===g&&(i=138,j=3)...
function x (line 14) | function x(a,b,c){var d,e,f=-1,g=b[1],h=0,k=7,l=4;for(0===g&&(k=138,l=3)...
function y (line 14) | function y(a){var b;for(w(a,a.dyn_ltree,a.l_desc.max_code),w(a,a.dyn_dtr...
function z (line 14) | function z(a,b,c,d){var e;for(i(a,b-257,5),i(a,c-1,5),i(a,d-4,4),e=0;e<d...
function A (line 14) | function A(a){var b,c=4093624447;for(b=0;b<=31;b++,c>>>=1)if(1&c&&0!==a....
function B (line 14) | function B(a){pa||(o(),pa=!0),a.l_desc=new f(a.dyn_ltree,ma),a.d_desc=ne...
function C (line 14) | function C(a,b,c,d){i(a,(L<<1)+(d?1:0),3),r(a,b,c,!0)}
function D (line 14) | function D(a){i(a,M<<1,3),j(a,Z,ga),l(a)}
function E (line 14) | function E(a,b,c,d){var e,f,g=0;a.level>0?(a.strm.data_type===K&&(a.strm...
function F (line 14) | function F(a,b,c){return a.pending_buf[a.d_buf+2*a.last_lit]=b>>>8&255,a...
function d (line 15) | function d(){this.input=null,this.next_in=0,this.avail_in=0,this.total_i...
FILE: themes/default/public/js/lufi-common.js
function escapeHtml (line 12) | function escapeHtml(string) {
function changeLang (line 17) | function changeLang() {
function formatDate (line 20) | function formatDate(unixTimestamp) {
function delItem (line 30) | function delItem(name) {
FILE: themes/default/public/js/lufi-down.js
function pageKey (line 6) | function pageKey() {
function base64ToArrayBuffer (line 24) | function base64ToArrayBuffer(base64) {
function addAlert (line 35) | function addAlert(msg) {
function spawnWebsocket (line 49) | function spawnWebsocket(pa) {
FILE: themes/default/public/js/lufi-files.js
function addItem (line 3) | function addItem(item) {
function itemExists (line 14) | function itemExists(name) {
function invertSelection (line 30) | function invertSelection(event) {
function purgeExpired (line 44) | function purgeExpired(event) {
function exportStorage (line 69) | function exportStorage(event) {
function importStorage (line 85) | function importStorage(f) {
function validURL (line 109) | function validURL(str) {
function delFile (line 122) | function delFile() {
function evaluateMassDelete (line 147) | function evaluateMassDelete() {
function massDelete (line 157) | function massDelete(event) {
function populateFilesTable (line 162) | function populateFilesTable() {
function clickImport (line 276) | function clickImport(event) {
FILE: themes/default/public/js/lufi-list-invitations.js
function invertSelection (line 1) | function invertSelection(e) {
function toggleHidden (line 12) | function toggleHidden(e) {
function deleteInvit (line 31) | function deleteInvit(e) {
function resendMail (line 64) | function resendMail(e) {
function toggleVisibility (line 88) | function toggleVisibility(e) {
function selectChecked (line 122) | function selectChecked() {
function handleCheckboxClic (line 130) | function handleCheckboxClic() {
function disableButtons (line 149) | function disableButtons() {
function fillModal (line 158) | function fillModal() {
FILE: themes/default/public/js/lufi-notifications.js
function notify (line 1) | function notify(title, body) {
FILE: themes/default/public/js/lufi-up.js
function copyToClipboard (line 18) | function copyToClipboard(txt) {
function copyAllToClipboard (line 41) | function copyAllToClipboard(event) {
function addItem (line 70) | function addItem(name, url, size, del_at_first_view, created_at, delay, ...
function destroyBlock (line 82) | function destroyBlock(el) {
function firstViewClicking (line 96) | function firstViewClicking() {
function zipClicking (line 105) | function zipClicking() {
function getZipname (line 125) | function getZipname() {
function updateZipname (line 142) | function updateZipname() {
function uploadZip (line 147) | function uploadZip(e) {
function updateMailLink (line 188) | function updateMailLink() {
function sendFilesURLs (line 200) | function sendFilesURLs() {
function handleFiles (line 222) | function handleFiles(f) {
function genRandomKey (line 271) | function genRandomKey() {
function uploadFile (line 276) | function uploadFile(i, delay, del_at_first_view) {
function sliceAndUpload (line 331) | function sliceAndUpload(randomkey, i, parts, j, delay, del_at_first_view...
function updateProgressBar (line 432) | function updateProgressBar(data) {
function addAlertOnFile (line 607) | function addAlertOnFile(msg, i, sent_delay, del_at_first_view) {
function handleDrop (line 634) | function handleDrop(evt) {
function handleDragOver (line 641) | function handleDragOver(evt) {
function spawnWebsocket (line 648) | function spawnWebsocket(i, callback) {
function bindDropZone (line 676) | function bindDropZone() {
FILE: themes/default/public/js/materialize.js
function t (line 220) | function t(e){var t=e.length,a=r.type(e);return"function"===a||r.isWindo...
function o (line 220) | function o(e,r){var a=r||[];return null!=e&&(t(Object(e))?!function(e,t)...
function e (line 220) | function e(){for(var e=this.offsetParent||document;e&&"html"===!e.nodeTy...
function n (line 220) | function n(e){for(var t=-1,r=e?e.length:0,a=[];++t<r;){var n=e[t];n&&a.p...
function o (line 220) | function o(e){return m.isWrapped(e)?e=[].slice.call(e):m.isNode(e)&&(e=[...
function i (line 220) | function i(e){var t=f.data(e,"velocity");return null===t?a:t}
function s (line 220) | function s(e){return function(t){return Math.round(t*e)*(1/e)}}
function l (line 220) | function l(e,r,a,n){function o(e,t){return 1-3*t+3*e}function i(e,t){ret...
function u (line 220) | function u(e,t){var r=e;return m.isString(e)?b.Easings[e]||(r=!1):r=m.is...
function c (line 220) | function c(e){if(e){var t=(new Date).getTime(),r=b.State.calls.length;r>...
function p (line 220) | function p(e,t){if(!b.State.calls[e])return!1;for(var r=b.State.calls[e]...
function e (line 220) | function e(e){return-e.tension*e.x-e.friction*e.v}
function t (line 220) | function t(t,r,a){var n={x:t.x+a.dx*r,v:t.v+a.dv*r,tension:t.tension,fri...
function r (line 220) | function r(r,a){var n={dx:r.v,dv:e(r)},o=t(r,.5*a,n),i=t(r,.5*a,o),s=t(r...
function s (line 220) | function s(e,r){function n(){u&&S.setPropertyValue(e,"display","none")}v...
function t (line 220) | function t(t){return parseFloat(S.getPropertyValue(e,t))}
function e (line 220) | function e(){return s?k.promise||null:l}
function n (line 220) | function n(){function e(e){function p(e,t){var r=a,n=a,i=a;return m.isAr...
function k (line 222) | function k(a,b,c){return setTimeout(q(a,c),b)}
function l (line 222) | function l(a,b,c){return Array.isArray(a)?(m(a,c[b],c),!0):!1}
function m (line 222) | function m(a,b,c){var e;if(a)if(a.forEach)a.forEach(b,c);else if(a.lengt...
function n (line 222) | function n(a,b,c){for(var e=Object.keys(b),f=0;f<e.length;)(!c||c&&a[e[f...
function o (line 222) | function o(a,b){return n(a,b,!0)}
function p (line 222) | function p(a,b,c){var e,d=b.prototype;e=a.prototype=Object.create(d),e.c...
function q (line 222) | function q(a,b){return function(){return a.apply(b,arguments)}}
function r (line 222) | function r(a,b){return typeof a==g?a.apply(b?b[0]||d:d,b):a}
function s (line 222) | function s(a,b){return a===d?b:a}
function t (line 222) | function t(a,b,c){m(x(b),function(b){a.addEventListener(b,c,!1)})}
function u (line 222) | function u(a,b,c){m(x(b),function(b){a.removeEventListener(b,c,!1)})}
function v (line 222) | function v(a,b){for(;a;){if(a==b)return!0;a=a.parentNode}return!1}
function w (line 222) | function w(a,b){return a.indexOf(b)>-1}
function x (line 222) | function x(a){return a.trim().split(/\s+/g)}
function y (line 222) | function y(a,b,c){if(a.indexOf&&!c)return a.indexOf(b);for(var d=0;d<a.l...
function z (line 222) | function z(a){return Array.prototype.slice.call(a,0)}
function A (line 222) | function A(a,b,c){for(var d=[],e=[],f=0;f<a.length;){var g=b?a[f][b]:a[f...
function B (line 222) | function B(a,b){for(var c,f,g=b[0].toUpperCase()+b.slice(1),h=0;h<e.leng...
function D (line 222) | function D(){return C++}
function E (line 222) | function E(a){var b=a.ownerDocument;return b.defaultView||b.parentWindow}
function ab (line 222) | function ab(a,b){var c=this;this.manager=a,this.callback=b,this.element=...
function bb (line 222) | function bb(a){var b,c=a.options.inputClass;return b=c?c:H?wb:I?Eb:G?Gb:...
function cb (line 222) | function cb(a,b,c){var d=c.pointers.length,e=c.changedPointers.length,f=...
function db (line 222) | function db(a,b){var c=a.session,d=b.pointers,e=d.length;c.firstInput||(...
function eb (line 222) | function eb(a,b){var c=b.center,d=a.offsetDelta||{},e=a.prevDelta||{},f=...
function fb (line 222) | function fb(a,b){var f,g,h,j,c=a.lastInterval||b,e=b.timeStamp-c.timeSta...
function gb (line 222) | function gb(a){for(var b=[],c=0;c<a.pointers.length;)b[c]={clientX:h(a.p...
function hb (line 222) | function hb(a){var b=a.length;if(1===b)return{x:h(a[0].clientX),y:h(a[0]...
function ib (line 222) | function ib(a,b,c){return{x:b/a||0,y:c/a||0}}
function jb (line 222) | function jb(a,b){return a===b?S:i(a)>=i(b)?a>0?T:U:b>0?V:W}
function kb (line 222) | function kb(a,b,c){c||(c=$);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];retu...
function lb (line 222) | function lb(a,b,c){c||(c=$);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];retu...
function mb (line 222) | function mb(a,b){return lb(b[1],b[0],_)-lb(a[1],a[0],_)}
function nb (line 222) | function nb(a,b){return kb(b[0],b[1],_)/kb(a[0],a[1],_)}
function rb (line 222) | function rb(){this.evEl=pb,this.evWin=qb,this.allow=!0,this.pressed=!1,a...
function wb (line 222) | function wb(){this.evEl=ub,this.evWin=vb,ab.apply(this,arguments),this.s...
function Ab (line 222) | function Ab(){this.evTarget=yb,this.evWin=zb,this.started=!1,ab.apply(th...
function Bb (line 222) | function Bb(a,b){var c=z(a.touches),d=z(a.changedTouches);return b&(Q|R)...
function Eb (line 222) | function Eb(){this.evTarget=Db,this.targetIds={},ab.apply(this,arguments)}
function Fb (line 222) | function Fb(a,b){var c=z(a.touches),d=this.targetIds;if(b&(O|P)&&1===c.l...
function Gb (line 222) | function Gb(){ab.apply(this,arguments);var a=q(this.handler,this);this.t...
function Pb (line 222) | function Pb(a,b){this.manager=a,this.set(b)}
function Qb (line 222) | function Qb(a){if(w(a,Mb))return Mb;var b=w(a,Nb),c=w(a,Ob);return b&&c?...
function Yb (line 222) | function Yb(a){this.id=D(),this.manager=null,this.options=o(a||{},this.d...
function Zb (line 222) | function Zb(a){return a&Wb?"cancel":a&Ub?"end":a&Tb?"move":a&Sb?"start":""}
function $b (line 222) | function $b(a){return a==W?"down":a==V?"up":a==T?"left":a==U?"right":""}
function _b (line 222) | function _b(a,b){var c=b.manager;return c?c.get(a):a}
function ac (line 222) | function ac(){Yb.apply(this,arguments)}
function bc (line 222) | function bc(){ac.apply(this,arguments),this.pX=null,this.pY=null}
function cc (line 222) | function cc(){ac.apply(this,arguments)}
function dc (line 222) | function dc(){Yb.apply(this,arguments),this._timer=null,this._input=null}
function ec (line 222) | function ec(){ac.apply(this,arguments)}
function fc (line 222) | function fc(){ac.apply(this,arguments)}
function gc (line 222) | function gc(){Yb.apply(this,arguments),this.pTime=!1,this.pCenter=!1,thi...
function hc (line 222) | function hc(a,b){return b=b||{},b.recognizers=s(b.recognizers,hc.default...
function kc (line 222) | function kc(a,b){b=b||{},this.options=o(b,hc.defaults),this.options.inpu...
function lc (line 222) | function lc(a,b){var c=a.element;m(a.options.cssProps,function(a,d){c.st...
function mc (line 222) | function mc(a,c){var d=b.createEvent("Event");d.initEvent(a,!0,!0),d.ges...
function d (line 222) | function d(d){b.manager.emit(b.options.event+(d?Zb(c):""),a)}
function hammerify (line 231) | function hammerify(el, options) {
function s4 (line 267) | function s4() {
function accordionOpen (line 327) | function accordionOpen(object) {
function expandableOpen (line 356) | function expandableOpen(object) {
function isChildrenOfPanelHeader (line 376) | function isChildrenOfPanelHeader(object) {
function getPanelHeader (line 388) | function getPanelHeader(object) {
function updateOptions (line 464) | function updateOptions() {
function placeDropdown (line 490) | function placeDropdown(eventType) {
function hideDropdown (line 580) | function hideDropdown() {
function returnToOriginal (line 1029) | function returnToOriginal() {
function updateParallax (line 1119) | function updateParallax(initial) {
function isWindow (line 1515) | function isWindow(obj) {
function getWindow (line 1519) | function getWindow(elem) {
function offset (line 1523) | function offset(elem) {
function convertStyle (line 1540) | function convertStyle(obj) {
function getWavesEffectElement (line 1751) | function getWavesEffectElement(e) {
function showEffect (line 1776) | function showEffect(e) {
function createToast (line 1898) | function createToast(html) {
function removeMenu (line 2045) | function removeMenu(restoreNav) {
function findElements (line 2323) | function findElements(top, right, bottom, left) {
function onScroll (line 2350) | function onScroll() {
function onWinSize (line 2392) | function onWinSize() {
function throttle (line 2418) | function throttle(func, wait, options) {
function textareaAutoResize (line 2674) | function textareaAutoResize($textarea) {
function toggleEntryFromArray (line 3115) | function toggleEntryFromArray(entriesArray, entryIndex, select) {
function setValueToInput (line 3134) | function setValueToInput(entriesArray, select) {
function captionTransition (line 3177) | function captionTransition(caption, duration) {
function moveToSlide (line 3190) | function moveToSlide(index) {
function removePinClasses (line 3526) | function removePinClasses(object) {
function updateElements (line 3532) | function updateElements(objects, scrolled) {
function PickerConstructor (line 3887) | function PickerConstructor( ELEMENT, NAME, COMPONENT, OPTIONS ) {
function isUsingDefaultTheme (line 4723) | function isUsingDefaultTheme( element ) {
function getScrollbarWidth (line 4747) | function getScrollbarWidth() {
function aria (line 4935) | function aria(element, attribute, value) {
function ariaSet (line 4945) | function ariaSet(element, attribute, value) {
function ariaAttr (line 4951) | function ariaAttr(attribute, data) {
function getActiveElement (line 4965) | function getActiveElement() {
function DatePicker (line 5013) | function DatePicker( picker, settings ) {
function getWordLengthFromCollection (line 5623) | function getWordLengthFromCollection( string, collection, dateObject ) {
function getFirstWordLength (line 5638) | function getFirstWordLength( string ) {
function updateCounter (line 6428) | function updateCounter(){
function addCounterElement (line 6439) | function addCounterElement($input){
function removeCounterElement (line 6449) | function removeCounterElement(){
function addInputStyle (line 6453) | function addInputStyle(isValidLength, $input){
function setupEvents (line 6518) | function setupEvents() {
function xpos (line 6530) | function xpos(e) {
function ypos (line 6540) | function ypos(e) {
function wrap (line 6550) | function wrap(x) {
function scroll (line 6554) | function scroll(x) {
function track (line 6627) | function track() {
function autoScroll (line 6640) | function autoScroll() {
function click (line 6655) | function click(e) {
function tap (line 6684) | function tap(e) {
function drag (line 6699) | function drag(e) {
function release (line 6734) | function release(e) {
FILE: themes/default/public/js/materialize.min.js
function b (line 1) | function b(a){var b=a.length,d=c.type(a);return"function"===d||c.isWindo...
function f (line 1) | function f(a,c){var d=c||[];return null!=a&&(b(Object(a))?!function(a,b)...
function a (line 1) | function a(){for(var a=this.offsetParent||document;a&&"html"===!a.nodeTy...
function e (line 1) | function e(a){for(var b=-1,c=a?a.length:0,d=[];++b<c;){var e=a[b];e&&d.p...
function f (line 1) | function f(a){return p.isWrapped(a)?a=[].slice.call(a):p.isNode(a)&&(a=[...
function g (line 1) | function g(a){var b=m.data(a,"velocity");return null===b?d:b}
function h (line 1) | function h(a){return function(b){return Math.round(b*a)*(1/a)}}
function i (line 1) | function i(a,c,d,e){function f(a,b){return 1-3*b+3*a}function g(a,b){ret...
function j (line 1) | function j(a,b){var c=a;return p.isString(a)?t.Easings[a]||(c=!1):c=p.is...
function k (line 1) | function k(a){if(a){var b=(new Date).getTime(),c=t.State.calls.length;c>...
function l (line 1) | function l(a,b){if(!t.State.calls[a])return!1;for(var c=t.State.calls[a]...
function a (line 1) | function a(a){return-a.tension*a.x-a.friction*a.v}
function b (line 1) | function b(b,c,d){var e={x:b.x+d.dx*c,v:b.v+d.dv*c,tension:b.tension,fri...
function c (line 1) | function c(c,d){var e={dx:c.v,dv:a(c)},f=b(c,.5*d,e),g=b(c,.5*d,f),h=b(c...
function h (line 1) | function h(a,c){function e(){j&&v.setPropertyValue(a,"display","none")}v...
function b (line 1) | function b(b){return parseFloat(v.getPropertyValue(a,b))}
function a (line 1) | function a(){return h?B.promise||null:i}
function e (line 1) | function e(){function a(a){function l(a,b){var c=d,e=d,g=d;return p.isAr...
function e (line 2) | function e(a,b,c){return setTimeout(k(a,c),b)}
function f (line 2) | function f(a,b,c){return Array.isArray(a)?(g(a,c[b],c),!0):!1}
function g (line 2) | function g(a,b,c){var e;if(a)if(a.forEach)a.forEach(b,c);else if(a.lengt...
function h (line 2) | function h(a,b,c){for(var e=Object.keys(b),f=0;f<e.length;)(!c||c&&a[e[f...
function i (line 2) | function i(a,b){return h(a,b,!0)}
function j (line 2) | function j(a,b,c){var d,e=b.prototype;d=a.prototype=Object.create(e),d.c...
function k (line 2) | function k(a,b){return function(){return a.apply(b,arguments)}}
function l (line 2) | function l(a,b){return typeof a==ka?a.apply(b?b[0]||d:d,b):a}
function m (line 2) | function m(a,b){return a===d?b:a}
function n (line 2) | function n(a,b,c){g(r(b),function(b){a.addEventListener(b,c,!1)})}
function o (line 2) | function o(a,b,c){g(r(b),function(b){a.removeEventListener(b,c,!1)})}
function p (line 2) | function p(a,b){for(;a;){if(a==b)return!0;a=a.parentNode}return!1}
function q (line 2) | function q(a,b){return a.indexOf(b)>-1}
function r (line 2) | function r(a){return a.trim().split(/\s+/g)}
function s (line 2) | function s(a,b,c){if(a.indexOf&&!c)return a.indexOf(b);for(var d=0;d<a.l...
function t (line 2) | function t(a){return Array.prototype.slice.call(a,0)}
function u (line 2) | function u(a,b,c){for(var d=[],e=[],f=0;f<a.length;){var g=b?a[f][b]:a[f...
function v (line 2) | function v(a,b){for(var c,e,f=b[0].toUpperCase()+b.slice(1),g=0;g<ia.len...
function w (line 2) | function w(){return oa++}
function x (line 2) | function x(a){var b=a.ownerDocument;return b.defaultView||b.parentWindow}
function y (line 2) | function y(a,b){var c=this;this.manager=a,this.callback=b,this.element=a...
function z (line 2) | function z(a){var b,c=a.options.inputClass;return new(b=c?c:ra?N:sa?Q:qa...
function A (line 2) | function A(a,b,c){var d=c.pointers.length,e=c.changedPointers.length,f=b...
function B (line 2) | function B(a,b){var c=a.session,d=b.pointers,e=d.length;c.firstInput||(c...
function C (line 2) | function C(a,b){var c=b.center,d=a.offsetDelta||{},e=a.prevDelta||{},f=a...
function D (line 2) | function D(a,b){var c,e,f,g,h=a.lastInterval||b,i=b.timeStamp-h.timeStam...
function E (line 2) | function E(a){for(var b=[],c=0;c<a.pointers.length;)b[c]={clientX:la(a.p...
function F (line 2) | function F(a){var b=a.length;if(1===b)return{x:la(a[0].clientX),y:la(a[0...
function G (line 2) | function G(a,b,c){return{x:b/a||0,y:c/a||0}}
function H (line 2) | function H(a,b){return a===b?Ca:ma(a)>=ma(b)?a>0?Da:Ea:b>0?Fa:Ga}
function I (line 2) | function I(a,b,c){c||(c=Ka);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];retu...
function J (line 2) | function J(a,b,c){c||(c=Ka);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];retu...
function K (line 2) | function K(a,b){return J(b[1],b[0],La)-J(a[1],a[0],La)}
function L (line 2) | function L(a,b){return I(b[0],b[1],La)/I(a[0],a[1],La)}
function M (line 2) | function M(){this.evEl=Na,this.evWin=Oa,this.allow=!0,this.pressed=!1,y....
function N (line 2) | function N(){this.evEl=Ra,this.evWin=Sa,y.apply(this,arguments),this.sto...
function O (line 2) | function O(){this.evTarget=Ua,this.evWin=Va,this.started=!1,y.apply(this...
function P (line 2) | function P(a,b){var c=t(a.touches),d=t(a.changedTouches);return b&(Aa|Ba...
function Q (line 2) | function Q(){this.evTarget=Xa,this.targetIds={},y.apply(this,arguments)}
function R (line 2) | function R(a,b){var c=t(a.touches),d=this.targetIds;if(b&(ya|za)&&1===c....
function S (line 2) | function S(){y.apply(this,arguments);var a=k(this.handler,this);this.tou...
function T (line 2) | function T(a,b){this.manager=a,this.set(b)}
function U (line 2) | function U(a){if(q(a,bb))return bb;var b=q(a,cb),c=q(a,db);return b&&c?c...
function V (line 2) | function V(a){this.id=w(),this.manager=null,this.options=i(a||{},this.de...
function W (line 2) | function W(a){return a&jb?"cancel":a&hb?"end":a&gb?"move":a&fb?"start":""}
function X (line 2) | function X(a){return a==Ga?"down":a==Fa?"up":a==Da?"left":a==Ea?"right":""}
function Y (line 2) | function Y(a,b){var c=b.manager;return c?c.get(a):a}
function Z (line 2) | function Z(){V.apply(this,arguments)}
function $ (line 2) | function $(){Z.apply(this,arguments),this.pX=null,this.pY=null}
function _ (line 2) | function _(){Z.apply(this,arguments)}
function aa (line 2) | function aa(){V.apply(this,arguments),this._timer=null,this._input=null}
function ba (line 2) | function ba(){Z.apply(this,arguments)}
function ca (line 2) | function ca(){Z.apply(this,arguments)}
function da (line 2) | function da(){V.apply(this,arguments),this.pTime=!1,this.pCenter=!1,this...
function ea (line 2) | function ea(a,b){return b=b||{},b.recognizers=m(b.recognizers,ea.default...
function fa (line 2) | function fa(a,b){b=b||{},this.options=i(b,ea.defaults),this.options.inpu...
function ga (line 2) | function ga(a,b){var c=a.element;g(a.options.cssProps,function(a,d){c.st...
function ha (line 2) | function ha(a,c){var d=b.createEvent("Event");d.initEvent(a,!0,!0),d.ges...
function b (line 2) | function b(b){c.manager.emit(c.options.event+(b?W(d):""),a)}
function c (line 2) | function c(c,d){var e=a(c);e.data("hammer")||e.data("hammer",new b(e[0],...
function a (line 2) | function a(){return Math.floor(65536*(1+Math.random())).toString(16).sub...
function c (line 2) | function c(b){h=g.find("> li > .collapsible-header"),b.hasClass("active"...
function d (line 2) | function d(b){b.hasClass("active")?b.parent().addClass("active"):b.paren...
function e (line 2) | function e(a){var b=f(a);return b.length>0}
function f (line 2) | function f(a){return a.closest("li > .collapsible-header")}
function d (line 2) | function d(){void 0!==g.data("induration")&&(h.inDuration=g.data("inDura...
function e (line 2) | function e(b){"focus"===b&&(i=!0),d(),j.addClass("active"),g.addClass("a...
function f (line 2) | function f(){i=!1,j.fadeOut(h.outDuration),j.removeClass("active"),g.rem...
function b (line 3) | function b(){f=!1;var b=i.parent(".material-placeholder"),d=(window.inne...
function d (line 3) | function d(c){var d;d=601>b?e.height()>0?e.height():e.children("img").he...
function b (line 3) | function b(a){return null!==a&&a===a.window}
function c (line 3) | function c(a){return b(a)?a:9===a.nodeType&&a.defaultView}
function d (line 3) | function d(a){var b,d,e={top:0,left:0},f=a&&a.ownerDocument;return b=f.d...
function e (line 3) | function e(a){var b="";for(var c in a)a.hasOwnProperty(c)&&(b+=c+":"+a[c...
function f (line 3) | function f(a){if(k.allowEvent(a)===!1)return null;for(var b=null,c=a.tar...
function g (line 3) | function g(b){var c=f(b);null!==c&&(j.show(b,c),"ontouchstart"in a&&(c.a...
function e (line 3) | function e(a){var b=document.createElement("div");if(b.classList.add("to...
function c (line 3) | function c(c){g=!1,h=!1,a("body").css("overflow",""),a("#sidenav-overlay...
function b (line 3) | function b(b,c,d,e){var f=a();return a.each(g,function(a,g){if(g.height(...
function c (line 3) | function c(){++j;var c=f.scrollTop(),d=f.scrollLeft(),e=d+f.width(),g=c+...
function d (line 3) | function d(){f.trigger("scrollSpy:winSize")}
function e (line 3) | function e(a,b,c){var d,e,f,g=null,h=0;c||(c={});var i=function(){h=c.le...
function b (line 3) | function b(b){var c=b.css("font-family"),e=b.css("font-size");e&&d.css("...
function c (line 3) | function c(a,b,c){var e=a.indexOf(b),f=-1===e;return f?a.push(b):a.splic...
function d (line 3) | function d(a,b){for(var c="",d=0,e=a.length;e>d;d++){var f=b.find("optio...
function c (line 3) | function c(a,b){a.hasClass("center-align")?a.velocity({opacity:0,transla...
function d (line 3) | function d(a){a>=j.length?a=0:0>a&&(a=j.length-1),k=i.find(".active").in...
function c (line 4) | function c(a){a.removeClass("pin-top"),a.removeClass("pinned"),a.removeC...
function d (line 4) | function d(d,e){d.each(function(){b.top<=e&&b.bottom>=e&&!a(this).hasCla...
function b (line 4) | function b(f,g,i,l){function m(){return b._.node("div",b._.node("div",b....
function c (line 4) | function c(a){var b,c="position";return a.currentStyle?b=a.currentStyle[...
function d (line 4) | function d(){if(k.height()<=i.height())return 0;var b=a('<div style="vis...
function e (line 4) | function e(b,c,d){if(a.isPlainObject(c))for(var e in c)f(b,e,c[e]);else ...
function f (line 4) | function f(a,b,c){a.setAttribute(("role"==b?"":"aria-")+b,c)}
function g (line 4) | function g(b,c){a.isPlainObject(b)||(b={attribute:c}),c="";for(var d in ...
function h (line 4) | function h(){try{return document.activeElement}catch(a){}}
function c (line 4) | function c(a,b){var c=this,d=a.$node[0],e=d.value,f=a.$node.data("value"...
function a (line 4) | function a(a,b,c){var d=a.match(/\w+/)[0];return c.mm||c.m||(c.m=b.index...
function b (line 4) | function b(a){return a.match(/\w+/)[0].length}
function b (line 4) | function b(){var b=+a(this).attr("length"),c=+a(this).val().length,d=b>=...
function c (line 4) | function c(b){var c=a("<span/>").addClass("character-counter").css("floa...
function d (line 4) | function d(){a(this).parent().find('span[class="character-counter"]').ht...
function e (line 4) | function e(a,b){var c=b.hasClass("invalid");a&&c?b.removeClass("invalid"...
function c (line 4) | function c(){"undefined"!=typeof window.ontouchstart&&(F[0].addEventList...
function d (line 4) | function d(a){return a.targetTouches&&a.targetTouches.length>=1?a.target...
function e (line 4) | function e(a){return a.targetTouches&&a.targetTouches.length>=1?a.target...
function f (line 4) | function f(a){return a>=s?a%s:0>a?f(s+a%s):a}
function g (line 4) | function g(a){var c,d,e,g,h,i,j;for(o="number"==typeof a?a:o,p=Math.floo...
function h (line 5) | function h(){var a,b,c,d;a=Date.now(),b=a-B,B=a,c=o-A,A=o,d=1e3*c/(1+b),...
function i (line 5) | function i(){var a,c;v&&(a=Date.now()-B,c=v*Math.exp(-a/b.time_constant)...
function j (line 5) | function j(c){if(D)return c.preventDefault(),c.stopPropagation(),!1;if(!...
function k (line 5) | function k(a){q=!0,D=!1,E=!1,t=d(a),u=e(a),x=v=0,A=o,B=Date.now(),clearI...
function l (line 5) | function l(a){var b,c,f;if(q)if(b=d(a),y=e(a),c=t-b,f=Math.abs(u-y),30>f...
function m (line 5) | function m(a){return q=!1,clearInterval(C),w=o,(x>10||-10>x)&&(v=.9*x,w=...
FILE: themes/default/public/js/sjcl.js
function t (line 6) | function t(a,b,c){if(4!==b.length)throw new sjcl.exception.invalid("inva...
function a (line 19) | function a(a){return 0x100000000*(a-Math.floor(a))|0}
function u (line 21) | function u(a,b){var c,d,e,f=a.F,g=a.b,h=f[0],k=f[1],l=f[2],n=f[3],m=f[4]...
function A (line 48) | function A(a,b){var c,d=sjcl.random.K[a],e=[];for(c in d)d.hasOwnPropert...
function C (line 48) | function C(a,b){"undefined"!==typeof window&&window.performance&&"functi...
function y (line 48) | function y(a){a.b=z(a).concat(z(a));a.L=new sjcl.cipher.aes(a.b)}
function z (line 48) | function z(a){for(var b=0;4>b&&(a.h[b]=a.h[b]+1|0,!a.h[b]);b++);return a...
function B (line 49) | function B(a,b){return function(){b.apply(a,arguments)}}
FILE: utilities/migrations/mysql.sql
type files (line 2) | CREATE TABLE IF NOT EXISTS files (
type slices (line 21) | CREATE TABLE IF NOT EXISTS slices (
type invitations (line 35) | CREATE TABLE IF NOT EXISTS invitations (
FILE: utilities/migrations/pg.sql
type files (line 2) | CREATE TABLE IF NOT EXISTS files (
type slices (line 20) | CREATE TABLE IF NOT EXISTS slices (
type invitations (line 38) | CREATE TABLE IF NOT EXISTS invitations (
FILE: utilities/migrations/sqlite.sql
type files (line 2) | CREATE TABLE IF NOT EXISTS files (
type slices (line 19) | CREATE TABLE IF NOT EXISTS slices (
type slices_idx (line 25) | CREATE INDEX IF NOT EXISTS slices_idx ON slices(short)
type files_backup (line 34) | CREATE TABLE files_backup (
type files_backup (line 59) | CREATE TABLE files_backup (
type invitations (line 82) | CREATE TABLE IF NOT EXISTS invitations (
Condensed preview — 142 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,921K chars).
[
{
"path": ".gitignore",
"chars": 152,
"preview": "local/*\nfiles/*\ncover_db/*\n*.conf\n*.db\n*.db-shm\n*.db-wal\n*.bak\n*.swp\nscript/*.pid\nstop-upload\n.zanata-cache/\nthemes/*\n!t"
},
{
"path": ".gitlab-ci.yml",
"chars": 3641,
"preview": "image: hatsoftwares/lufi-test-ci:bullseye\nstages:\n - create_release\n - publish_changelog\n - pouet_it\n - carton\n - c"
},
{
"path": ".provision/README.md",
"chars": 363,
"preview": "## ansible-role-lufi\n\nAn ansible role deploy the application on host machine(Ubuntu 20.04)\n\n## terraform-aws-lufi\n\nA ter"
},
{
"path": ".provision/ansible-role-lufi/README.md",
"chars": 1491,
"preview": "Ansible-Role-Lufi\n=========\nThis role installs the and configures Lufi on Debian/Ubuntu servers with nginx web server co"
},
{
"path": ".provision/ansible-role-lufi/defaults/main.yml",
"chars": 67,
"preview": "---\n# defaults file for roles/servers\n\nrobots_text: /var/www/html/\n"
},
{
"path": ".provision/ansible-role-lufi/files/cronjob",
"chars": 209,
"preview": "#Path of the script\nPATH=/var/www/lufi\n\ncarton exec script/lufi cron cleanbdd --mode production\ncarton exec script/lufi "
},
{
"path": ".provision/ansible-role-lufi/files/robots.txt",
"chars": 90,
"preview": "User-agent: *\nAllow: /$\nAllow: /js/\nAllow: /css/\nAllow: /font/\nAllow: /img/\nDisallow: /r/\n"
},
{
"path": ".provision/ansible-role-lufi/handlers/main.yml",
"chars": 99,
"preview": "---\n# handlers file for roles/servers\n\n- name: restart nginx\n service: name=nginx state=restarted\n"
},
{
"path": ".provision/ansible-role-lufi/tasks/apprun.yml",
"chars": 726,
"preview": "#apprun.yml\n---\n - name: This command will install the postgress module\n ansible.builtin.shell:\n cmd: car"
},
{
"path": ".provision/ansible-role-lufi/tasks/cron.yml",
"chars": 823,
"preview": "#cron.yml\n---\n - name: Copy the cronjob file\n ansible.builtin.copy:\n src: ../files/cronjob\n dest: /etc/cro"
},
{
"path": ".provision/ansible-role-lufi/tasks/dependencies.yml",
"chars": 459,
"preview": "#dependencies.yml\n--- \n - name: Install Dependencies\n ansible.builtin.apt:\n name:\n - nginx\n "
},
{
"path": ".provision/ansible-role-lufi/tasks/gitclone.yml",
"chars": 530,
"preview": "#gitclone\n---\n\n- name: clone the repository\n ansible.builtin.git:\n repo: 'https://framagit.org/fiat-tux/hat-software"
},
{
"path": ".provision/ansible-role-lufi/tasks/main.yml",
"chars": 130,
"preview": "---\n# tasks file for roles/servers\n\n- include: dependencies.yml\n- include: gitclone.yml\n- include: apprun.yml\n- include:"
},
{
"path": ".provision/ansible-role-lufi/templates/lufi.conf.j2",
"chars": 15951,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\n{\n ####################\n # Hypnotoad settings\n ###################"
},
{
"path": ".provision/ansible-role-lufi/templates/update.sh",
"chars": 218,
"preview": "# install perl dependencies\napt install liblwp-protocol-https-perl carton\nsleep 5\ngit pull\nsleep 5\ncarton install --depl"
},
{
"path": ".provision/ansible-role-lufi/vars/main.yml",
"chars": 198,
"preview": "---\n# vars file for roles/servers\n\nlufi_owner: \"www-data\"\n\nlufi_group: \"www-data\"\n\napp_dir: \"\"\n\n_contact: \"contact.examp"
},
{
"path": ".provision/terraform-aws-lufi/README.md",
"chars": 2964,
"preview": "# Terraform-AWS-Lufi\n\n This terraform plan create the resourcess of EC2 instance\n\n## Terraform Variables\n Edit the `vars"
},
{
"path": ".provision/terraform-aws-lufi/lufi_startup.sh",
"chars": 2772,
"preview": "#!/usr/bin/env bash\nset -euo pipefail\n\necho \"**********************************************************************\"\nech"
},
{
"path": ".provision/terraform-aws-lufi/main.tf",
"chars": 2929,
"preview": "locals {\n user_data_vars = {\n user = var.lufi_owner\n group = var.lufi_group\n directory = var.app_dir\n conta"
},
{
"path": ".provision/terraform-aws-lufi/output.tf",
"chars": 166,
"preview": "output \"public_ip\" {\n value = \"${aws_instance.ec2_instance.public_ip}\"\n}\n\noutput \"App_running_at\" {\n value = \"http://$"
},
{
"path": ".provision/terraform-aws-lufi/provider.tf",
"chars": 242,
"preview": "terraform {\n required_providers {\n aws = {\n source = \"hashicorp/aws\"\n version = \"~> 3.0\"\n }\n }\n}\n\npro"
},
{
"path": ".provision/terraform-aws-lufi/vars.tf",
"chars": 806,
"preview": "variable \"aws_region\" {\n default = \"aws_region\"\n}\nvariable \"vpc_cidr\" {\n default = \"cidr_value\"\n}\nvariable \"public"
},
{
"path": "AUTHORS.md",
"chars": 1267,
"preview": "# Lufi's authors\n\n## Main developer 🤪\n\n- Luc Didry, aka Sky (<https://fiat-tux.fr>), core developer, [@framasky@framapia"
},
{
"path": "CHANGELOG",
"chars": 7112,
"preview": "Revision history for Lufi\n\n0.08.0 ????-??-??\n\n0.07.3 2025-11-15\n\t- 🔖 — Fix 0.07.2 release (tag on wrong commit)\n\n0.07.2 "
},
{
"path": "CONTRIBUTING.md",
"chars": 99,
"preview": "# CONTRIBUTING\n\nPlease, read about contributing at <https://framagit.org/luc/lufi/wikis/contribute>"
},
{
"path": "LICENSE",
"chars": 34520,
"preview": " GNU AFFERO GENERAL PUBLIC LICENSE\n Version 3, 19 November 2007\n\n Copyright (C)"
},
{
"path": "Makefile",
"chars": 1503,
"preview": "EXTRACTDIR ?= -D lib -D themes/default/templates\nPOT ?= themes/default/lib/Lufi/I18N/lufi.pot\nENPO ?= themes/default/lib"
},
{
"path": "README.md",
"chars": 4025,
"preview": "# Lufi\n\n## What does Lufi mean?\n\nLufi means Let's Upload that FIle. It's a E2E encrypted file sharing software.\n\n## Whic"
},
{
"path": "cpanfile",
"chars": 2564,
"preview": "requires 'inc::Module::Install';\nrequires 'Mojolicious', '>= 8.05';\nrequires 'Mojolicious::Plugin::DebugDumperHelper';\nr"
},
{
"path": "cpanfile.snapshot",
"chars": 66834,
"preview": "# carton snapshot format: version 1.0\nDISTRIBUTIONS\n Apache-Htpasswd-1.9\n pathname: K/KM/KMELTZ/Apache-Htpasswd-1.9."
},
{
"path": "lib/Date/Language/Occitan.pm",
"chars": 957,
"preview": "##\n## Occitan tables, contributed by Quentn PAGÈS\n##\n\npackage Date::Language::Occitan;\n\nuse Date::Language ();\nuse vars "
},
{
"path": "lib/Lufi/Command/copyFilesToSwift.pm",
"chars": 2739,
"preview": "package Lufi::Command::copyFilesToSwift;\nuse Mojo::Base 'Mojolicious::Command';\nuse File::Spec;\nuse Term::ProgressBar;\n\n"
},
{
"path": "lib/Lufi/Command/cron/cleanbdd.pm",
"chars": 1079,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::Command::cron::cleanbdd;\nuse Mojo::Base 'Mojolicious::Command"
},
{
"path": "lib/Lufi/Command/cron/cleanfiles.pm",
"chars": 1482,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::Command::cron::cleanfiles;\nuse Mojo::Base 'Mojolicious::Comma"
},
{
"path": "lib/Lufi/Command/cron/watch.pm",
"chars": 2673,
"preview": "package Lufi::Command::cron::watch;\nuse Mojo::Base 'Mojolicious::Command';\nuse Filesys::DiskUsage qw/du/;\nuse Lufi::DB::"
},
{
"path": "lib/Lufi/Command/cron.pm",
"chars": 540,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::Command::cron;\nuse Mojo::Base 'Mojolicious::Commands';\n\nhas d"
},
{
"path": "lib/Lufi/Command/sqliteToOtherDB.pm",
"chars": 4100,
"preview": "package Lufi::Command::sqliteToOtherDB;\nuse Mojo::Base 'Mojolicious::Command';\nuse Lufi::DB::File;\nuse Lufi::DB::Slice;\n"
},
{
"path": "lib/Lufi/Command/theme.pm",
"chars": 3073,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::Command::theme;\nuse Mojo::Base 'Mojolicious::Commands';\nuse F"
},
{
"path": "lib/Lufi/Controller/Auth.pm",
"chars": 2093,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::Controller::Auth;\nuse Mojo::Base 'Mojolicious::Controller';\n\n"
},
{
"path": "lib/Lufi/Controller/Files.pm",
"chars": 22381,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::Controller::Files;\nuse Mojo::Base 'Mojolicious::Controller';\n"
},
{
"path": "lib/Lufi/Controller/Invitation.pm",
"chars": 12071,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::Controller::Invitation;\nuse Mojo::Base 'Mojolicious::Controll"
},
{
"path": "lib/Lufi/Controller/Mail.pm",
"chars": 3481,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::Controller::Mail;\nuse Mojo::Base 'Mojolicious::Controller';\nu"
},
{
"path": "lib/Lufi/Controller/Misc.pm",
"chars": 2610,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::Controller::Misc;\nuse Mojo::Base 'Mojolicious::Controller';\nu"
},
{
"path": "lib/Lufi/DB/File/Mysql.pm",
"chars": 191,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::DB::File::Mysql;\nuse Mojo::Base 'Lufi::DB::File';\n\nsub new {\n"
},
{
"path": "lib/Lufi/DB/File/Pg.pm",
"chars": 188,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::DB::File::Pg;\nuse Mojo::Base 'Lufi::DB::File';\n\nsub new {\n "
},
{
"path": "lib/Lufi/DB/File/SQLite.pm",
"chars": 235,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::DB::File::SQLite;\nuse Mojo::Base 'Lufi::DB::File';\n\nsub new {"
},
{
"path": "lib/Lufi/DB/File.pm",
"chars": 12804,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::DB::File;\nuse Mojo::Base -base;\nuse Mojo::File;\nuse Mojo::Col"
},
{
"path": "lib/Lufi/DB/Invitation/Mysql.pm",
"chars": 203,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::DB::Invitation::Mysql;\nuse Mojo::Base 'Lufi::DB::Invitation';"
},
{
"path": "lib/Lufi/DB/Invitation/Pg.pm",
"chars": 200,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::DB::Invitation::Pg;\nuse Mojo::Base 'Lufi::DB::Invitation';\n\ns"
},
{
"path": "lib/Lufi/DB/Invitation/SQLite.pm",
"chars": 247,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::DB::Invitation::SQLite;\nuse Mojo::Base 'Lufi::DB::Invitation'"
},
{
"path": "lib/Lufi/DB/Invitation.pm",
"chars": 8947,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::DB::Invitation;\nuse Mojo::Base -base;\nuse Mojo::File;\nuse Moj"
},
{
"path": "lib/Lufi/DB/Slice/Mysql.pm",
"chars": 237,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::DB::Slice::Mysql;\nuse Mojo::Base 'Lufi::DB::Slice';\n\nsub new "
},
{
"path": "lib/Lufi/DB/Slice/Pg.pm",
"chars": 234,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::DB::Slice::Pg;\nuse Mojo::Base 'Lufi::DB::Slice';\n\nsub new {\n "
},
{
"path": "lib/Lufi/DB/Slice/SQLite.pm",
"chars": 238,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::DB::Slice::SQLite;\nuse Mojo::Base 'Lufi::DB::Slice';\n\nsub new"
},
{
"path": "lib/Lufi/DB/Slice.pm",
"chars": 7397,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::DB::Slice;\nuse Mojo::Base -base;\nuse Encode 'encode';\nuse Fil"
},
{
"path": "lib/Lufi/DefaultConfig.pm",
"chars": 1048,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::DefaultConfig;\nrequire Exporter;\n@ISA = qw(Exporter);\n@EXPORT"
},
{
"path": "lib/Lufi/Plugin/Headers.pm",
"chars": 2010,
"preview": "package Lufi::Plugin::Headers;\nuse Mojo::Base 'Mojolicious::Plugin';\n\nsub register {\n my ($self, $app) = @_;\n\n # A"
},
{
"path": "lib/Lufi/Plugin/Helpers.pm",
"chars": 7377,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi::Plugin::Helpers;\nuse Mojo::Base 'Mojolicious::Plugin';\nuse Lu"
},
{
"path": "lib/Lufi.pm",
"chars": 7476,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lufi;\nuse Mojo::Base 'Mojolicious';\nuse Mojolicious::Sessions;\nuse "
},
{
"path": "lib/Mounter.pm",
"chars": 1117,
"preview": "package Mounter;\nuse Mojo::Base 'Mojolicious';\nuse FindBin qw($Bin);\nuse File::Spec qw(catfile);\nuse Lufi::DefaultConfig"
},
{
"path": "lufi.conf.template",
"chars": 17148,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\n{\n ####################\n # Hypnotoad settings\n ###################"
},
{
"path": "script/application",
"chars": 184,
"preview": "#!/usr/bin/env perl\n\nuse strict;\nuse warnings;\n\nuse lib 'lib';\n\n# Start command line interface for application\nrequire M"
},
{
"path": "script/lufi",
"chars": 232,
"preview": "#!/usr/bin/env perl\n\nuse strict;\nuse warnings;\n\nuse FindBin;\nBEGIN { unshift @INC, \"$FindBin::Bin/../lib\" }\n\n# Start com"
},
{
"path": "t/lufi.passwd",
"chars": 42,
"preview": "luc:$apr1$zG4UAKGa$FqSi4widrkVH/pT3qPawd.\n"
},
{
"path": "t/test.t",
"chars": 9323,
"preview": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\nuse Mojo::Base -strict;\nuse Mojo::File;\nuse Mojo::JSON qw(to_json from_json"
},
{
"path": "themes/default/lib/Lufi/I18N/ar.po",
"chars": 35252,
"preview": "# ButterflyOfFire <butterflyoffire@protonmail.com>, 2018. #zanata\n# ButterflyOfFire <butterflyoffire@protonmail.com>, 20"
},
{
"path": "themes/default/lib/Lufi/I18N/br.po",
"chars": 27786,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same "
},
{
"path": "themes/default/lib/Lufi/I18N/ca.po",
"chars": 33195,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same "
},
{
"path": "themes/default/lib/Lufi/I18N/co.po",
"chars": 37919,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same "
},
{
"path": "themes/default/lib/Lufi/I18N/de.po",
"chars": 38773,
"preview": "# frju365 <abld@abld.info>, 2018. #zanata\n# Armando <armando@noplanman.ch>, 2019. #zanata\n# Luc Didry <luc@framasoft.org"
},
{
"path": "themes/default/lib/Lufi/I18N/el.po",
"chars": 37158,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same "
},
{
"path": "themes/default/lib/Lufi/I18N/en.po",
"chars": 35135,
"preview": "# Luc Didry <luc@framasoft.org>, 2018. #zanata\n# Armando <armando@noplanman.ch>, 2019. #zanata\n# Luc Didry <luc@framasof"
},
{
"path": "themes/default/lib/Lufi/I18N/es.po",
"chars": 37811,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same "
},
{
"path": "themes/default/lib/Lufi/I18N/fa.po",
"chars": 26684,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same "
},
{
"path": "themes/default/lib/Lufi/I18N/fr.po",
"chars": 38143,
"preview": "# Lufi FR translation\n# Copyright (C) 2015 Luc Didry\n# This file is distributed under the same license as the Lufi packa"
},
{
"path": "themes/default/lib/Lufi/I18N/fr_FR.po",
"chars": 38824,
"preview": "# Lufi FR translation\n# Copyright (C) 2015 Luc Didry\n# This file is distributed under the same license as the Lufi packa"
},
{
"path": "themes/default/lib/Lufi/I18N/hr.po",
"chars": 35703,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same "
},
{
"path": "themes/default/lib/Lufi/I18N/it.po",
"chars": 37512,
"preview": "# Lufi IT translation\n# Copyright (C) 2015 Luc Didry\n# This file is distributed under the same license as the Lufi packa"
},
{
"path": "themes/default/lib/Lufi/I18N/ja_JP.po",
"chars": 31302,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same "
},
{
"path": "themes/default/lib/Lufi/I18N/lufi.pot",
"chars": 26008,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same "
},
{
"path": "themes/default/lib/Lufi/I18N/nl.po",
"chars": 31794,
"preview": "# Luc Didry <luc@framasoft.org>, 2018. #zanata\n# Luc Didry <luc@framasoft.org>, 2019. #zanata\nmsgid \"\"\nmsgstr \"\"\n\"Projec"
},
{
"path": "themes/default/lib/Lufi/I18N/oc.po",
"chars": 38333,
"preview": "# Lufi OC translation\n# Copyright (C) 2015 Luc Didry\n# This file is distributed under the same license as the Lufi packa"
},
{
"path": "themes/default/lib/Lufi/I18N/pl.po",
"chars": 36068,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same "
},
{
"path": "themes/default/lib/Lufi/I18N/pt.po",
"chars": 37989,
"preview": "# Lufi PT translation\n# Copyright (C) 2015 Luc Didry\n# This file is distributed under the same license as the Lufi packa"
},
{
"path": "themes/default/lib/Lufi/I18N/ru.po",
"chars": 35723,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same "
},
{
"path": "themes/default/lib/Lufi/I18N/sk.po",
"chars": 35808,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same "
},
{
"path": "themes/default/lib/Lufi/I18N/sv.po",
"chars": 35415,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same "
},
{
"path": "themes/default/lib/Lufi/I18N/zh_Hans.po",
"chars": 29463,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same "
},
{
"path": "themes/default/lib/Lufi/I18N/zh_Hant.po",
"chars": 29142,
"preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same "
},
{
"path": "themes/default/lib/Lufi/I18N.pm",
"chars": 238,
"preview": "package Lufi::I18N;\n\nuse base 'Locale::Maketext';\nuse File::Basename qw/dirname/;\nuse Locale::Maketext::Lexicon {\n _a"
},
{
"path": "themes/default/public/MATERIALIZE_LICENSE",
"chars": 1083,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2014-2015 Materialize\n\nPermission is hereby granted, free of charge, to any person "
},
{
"path": "themes/default/public/css/cover.css",
"chars": 2637,
"preview": "/*\n * Globals\n */\n\n/* Links */\na,\na:focus,\na:hover {\n color: #888;\n}\n\n/* Custom default button */\n.btn-default,\n.btn-de"
},
{
"path": "themes/default/public/css/lufi.css",
"chars": 34687,
"preview": "body {\n background-color: #ffffff;\n}\n#files {\n border: 2px dashed #BBB;\n border-radius: 5px;\n padding: 25px "
},
{
"path": "themes/default/public/css/materialize.css",
"chars": 189105,
"preview": ".materialize-red.lighten-5 {\n background-color: #fdeaeb !important;\n}\n\n.materialize-red-text.text-lighten-5 {\n color: "
},
{
"path": "themes/default/public/css/materialize.min.css",
"chars": 146941,
"preview": ".materialize-red.lighten-5{background-color:#fdeaeb !important}.materialize-red-text.text-lighten-5{color:#fdeaeb !impor"
},
{
"path": "themes/default/public/font/material-design-icons/LICENSE.txt",
"chars": 20164,
"preview": "https://github.com/google/material-design-icons/blob/master/LICENSE\nhttps://github.com/FezVrasta/bootstrap-material-desi"
},
{
"path": "themes/default/public/js/filesize.min.js",
"chars": 1970,
"preview": "/*\n 2018 Jason Mulligan <jason.mulligan@avoidwork.com>\n @version 3.6.1\n*/\n\"use strict\";!function(e){var i=/^(b|B)$/,t={i"
},
{
"path": "themes/default/public/js/filesize.min.js.map",
"chars": 2919,
"preview": "{\"version\":3,\"sources\":[\"filesize.js\"],\"names\":[\"global\",\"b\",\"symbol\",\"iec\",\"bits\",\"bytes\",\"jedec\",\"fullform\",\"filesize\""
},
{
"path": "themes/default/public/js/ie-detection.js",
"chars": 1073,
"preview": "function confirmExit() {\n console.log(i18n.confirmExit);\n return i18n.confirmExit;\n}\n\n// Is the browser IE?\nvar is"
},
{
"path": "themes/default/public/js/jquery-3.7.1.min.js",
"chars": 87533,
"preview": "/*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */\n!function(e,t){\"use strict\";\"ob"
},
{
"path": "themes/default/public/js/jquery-3.7.1.min.map",
"chars": 134767,
"preview": "{\"version\":3,\"sources\":[\"jquery-3.7.1.js\"],\"names\":[\"global\",\"factory\",\"module\",\"exports\",\"document\",\"w\",\"Error\",\"window"
},
{
"path": "themes/default/public/js/jszip.js",
"chars": 366220,
"preview": "/*!\n\nJSZip v3.2.1 - A JavaScript class for generating and reading zip files\n<http://stuartk.com/jszip>\n\n(c) 2009-2016 St"
},
{
"path": "themes/default/public/js/jszip.min.js",
"chars": 97436,
"preview": "/*!\n\nJSZip v3.2.1 - A JavaScript class for generating and reading zip files\n<http://stuartk.com/jszip>\n\n(c) 2009-2016 St"
},
{
"path": "themes/default/public/js/lufi-common.js",
"chars": 1284,
"preview": "// vim:set sw=4 ts=4 sts=4 ft=javascript expandtab:\n// Escape HTML chars\nvar entityMap = {\n \"&\": \"&\",\n \"<\": \"&"
},
{
"path": "themes/default/public/js/lufi-down.js",
"chars": 12026,
"preview": "// vim:set sw=4 ts=4 sts=4 ft=javascript expandtab:\n/*\n * Return the deciphering key stored in anchor part of the URL\n *"
},
{
"path": "themes/default/public/js/lufi-files.js",
"chars": 8959,
"preview": "// vim:set sw=4 ts=4 sts=4 ft=javascript expandtab:\n// Add item to localStorage\nfunction addItem(item) {\n var files ="
},
{
"path": "themes/default/public/js/lufi-list-invitations.js",
"chars": 6469,
"preview": "function invertSelection(e) {\n e.preventDefault();\n $('#myInvitations input[type=\"checkbox\"]').each(function () {\n"
},
{
"path": "themes/default/public/js/lufi-notifications.js",
"chars": 775,
"preview": "function notify(title, body) {\n if (!'Notification' in window || typeof(Notification) === 'undefined') {\n cons"
},
{
"path": "themes/default/public/js/lufi-up.js",
"chars": 26386,
"preview": "// vim:set sw=4 ts=4 sts=4 ft=javascript expandtab:\n\n// total file counter\nwindow.fc = 0;\n// Cancelled files indexes\nwin"
},
{
"path": "themes/default/public/js/materialize.js",
"chars": 277968,
"preview": "// Check for jQuery.\nif (typeof(jQuery) === 'undefined') {\n var jQuery = $ = require('jQuery');\n};/*\n * jQuery Easing v"
},
{
"path": "themes/default/public/js/materialize.min.js",
"chars": 130344,
"preview": "if(\"undefined\"==typeof jQuery)var jQuery=$=require(\"jQuery\");jQuery.easing.jswing=jQuery.easing.swing,jQuery.extend(jQue"
},
{
"path": "themes/default/public/js/sidenav.js",
"chars": 72,
"preview": "$(document).ready(function() {\n $(\".button-collapse\").sideNav();\n});\n"
},
{
"path": "themes/default/public/js/sjcl.js",
"chars": 25378,
"preview": "\"use strict\";var sjcl={cipher:{},hash:{},keyexchange:{},mode:{},misc:{},codec:{},exception:{corrupt:function(a){this.toS"
},
{
"path": "themes/default/templates/about.html.ep",
"chars": 2871,
"preview": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n<div class=\"text-left\">\n <h3><%= l('What is Lufi?') %></h3>\n <p"
},
{
"path": "themes/default/templates/delays.html.ep",
"chars": 2347,
"preview": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n% use Number::Bytes::Human qw(format_bytes);\n<div id=\"delays-info\" cl"
},
{
"path": "themes/default/templates/delete_file.html.ep",
"chars": 722,
"preview": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n% if (defined stash('msg')) {\n<div class=\"col s12\">\n <div class=\"c"
},
{
"path": "themes/default/templates/files.html.ep",
"chars": 1939,
"preview": "% # vim:set sts=4 sw=4 ts=4 ft=html.epl expandtab:\n\n<h2><%= l('My files') %></h2>\n<hr>\n\n\n<p>\n <%= l('Only the files s"
},
{
"path": "themes/default/templates/index.html.ep",
"chars": 7223,
"preview": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n% my %d = (\n% delay_0 => l('no time limit'),\n% delay_1 => l('"
},
{
"path": "themes/default/templates/invitations/exception.html.ep",
"chars": 675,
"preview": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n\n% if (stash('expired_or_deleted_invitation')) {\n <div class=\"col "
},
{
"path": "themes/default/templates/invitations/invite.html.ep",
"chars": 1884,
"preview": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n\n% if (scalar(@{$self->stash('fails')})) {\n <div class=\"col s12\">\n"
},
{
"path": "themes/default/templates/invitations/invite.mail.ep",
"chars": 484,
"preview": "% # vim:set sw=4 ts=4 sts=4 ft=mail.epl expandtab:\n% stash subject => l('%1 invites you to send him/her files', stash('l"
},
{
"path": "themes/default/templates/invitations/my_invitations.html.ep",
"chars": 3757,
"preview": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n% use Number::Bytes::Human qw(format_bytes);\n% my $lang = $self->get_"
},
{
"path": "themes/default/templates/invitations/notification_files_sent.mail.ep",
"chars": 804,
"preview": "% # vim:set sw=4 ts=4 sts=4 ft=mail.epl expandtab:\n% use Number::Bytes::Human qw(format_bytes);\n% my $lang = $self->get_"
},
{
"path": "themes/default/templates/layouts/default.html.ep",
"chars": 7069,
"preview": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n% my $lang = $self->languages;\n% $lang =~ s/-(.*)/_\\U$1/;\n<!DOCTYP"
},
{
"path": "themes/default/templates/login.html.ep",
"chars": 1122,
"preview": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n% if (defined stash('msg')) {\n<div class=\"col s12\">\n <div class=\"c"
},
{
"path": "themes/default/templates/logout.html.ep",
"chars": 615,
"preview": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n% if (defined stash('msg')) {\n<div class=\"col s12\">\n <div class=\"c"
},
{
"path": "themes/default/templates/mail.html.ep",
"chars": 2380,
"preview": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n<div class=\"row\">\n% if (defined(stash('msg'))) {\n <div class=\"col "
},
{
"path": "themes/default/templates/msg.html.ep",
"chars": 900,
"preview": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n\n<div class=\"row\">\n <div class=\"col s12\">\n% if (!defined(stash('f'"
},
{
"path": "themes/default/templates/partial/files.js.ep",
"chars": 1183,
"preview": "% # vim:set sts=4 sw=4 ts=4 ft=javascript expandtab:\n% if (defined($self->config('fixed_domain')) && $self->config('fixe"
},
{
"path": "themes/default/templates/partial/index.js.ep",
"chars": 1965,
"preview": "% # vim:set sts=4 sw=4 ts=4 ft=javascript expandtab:\n$(document).ready(function(){\n $('.modal-trigger').leanModal();\n"
},
{
"path": "themes/default/templates/partial/invitations.js.ep",
"chars": 834,
"preview": "% # vim:set sts=4 sw=4 ts=4 ft=javascript expandtab:\nvar i18n = {\n confirmDeleteInvit: '<%= l('Are you sure you want "
},
{
"path": "themes/default/templates/partial/layout.js.ep",
"chars": 145,
"preview": "% # vim:set sts=4 sw=4 ts=4 ft=javascript expandtab:\nvar langUrl = '<%= url_for('lang') %>';\nvar prefix = '<%= substr(c"
},
{
"path": "themes/default/templates/partial/mail.js.ep",
"chars": 2266,
"preview": "% # vim:set sts=4 sw=4 ts=4 ft=javascript expandtab:\nfunction findItem(name) {\n var files = localStorage.getItem(`${w"
},
{
"path": "themes/default/templates/partial/render.js.ep",
"chars": 1091,
"preview": "% # vim:set sts=4 sw=4 ts=4 ft=javascript expandtab:\nvar ws_url = '<%= url_for('download')->to_abs().stash('file') %>';\n"
},
{
"path": "themes/default/templates/render.html.ep",
"chars": 2347,
"preview": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n<div class=\"row valign-wrapper\">\n <div class=\"valign center col s1"
},
{
"path": "utilities/lufi.default",
"chars": 150,
"preview": "# LDIR is the path where you installed Lufi\n# It has to end with a final /\nLDIR=/var/www/lufi/\n\n# USER is the user who w"
},
{
"path": "utilities/lufi.init",
"chars": 4676,
"preview": "#!/bin/sh\n# vim: set ts=4 sw=4 sts=4 tw=0:\n# vim: set expandtab:\n\n### BEGIN INIT INFO\n# Provides: lufi\n# Requir"
},
{
"path": "utilities/lufi.service",
"chars": 496,
"preview": "[Unit]\nDescription=File hosting service with encryption\nDocumentation=https://framagit.org/luc/lufi\nRequires=network.tar"
},
{
"path": "utilities/migrations/mysql.sql",
"chars": 1839,
"preview": "-- 1 up\nCREATE TABLE IF NOT EXISTS files (\n short varchar(255) PRIMARY KEY,\n deleted b"
},
{
"path": "utilities/migrations/pg.sql",
"chars": 1937,
"preview": "-- 1 up\nCREATE TABLE IF NOT EXISTS files (\n short text PRIMARY KEY,\n deleted boolean d"
},
{
"path": "utilities/migrations/sqlite.sql",
"chars": 3440,
"preview": "-- 1 up\nCREATE TABLE IF NOT EXISTS files (\n short TEXT PRIMARY KEY,\n deleted I"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the ldidry/lufi GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 142 files (2.6 MB), approximately 694.4k tokens, and a symbol index with 673 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.