diff --git a/.gitignore b/.gitignore index 063129a..12fe3d8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,11 @@ CMakeCache.txt !.editorconfig !.gitignore !.github +!.gitkeep .venv -build* +build/* +build_debug/* +build_release/* cmake_install.cmake database.sqlite demo_* @@ -18,3 +21,6 @@ src/rust/Cargo.lock src/rust/target *.swp tmp* +web/_cache/* +web/_site/* +web/Gemfile.lock diff --git a/web/CODE_OF_CONDUCT.md b/web/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..d92b7c4 --- /dev/null +++ b/web/CODE_OF_CONDUCT.md @@ -0,0 +1,132 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +community@xw3.org. All complaints will be reviewed and investigated promptly and +fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/web/Gemfile b/web/Gemfile new file mode 100644 index 0000000..a3dbbf1 --- /dev/null +++ b/web/Gemfile @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem 'addressable' +gem 'colorator' +gem 'concurrent-ruby' +gem 'csv' +gem 'em-websocket' +gem 'i18n' +gem 'jekyll' +gem 'jekyll-admin' +gem 'jekyll-paginate' +gem 'jekyll-sass-converter' +gem 'jekyll-seo-tag' +gem 'jekyll-sitemap' +gem 'jekyll-toc' +gem 'jekyll-watch' +gem 'json' +gem 'kramdown' +gem 'kramdown-parser-gfm' +gem 'liquid' +gem 'listen' +gem 'mercenary' +gem 'nokogiri' +gem 'pathutil' +gem 'rack' +gem 'rackup' +gem 'rouge' +gem 'safe_yaml' +gem 'terminal-table' +gem 'webrick' + diff --git a/web/LICENSE b/web/LICENSE new file mode 100644 index 0000000..0c72923 --- /dev/null +++ b/web/LICENSE @@ -0,0 +1,13 @@ +Copyright 2024 Johannes Findeisen + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/web/Makefile b/web/Makefile new file mode 100644 index 0000000..c1c7dff --- /dev/null +++ b/web/Makefile @@ -0,0 +1,73 @@ +all: + make release + +build: + #wget -O ./handbook/handbook.md https://git.xw3.org/fun/fun/raw/branch/main/docs/handbook.md + bundle exec jekyll b --incremental + +clean: + rm -rf _site/* + +freshrelease: + make clean + make release + +freshreleaseraw: + make clean + make build + make sync + +freshrun: + make clean + make build + make minify + make run + +local: + make clean + make build + make minify + +localraw: + make clean + make build + +localrelease: + make local + make minify + +minify: + find ./_site -type f -name "*.html" -exec minify --html-keep-document-tags --html-keep-end-tags -o {} {} \; + find ./_site -type f -name "*.html" -exec sed -i 's/ \/>/>/g' {} + + #find ./_site -type f -name "*.html" -exec perl -0777 -pi -e 's/\n/ /g' {} + + find ./_site -type f -name "*.css" -exec minify --css-precision 0 -o {} {} \; + find ./_site -type f -name "*.xml" -exec minify -o {} {} \; + +release: + make build + make minify + make sync + +releaseraw: + make build + make sync + +run: + bundle exec jekyll s --incremental --drafts + +runclean: + make clean + bundle exec jekyll s --incremental --drafts + +runcleanreload: + make clean + bundle exec jekyll s --incremental --drafts --livereload + +runreload: + bundle exec jekyll s --incremental --drafts --livereload + +sync: + rsync -avr --delete --delete-excluded ./_site/ fun-lang.xyz:/var/www/fun-lang.xyz/www/htdocs/ + #ssh a.xw3.org 'cd /var/www/fun-lang.xyz/www/lib/ && git pull' + #ssh a.xw3.org 'cd /var/www/fun-lang.xyz/www/htdocs/cgi/bin/ && gcc index.c -o index' + diff --git a/web/README.md b/web/README.md new file mode 100644 index 0000000..fc894df --- /dev/null +++ b/web/README.md @@ -0,0 +1,10 @@ +# [fun-lang.xyz](https://fun-lang.xyz) + +The [Fun Programming Language Website](https://fun-lang.xyz). + +## Rules + +- No target="_blank" +- No line numbers in "pre" tags +- More to come... ;) + diff --git a/web/_cache/.gitkeep b/web/_cache/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/web/_config.yml b/web/_config.yml new file mode 100644 index 0000000..a4bbe02 --- /dev/null +++ b/web/_config.yml @@ -0,0 +1,115 @@ +document_root: /var/www/fun-lang.xyz/www/htdocs/ +data_dir: /var/www/fun-lang.xyz/www/htdocs/ +title: fun> +subtitle: The programming language that makes you have fun! +description: The programming language that makes you have fun! +keywords: + - fun + - static + - dynamic + - programming + - language + - c + - python + - scrpts + - repl + - type + - safety +author: Johannes Findeisen +email: hanez@fun-lang.xyz +baseurl: +url: https://fun-lang.xyz +url_short: fun-lang.xyz +lang: en +os: GNU/Linux +charset: utf-8 +libdir: /var/www/fun-lang.xyz/www/lib +license: CC BY-NC-SA +license_name: Attribution-NonCommercial-ShareAlike 4.0 International +license_url: https://creativecommons.org/licenses/by-nc-sa/4.0/ + +mastodon: https://fosstodon.org/@fun + +truncatewords_length: 100000 + +# Set to your git root and branch to show a link to the file source in the footer. Unset to disable. +git: https://git.xw3.org/fun/fun/ +git_short: https://git.xw3.org +branch: src/branch/main/ + +lifetime: 3600 + +challenge_error: Invalid challenge result! Please try again... :( + +mail_thank_you: Thank you for contacting me... :) + +username: xw3 + +cookiebanner_text: This website uses cookies to provide you with a better online experience. Leave this site if you don't accept the usage of cookies. No tracking cookies are being used! To find out more, please visit this website's +cookiebanner_dismiss_text: Got it! +cookiebanner_link_text: Privacy Policy +cookiebanner_link: /privacy/ + +paginate: 2 +paginate_path: /page/:num/ +permalink: /:year/:month/:day/:title/ + +markdown: kramdown +highlighter: rouge +kramdown: + input: GFM +# syntax_highlighter_opts: + # Rouge Options › https://github.com/jneen/rouge#full-options +# css_class: 'highlight' + #line_numbers: true # bad idea, spans don't need linenos and would inherit this option +# span: +# line_numbers: false +# block: +# line_numbers: true +# start_line: 1 + +tocTopTag: h2 +anchorPrefix: "" +showToggleButton: false +contentsLabel: Table of contents + +exclude: + - .idea/ + - lib/ + - venv/ + - .project + - build.log + - Makefile + - README.md + - requirements.txt + - package.json + - package-lock.json + - xw3.code-workspace + +category_archive: + path: /category/ + +plugins: + - jekyll-paginate +# - jekyll-seo-tag + - jekyll-sitemap + - jekyll-toc + +# - jekyll-admin +# https://stackoverflow.com/questions/10218779/custom-variables-in-jekyll-front-matter +# https://github.com/gjtorikian/jekyll-conrefifier +# https://stackoverflow.com/questions/65989040/bundle-exec-jekyll-serve-cannot-load-such-file +# - jekyll-conrefifier + +defaults: + - + scope: + path: "cgi/*" + values: + sitemap: false + - + scope: + path: "files/*" + values: + sitemap: false + diff --git a/web/_data/.gitkeep b/web/_data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/web/_drafts/.gitkeep b/web/_drafts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/web/_includes/footer.html b/web/_includes/footer.html new file mode 100644 index 0000000..e323926 --- /dev/null +++ b/web/_includes/footer.html @@ -0,0 +1,26 @@ + + diff --git a/web/_includes/head.html b/web/_includes/head.html new file mode 100644 index 0000000..fc58c8a --- /dev/null +++ b/web/_includes/head.html @@ -0,0 +1,18 @@ + + + + {{ site.title }} {{ page.title }} - {{ site.subtitle }} + + {% if page.tags %}{% endif %} + + + + + + + + + + + + diff --git a/web/_includes/header.html b/web/_includes/header.html new file mode 100644 index 0000000..86e3e28 --- /dev/null +++ b/web/_includes/header.html @@ -0,0 +1,48 @@ + + diff --git a/web/_layouts/default.html b/web/_layouts/default.html new file mode 100644 index 0000000..7161dd2 --- /dev/null +++ b/web/_layouts/default.html @@ -0,0 +1,31 @@ +--- +layout: +--- + + + +{% include head.html %} + +
+ +{% include header.html %} +
+
+{{ content }} +
+
+{% include footer.html %} +
+ +

+ Page generated at: {{ site.time | date: "%b %-d, %Y" }} ({{ site.time | date: "%Z" }}) using Jekyll and xw3 on {{ site.os }}
+

+ + + + + + + + + diff --git a/web/_layouts/page.html b/web/_layouts/page.html new file mode 100644 index 0000000..b1d2665 --- /dev/null +++ b/web/_layouts/page.html @@ -0,0 +1,21 @@ +--- +layout: default +--- + +
+
+

{{ site.title }} {{ page.title }}

+ {% if page.noDate != true %} + {% if page.subtitle %}

{{ page.subtitle }}

{% endif %} +
+
+ {{ content | toc_generate }} + {% if page.noComments != true %} +

Comments

+
+ + {% endif %} +
+
+ diff --git a/web/_layouts/post.html b/web/_layouts/post.html new file mode 100644 index 0000000..cf5e77c --- /dev/null +++ b/web/_layouts/post.html @@ -0,0 +1,23 @@ +--- +layout: default +--- + +
+
+

{{ site.title }} {{ page.title }}

+ +
+
+ {{ content }} + {% if page.noComments != true %} +

Comments

+
+ + {% endif %} + +
+
+ diff --git a/web/_plugins/.gitkeep b/web/_plugins/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/web/_plugins/myFilters.rb b/web/_plugins/myFilters.rb new file mode 100644 index 0000000..f2f9d44 --- /dev/null +++ b/web/_plugins/myFilters.rb @@ -0,0 +1,12 @@ +# https://stackoverflow.com/questions/14978474/how-to-show-the-modification-date-of-a-file-in-jekyll + +module Jekyll + module MyFilters + def file_date(input) + File.mtime(input) + end + end +end + +Liquid::Template.register_filter(Jekyll::MyFilters) + diff --git a/web/_plugins/tocGenerator.rb b/web/_plugins/tocGenerator.rb new file mode 100644 index 0000000..41631f4 --- /dev/null +++ b/web/_plugins/tocGenerator.rb @@ -0,0 +1,144 @@ +# This code was originally written by Davide Ficano: +# https://github.com/dafi/jekyll-toc-generator +# Thank you for that! + +require 'nokogiri' +require 'digest/md5' + +module Jekyll + module TOCGenerator + TOGGLE_HTML = '

%1

%2
' + TOC_CONTAINER_HTML = '
%1
    %2
' + + def toc_generate(html) + # No Toc can be specified on every single page + # For example the index page has no table of contents + no_toc = @context.environments.first["page"]["noToc"] || false; + + if no_toc + return html + end + + config = @context.registers[:site].config + # Minimum number of items needed to show TOC, default 0 (0 means no minimum) + min_items_to_show_toc = config["minItemsToShowToc"] || 0 + + anchor_prefix = config["anchorPrefix"] || 'tocAnchor-' + + # better for traditional page seo, commonlly use h1 as title + toc_top_tag = config["tocTopTag"] || 'h1' + toc_top_tag = toc_top_tag.gsub(/h/, '').to_i + if toc_top_tag > 5 + toc_top_tag = 5 + end + toc_sec_tag = toc_top_tag + 1 + toc_top_tag = "h#{toc_top_tag}" + toc_sec_tag = "h#{toc_sec_tag}" + + + # Text labels + contents_label = config["contentsLabel"] || 'Contents' + hide_label = config["hideLabel"] || 'hide' + show_label = config["showLabel"] || 'show' + show_toggle_button = config["showToggleButton"] + + toc_html = '' + toc_level = 1 + toc_section = 1 + item_number = 1 + level_html = '' + + doc = Nokogiri::HTML(html) + + # Find H1 tag and all its H2 siblings until next H1 + doc.css(toc_top_tag).each do |tag| + # TODO This XPATH expression can greatly improved + ct = tag.xpath("count(following-sibling::#{toc_top_tag})") + sects = tag.xpath("following-sibling::#{toc_sec_tag}[count(following-sibling::#{toc_top_tag})=#{ct}]") + + level_html = ''; + inner_section = 0; + + sects.map.each do |sect| + inner_section += 1; + #anchor_id = anchor_prefix + toc_level.to_s + '-' + toc_section.to_s + '-' + inner_section.to_s + anchor_id = anchor_prefix + Digest::SHA256.hexdigest(tag.text + sect.text); + anchor_id = anchor_id[0..7]; + sect['id'] = "#{anchor_id}" + + level_html += create_level_html(anchor_id, + toc_level + 1, + toc_section + inner_section, + item_number.to_s + '.' + inner_section.to_s, + sect.text, + '') + end + if level_html.length > 0 + level_html = ''; + end + + #anchor_id = anchor_prefix + toc_level.to_s + '-' + toc_section.to_s; + anchor_id = anchor_prefix + Digest::SHA256.hexdigest(tag.text); + anchor_id = anchor_id[0..7]; + tag['id'] = "#{anchor_id}" + + toc_html += create_level_html(anchor_id, + toc_level, + toc_section, + item_number, + tag.text, + level_html); + + toc_section += 1 + inner_section; + item_number += 1; + end + + #toc_html += create_level_html("ccba53", + # 1, + # toc_section, + # item_number, + # "Comments", + # ""); + + # for convenience item_number starts from 1 + # so we decrement it to obtain the index count + toc_index_count = item_number - 1 + + if toc_html.length > 0 + hide_html = ''; + if (show_toggle_button) + hide_html = HIDE_HTML.gsub('%1', hide_label) + end + + if min_items_to_show_toc <= toc_index_count + replaced_toggle_html = TOGGLE_HTML + .gsub('%1', contents_label) + .gsub('%2', hide_html); + toc_table = TOC_CONTAINER_HTML + .gsub('%1', replaced_toggle_html) + .gsub('%2', toc_html); + doc.css('body').children.before(toc_table) + end + doc.css('body').children.to_xhtml(indent:3, indent_text:" ") + else + return html + end + end + +private + + def create_level_html(anchor_id, toc_level, toc_section, tocNumber, tocText, tocInner) + link = '%2 %3%4' + .gsub('%1', anchor_id.to_s) + .gsub('%2', tocNumber.to_s) + .gsub('%3', tocText) + .gsub('%4', tocInner ? tocInner : ''); + '
  • %3
  • ' + .gsub('%1', toc_level.to_s) + .gsub('%2', toc_section.to_s) + .gsub('%3', link) + end + end +end + +Liquid::Template.register_filter(Jekyll::TOCGenerator) diff --git a/web/_posts/.gitkeep b/web/_posts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/web/_posts/2025-10-08-init.md b/web/_posts/2025-10-08-init.md new file mode 100644 index 0000000..4c853a1 --- /dev/null +++ b/web/_posts/2025-10-08-init.md @@ -0,0 +1,21 @@ +--- +layout: post +published: true +author: hanez +title: Init Fun! +description: Blog - Init Fun! +date: 2025-10-05 +_date_updated: 2024-02-07 +categories: +- news +- project +tags: +- fun +- programming +- static +- dynamic +- language +--- + +Initial homepage... no content actually! + diff --git a/web/_posts/2026-01-25-announcing-fun-0.37.62.md b/web/_posts/2026-01-25-announcing-fun-0.37.62.md new file mode 100644 index 0000000..411e26c --- /dev/null +++ b/web/_posts/2026-01-25-announcing-fun-0.37.62.md @@ -0,0 +1,177 @@ +--- +layout: post +published: true +author: hanez +noToc: false +title: Announcing Fun 0.37.62 +description: Homepage and Blog +date: 2026-01-25 +date_updated: 2026-01-31 21:45:03 +categories: +- news +- project +tags: +- fun +- programming +- static +- dynamic +- language +--- + +### First at all! Special thanks go to my wonderful girlfriend Sabine, my friends [Armin](https://m2m.pm/){:class="ext"} and [Ole](https://schizzoteam.org/){:class="ext"}, who motivated me over the past month to implement this. Cheers! Markus, I miss YOU, R.I.P! + +We're excited to announce the release of Fun version 0.37.62, the latest iteration of our experimental programming language that prioritizes simplicity, consistency, and most importantly — joy in coding. + +[Link to Hackernews post](https://news.ycombinator.com/item?id=46787331){:class="ext"}. + +### What's Fun All About? + +Fun is a highly strict yet highly simple programming language that draws inspiration from Bash, C, Lua, PHP, Python, and Rust. If you love Python's clean syntax but want something with stricter rules and built-in type safety, Fun might be worth exploring. It's dynamically typed with optional static typing, written in C (C99) and Fun itself, and designed to be small, embeddable, and hackable. More on the [about](https://fun-lang.xyz/about/) page. + +### Important: This is an Experiment + +Please note: Fun is an experimental language and should be treated as such. While Fun works, it has many known and unknown bugs. We will not declare Fun as stable until we reach the 1.0 release. This is a project born out of curiosity and passion for elegant code, not production readiness — at least not yet. + +### What Makes Fun... Fun? + +#### Philosophy + +Fun is built on the idea that coding should be enjoyable, elegant, and consistent. Our manifesto includes core principles like: + +- Fun is Fun – Programming should spark creativity, not frustration +- Fun Uses Nothing – Minimalism is power; no unnecessary features or syntax variations +- Indentation is Truth – Two spaces, always (no tabs, no debates, no four-space wars) +- One Way to Do It – No clutter, no 15 ways of writing the same thing. Simplicity means clarity +- Hackable by Nature – Small and embeddable, like Lua. Easy to understand, extend, and tinker with +- Beautiful Defaults – A language that doesn't need linters, formatters, or style guides. Beauty is built in + +### What's New in Specification v0.3 (and Fun 0.37.62) + +This release brings Fun closer to its vision with significant language enhancements: + +- Object-Oriented Programming Classes and objects with methods, constructors, and inheritance using extends +- Explicit this in method definitions for clarity +- Private members by convention (leading underscore) +- Dot-call syntax sugar for clean method invocations: obj.method(a, b) + +
    +class Counter
    +  value = 0
    +  fun inc(this)
    +    this.value = this.value + 1
    +    return this.value
    +
    +c = Counter()
    +print(c.inc())  // 1
    +
    + +### Module System + +- Namespaced includes with #include as alias for clean imports +- Organize code into reusable modules without naming conflicts + +
    +#include  as m
    +print(m.add(2, 3))  // 5
    +
    + +### Enhanced Type System + +- Fixed-width integers: int8, uint8, int16, uint16, int32, uint32, int64, uint64 +- Maps/dictionaries: map with literal syntax { "key": value } +- Typed arrays: array for type-safe collections +- Byte type for low-level operations + +### Concurrency Support + +- Thread primitives: thread_spawn, thread_join, and sleep +- Write concurrent programs with ease + +
    +fun square(n)
    +  sleep(100)
    +  return n * n
    +
    +tid = thread_spawn(square, 5)
    +print(thread_join(tid))  // 25
    +
    + +### Control Flow Improvements + +- Loop control: break and continue statements +- Exception handling: try/catch/finally syntax (runtime implementation evolving) + +### System and Network Integration + +- Process execution: Blocking (exec, system) and non-blocking (nexec, nspawn) with process management +- TCP and Unix domain sockets: Build networked applications +- Serial port support: Communicate with hardware devices +- Environment variables: Access with env(NAME) +- CLI argument handling: Parse command-line arguments + +### Additional Features + +- Bitwise operations: band, bor, bxor, bnot, shl +- Rich standard library with modules for cryptography (MD5, SHA1/256/384/512, CRC32), encoding (Base64, hex), JSON, XML, INI, regular expressions (PCRE2), datetime utilities, and more +- Optional extensions for cURL, SQLite/libSQL, PC/SC smart cards, and Tk GUI toolkit + +### Core Language Features + +Fun provides a clean, readable syntax with: + +- Strict indentation-based structure (2 spaces, no semicolons) +- Type safety with no implicit numeric coercions +- Bounds-checked operations to prevent common errors +- Higher-order functions: map, filter, reduce for functional programming +- Multiple return values from functions +- Comprehensive built-ins for common tasks + +### The Community: Fun Unites Nerds + +Fun isn't about being the fastest or most feature-rich language — it's about sharing the joy of coding. We welcome contributors who are: + +- Respectful +- Curious +- Creative + +A language that feels like home for developers who love minimal, elegant tools, believe consistency is freedom, and want to write code that looks good and feels good. + +### Want to Participate? + +Everybody is welcome to participate! However, before you can get started, you need to contact me at [hanez@fun-lang.org](mailto:hanez@fun-lang.org){:class="mail"} to request an account on our Git server. + +Important: Fun is not developed on third-party Git servers like GitHub or GitLab. All Fun infrastructure is self-hosted at git.xw3.org. This keeps us independent and aligned with the hacker spirit of the project — we control our tools, our code, and our community. + +### Getting Started + +If you're curious about Fun, check out: + +- [Website](https://fun-lang.xyz) +- [Git Repository](https://git.xw3.org/fun/fun){:class="git"} +- [Fun Handbook](https://git.xw3.org/fun/fun/src/branch/main/docs/handbook.md){:class="git"} +- [Fun REPL Guide](https://git.xw3.org/fun/fun/src/branch/main/docs/repl.md){:class="git"} +- [Specification v0.3](https://git.xw3.org/fun/fun/src/branch/main/spec/v0.3.md){:class="git"} +- [Examples](https://git.xw3.org/fun/fun/src/branch/main/examples){:class="git"} +- [Standard Library](https://git.xw3.org/fun/fun/src/branch/main/lib){:class="git"} +- [Community](https://fun-lang.xyz/community/) + +The examples directory contains demonstrations of most Fun features, from basic "Hello, World!" to threading, networking, classes, and more. The lib directory includes modules written in Fun itself — and in the future, most enhancements will be written in Fun rather than C. + +### For Developers + +- [Fun Internals](https://git.xw3.org/fun/fun/src/branch/main/docs/internals.md){:class="git"} +- [Fun Opcodes](https://git.xw3.org/fun/fun/src/branch/main/docs/opcodes.md){:class="git"} +- [Basic Rust Opcodes Support](https://git.xw3.org/fun/fun/src/branch/main/docs/rust.md){:class="git"} + +### The Road Ahead + +Documentation is a work in progress as we continue debugging, fixing bugs, and evolving the language. Complete API documentation will follow in future releases. Version 0.37.62 represents substantial progress, but remember: this is an experiment, and stability won't be declared until we reach 1.0. + +Fun may not change the world, but it aims to make programming a little more fun. We're on a journey, and we'd love to have you along for the ride — bugs and all. + +Fun is and will always be 100% free under the terms of the [Apache-2.0 License](https://opensource.org/license/apache-2-0){:class="ext"}. + +Happy hacking, and remember: Fun is Fun! + +Johannes Findeisen (hanez) - [hanez@fun-lang.org](mailto:hanez@fun-lang.org){:class="mail"} + diff --git a/web/_sass/.gitkeep b/web/_sass/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/web/_sass/_base.scss b/web/_sass/_base.scss new file mode 100644 index 0000000..2f5dbad --- /dev/null +++ b/web/_sass/_base.scss @@ -0,0 +1,188 @@ +html { + margin: 0; + padding: 0; +} + +body, h1, h2, h3, h4, h5, h6, p, code, blockquote, +pre, hr, dl, dd, ol, ul, figure, span { + margin: 0; + padding: 0; +} + +body { + background: $background-color; + //background-color: $background-color; + //background-image: url("/images/fractalized.jpg"); + //background-repeat: no-repeat; + //background-attachment: fixed; + //background-size: 100%; + color: $text-color; + font-family: $base-font-family; + font-size: $base-font-size; + font-weight: 300; + line-height: $base-line-height; +} + +h1, h2, h3, h4, h5, h6 { + color: $headline-color; + padding-top: 18px; +} + +h1 { + color: $headline-color; + padding-top: 0px; +} + +h2 { + > a, + a:link, + a:visited { + text-decoration: none; + } +} + +img { + max-width: 100%; + vertical-align: middle; +} + +img.l { + border: 0; + float: left; + margin: 6px 16px 0 0; + padding: 0; +} + +img.r { + border: 0; + float: right; + margin: 6px 0 0 16px; + padding: 0; +} + +img.x { + max-width: 99.8%; + border: 1px solid #000; +} + +ul, ol { + margin: 0 0 0 25px; + padding: 0 0 12px 0; +} + +li { + > ul, + > ol { + margin-bottom: 0; + } +} + +p { + padding: 0px 0px 14px 0px; +} + +blockquote { + color: $grey-color; + border-left: 4px solid $grey-color-light; + font-size: 18px; + font-style: italic; + letter-spacing: -1px; + padding-left: calc($spacing-unit / 2); + > :last-child { + margin-bottom: 0; + } +} + +pre { + background: $grey-color-dark; + /*background-image: -webkit-linear-gradient($grey-color-dark 50%, $grey-color-light 50%); + background-image: -moz-linear-gradient($grey-color-dark 50%, $grey-color-light 50%); + background-image: -ms-linear-gradient($grey-color-dark 50%, $grey-color-light 50%); + background-image: -o-linear-gradient($grey-color-dark 50%, $grey-color-light 50%); + background-image: linear-gradient($grey-color-dark 50%, $grey-color-light 50%);*/ + background-position: 0 0; + background-repeat: repeat; + background-size: 2.8em 2.8em; + border: 0px $grey-color solid; + border-radius: 8px; + counter-reset: line-numbering; + font-family: $base-font-family; + font-size: $base-font-size; + // https://stackoverflow.com/questions/5840328/styling-each-line-inside-pre-with-css + line-height: 1.4em; + margin: 0 0 0 0; + overflow: auto; + overflow-x: auto; + padding: 8px; + tab-size: 2; + -moz-tab-size: 2; +} + + + +/*pre::before { + content: counter(linex); + counter-increment: linex; + padding-right: 1em; + width: 1.5em; + text-align: right; + opacity: 0.5; +}*/ + +/*pre > code { + font-family: $base-font-family; + font-size: $base-font-size; + counter-increment: line; + margin: 0 0 0 0; + padding: 0 0 0 0; +}*/ + +/**pre > code:before{ + content: counter(line); + display: inline-block; + width: 2.0em; + border-right: 1px solid $grey-color; + padding-right: .7em; + margin-right: .7em; + color: #bc6c21; + -webkit-user-select: none; + text-align: right; +}**/ + +audio { + height: 24px; + width: 100%; +} + +table { + border: 0px solid black; + //border-collapse: collapse; +} + +table > thead > tr { +} + +table > thead > tr > th { + background: $tablehead-color; + border: 0px solid black; + color: white; + padding: 4px; +} + +table > tbody > tr:nth-child(even) { + background: $grey-color-light; +} + +table > tbody > tr:nth-child(odd) { + background: $grey-color-dark; +} + +table > tbody > tr > td { + border: 0px solid black; + padding: 4px; +} + +table.sortable th:not(.sorttable_sorted):not(.sorttable_sorted_reverse):not(.sorttable_nosort):after { + content: " \25B4 \25BE" +} + diff --git a/web/_sass/_fonts.scss b/web/_sass/_fonts.scss new file mode 100644 index 0000000..148e724 --- /dev/null +++ b/web/_sass/_fonts.scss @@ -0,0 +1,9 @@ +@font-face { + font-family: "CPS"; + src: url("../fonts/Courier-Prime-Sans.ttf"); +} + +@font-face { + font-family: "MDI"; + src: url("../fonts/materialdesignicons-webfont.woff2") format("woff2"); +} diff --git a/web/_sass/_forms.scss b/web/_sass/_forms.scss new file mode 100644 index 0000000..f2761d7 --- /dev/null +++ b/web/_sass/_forms.scss @@ -0,0 +1,126 @@ +// Contact form +#contactform { + //padding: 20px; + //border: 1px solid $grey-color; + //background: $grey-color-light; + //display: inline; +} + +#contactform label, #contactform input, #contactform textarea { + display: block; + width: 98%; + resize: none; +} + +#contactform textarea { + height: 120px; +} + +#contactform label { margin: 10px 0; } + +#contactform label:first-child { margin-top: 0; } + +#contactform input, #contactform textarea { + font-family: $base-font-family; + font-size: $base-font-size; + line-height: $base-line-height; + font-weight: 300; + padding: 10px; + margin-bottom: 10px; + border: 1px solid $grey-color; +} + +#contactform input[type=submit] { + border: 0; + color: #fff; + background: $brand-color; + cursor: pointer; + width: 100%; +} + +#contactform input[type=submit]:hover { + background: $headline-color; +} + +// Login form +#loginform { + //background: $grey-color-light; + //border: 1px solid $grey-color; + display: inline; + //padding: 20px; + //width: 380px; +} + +#loginform label, #loginform input{ + //display: block; + resize: none; +} + +#loginform label { margin: 10px 0; } + +#loginform label:first-child { margin-top: 0; } + +#loginform input { + border: 1px solid $grey-color; + font-family: $base-font-family; + line-height: $base-line-height; + font-size: $base-font-size; + //font-weight: 300; + margin: 10px; + padding: 10px; +} + +#loginform input[type=submit] { + border: 0; + background: $brand-color; + color: #fff; + cursor: pointer; +} + +#loginform input[type=submit]:hover { + background: $headline-color; +} + +// Search form +#searchform { + //padding: 20px; + //border: 1px solid $grey-color; + //background: $grey-color-light; +} + +#searchform label, #searchform input, #searchform textarea { + display: block; + width: 98%; + resize: none; +} + +#searchform textarea { + height: 120px; +} + +#searchform label { margin: 10px 0; } + +#searchform label:first-child { margin-top: 0; } + +#searchform input, #searchform textarea { + font-family: $base-font-family; + font-size: $base-font-size; + line-height: $base-line-height; + font-weight: 300; + padding: 10px; + margin-bottom: 10px; + border: 1px solid $grey-color; +} + +#searchform input[type=submit] { + border: 0; + color: #fff; + background: $brand-color; + cursor: pointer; + width: 100%; +} + +#searchform input[type=submit]:hover { + background: $headline-color; +} + diff --git a/web/_sass/_highlight.scss b/web/_sass/_highlight.scss new file mode 100644 index 0000000..5444c0f --- /dev/null +++ b/web/_sass/_highlight.scss @@ -0,0 +1,61 @@ +/*.highlight { background: #ffffff; }*/ +.highlight .c { color: #999988; font-style: italic } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { font-weight: bold } /* Keyword */ +.highlight .o { font-weight: bold } /* Operator */ +.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ +.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #999999 } /* Generic.Heading */ +.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #aaaaaa } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { font-weight: bold } /* Keyword.Constant */ +.highlight .kd { font-weight: bold } /* Keyword.Declaration */ +.highlight .kp { font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #009999 } /* Literal.Number */ +.highlight .s { color: #d14 } /* Literal.String */ +.highlight .na { color: #008080 } /* Name.Attribute */ +.highlight .nb { color: #0086B3 } /* Name.Builtin */ +.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ +.highlight .no { color: #008080 } /* Name.Constant */ +.highlight .ni { color: #800080 } /* Name.Entity */ +.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ +.highlight .nn { color: #555555 } /* Name.Namespace */ +.highlight .nt { color: #000080 } /* Name.Tag */ +.highlight .nv { color: #008080 } /* Name.Variable */ +.highlight .ow { font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #009999 } /* Literal.Number.Float */ +.highlight .mh { color: #009999 } /* Literal.Number.Hex */ +.highlight .mi { color: #009999 } /* Literal.Number.Integer */ +.highlight .mo { color: #009999 } /* Literal.Number.Oct */ +.highlight .sb { color: #d14 } /* Literal.String.Backtick */ +.highlight .sc { color: #d14 } /* Literal.String.Char */ +.highlight .sd { color: #d14 } /* Literal.String.Doc */ +.highlight .s2 { color: #d14 } /* Literal.String.Double */ +.highlight .se { color: #d14 } /* Literal.String.Escape */ +.highlight .sh { color: #d14 } /* Literal.String.Heredoc */ +.highlight .si { color: #d14 } /* Literal.String.Interpol */ +.highlight .sx { color: #d14 } /* Literal.String.Other */ +.highlight .sr { color: #009926 } /* Literal.String.Regex */ +.highlight .s1 { color: #d14 } /* Literal.String.Single */ +.highlight .ss { color: #990073 } /* Literal.String.Symbol */ +.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #008080 } /* Name.Variable.Class */ +.highlight .vg { color: #008080 } /* Name.Variable.Global */ +.highlight .vi { color: #008080 } /* Name.Variable.Instance */ +.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ + diff --git a/web/_sass/_isso.scss b/web/_sass/_isso.scss new file mode 100644 index 0000000..2426190 --- /dev/null +++ b/web/_sass/_isso.scss @@ -0,0 +1,44 @@ +.isso-input-wrapper { + margin: 0px; + padding: 0px; + width: 238px; +} + +.isso-input-wrapper input { + box-shadow: 0 0 0 0; + margin-top: 3px; +} + +.isso-input-wrapper input[type="email"] { + box-shadow: 0 0 0 0; +} + +.isso-input-wrapper input[type="text"] { + box-shadow: 0 0 0 0; +} + +.isso-textarea-wrapper textarea { + border-radius: 0; + box-shadow: 0 0 0 0; +} + +#isso-postbox-author, #isso-postbox-email, #isso-postbox-website, .isso-post-action input, .isso-textarea { + border-radius: 0; + font-family: $base-font-family; + font-size: $base-font-size; +} + +.isso-post-action input[type=button], .isso-post-action input[type=submit] { + border: 0; + color: #fff; + background: $brand-color; + cursor: pointer; + margin-top: 3px; + padding: 6px 18px 6px 18px; + width: 100%; +} + +.isso-post-action input[type=button]:hover, .isso-post-action input[type=submit]:hover { + background: $headline-color; +} + diff --git a/web/_sass/_layout.scss b/web/_sass/_layout.scss new file mode 100644 index 0000000..c419214 --- /dev/null +++ b/web/_sass/_layout.scss @@ -0,0 +1,401 @@ +.site { + //border-radius: 12px 12px; + border: 1px solid #000; + border-radius: 8px; + background-color: #fcfbf9; + max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit} * 2)); + max-width: calc(#{$content-width} - (#{$spacing-unit} * 2)); + margin-right: auto; + margin-left: auto; + margin-top: 4px; + margin-bottom: 4px; + //box-shadow: 0px 0px 3px #000; +} + +.pagination { + margin-top: $spacing-unit; + margin-bottom: $spacing-unit; + text-align: center; +} + +.site-header { + min-height: 56px; + position: relative; +} + +.site-title { + line-height: 56px; + margin-bottom: 0; + float: left; +} + +.site-nav { + float: right; + z-index: 998; + position: absolute; + top: 18px; + right: 18px; + background-color: white; + border: 1px solid $brand-color; + //border-radius: 6px; + text-align: right; + text-decoration: none; + .menu-icon { + display: block; + float: right; + width: 36px; + height: 26px; + line-height: 0; + padding-top: 10px; + text-align: center; + text-decoration: none; + //> svg { + // width: 18px; + // height: 15px; + // path { + // fill: $grey-color-dark; + // } + //} + > span { + align-items: center; + justify-content: center; + display: flex; + flex-direction: column; + font-size: 24px; + padding-top: 10px; + } + } + .trigger { + clear: both; + display: none; + } + &:hover .trigger { + display: block; + //padding-bottom: 5px; + //text-decoration: none; + //color: $brand-color; + } + .page-link { + display: block; + padding: 5px 10px; + } +} + +/*.ham-menu { + display: inline-block; + position: relative; + margin: 2px 0; +} + +.ham-menu, .ham-menu::before, .ham-menu::after { + width: 100px; + height: 20px; + border-radius: 7px; + background-color: black; +} + +.ham-menu::before, .ham-menu::after { + content: ""; + display: block; + position: absolute; +} + +.ham-menu::before { + bottom: 130%; +} + +.ham-menu::after { + top: 130%; +}*/ + +.site-footer { + margin: calc($spacing-unit / 4); + //border-radius: 12px 12px; + //background-color: $grey-color-light; + //border: 1px solid $grey-color; +} + +.footer-col-wrapper { + margin-left: calc($spacing-unit / 2); + @extend %clearfix; +} + +.footer-col { + float: left; + margin-bottom: calc($spacing-unit / 2); + padding-left: calc($spacing-unit / 2); +} + +@include media-query($on-palm) { + .footer-col { + float: none; + width: -webkit-calc(100% - (#{$spacing-unit} / 2)); + width: calc(100% - (#{$spacing-unit} / 2)); + } +} + +.page-content { + +} + +.page-heading { + +} + +.post-list { + margin-left: 0; + list-style: none; + > li { + margin-bottom: $spacing-unit; + } +} + +.post-meta { + font-size: $small-font-size; + color: $grey-color; +} + +.post-link { + display: block; + font-size: 24px; +} + +.post-header { + margin-bottom: $spacing-unit; +} + +.post-title { + letter-spacing: -1px; + line-height: 1; + @include media-query($on-laptop) { + + } +} + +.post-content { + margin-bottom: $spacing-unit; +} + +.post-content img { +} + +.overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + min-width: 100%; + height: 100%; + min-height: 100%; + background: rgba(0,0,0,.8); + z-index: 999; + opacity: 1; + transition: all 0.5s; +} + +.wrapper { + max-width: calc(#{$content-width} - (#{$spacing-unit} * 2)); + margin-right: auto; + margin-left: auto; + padding-right: $spacing-unit; + padding-left: $spacing-unit; + padding-top: calc($spacing-unit / 2); + padding-bottom: 0; + @extend %clearfix; + @include media-query($on-laptop) { + max-width: calc(#{$content-width} - (#{$spacing-unit})); + padding-right: calc($spacing-unit / 2); + padding-left: calc($spacing-unit / 2); + } +} + +%clearfix { + &:after { + content: ""; + display: table; + clear: both; + } +} + +.icon { + > svg { + display: inline-block; + width: 16px; + height: 16px; + vertical-align: middle; + path { + fill: $grey-color; + } + } +} + +.pagination a, span { + margin-left: 4px; + margin-right: 4px; +} + +span.feed { + border: 1px solid; + border-color: #FC9 #630 #330 #F96; + padding: 0 3px; + font: bold 0.4em sans-serif; + color: #fff; + background: #f60; + text-decoration: none; + margin: 0; +} + +#topbutton { + text-align: center; + padding: 0; + width: 46px; + height: 46px; + background: $topbutton-color url(/images/up-arrow.png) no-repeat center center; + border: 1px solid $grey-color-dark; + position: fixed; + bottom: 10px; + right: 10px; + cursor: pointer; +} + +span.cursor { + color: #FF9500; + display: inline-block; + background: transparent; + margin-left: 1px; + animation: 1s blink step-end infinite; +} + +@keyframes "blink" bold { + from, to { + color: transparent; + } + 50% { + color: black; + } +} + +@-webkit-keyframes "blink" bold { + from, to { + color: transparent; + } + 50% { + color: black; + } +} + +@-ms-keyframes "blink" bold { + from, to { + color: transparent; + } + 50% { + color: black; + } +} + +@-o-keyframes "blink" { + from, to { + color: transparent; + } + 50% { + color: black; + } +} + +#pages { + text-align: center; +} + +#pages a:link, +#pages a:visited, +#pages strong { + float: left; + width: 1.8em; + border: 1px solid #000; + font-weight: bold; + text-decoration: none; + text-align: center; + margin: 0px 4px 4px 0; + padding: 2px; + background: $brand-color; + color: #fff; +} + +#pages > a.active { + color: $grey-color-light; + background: #fff; + border-color: $grey-color; +} + +#pages a:focus, +#pages a:hover, +#pages a:active { + color: $hover-color; + background: #fff; +} + +#pages p { + float: left; + width: 100%; +} + +#notify { + padding: 10px; + margin-bottom: 20px; + border: 1px solid $grey-color; + background: $headline-color; +} + +.lds-dual-ring.hidden { + display: none; +} + +.lds-dual-ring { + display: inline-block; + width: 80px; + height: 80px; +} +.lds-dual-ring:after { + content: " "; + display: block; + width: 64px; + height: 64px; + margin: 5% auto; + border-radius: 50%; + border: 6px solid #fff; + border-color: #fff transparent #fff transparent; + animation: lds-dual-ring 1.2s linear infinite; +} +@keyframes lds-dual-ring { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} + +#terminal::before { + content: ""; +} + +@media (prefers-reduced-motion: no-preference) { + @keyframes flash { + 50% { opacity: 0; } + } + @keyframes reveal { + from { width: 2em; } + to { width: 100%; } + } + #terminal { + animation: reveal 6s linear; + overflow: hidden; + text-overflow: "▉"; + white-space: nowrap; + } + #terminal::after { + animation: flash 1.5s step-end infinite; + content: "▉"; + } +} + diff --git a/web/_sass/_links.scss b/web/_sass/_links.scss new file mode 100644 index 0000000..6910bae --- /dev/null +++ b/web/_sass/_links.scss @@ -0,0 +1,269 @@ +a { + color: $brand-color; + //display: inline-block; + //position: relative; +} + +a:link { + text-decoration: underline; +} + +a:visited { + color: $brand-color; + text-decoration: underline; +} + +a:focus, +a:hover { + color: $hover-color; + text-decoration: none; + text-shadow: $hover-color 0px 0px 6px; +} + +a:active { + color: $hover-color; + text-decoration: none; +} + +// https://stackoverflow.com/questions/2011142/how-to-change-the-style-of-the-title-attribute-inside-an-anchor-tag +// https://css-tricks.com/css-content/ +/*a[title]:hover::after { + background: rgba(0,0,0,1.0); + //content: attr(title); + //position: absolute; + //top: -100%; + //left: 0; + border-radius: 0px; + //border: 1px solid red; + //color: #fff; + //background: $brand-color; +}*/ + +a.bug::after { + content: "\F0A30"; + color: $base-icon-color; + font-family: $base-icon-font-family; + font-size: $base-icon-size; + padding-left: 5px; +} + +a.bug:hover::after { + color: $hover-color; +} + +a.chat::after { + content: "\F0EDE"; + color: $base-icon-color; + font-family: $base-icon-font-family; + font-size: $base-icon-size; + padding-left: 5px; +} + +a.chat:hover::after { + color: $hover-color; +} + +a.code::after { + content: "\F102B"; + color: $base-icon-color; + font-family: $base-icon-font-family; + font-size: $base-icon-size; + padding-left: 5px; +} + +a.code:hover::after { + color: $hover-color; +} + +a.commit::after { + content: "\F05D6"; + color: $base-icon-color; + font-family: $base-icon-font-family; + font-size: $base-icon-size; + padding-left: 5px; +} + +a.commit:hover::after { + color: $hover-color; +} + +a.community::after { + content: "\F112D"; + color: $base-icon-color; + font-family: $base-icon-font-family; + font-size: $base-icon-size; + padding-left: 5px; +} + +a.community:hover::after { + color: $hover-color; +} + +a.cube::after { + content: "\F01A7"; + color: $base-icon-color; + font-family: $base-icon-font-family; + font-size: $base-icon-size; + padding-left: 5px; +} + +a.cube:hover::after { + color: $hover-color; +} + +a.document::after { + content: "\F09EE"; + color: $base-icon-color; + font-family: $base-icon-font-family; + font-size: $base-icon-size; + padding-left: 5px; +} + +a.document:hover::after { + color: $hover-color; +} + +a.ext::after { + content: "\F03CC"; + color: $base-icon-color; + font-family: $base-icon-font-family; + font-size: $base-icon-size; + padding-left: 5px; +} + +a.ext:hover::after { + color: $hover-color; +} + +a.file::after { + content: "\F0224"; + color: $base-icon-color; + font-family: $base-icon-font-family; + font-size: $base-icon-size; + padding-left: 5px; +} + +a.file:hover::after { + color: $hover-color; +} + +a.git::after { + content: "\F02A2"; + color: $base-icon-color; + font-family: $base-icon-font-family; + font-size: $base-icon-size; + padding-left: 5px; +} + +a.git:hover::after { + color: $hover-color; +} + +a.home::after { + content: "\F06A1"; + color: $base-icon-color; + font-family: $base-icon-font-family; + font-size: $base-icon-size; + padding-left: 5px; +} + +a.home:hover::after { + color: $hover-color; +} + +a.love::after { + content: "\F02D5"; + color: $base-icon-color; + font-family: $base-icon-font-family; + font-size: $base-icon-size; + padding-left: 5px; +} + +a.love:hover::after { + color: $hover-color; +} + +a.mail::after { + content: "\F01F0"; + color: $base-icon-color; + font-family: $base-icon-font-family; + font-size: $base-icon-size; + padding-left: 5px; +} + +a.mail:hover::after { + color: $hover-color; +} + +a.mastodon::after { + content: "\F0AD1"; + color: $base-icon-color; + font-family: $base-icon-font-family; + font-size: $base-icon-size; + padding-left: 5px; +} + +a.mastodon:hover::after { + color: $hover-color; +} + +a.privacy::after { + content: "\F0CC8"; + color: $base-icon-color; + font-family: $base-icon-font-family; + font-size: $base-icon-size; + padding-left: 5px; +} + +a.privacy:hover::after { + color: $hover-color; +} + +a.rss::after { + content: "\F046B"; + color: $base-icon-color; + font-family: $base-icon-font-family; + font-size: $base-icon-size; + padding-left: 5px; +} + +a.rss:hover::after { + color: $hover-color; +} + +a.search::after { + content: "\F0349"; + color: $base-icon-color; + font-family: $base-icon-font-family; + font-size: $base-icon-size; + padding-left: 5px; +} + +a.search:hover::after { + color: $hover-color; +} + +a.user::after { + content: "\F0013"; + color: $base-icon-color; + font-family: $base-icon-font-family; + font-size: $base-icon-size; + padding-left: 5px; +} + +a.user:hover::after { + color: $hover-color; +} + +a.wiki::after { + content: "\F1CCC"; + color: $base-icon-color; + font-family: $base-icon-font-family; + font-size: $base-icon-size; + padding-left: 5px; +} + +a.wiki:hover::after { + color: $hover-color; +} + diff --git a/web/_sass/_toc.scss b/web/_sass/_toc.scss new file mode 100644 index 0000000..9efb4b8 --- /dev/null +++ b/web/_sass/_toc.scss @@ -0,0 +1,17 @@ +//#toc-container h2 { +// font-size: 1.4em; +//} + +#toc-container ul { + list-style-image: none; + list-style-type: none; + margin-left: $spacing-unit; + //margin:0; + //padding: 0; + //text-align: left; +} + +#toc-container ul li { + list-style-type: none; + padding-left: 0; +} diff --git a/web/_site/.gitkeep b/web/_site/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/web/_tmp/.gitkeep b/web/_tmp/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/web/about/about.md b/web/about/about.md new file mode 100644 index 0000000..a66f6a1 --- /dev/null +++ b/web/about/about.md @@ -0,0 +1,124 @@ +--- +layout: page +title: About +subtitle: More information about having fun... :) +description: About +metasub: news +noToc: true +noDate: false +tags: +- fun +- programming +- language +- about +_description: The programming language that just makes fun! +noComments: true +permalink: /about/ +--- + +## What is Fun? + +Fun is an experiment, just for fun, but Fun works! + +Fun is a highly strict programming language, but also highly simple. It looks like Python (My favorite language), but there are differences. + +Influenced by **[Bash](https://www.gnu.org/software/bash/){:class="ext"}**, **[C](https://en.wikipedia.org/wiki/The_C_Programming_Language){:class="ext"}**, **[Lua](https://www.lua.org/){:class="ext"}**, PHP, **[Python](https://www.python.org/){:class="ext"}**, and a little Rust (Most influences came from linked languages). + +Fun is and will ever be 100% free under the terms of the [Apache-2.0 License](https://opensource.org/license/apache-2-0){:class="ext"}. + +## Idea + +- Simplicity +- Consistency +- Simple to extend +- Hackable +- Joy in coding +- Fun! + +## Characteristics + +- Dynamic and optionally statically typed +- Type safety +- Written in C (C99) and Fun +- Internal libs are written with no_camel_case even when written in Fun, except class names +- Only a minimal function set is written in C, and most other core functions and libraries are implemented in Fun + +## The Fun Manifesto + +Fun is a programming language built on a simple idea: +Coding should be enjoyable, elegant, and consistent. + +### Philosophy + +- **Fun is Fun**
    + Programming should spark creativity, not frustration. Code in Fun feels light, playful, and rewarding. +- **Fun Uses Nothing**
    + Minimalism is power. No unnecessary features, no endless syntax variations, no formatting debates. Just clean, uniform code. +- **Indentation is Truth**
    + Two spaces, always. No tabs, no four-space wars. Code should look the same everywhere, from your laptop to /usr/bin/fun. +- **One Way to Do It**
    + No clutter, no 15 ways of writing the same thing. Simplicity means clarity. +- **Hackable by Nature**
    + Fun should be small and embeddable, like Lua. Easy to understand, extend, and tinker with — true to the hacker spirit. +- **Beautiful Defaults**
    + A language that doesn’t need linters, formatters, or style guides. Beauty is built in. + +## The Community + +Fun is not about being the fastest or the most feature-rich. It’s about sharing joy in coding. The community should be: + +- Respectful +- Curious +- Creative + +Like the name says: Fun Unites Nerds. + +Please visit the [Fun Community Page](https://fun-lang.xyz/community/){:class="git"} to get in touch. + +## The Goal + +A language that feels like home for developers who: + +- Love minimal, elegant tools +- Believe consistency is freedom +- Want to write code that looks good and feels good + +Fun may not change the world — but it will make programming a little more fun. + +## Features + +### Core + +- functions/classes/objects +- if/else if/else +- try/catch/finally + +and much more... + +Look at the examples here: [https://git.xw3.org/fun/fun/src/branch/main/examples](https://git.xw3.org/fun/fun/src/branch/main/examples){:class="ext"} + +### Lib + +See [https://git.xw3.org/fun/fun/src/branch/main/lib](https://git.xw3.org/fun/fun/src/branch/main/lib) for what the standard library provides. + +### Extensions (only Linux actually) + +- [CGI](https://en.wikipedia.org/wiki/Common_Gateway_Interface){:class="ext"} support builtin using [kcgi](https://kristaps.bsd.lv/kcgi/){:class="ext"} (optional) +- [cURL](https://curl.se/){:class="ext"} support builtin using [libcurl](https://curl.se/libcurl/){:class="ext"} (optional) +- [INI](https://en.wikipedia.org/wiki/INI_file){:class="ext"} support builtin using [iniparser](https://gitlab.com/iniparser/iniparser/){:class="ext"} (optional) +- [JSON](https://www.json.org/){:class="ext"} support builtin using [json-c](https://github.com/json-c/json-c){:class="ext"} (optional) +- [PCRE2](https://pcre2project.github.io/pcre2/){:class="ext"} support builtin for Perl-Compatible Regular Expressions (optional) +- [PCSC](https://pcscworkgroup.com/){:class="ext"} smart card support builtin using [PCSC lite](https://pcsclite.apdu.fr/){:class="ext"} (optional) +- [SQLite](https://sqlite.org/){:class="ext"} support builtin (optional) +- [XML](https://www.w3.org/XML/){:class="ext"} support builtin using [libxml2](https://gitlab.gnome.org/GNOME/libxml2/-/wikis/home){:class="ext"} (optional) + + = Done / = Planned or in progress. + +Note: Not all of the above features will be implemented. Those who are marked "Done" will probably remain in Fun, but I don't know actually... ;) + +There are some libs written in Fun available in the [./lib/](https://git.xw3.org/fun/fun/src/branch/main/lib){:class="ext"} diretory. In the future most Fun enhancements should be written in Fun itself. + +## Code + + - [https://git.xw3.org/fun/fun/](https://git.xw3.org/fun/fun/){:class="git"} + diff --git a/web/cgi/challenge/challenge.php b/web/cgi/challenge/challenge.php new file mode 100644 index 0000000..7c133e9 --- /dev/null +++ b/web/cgi/challenge/challenge.php @@ -0,0 +1,27 @@ +--- +permalink: /cgi/challenge/ +--- + + diff --git a/web/cgi/mail/mail.php b/web/cgi/mail/mail.php new file mode 100644 index 0000000..fbcebc4 --- /dev/null +++ b/web/cgi/mail/mail.php @@ -0,0 +1,47 @@ +--- +permalink: /cgi/mail/ +--- + +" . "\r\n" . + "Date: " . date(DATE_RFC822); + + $mailSubject = "[{{ site.url_short }}]: No subject!"; + if($_POST["subject"]) { + $mailSubject = "[{{ site.url_short }}]: " . $_POST["subject"]; + } + + $mailBody = $_POST["message"] . "\n\n" . "Website: " . $_POST["website"] . "\nUser Agent: " . $_SERVER['HTTP_USER_AGENT']; + if (!@mail($mailTo, $mailSubject, $mailBody, $mailHeaders)) { $error = "Failed to send mail!"; } + + unset($_SESSION["one"]); + unset($_SESSION["two"]); +} + +header('Content-Type: text/plain; charset=utf-8'); +if ($error=="") { + echo("{{ site.mail_thank_you }}"); +} else { + //echo($error . " (". $_POST["sum"] . "/" . $sum . ")"); + echo($error); +} +?> diff --git a/web/community/code-of-conduct/code-of-conduct.md b/web/community/code-of-conduct/code-of-conduct.md new file mode 100644 index 0000000..24dcd1d --- /dev/null +++ b/web/community/code-of-conduct/code-of-conduct.md @@ -0,0 +1,89 @@ +--- +layout: page +published: true +noToc: false +noDate: false +title: Code of Conduct +subtitle: Contributor Covenant Code of Conduct +description: Code of Conduct +permalink: /community/code-of-conduct/ +--- + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our community include: + + - Demonstrating empathy and kindness toward other people + - Being respectful of differing opinions, viewpoints, and experiences + - Giving and gracefully accepting constructive feedback + - Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience + - Focusing on what is best not just for us as individuals, but for the overall community + +
    + +Examples of unacceptable behavior include: + + - The use of sexualized language or imagery, and sexual attention or advances of any kind + - Trolling, insulting or derogatory comments, and personal or political attacks + - Public or private harassment + - Publishing others' private information, such as a physical or email address, without their explicit permission + - Other conduct which could reasonably be considered inappropriate in a professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [community@fun-lang.xyz](mailto:community@fun-lang.xyz){:class="mail"}. All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: + +### Correction + +Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. + +Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. + +### Warning + +Community Impact: A violation through a single incident or series of actions. + +Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. + +### Temporary Ban + +Community Impact: A serious violation of community standards, including sustained inappropriate behavior. + +Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. + +### Permanent Ban + +Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. + +Consequence: A permanent ban from any sort of public interaction within the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org){:class="ext"}, version 2.1, available at [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html](https://www.contributor-covenant.org/version/2/1/code_of_conduct.html){:class="ext"}. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity){:class="ext"}. + +For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq](https://www.contributor-covenant.org/faq){:class="ext"}. Translations are available at [https://www.contributor-covenant.org/translations](https://www.contributor-covenant.org/translations){:class="ext"}. + diff --git a/web/community/community.html b/web/community/community.html new file mode 100644 index 0000000..36a4dcf --- /dev/null +++ b/web/community/community.html @@ -0,0 +1,92 @@ +--- +layout: page +published: true +noToc: false +noDate: false +title: Community +subtitle: The place to contact the Fun community. +permalink: /community/ +description: Community +--- + +

    Important

    + +

    Please read the Code of Conduct before participating in xw3 community discussions.

    + +

    IRC

    + +

    We use the Libera.Chat IRC network for realtime collaboration.

    + +

    Just click the channel name to open a web based client in your browser for instant chat.

    + + + + + + + + + + + + + + +
    ChannelDescription
    #fun-langAll discussion about the Fun programming language
    + +

    Mailinglists

    + +

    Mailinglists are provided by the lists.xw3.org mailinglist server.

    + +

    Simply click "Subscribe" to join a list by sending a blank email. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ListDescriptionAction
    fun-announcements@fun-lang.xyzFor Fun announcements[Subscribe][Unsubscribe]
    xw3-developers@fun-lang.xyzDeveloper discussion about Fun[Subscribe][Unsubscribe]
    xw3-users@fun-lang.xyzUser discussion about Fun[Subscribe][Unsubscribe]
    + +
    + +

    You can also post to a list without a subscription, but your messages will be moderated and experience indefinite delays in delivery, and you won't receive replies if other users simply reply to the list without CCing you.

    + +

    Mastodon

    + +

    We will use Mastodon for announcements in the future: https://fosstodon.org/@fun.

    + +

    Others

    + +

    We believe that the communication channels mentioned above are sufficient for Fun development. IRC, mailing lists and Mastodon provide you with the perfect entry points for discussions about Fun development. Nothing more is needed.

    + +

    Matrix

    + +

    We do not and will never provide chat over the Matrix protocol in any way. Matrix sucks!

    + +

    We also will in no way provide an IRC <-> Matrix bridge. Again, Matrix sucks!

    + +

    For details read why Matrix sucks!

    + diff --git a/web/contact/contact.html b/web/contact/contact.html new file mode 100644 index 0000000..3a135c7 --- /dev/null +++ b/web/contact/contact.html @@ -0,0 +1,69 @@ +--- +layout: page +published: true +noToc: true +noDate: false +noPermalink: true +noComments: true +title: Contact +subtitle: Please use the following form to contact us directly, anonymously if you prefer. +description: Contact +permalink: /contact/ +tags: +- contact +--- + + + +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    * = Required fields
    + +
    +
    +
    + diff --git a/web/copyright/copyright.md b/web/copyright/copyright.md new file mode 100644 index 0000000..908786b --- /dev/null +++ b/web/copyright/copyright.md @@ -0,0 +1,19 @@ +--- +layout: page +published: true +noToc: true +title: Copyright +description: The copyright for the content at fun-lang.xyz. +permalink: /copyright/ +tags: +- license +- copyright +metasub: projects +--- + +The contents of this website (unless otherwise noted) are licensed under a non-commercial share-alike license. This means (among other things) that you may not put my content on a web page that contains a paywall, Google AdWords or any other similar advertising, and you may not use any automated system to take an RSS feed from my blog (either directly, via Feedburner, or via a Planet installation or other syndication service that includes my posts) and post it to another blog for commercial purposes (which includes attempts to increase page-rank or other SEO). + +So, all content is licensed under an [{{ site.license_name }} ({{ site.license }})]({{ site.license_url }}){:class="ext"} license if not otherwise mentioned. You must [contact](/contact/){:class="ext"} me and ask for permission if you want to use some of my content for commercial purposes. + +Original source: [https://doc.coker.com.au/legal/blog-license/](https://doc.coker.com.au/legal/blog-license/){:class="ext"} - I modified the content to what you read above. + diff --git a/web/css/.gitkeep b/web/css/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/web/css/cookieconsent.min.css b/web/css/cookieconsent.min.css new file mode 100644 index 0000000..d4d4390 --- /dev/null +++ b/web/css/cookieconsent.min.css @@ -0,0 +1,6 @@ +.cc-window{opacity:1;-webkit-transition:opacity 1s ease;transition:opacity 1s ease}.cc-window.cc-invisible{opacity:0}.cc-animate.cc-revoke{-webkit-transition:transform 1s ease;-webkit-transition:-webkit-transform 1s ease;transition:-webkit-transform 1s ease;transition:transform 1s ease;transition:transform 1s ease,-webkit-transform 1s ease}.cc-animate.cc-revoke.cc-top{-webkit-transform:translateY(-2em);transform:translateY(-2em)}.cc-animate.cc-revoke.cc-bottom{-webkit-transform:translateY(2em);transform:translateY(2em)}.cc-animate.cc-revoke.cc-active.cc-top{-webkit-transform:translateY(0);transform:translateY(0)}.cc-animate.cc-revoke.cc-active.cc-bottom{-webkit-transform:translateY(0);transform:translateY(0)}.cc-revoke:hover{-webkit-transform:translateY(0);transform:translateY(0)}.cc-grower{max-height:0;overflow:hidden;-webkit-transition:max-height 1s;transition:max-height 1s} +.cc-revoke,.cc-window{position:fixed;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:Helvetica,Calibri,Arial,sans-serif;font-size:16px;line-height:1.5em;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;z-index:9999}.cc-window.cc-static{position:static}.cc-window.cc-floating{padding:2em;max-width:24em;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.cc-window.cc-banner{padding:1em 1.8em;width:100%;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.cc-revoke{padding:.5em}.cc-revoke:hover{text-decoration:underline}.cc-header{font-size:18px;font-weight:700}.cc-btn,.cc-close,.cc-link,.cc-revoke{cursor:pointer}.cc-link{opacity:.8;display:inline-block;padding:.2em;text-decoration:underline}.cc-link:hover{opacity:1}.cc-link:active,.cc-link:visited{color:initial}.cc-btn{display:block;padding:.4em .8em;font-size:.9em;font-weight:700;border-width:2px;border-style:solid;text-align:center;white-space:nowrap}.cc-highlight .cc-btn:first-child{background-color:transparent;border-color:transparent}.cc-highlight .cc-btn:first-child:focus,.cc-highlight .cc-btn:first-child:hover{background-color:transparent;text-decoration:underline}.cc-close{display:block;position:absolute;top:.5em;right:.5em;font-size:1.6em;opacity:.9;line-height:.75}.cc-close:focus,.cc-close:hover{opacity:1} +.cc-revoke.cc-top{top:0;left:3em;border-bottom-left-radius:.5em;border-bottom-right-radius:.5em}.cc-revoke.cc-bottom{bottom:0;left:3em;border-top-left-radius:.5em;border-top-right-radius:.5em}.cc-revoke.cc-left{left:3em;right:unset}.cc-revoke.cc-right{right:3em;left:unset}.cc-top{top:1em}.cc-left{left:1em}.cc-right{right:1em}.cc-bottom{bottom:1em}.cc-floating>.cc-link{margin-bottom:1em}.cc-floating .cc-message{display:block;margin-bottom:1em}.cc-window.cc-floating .cc-compliance{-webkit-box-flex:1;-ms-flex:1 0 auto;flex:1 0 auto}.cc-window.cc-banner{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.cc-banner.cc-top{left:0;right:0;top:0}.cc-banner.cc-bottom{left:0;right:0;bottom:0}.cc-banner .cc-message{display:block;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;max-width:100%;margin-right:1em}.cc-compliance{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-line-pack:justify;align-content:space-between}.cc-floating .cc-compliance>.cc-btn{-webkit-box-flex:1;-ms-flex:1;flex:1}.cc-btn+.cc-btn{margin-left:.5em} +@media print{.cc-revoke,.cc-window{display:none}}@media screen and (max-width:900px){.cc-btn{white-space:normal}}@media screen and (max-width:414px) and (orientation:portrait),screen and (max-width:736px) and (orientation:landscape){.cc-window.cc-top{top:0}.cc-window.cc-bottom{bottom:0}.cc-window.cc-banner,.cc-window.cc-floating,.cc-window.cc-left,.cc-window.cc-right{left:0;right:0}.cc-window.cc-banner{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.cc-window.cc-banner .cc-compliance{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto}.cc-window.cc-floating{max-width:none}.cc-window .cc-message{margin-bottom:1em}.cc-window.cc-banner{-webkit-box-align:unset;-ms-flex-align:unset;align-items:unset}.cc-window.cc-banner .cc-message{margin-right:0}} +.cc-floating.cc-theme-classic{padding:1.2em;border-radius:5px}.cc-floating.cc-type-info.cc-theme-classic .cc-compliance{text-align:center;display:inline;-webkit-box-flex:0;-ms-flex:none;flex:none}.cc-theme-classic .cc-btn{border-radius:5px}.cc-theme-classic .cc-btn:last-child{min-width:140px}.cc-floating.cc-type-info.cc-theme-classic .cc-btn{display:inline-block} +.cc-theme-edgeless.cc-window{padding:0}.cc-floating.cc-theme-edgeless .cc-message{margin:2em;margin-bottom:1.5em}.cc-banner.cc-theme-edgeless .cc-btn{margin:0;padding:.8em 1.8em;height:100%}.cc-banner.cc-theme-edgeless .cc-message{margin-left:1em}.cc-floating.cc-theme-edgeless .cc-btn+.cc-btn{margin-left:0} \ No newline at end of file diff --git a/web/css/main.scss b/web/css/main.scss new file mode 100644 index 0000000..01b4373 --- /dev/null +++ b/web/css/main.scss @@ -0,0 +1,33 @@ +--- +# Only the main Sass file needs front matter (the dashes are enough) +--- +@charset "utf-8"; +$base-font-family: "CPS"; +$base-font-size: 16px; +$small-font-size: $base-font-size * 0.875; +$base-icon-font-family: "MDI"; +$base-icon-size: 12px; +$base-icon-color: #565656; +$base-line-height: 1.6; +$spacing-unit: 18px; +$text-color: #000; +$background-color: #565656; +$headline-color: #bc6c21; //#b40000; +$hover-color: #bc6c21; +$topbutton-color: $headline-color; +$brand-color: #1fa2af; +$brand-color-light: lighten($brand-color, 40%); +$grey-color: #828282; +$grey-color-light: #e8e8e8; +$grey-color-dark: #dbdbdb; +$green-color: #3ab215; +$tablehead-color: #bc6c21; +$content-width: 1024px; +$on-palm: 761px; +$on-laptop: 1024px; +@mixin media-query($device) { + @media screen and (max-width: $device) { + @content; + } +} +@import "base", "fonts", "forms", "highlight", "isso", "layout", "links", "toc"; diff --git a/web/documentation/documentation.md b/web/documentation/documentation.md new file mode 100644 index 0000000..8354785 --- /dev/null +++ b/web/documentation/documentation.md @@ -0,0 +1,49 @@ +--- +layout: page +published: true +noToc: true +noComments: false +noDate: false +title: Documentation +subtitle: Some documentation about the Fun programming language. +description: The Fun Documentation +permalink: /documentation/ +lang: en +tags: +- documentation +- handbook +- installation +- usage +- introduction +- help +- guide +- howto +- docs +- specifications +- specs +- repl +--- + +## Basics + +[The Fun Handbook is found here](https://git.xw3.org/fun/fun/src/branch/main/docs/handbook.md){:class="git"}! + +Look at [https://git.xw3.org/fun/fun/src/branch/main/docs](https://git.xw3.org/fun/fun/src/branch/main/docs){:class="git"} for more detailed documentation! + +## More information + +- [Specification v0.3](https://git.xw3.org/fun/fun/src/branch/main/spec/v0.3.md){:class="git"} +- [Specification v0.2](https://git.xw3.org/fun/fun/src/branch/main/spec/v0.2.md){:class="git"} +- [Specification v0.1](https://git.xw3.org/fun/fun/src/branch/main/spec/v0.1.md){:class="git"} +- [Examples](https://git.xw3.org/fun/fun/src/branch/main/examples){:class="git"} +- [Standard Library](https://git.xw3.org/fun/fun/src/branch/main/lib){:class="git"} +- [Fun REPL Guide](https://git.xw3.org/fun/fun/src/branch/main/docs/repl.md){:class="git"} + +The examples directory contains demonstrations of most Fun features, from basic "Hello, World!" to threading, networking, classes, and more. The lib directory includes modules written in Fun itself. + +## For Developers + +- [Fun Internals](https://git.xw3.org/fun/fun/src/branch/main/docs/internals.md){:class="git"} +- [Fun Opcodes](https://git.xw3.org/fun/fun/src/branch/main/docs/opcodes.md){:class="git"} +- [Basic Rust Opcodes Support](https://git.xw3.org/fun/fun/src/branch/main/docs/rust.md){:class="git"} + diff --git a/web/faq/faq.md b/web/faq/faq.md new file mode 100644 index 0000000..5c6d9bc --- /dev/null +++ b/web/faq/faq.md @@ -0,0 +1,17 @@ +--- +layout: page +published: true +noToc: true +title: FAQ +subtitle: Frequently Asked Questions +description: Frequently Asked Questions (FAQ) +permalink: /faq/ +tags: +- faq +- about +--- + +## Why Fun? + +Because of fun... ;) + diff --git a/web/favicon.png b/web/favicon.png new file mode 100644 index 0000000..920ede3 Binary files /dev/null and b/web/favicon.png differ diff --git a/web/feed/feed.xml b/web/feed/feed.xml new file mode 100644 index 0000000..ac727c6 --- /dev/null +++ b/web/feed/feed.xml @@ -0,0 +1,30 @@ +--- +layout: +permalink: /feed/ +--- + + + + {{ site.title | xml_escape }} + {{ site.description | xml_escape }} + {{ site.url }} + + {{ site.time | date_to_rfc822 }} + {{ site.time | date_to_rfc822 }} + {% for post in site.posts limit:10 %} + + {{ post.title | xml_escape }} + {{ post.content | xml_escape }} + {{ post.date | date_to_rfc822 }} + {{ site.url }}{{ post.url }} + {{ site.url }}{{ post.url }} + {% for tag in post.tags %} + {{ tag | xml_escape }} + {% endfor %} + {% for cat in post.categories %} + {{ cat | xml_escape }} + {% endfor %} + + {% endfor %} + + diff --git a/web/files/.gitkeep b/web/files/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/web/fonts/.gitkeep b/web/fonts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/web/fonts/Courier-Prime-Sans.ttf b/web/fonts/Courier-Prime-Sans.ttf new file mode 100644 index 0000000..32e795a Binary files /dev/null and b/web/fonts/Courier-Prime-Sans.ttf differ diff --git a/web/fonts/materialdesignicons-webfont.woff2 b/web/fonts/materialdesignicons-webfont.woff2 new file mode 100644 index 0000000..8c69b85 Binary files /dev/null and b/web/fonts/materialdesignicons-webfont.woff2 differ diff --git a/web/images/.gitkeep b/web/images/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/web/images/by-nc-sa-80x15.png b/web/images/by-nc-sa-80x15.png new file mode 100644 index 0000000..5fbfc92 Binary files /dev/null and b/web/images/by-nc-sa-80x15.png differ diff --git a/web/images/by-nc-sa-88x31.png b/web/images/by-nc-sa-88x31.png new file mode 100644 index 0000000..e2d1df9 Binary files /dev/null and b/web/images/by-nc-sa-88x31.png differ diff --git a/web/images/fun-square.png b/web/images/fun-square.png new file mode 100644 index 0000000..82507b4 Binary files /dev/null and b/web/images/fun-square.png differ diff --git a/web/images/fun.png b/web/images/fun.png new file mode 100644 index 0000000..ef12eed Binary files /dev/null and b/web/images/fun.png differ diff --git a/web/images/spinner.gif b/web/images/spinner.gif new file mode 100644 index 0000000..09e286c Binary files /dev/null and b/web/images/spinner.gif differ diff --git a/web/images/up-arrow.png b/web/images/up-arrow.png new file mode 100644 index 0000000..122d320 Binary files /dev/null and b/web/images/up-arrow.png differ diff --git a/web/index.md b/web/index.md new file mode 100644 index 0000000..8e99c29 --- /dev/null +++ b/web/index.md @@ -0,0 +1,66 @@ +--- +layout: page +title: :load /index.fun +subtitle: The programming language that makes you have fun! +description: Blog and Homepage +metasub: news +noToc: true +noDate: false +tags: +- fun +- project +- dynamic +- static +- programming +- blog +- language +permalink: / +--- + +

    What is Fun?

    + +

    Fun is an experiment, just for fun, but Fun works!

    + +

    Fun is a highly strict programming language, but also highly simple. It looks like Python (My favorite language), but there are differences.

    + +

    Influenced by Bash, C, Lua, PHP, Python, and a little Rust (Most influences came from linked languages).

    + +

    Fun is and will ever be 100% free under the terms of the Apache-2.0 License.

    + +

    [Read more]

    + + + +

    Blog (Feed)

    + +{% for post in site.tags.pinned %} +
    +

    {{ post.title }} 📌

    + +{{ post.content | truncatewords: site.truncatewords_length }} +

    [Read post]

    +
    +{% endfor %} + +{% for post in site.posts %} +{% unless post.tags contains 'pinned' %} +
    +

    {{ post.title }}

    + +{{ post.content | truncatewords: site.truncatewords_length }} +

    [Read post]

    +
    +{% endunless %} +{% endfor %} + +

    Pages

    + +
    +{% if paginator.page == 1 %}1{% else %}1{% endif %} +{% for count in (2..paginator.total_pages) %} +{% if count == paginator.page %}{{ count }}{% else %}{{ count }}{% endif %} +{% endfor %} +

    + diff --git a/web/js/.gitkeep b/web/js/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/web/js/cookieconsent.min.js b/web/js/cookieconsent.min.js new file mode 100644 index 0000000..54105e0 --- /dev/null +++ b/web/js/cookieconsent.min.js @@ -0,0 +1 @@ +!function(e){if(!e.hasInitialised){var t={escapeRegExp:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},hasClass:function(e,t){var i=" ";return 1===e.nodeType&&(i+e.className+i).replace(/[\n\t]/g,i).indexOf(i+t+i)>=0},addClass:function(e,t){e.className+=" "+t},removeClass:function(e,t){var i=new RegExp("\\b"+this.escapeRegExp(t)+"\\b");e.className=e.className.replace(i,"")},interpolateString:function(e,t){return e.replace(/{{([a-z][a-z0-9\-_]*)}}/gi,function(e){return t(arguments[1])||""})},getCookie:function(e){var t=("; "+document.cookie).split("; "+e+"=");return t.length<2?void 0:t.pop().split(";").shift()},setCookie:function(e,t,i,n,o,s){var r=new Date;r.setHours(r.getHours()+24*(i||365));var a=[e+"="+t,"expires="+r.toUTCString(),"path="+(o||"/")];n&&a.push("domain="+n),s&&a.push("secure"),document.cookie=a.join(";")},deepExtend:function(e,t){for(var i in t)t.hasOwnProperty(i)&&(i in e&&this.isPlainObject(e[i])&&this.isPlainObject(t[i])?this.deepExtend(e[i],t[i]):e[i]=t[i]);return e},throttle:function(e,t){var i=!1;return function(){i||(e.apply(this,arguments),i=!0,setTimeout(function(){i=!1},t))}},hash:function(e){var t,i,n=0;if(0===e.length)return n;for(t=0,i=e.length;t=128?"#000":"#fff"},getLuminance:function(e){var t=parseInt(this.normaliseHex(e),16),i=38+(t>>16),n=38+(t>>8&255),o=38+(255&t);return"#"+(16777216+65536*(i<255?i<1?0:i:255)+256*(n<255?n<1?0:n:255)+(o<255?o<1?0:o:255)).toString(16).slice(1)},isMobile:function(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},isPlainObject:function(e){return"object"==typeof e&&null!==e&&e.constructor==Object},traverseDOMPath:function(e,i){return e&&e.parentNode?t.hasClass(e,i)?e:this.traverseDOMPath(e.parentNode,i):null}};e.status={deny:"deny",allow:"allow",dismiss:"dismiss"},e.transitionEnd=function(){var e=document.createElement("div"),t={t:"transitionend",OT:"oTransitionEnd",msT:"MSTransitionEnd",MozT:"transitionend",WebkitT:"webkitTransitionEnd"};for(var i in t)if(t.hasOwnProperty(i)&&void 0!==e.style[i+"ransition"])return t[i];return""}(),e.hasTransition=!!e.transitionEnd;var i=Object.keys(e.status).map(t.escapeRegExp);e.customStyles={},e.Popup=function(){var n={enabled:!0,container:null,cookie:{name:"cookieconsent_status",path:"/",domain:"",expiryDays:365,secure:!1},onPopupOpen:function(){},onPopupClose:function(){},onInitialise:function(e){},onStatusChange:function(e,t){},onRevokeChoice:function(){},onNoCookieLaw:function(e,t){},content:{header:"Cookies used on the website!",message:"This website uses cookies to ensure you get the best experience on our website.",dismiss:"Got it!",allow:"Allow cookies",deny:"Decline",link:"Learn more",href:"https://www.cookiesandyou.com",close:"❌",target:"_self",policy:"Cookie Policy"},elements:{header:'{{header}} ',message:'{{message}}',messagelink:'{{message}} {{link}}',dismiss:'{{dismiss}}',allow:'{{allow}}',deny:'{{deny}}',link:'{{link}}',close:'{{close}}'},window:'',revokeBtn:'
    {{policy}}
    ',compliance:{info:'
    {{dismiss}}
    ',"opt-in":'
    {{deny}}{{allow}}
    ',"opt-out":'
    {{deny}}{{allow}}
    '},type:"info",layouts:{basic:"{{messagelink}}{{compliance}}","basic-close":"{{messagelink}}{{compliance}}{{close}}","basic-header":"{{header}}{{message}}{{link}}{{compliance}}"},layout:"basic",position:"bottom",theme:"block",static:!1,palette:null,revokable:!1,animateRevokable:!0,showLink:!0,dismissOnScroll:!1,dismissOnTimeout:!1,dismissOnWindowClick:!1,ignoreClicksFrom:["cc-revoke","cc-btn"],autoOpen:!0,autoAttach:!0,whitelistPage:[],blacklistPage:[],overrideHTML:null};function o(){this.initialise.apply(this,arguments)}function s(e){this.openingTimeout=null,t.removeClass(e,"cc-invisible")}function r(t){t.style.display="none",t.removeEventListener(e.transitionEnd,this.afterTransition),this.afterTransition=null}function a(){var e=this.options.position.split("-"),t=[];return e.forEach(function(e){t.push("cc-"+e)}),t}function c(n){var o=this.options,s=document.createElement("div"),r=o.container&&1===o.container.nodeType?o.container:document.body;s.innerHTML=n;var a=s.children[0];return a.style.display="none",t.hasClass(a,"cc-window")&&e.hasTransition&&t.addClass(a,"cc-invisible"),this.onButtonClick=function(n){var o=t.traverseDOMPath(n.target,"cc-btn")||n.target;if(t.hasClass(o,"cc-btn")){var s=o.className.match(new RegExp("\\bcc-("+i.join("|")+")\\b")),r=s&&s[1]||!1;r&&(this.setStatus(r),this.close(!0))}t.hasClass(o,"cc-close")&&(this.setStatus(e.status.dismiss),this.close(!0));t.hasClass(o,"cc-revoke")&&this.revokeChoice()}.bind(this),a.addEventListener("click",this.onButtonClick),o.autoAttach&&(r.firstChild?r.insertBefore(a,r.firstChild):r.appendChild(a)),a}function l(e){return"000000"==(e=t.normaliseHex(e))?"#222":t.getLuminance(e)}function u(e,t){for(var i=0,n=e.length;i=0;o&&t(n);return o}.call(this)&&(this.options.enabled=!1),u(this.options.blacklistPage,location.pathname)&&(this.options.enabled=!1),u(this.options.whitelistPage,location.pathname)&&(this.options.enabled=!0);var o=this.options.window.replace("{{classes}}",function(){var i=this.options,n="top"==i.position||"bottom"==i.position?"banner":"floating";t.isMobile()&&(n="floating");var o=["cc-"+n,"cc-type-"+i.type,"cc-theme-"+i.theme];i.static&&o.push("cc-static");o.push.apply(o,a.call(this));(function(i){var n=t.hash(JSON.stringify(i)),o="cc-color-override-"+n,s=t.isPlainObject(i);this.customStyleSelector=s?o:null,s&&function(i,n,o){if(e.customStyles[i])return void++e.customStyles[i].references;var s={},r=n.popup,a=n.button,c=n.highlight;r&&(r.text=r.text?r.text:t.getContrast(r.background),r.link=r.link?r.link:r.text,s[o+".cc-window"]=["color: "+r.text,"background-color: "+r.background],s[o+".cc-revoke"]=["color: "+r.text,"background-color: "+r.background],s[o+" .cc-link,"+o+" .cc-link:active,"+o+" .cc-link:visited"]=["color: "+r.link],a&&(a.text=a.text?a.text:t.getContrast(a.background),a.border=a.border?a.border:"transparent",s[o+" .cc-btn"]=["color: "+a.text,"border-color: "+a.border,"background-color: "+a.background],a.padding&&s[o+" .cc-btn"].push("padding: "+a.padding),"transparent"!=a.background&&(s[o+" .cc-btn:hover, "+o+" .cc-btn:focus"]=["background-color: "+(a.hover||l(a.background))]),c?(c.text=c.text?c.text:t.getContrast(c.background),c.border=c.border?c.border:"transparent",s[o+" .cc-highlight .cc-btn:first-child"]=["color: "+c.text,"border-color: "+c.border,"background-color: "+c.background]):s[o+" .cc-highlight .cc-btn:first-child"]=["color: "+r.text]));var u=document.createElement("style");document.head.appendChild(u),e.customStyles[i]={references:1,element:u.sheet};var h=-1;for(var p in s)s.hasOwnProperty(p)&&u.sheet.insertRule(p+"{"+s[p].join(";")+"}",++h)}(n,i,"."+o);return s}).call(this,this.options.palette);this.customStyleSelector&&o.push(this.customStyleSelector);return o}.call(this).join(" ")).replace("{{children}}",function(){var e={},i=this.options;i.showLink||(i.elements.link="",i.elements.messagelink=i.elements.message);Object.keys(i.elements).forEach(function(n){e[n]=t.interpolateString(i.elements[n],function(e){var t=i.content[e];return e&&"string"==typeof t&&t.length?t:""})});var n=i.compliance[i.type];n||(n=i.compliance.info);e.compliance=t.interpolateString(n,function(t){return e[t]});var o=i.layouts[i.layout];o||(o=i.layouts.basic);return t.interpolateString(o,function(t){return e[t]})}.call(this)),s=this.options.overrideHTML;if("string"==typeof s&&s.length&&(o=s),this.options.static){var r=c.call(this,'
    '+o+"
    ");r.style.display="",this.element=r.firstChild,this.element.style.display="none",t.addClass(this.element,"cc-invisible")}else this.element=c.call(this,o);(function(){var i=this.setStatus.bind(this),n=this.close.bind(this),o=this.options.dismissOnTimeout;"number"==typeof o&&o>=0&&(this.dismissTimeout=window.setTimeout(function(){i(e.status.dismiss),n(!0)},Math.floor(o)));var s=this.options.dismissOnScroll;if("number"==typeof s&&s>=0){var r=function(t){window.pageYOffset>Math.floor(s)&&(i(e.status.dismiss),n(!0),window.removeEventListener("scroll",r),this.onWindowScroll=null)};this.options.enabled&&(this.onWindowScroll=r,window.addEventListener("scroll",r))}var a=this.options.dismissOnWindowClick,c=this.options.ignoreClicksFrom;if(a){var l=function(o){for(var s=!1,r=o.path.length,a=c.length,u=0;uo&&(i=!0),i?t.hasClass(n,"cc-active")||t.addClass(n,"cc-active"):t.hasClass(n,"cc-active")&&t.removeClass(n,"cc-active")},200);this.onMouseMove=o,window.addEventListener("mousemove",o)}}}.call(this),this.options.autoOpen&&this.autoOpen()},o.prototype.destroy=function(){this.onButtonClick&&this.element&&(this.element.removeEventListener("click",this.onButtonClick),this.onButtonClick=null),this.dismissTimeout&&(clearTimeout(this.dismissTimeout),this.dismissTimeout=null),this.onWindowScroll&&(window.removeEventListener("scroll",this.onWindowScroll),this.onWindowScroll=null),this.onWindowClick&&(window.removeEventListener("click",this.onWindowClick),this.onWindowClick=null),this.onMouseMove&&(window.removeEventListener("mousemove",this.onMouseMove),this.onMouseMove=null),this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.element=null,this.revokeBtn&&this.revokeBtn.parentNode&&this.revokeBtn.parentNode.removeChild(this.revokeBtn),this.revokeBtn=null,function(i){if(t.isPlainObject(i)){var n=t.hash(JSON.stringify(i)),o=e.customStyles[n];if(o&&!--o.references){var s=o.element.ownerNode;s&&s.parentNode&&s.parentNode.removeChild(s),e.customStyles[n]=null}}}(this.options.palette),this.options=null},o.prototype.open=function(t){if(this.element)return this.isOpen()||(e.hasTransition?this.fadeIn():this.element.style.display="",this.options.revokable&&this.toggleRevokeButton(),this.options.onPopupOpen.call(this)),this},o.prototype.close=function(t){if(this.element)return this.isOpen()&&(e.hasTransition?this.fadeOut():this.element.style.display="none",t&&this.options.revokable&&this.toggleRevokeButton(!0),this.options.onPopupClose.call(this)),this},o.prototype.fadeIn=function(){var i=this.element;if(e.hasTransition&&i&&(this.afterTransition&&r.call(this,i),t.hasClass(i,"cc-invisible"))){if(i.style.display="",this.options.static){var n=this.element.clientHeight;this.element.parentNode.style.maxHeight=n+"px"}this.openingTimeout=setTimeout(s.bind(this,i),20)}},o.prototype.fadeOut=function(){var i=this.element;e.hasTransition&&i&&(this.openingTimeout&&(clearTimeout(this.openingTimeout),s.bind(this,i)),t.hasClass(i,"cc-invisible")||(this.options.static&&(this.element.parentNode.style.maxHeight=""),this.afterTransition=r.bind(this,i),i.addEventListener(e.transitionEnd,this.afterTransition),t.addClass(i,"cc-invisible")))},o.prototype.isOpen=function(){return this.element&&""==this.element.style.display&&(!e.hasTransition||!t.hasClass(this.element,"cc-invisible"))},o.prototype.toggleRevokeButton=function(e){this.revokeBtn&&(this.revokeBtn.style.display=e?"":"none")},o.prototype.revokeChoice=function(e){this.options.enabled=!0,this.clearStatus(),this.options.onRevokeChoice.call(this),e||this.autoOpen()},o.prototype.hasAnswered=function(t){return Object.keys(e.status).indexOf(this.getStatus())>=0},o.prototype.hasConsented=function(t){var i=this.getStatus();return i==e.status.allow||i==e.status.dismiss},o.prototype.autoOpen=function(e){!this.hasAnswered()&&this.options.enabled?this.open():this.hasAnswered()&&this.options.revokable&&this.toggleRevokeButton(!0)},o.prototype.setStatus=function(i){var n=this.options.cookie,o=t.getCookie(n.name),s=Object.keys(e.status).indexOf(o)>=0;Object.keys(e.status).indexOf(i)>=0?(t.setCookie(n.name,i,n.expiryDays,n.domain,n.path,n.secure),this.options.onStatusChange.call(this,i,s)):this.clearStatus()},o.prototype.getStatus=function(){return t.getCookie(this.options.cookie.name)},o.prototype.clearStatus=function(){var e=this.options.cookie;t.setCookie(e.name,"",-1,e.domain,e.path)},o}(),e.Location=function(){var e={timeout:5e3,services:["ipinfo"],serviceDefinitions:{ipinfo:function(){return{url:"//ipinfo.io",headers:["Accept: application/json"],callback:function(e,t){try{var i=JSON.parse(t);return i.error?s(i):{code:i.country}}catch(e){return s({error:"Invalid response ("+e+")"})}}}},ipinfodb:function(e){return{url:"//api.ipinfodb.com/v3/ip-country/?key={api_key}&format=json&callback={callback}",isScript:!0,callback:function(e,t){try{var i=JSON.parse(t);return"ERROR"==i.statusCode?s({error:i.statusMessage}):{code:i.countryCode}}catch(e){return s({error:"Invalid response ("+e+")"})}}}},maxmind:function(){return{url:"//js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js",isScript:!0,callback:function(e){window.geoip2?geoip2.country(function(t){try{e({code:t.country.iso_code})}catch(t){e(s(t))}},function(t){e(s(t))}):e(new Error("Unexpected response format. The downloaded script should have exported `geoip2` to the global scope"))}}}}};function i(i){t.deepExtend(this.options={},e),t.isPlainObject(i)&&t.deepExtend(this.options,i),this.currentServiceIndex=-1}function n(e,t,i){var n,o=document.createElement("script");o.type="text/"+(e.type||"javascript"),o.src=e.src||e,o.async=!1,o.onreadystatechange=o.onload=function(){var e=o.readyState;clearTimeout(n),t.done||e&&!/loaded|complete/.test(e)||(t.done=!0,t(),o.onreadystatechange=o.onload=null)},document.body.appendChild(o),n=setTimeout(function(){t.done=!0,t(),o.onreadystatechange=o.onload=null},i)}function o(e,t,i,n,o){var s=new(window.XMLHttpRequest||window.ActiveXObject)("MSXML2.XMLHTTP.3.0");if(s.open(n?"POST":"GET",e,1),s.setRequestHeader("Content-type","application/x-www-form-urlencoded"),Array.isArray(o))for(var r=0,a=o.length;r3&&t(s)}),s.send(n)}function s(e){return new Error("Error ["+(e.code||"UNKNOWN")+"]: "+e.error)}return i.prototype.getNextService=function(){var e;do{e=this.getServiceByIdx(++this.currentServiceIndex)}while(this.currentServiceIndex=0,revokable:t.revokable.indexOf(e)>=0,explicitAction:t.explicitAction.indexOf(e)>=0}},i.prototype.applyLaw=function(e,t){var i=this.get(t);return i.hasLaw||(e.enabled=!1,"function"==typeof e.onNoCookieLaw&&e.onNoCookieLaw(t,i)),this.options.regionalLaw&&(i.revokable&&(e.revokable=!0),i.explicitAction&&(e.dismissOnScroll=!1,e.dismissOnTimeout=!1)),e},i}(),e.initialise=function(i,n,o){var s=new e.Law(i.law);n||(n=function(){}),o||(o=function(){});var r=Object.keys(e.status),a=t.getCookie("cookieconsent_status");r.indexOf(a)>=0?n(new e.Popup(i)):e.getCountryCode(i,function(t){delete i.law,delete i.location,t.code&&(i=s.applyLaw(i,t.code)),n(new e.Popup(i))},function(t){delete i.law,delete i.location,o(t,new e.Popup(i))})},e.getCountryCode=function(t,i,n){t.law&&t.law.countryCode?i({code:t.law.countryCode}):t.location?new e.Location(t.location).locate(function(e){i(e||{})},n):i({})},e.utils=t,e.hasInitialised=!0,window.cookieconsent=e}}(window.cookieconsent||{}); diff --git a/web/js/jquery-3.6.4.min.js b/web/js/jquery-3.6.4.min.js new file mode 100644 index 0000000..0de648e --- /dev/null +++ b/web/js/jquery-3.6.4.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.4 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,y=n.hasOwnProperty,a=y.toString,l=a.call(Object),v={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.4",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&v(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!y||!y.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ve(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ye(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.cssHas=ce(function(){try{return C.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],y=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||y.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||y.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||y.push(".#.+[+~]"),e.querySelectorAll("\\\f"),y.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),d.cssHas||y.push(":has"),y=y.length&&new RegExp(y.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),v=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType&&e.documentElement||e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&v(p,e)?-1:t==C||t.ownerDocument==p&&v(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!y||!y.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),v.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",v.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",v.option=!!ce.lastChild;var ge={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),v.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
    ",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(v.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return B(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=_e(v.pixelPosition,function(e,t){if(t)return t=Be(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return B(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
    ",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0 to your HTML + Add class="sortable" to any table you'd like to make sortable + Click on the headers to sort + + Thanks to many, many people for contributions and suggestions. + Licenced as X11: http://www.kryogenix.org/code/browser/licence.html + This basically means: do what you want with it. +*/ + + +var stIsIE = /*@cc_on!@*/false; + +sorttable = { + init: function() { + // quit if this function has already been called + if (arguments.callee.done) return; + // flag this function so we don't do the same thing twice + arguments.callee.done = true; + // kill the timer + if (_timer) clearInterval(_timer); + + if (!document.createElement || !document.getElementsByTagName) return; + + sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; + + forEach(document.getElementsByTagName('table'), function(table) { + if (table.className.search(/\bsortable\b/) != -1) { + sorttable.makeSortable(table); + } + }); + + }, + + makeSortable: function(table) { + if (table.getElementsByTagName('thead').length == 0) { + // table doesn't have a tHead. Since it should have, create one and + // put the first table row in it. + the = document.createElement('thead'); + the.appendChild(table.rows[0]); + table.insertBefore(the,table.firstChild); + } + // Safari doesn't support table.tHead, sigh + if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; + + if (table.tHead.rows.length != 1) return; // can't cope with two header rows + + // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as + // "total" rows, for example). This is B&R, since what you're supposed + // to do is put them in a tfoot. So, if there are sortbottom rows, + // for backwards compatibility, move them to tfoot (creating it if needed). + sortbottomrows = []; + for (var i=0; i5' : ' ▴'; + this.appendChild(sortrevind); + return; + } + if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { + // if we're already sorted by this column in reverse, just + // re-reverse the table, which is quicker + sorttable.reverse(this.sorttable_tbody); + this.className = this.className.replace('sorttable_sorted_reverse', + 'sorttable_sorted'); + this.removeChild(document.getElementById('sorttable_sortrevind')); + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + return; + } + + // remove sorttable_sorted classes + theadrow = this.parentNode; + forEach(theadrow.childNodes, function(cell) { + if (cell.nodeType == 1) { // an element + cell.className = cell.className.replace('sorttable_sorted_reverse',''); + cell.className = cell.className.replace('sorttable_sorted',''); + } + }); + sortfwdind = document.getElementById('sorttable_sortfwdind'); + if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } + sortrevind = document.getElementById('sorttable_sortrevind'); + if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } + + this.className += ' sorttable_sorted'; + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + + // build an array to sort. This is a Schwartzian transform thing, + // i.e., we "decorate" each row with the actual sort key, + // sort based on the sort keys, and then put the rows back in order + // which is a lot faster because you only do getInnerText once per row + row_array = []; + col = this.sorttable_columnindex; + rows = this.sorttable_tbody.rows; + for (var j=0; j 12) { + // definitely dd/mm + return sorttable.sort_ddmm; + } else if (second > 12) { + return sorttable.sort_mmdd; + } else { + // looks like a date, but we can't tell which, so assume + // that it's dd/mm (English imperialism!) and keep looking + sortfn = sorttable.sort_ddmm; + } + } + } + } + return sortfn; + }, + + getInnerText: function(node) { + // gets the text we want to use for sorting for a cell. + // strips leading and trailing whitespace. + // this is *not* a generic getInnerText function; it's special to sorttable. + // for example, you can override the cell text with a customkey attribute. + // it also gets .value for fields. + + if (!node) return ""; + + hasInputs = (typeof node.getElementsByTagName == 'function') && + node.getElementsByTagName('input').length; + + if (node.getAttribute("sorttable_customkey") != null) { + return node.getAttribute("sorttable_customkey"); + } + else if (typeof node.textContent != 'undefined' && !hasInputs) { + return node.textContent.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.innerText != 'undefined' && !hasInputs) { + return node.innerText.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.text != 'undefined' && !hasInputs) { + return node.text.replace(/^\s+|\s+$/g, ''); + } + else { + switch (node.nodeType) { + case 3: + if (node.nodeName.toLowerCase() == 'input') { + return node.value.replace(/^\s+|\s+$/g, ''); + } + case 4: + return node.nodeValue.replace(/^\s+|\s+$/g, ''); + break; + case 1: + case 11: + var innerText = ''; + for (var i = 0; i < node.childNodes.length; i++) { + innerText += sorttable.getInnerText(node.childNodes[i]); + } + return innerText.replace(/^\s+|\s+$/g, ''); + break; + default: + return ''; + } + } + }, + + reverse: function(tbody) { + // reverse the rows in a tbody + newrows = []; + for (var i=0; i=0; i--) { + tbody.appendChild(newrows[i]); + } + delete newrows; + }, + + /* sort functions + each sort function takes two parameters, a and b + you are comparing a[0] and b[0] */ + sort_numeric: function(a,b) { + aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); + if (isNaN(aa)) aa = 0; + bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); + if (isNaN(bb)) bb = 0; + return aa-bb; + }, + sort_alpha: function(a,b) { + if (a[0]==b[0]) return 0; + if (a[0] 0 ) { + var q = list[i]; list[i] = list[i+1]; list[i+1] = q; + swap = true; + } + } // for + t--; + + if (!swap) break; + + for(var i = t; i > b; --i) { + if ( comp_func(list[i], list[i-1]) < 0 ) { + var q = list[i]; list[i] = list[i-1]; list[i-1] = q; + swap = true; + } + } // for + b++; + + } // while(swap) + } +} + +/* ****************************************************************** + Supporting functions: bundled here to avoid depending on a library + ****************************************************************** */ + +// Dean Edwards/Matthias Miller/John Resig + +/* for Mozilla/Opera9 */ +if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", sorttable.init, false); +} + +/* for Internet Explorer */ +/*@cc_on @*/ +/*@if (@_win32) + document.write("