diff --git a/application/config/.gitignore b/application/config/.gitignore new file mode 100644 index 00000000..aa5195c6 --- /dev/null +++ b/application/config/.gitignore @@ -0,0 +1 @@ +local/* \ No newline at end of file diff --git a/application/config/error.php b/application/config/error.php index d0029390..6b13b0d2 100644 --- a/application/config/error.php +++ b/application/config/error.php @@ -49,7 +49,7 @@ 'logger' => function($severity, $message) { - System\File::append(APP_PATH.'storage/log.txt', date('Y-m-d H:i:s').' '.$severity.' - '.$message.PHP_EOL); + System\File::append(STORAGE_PATH.'log.txt', date('Y-m-d H:i:s').' '.$severity.' - '.$message.PHP_EOL); }, ); \ No newline at end of file diff --git a/application/storage/db/.gitignore b/application/storage/db/.gitignore index e69de29b..6a91a439 100644 --- a/application/storage/db/.gitignore +++ b/application/storage/db/.gitignore @@ -0,0 +1 @@ +*.sqlite \ No newline at end of file diff --git a/license.txt b/license.txt deleted file mode 100644 index 49ab775e..00000000 --- a/license.txt +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2011 Taylor Otwell - taylorotwell@gmail.com - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/public/index.php b/public/index.php index aed6bb74..d7cf0932 100644 --- a/public/index.php +++ b/public/index.php @@ -5,18 +5,32 @@ * @package Laravel * @version 1.3.0 * @author Taylor Otwell - * @license MIT License - * @link http://laravel.com + * @link http://laravel.com */ // -------------------------------------------------------------- -// Define the framework paths. +// Define the core framework paths. // -------------------------------------------------------------- -define('BASE_PATH', realpath('../').'/'); define('APP_PATH', realpath('../application').'/'); define('SYS_PATH', realpath('../system').'/'); define('PUBLIC_PATH', realpath(__DIR__.'/')); +define('BASE_PATH', realpath('../').'/'); + +// -------------------------------------------------------------- +// Define various other framework paths. +// -------------------------------------------------------------- +define('CACHE_PATH', APP_PATH.'storage/cache/'); +define('CONFIG_PATH', APP_PATH.'config/'); +define('DATABASE_PATH', APP_PATH.'storage/db/'); +define('LANG_PATH', APP_PATH.'lang/'); +define('LIBRARY_PATH', APP_PATH.'libraries/'); +define('MODEL_PATH', APP_PATH.'models/'); define('PACKAGE_PATH', APP_PATH.'packages/'); +define('ROUTE_PATH', APP_PATH.'routes/'); +define('SESSION_PATH', APP_PATH.'storage/sessions/'); +define('STORAGE_PATH', APP_PATH.'storage/'); +define('SYS_VIEW_PATH', SYS_PATH.'views/'); +define('VIEW_PATH', APP_PATH.'views/'); // -------------------------------------------------------------- // Define the PHP file extension. @@ -32,7 +46,25 @@ // -------------------------------------------------------------- // Register the auto-loader. // -------------------------------------------------------------- -spl_autoload_register(require SYS_PATH.'loader'.EXT); +spl_autoload_register(function($class) +{ + $file = strtolower(str_replace('\\', '/', $class)); + + if (array_key_exists($class, $aliases = System\Config::get('aliases'))) + { + return class_alias($aliases[$class], $class); + } + + foreach (array(BASE_PATH, MODEL_PATH, LIBRARY_PATH) as $directory) + { + if (file_exists($path = $directory.$file.EXT)) + { + require $path; + + return; + } + } +}); // -------------------------------------------------------------- // Set the error reporting and display levels. @@ -91,9 +123,9 @@ // ---------------------------------------------------------- if (is_null($response)) { - $route = System\Router::route(Request::method(), Request::uri()); + $route = System\Router::route(System\Request::method(), System\Request::uri()); - $response = (is_null($route)) ? System\Response::make(View::make('error/404'), 404) : $route->call(); + $response = (is_null($route)) ? System\Response::make(System\View::make('error/404'), 404) : $route->call(); } else { diff --git a/readme.md b/readme.md deleted file mode 100644 index b498e6bd..00000000 --- a/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -# Laravel - A Clean & Classy PHP Framework - -## For complete documentation: http://laravel.com \ No newline at end of file diff --git a/readme.txt b/readme.txt new file mode 100644 index 00000000..52e8b5d9 --- /dev/null +++ b/readme.txt @@ -0,0 +1,10 @@ +Laravel - A Clean & Classy PHP Framework + +For complete documentation: http://laravel.com + +Laravel is a clean and classy framework for PHP web development. Freeing you +from spaghetti code, Laravel helps you create wonderful applications using +simple, expressive syntax. Development should be a creative experience that you +enjoy, not something that is painful. + +Creator: Taylor Otwell \ No newline at end of file diff --git a/system/cache/driver/file.php b/system/cache/driver/file.php index 442f1cfd..3b266d96 100644 --- a/system/cache/driver/file.php +++ b/system/cache/driver/file.php @@ -22,12 +22,12 @@ public function has($key) */ public function get($key) { - if ( ! file_exists(APP_PATH.'storage/cache/'.$key)) + if ( ! file_exists(CACHE_PATH.$key)) { return null; } - $cache = file_get_contents(APP_PATH.'storage/cache/'.$key); + $cache = file_get_contents(CACHE_PATH.$key); if (time() >= substr($cache, 0, 10)) { @@ -49,7 +49,7 @@ public function get($key) */ public function put($key, $value, $minutes) { - file_put_contents(APP_PATH.'storage/cache/'.$key, (time() + ($minutes * 60)).serialize($value), LOCK_EX); + file_put_contents(CACHE_PATH.$key, (time() + ($minutes * 60)).serialize($value), LOCK_EX); } /** @@ -60,7 +60,7 @@ public function put($key, $value, $minutes) */ public function forget($key) { - @unlink(APP_PATH.'storage/cache/'.$key); + @unlink(CACHE_PATH.$key); } } \ No newline at end of file diff --git a/system/config.php b/system/config.php index af8360c3..e1727da9 100644 --- a/system/config.php +++ b/system/config.php @@ -7,7 +7,7 @@ class Config { * * @var array */ - private static $items = array(); + public static $items = array(); /** * Determine if a configuration item or file exists. @@ -95,14 +95,26 @@ private static function parse($key) /** * Load all of the configuration items from a file. * + * If it exists, the configuration file in the application/config directory will be loaded first. + * Any environment specific configuration files will be merged with the root file. + * * @param string $file * @return void */ public static function load($file) { - if ( ! array_key_exists($file, static::$items) and file_exists($path = APP_PATH.'config/'.$file.EXT)) + if (array_key_exists($file, static::$items)) return; + + $config = (file_exists($path = CONFIG_PATH.$file.EXT)) ? require $path : array(); + + if (isset($_SERVER['LARAVEL_ENV']) and file_exists($path = CONFIG_PATH.$_SERVER['LARAVEL_ENV'].'/'.$file.EXT)) { - static::$items[$file] = require $path; + $config = array_merge($config, require $path); + } + + if (count($config) > 0) + { + static::$items[$file] = $config; } } diff --git a/system/db.php b/system/db.php index 4769fc74..e2765f61 100644 --- a/system/db.php +++ b/system/db.php @@ -33,6 +33,19 @@ public static function connection($connection = null) return static::$connections[$connection]; } + /** + * Execute a SQL query against the connection and return the first result. + * + * @param string $sql + * @param array $bindings + * @param string $connection + * @return object + */ + public static function first($sql, $bindings = array(), $connection = null) + { + return (count($results = static::query($sql, $bindings, $connection)) > 0) ? $results[0] : null; + } + /** * Execute a SQL query against the connection. * @@ -46,7 +59,7 @@ public static function connection($connection = null) * @param string $sql * @param array $bindings * @param string $connection - * @return mixed + * @return array */ public static function query($sql, $bindings = array(), $connection = null) { diff --git a/system/db/connector.php b/system/db/connector.php index 13d44184..769f4f27 100644 --- a/system/db/connector.php +++ b/system/db/connector.php @@ -54,7 +54,7 @@ public static function connect($connection) */ private static function connect_to_sqlite($config) { - if (file_exists($path = APP_PATH.'storage/db/'.$config->database.'.sqlite')) + if (file_exists($path = DATABASE_PATH.$config->database.'.sqlite')) { return new \PDO('sqlite:'.$path, null, null, static::$options); } diff --git a/system/db/eloquent.php b/system/db/eloquent.php index d4a1a64f..f0eb9d9e 100644 --- a/system/db/eloquent.php +++ b/system/db/eloquent.php @@ -202,7 +202,7 @@ private function _paginate($per_page = null) $current_page = \System\Paginator::page($total, $per_page); - return new \System\Paginator($this->for_page($current_page, $per_page)->get(), $total, $per_page); + return \System\Paginator::make($this->for_page($current_page, $per_page)->get(), $total, $per_page); } /** diff --git a/system/db/query.php b/system/db/query.php index 15a2e4f8..5260f9a8 100644 --- a/system/db/query.php +++ b/system/db/query.php @@ -413,7 +413,6 @@ public function find($id, $columns = array('*')) */ public function first($columns = array('*')) { - return (count($results = $this->take(1)->get($columns)) > 0) ? $results[0] : null; } @@ -458,15 +457,29 @@ private function aggregate($aggregator, $column) * Get paginated query results. * * @param int $per_page + * @param array $columns * @return Paginator */ - public function paginate($per_page) + public function paginate($per_page, $columns = array('*')) { + $select = $this->select; + $total = $this->count(); + // Every query clears the SELECT clause, so we store the contents of the clause + // before executing the count query and then put the contents back in afterwards. + if ( ! is_null($select)) + { + $this->select = $select; + } + else + { + $this->select($columns); + } + $current_page = \System\Paginator::page($total, $per_page); - return new \System\Paginator($this->for_page($current_page, $per_page)->get(), $total, $per_page); + return \System\Paginator::make($this->for_page($current_page, $per_page)->get(), $total, $per_page); } /** diff --git a/system/html.php b/system/html.php index f7c53282..e4da34ee 100644 --- a/system/html.php +++ b/system/html.php @@ -35,6 +35,18 @@ public static function style($url, $media = 'all') return ''.PHP_EOL; } + /** + * Generate a HTML span. + * + * @param string $value + * @param array $attributes + * @return string + */ + public static function span($value, $attributes = array()) + { + return ''.static::entities($value).''; + } + /** * Generate a HTML link. * diff --git a/system/lang.php b/system/lang.php index 711d489d..7a0b177e 100644 --- a/system/lang.php +++ b/system/lang.php @@ -9,21 +9,21 @@ class Lang { * * @var array */ - private static $lines = array(); + public static $lines = array(); /** * The key of the line that is being requested. * * @var string */ - private $key; + public $key; /** * The place-holder replacements. * * @var array */ - private $replacements = array(); + public $replacements = array(); /** * Create a new Lang instance. @@ -117,7 +117,9 @@ private function parse($key) */ private function load($file, $language) { - if ( ! array_key_exists($language.$file, static::$lines) and file_exists($path = APP_PATH.'lang/'.$language.'/'.$file.EXT)) + if (array_key_exists($language.$file, static::$lines)) return; + + if (file_exists($path = LANG_PATH.$language.'/'.$file.EXT)) { static::$lines[$language.$file] = require $path; } diff --git a/system/loader.php b/system/loader.php deleted file mode 100644 index adf3a126..00000000 --- a/system/loader.php +++ /dev/null @@ -1,35 +0,0 @@ -last_page = $last_page; + $this->per_page = $per_page; + $this->results = $results; + $this->total = $total; + $this->page = $page; + } /** * Create a new Paginator instance. * - * @param array $results - * @param int $total - * @param int $per_page - * @return void + * @param array $results + * @param int $total + * @param int $per_page + * @return Paginator */ - public function __construct($results, $total, $per_page) + public static function make($results, $total, $per_page) { - $this->page = static::page($total, $per_page); - $this->last_page = ceil($total / $per_page); - $this->per_page = $per_page; - $this->results = $results; - $this->total = $total; + return new static($results, static::page($total, $per_page), $total, $per_page, ceil($total / $per_page)); } /** * Get the current page from the request query string. * * The page will be validated and adjusted if it is less than one or greater than the last page. + * For example, if the current page is not an integer or less than one, one will be returned. + * If the current page is greater than the last page, the last page will be returned. * * @param int $total * @param int $per_page @@ -83,10 +93,10 @@ public static function page($total, $per_page) if (is_numeric($page) and $page > $last_page = ceil($total / $per_page)) { - return $last_page; + return ($last_page > 0) ? $last_page : 1; } - return (filter_var($page, FILTER_VALIDATE_INT) === false or $page < 1) ? 1 : $page; + return ($page < 1 or filter_var($page, FILTER_VALIDATE_INT) === false) ? 1 : $page; } /** @@ -110,8 +120,6 @@ public function links($adjacent = 3) */ private function numbers($adjacent = 3) { - // "7" is added to the adjacent range to account for the seven constant elements - // in a slider: the first and last two links, the current page, and the two "..." strings. return ($this->last_page < 7 + ($adjacent * 2)) ? $this->range(1, $this->last_page) : $this->slider($adjacent); } @@ -125,7 +133,7 @@ private function slider($adjacent) { if ($this->page <= $adjacent * 2) { - return $this->range(1, 4 + ($adjacent * 2)).$this->ending(); + return $this->range(1, 2 + ($adjacent * 2)).$this->ending(); } elseif ($this->page >= $this->last_page - ($adjacent * 2)) { @@ -144,12 +152,7 @@ public function previous() { $text = Lang::line('pagination.previous')->get($this->language); - if ($this->page > 1) - { - return HTML::link(Request::uri().'?page='.($this->page - 1), $text, array('class' => 'prev_page'), $this->https).' '; - } - - return "$text "; + return ($this->page > 1) ? $this->link($this->page - 1, $text, 'prev_page').' ' : HTML::span($text, array('class' => 'disabled prev_page')).' '; } /** @@ -161,12 +164,7 @@ public function next() { $text = Lang::line('pagination.next')->get($this->language); - if ($this->page < $this->last_page) - { - return HTML::link(Request::uri().'?page='.($this->page + 1), $text, array('class' => 'next_page'), $this->https); - } - - return "$text"; + return ($this->page < $this->last_page) ? $this->link($this->page + 1, $text, 'next_page') : HTML::span($text, array('class' => 'disabled next_page')); } /** @@ -176,7 +174,7 @@ public function next() */ private function beginning() { - return $this->range(1, 2).'... '; + return $this->range(1, 2).'...'; } /** @@ -186,7 +184,7 @@ private function beginning() */ private function ending() { - return '... '.$this->range($this->last_page - 1, $this->last_page); + return '...'.$this->range($this->last_page - 1, $this->last_page); } /** @@ -194,8 +192,8 @@ private function ending() * * For the current page, an HTML span element will be generated instead of a link. * - * @param int $start - * @param int $end + * @param int $start + * @param int $end * @return string */ private function range($start, $end) @@ -204,14 +202,27 @@ private function range($start, $end) for ($i = $start; $i <= $end; $i++) { - $pages .= ($this->page == $i) ? "$i " : HTML::link(Request::uri().'?page='.$i, $i, array(), $this->https).' '; + $pages .= ($this->page == $i) ? HTML::span($i, array('class' => 'current')).' ' : $this->link($i, $i, null).' '; } return $pages; } /** - * Set the language that should be used when generating pagination links. + * Create a HTML page link. + * + * @param int $page + * @param string $text + * @param string $attributes + * @return string + */ + private function link($page, $text, $class) + { + return HTML::link(Request::uri().'?page='.$page, $text, array('class' => $class), Request::is_secure()); + } + + /** + * Set the language that should be used when generating page links. * * @param string $language * @return Paginator @@ -222,15 +233,4 @@ public function lang($language) return $this; } - /** - * Force the pagination links to use HTTPS. - * - * @return Paginator - */ - public function secure() - { - $this->https = true; - return $this; - } - } \ No newline at end of file diff --git a/system/response.php b/system/response.php index c1734d2b..3a3f7dd6 100644 --- a/system/response.php +++ b/system/response.php @@ -101,6 +101,18 @@ public static function make($content, $status = 200) return new static($content, $status); } + /** + * Factory for creating new error response instances. + * + * @param int $code + * @param array $data + * @return Response + */ + public static function error($code, $data = array()) + { + return static::make(View::make('error/'.$code, $data), $code); + } + /** * Take a value returned by a route and prepare a Response instance. * diff --git a/system/router.php b/system/router.php index e7328759..731d64f0 100644 --- a/system/router.php +++ b/system/router.php @@ -3,11 +3,27 @@ class Router { /** - * All of the loaded routes. + * All of the loaded routes keyed by route file. * * @var array */ - public static $routes; + public static $routes = array(); + + /** + * Simulate a request to a given route. Useful for implementing HMVC. + * + * @param array|string $parameters + * @return Response + */ + public static function call($parameters) + { + $route = static::route('GET', (is_array($parameters)) ? implode('/', $parameters) : (string) $parameters); + + if ( ! is_null($route)) + { + return $route->call(); + } + } /** * Search a set of routes for the route matching a method and URI. @@ -18,22 +34,19 @@ class Router { */ public static function route($method, $uri) { - if (is_null(static::$routes)) - { - static::$routes = static::load($uri); - } + $routes = static::load($uri); // Put the request method and URI in route form. // Routes begin with the request method and a forward slash. $uri = $method.' /'.trim($uri, '/'); // Is there an exact match for the request? - if (isset(static::$routes[$uri])) + if (isset($routes[$uri])) { - return Request::$route = new Route($uri, static::$routes[$uri]); + return Request::$route = new Route($uri, $routes[$uri]); } - foreach (static::$routes as $keys => $callback) + foreach ($routes as $keys => $callback) { // Only check routes that have multiple URIs or wildcards. // Other routes would have been caught by the check for literal matches. @@ -58,7 +71,7 @@ public static function route($method, $uri) */ public static function load($uri) { - $base = require APP_PATH.'routes'.EXT; + $base = (isset(static::$routes[$path = APP_PATH.'routes'.EXT])) ? static::$routes[$path] : static::$routes[$path] = require $path; return (is_dir(APP_PATH.'routes') and $uri !== '') ? array_merge(static::load_from_directory($uri), $base) : $base; } @@ -77,9 +90,13 @@ private static function load_from_directory($uri) // Iterate backwards through the URI looking for the deepest matching file. foreach (array_reverse($segments, true) as $key => $value) { - if (file_exists($path = APP_PATH.'routes/'.implode('/', array_slice($segments, 0, $key + 1)).EXT)) + if (isset(static::$routes[$path = ROUTE_PATH.implode('/', array_slice($segments, 0, $key + 1)).EXT])) { - return require $path; + return static::$routes[$path]; + } + elseif (file_exists($path)) + { + return static::$routes[$path] = require $path; } } diff --git a/system/session/driver/file.php b/system/session/driver/file.php index 47c70f10..e6788ab0 100644 --- a/system/session/driver/file.php +++ b/system/session/driver/file.php @@ -10,7 +10,7 @@ class File implements \System\Session\Driver { */ public function load($id) { - if (file_exists($path = APP_PATH.'storage/sessions/'.$id)) + if (file_exists($path = SESSION_PATH.$id)) { return unserialize(file_get_contents($path)); } @@ -24,7 +24,7 @@ public function load($id) */ public function save($session) { - file_put_contents(APP_PATH.'storage/sessions/'.$session['id'], serialize($session), LOCK_EX); + file_put_contents(SESSION_PATH.$session['id'], serialize($session), LOCK_EX); } /** @@ -35,7 +35,7 @@ public function save($session) */ public function delete($id) { - @unlink(APP_PATH.'storage/sessions/'.$id); + @unlink(SESSION_PATH.$id); } /** @@ -46,7 +46,7 @@ public function delete($id) */ public function sweep($expiration) { - foreach (glob(APP_PATH.'storage/sessions/*') as $file) + foreach (glob(SESSION_PATH.'*') as $file) { if (filetype($file) == 'file' and filemtime($file) < $expiration) { diff --git a/system/url.php b/system/url.php index 0755ba56..30cd3c2d 100644 --- a/system/url.php +++ b/system/url.php @@ -5,6 +5,8 @@ class URL { /** * Generate an application URL. * + * If the given URL is already well-formed, it will be returned unchanged. + * * @param string $url * @param bool $https * @param bool $asset @@ -12,26 +14,18 @@ class URL { */ public static function to($url = '', $https = false, $asset = false) { - if (strpos($url, '://') !== false) + if (filter_var($url, FILTER_VALIDATE_URL) !== false) { return $url; } - $base = Config::get('application.url'); + $base = Config::get('application.url').'/'.Config::get('application.index'); - // If the URL is being generated for a public asset such as an - // image, we do not want to include "index.php" in the path. - if ( ! $asset) - { - $base .= '/'.Config::get('application.index'); - } + $base = ($asset) ? str_replace('/'.Config::get('application.index'), '', $base) : $base; - if (strpos($base, 'http://') === 0 and $https) - { - $base = 'https://'.substr($base, 7); - } + $base = ($https and strpos($base, 'http://') === 0) ? 'https://'.substr($base, 7) : $base; - return rtrim($base, '/').'/'.trim($url, '/'); + return rtrim($base, '/').'/'.ltrim($url, '/'); } /** @@ -52,9 +46,9 @@ public static function to_secure($url = '') * @param string $url * @return string */ - public static function to_asset($url = '') + public static function to_asset($url) { - return static::to($url, false, true); + return static::to($url, Request::is_secure(), true); } /** diff --git a/system/view.php b/system/view.php index 40b64467..bcfc9750 100644 --- a/system/view.php +++ b/system/view.php @@ -49,6 +49,25 @@ public static function make($view, $data = array()) return new static($view, $data); } + /** + * Create a new named view instance. + * + * @param string $view + * @param array $data + * @return View + */ + public static function of($view, $data = array()) + { + $views = Config::get('view.names'); + + if ( ! array_key_exists($view, $views)) + { + throw new \Exception("Named view [$view] is not defined."); + } + + return static::make($views[$view], $data); + } + /** * Get the parsed content of the view. * @@ -82,20 +101,31 @@ public function get() * * @return string */ - private function find() + protected function find() { - if (file_exists($path = APP_PATH.'views/'.$this->view.EXT)) + if (file_exists($path = VIEW_PATH.$this->view.EXT)) { return $path; } - elseif (file_exists($path = SYS_PATH.'views/'.$this->view.EXT)) + elseif (file_exists($path = SYS_VIEW_PATH.$this->view.EXT)) { return $path; } - else - { - throw new \Exception("View [".$this->view."] doesn't exist."); - } + + throw new \Exception("View [".$this->view."] doesn't exist."); + } + + /** + * Add a view instance to the view data. + * + * @param string $key + * @param string $view + * @param array $data + * @return View + */ + public function partial($key, $view, $data = array()) + { + return $this->bind($key, static::make($view, $data)); } /** @@ -118,14 +148,7 @@ public static function __callStatic($method, $parameters) { if (strpos($method, 'of_') === 0) { - $views = Config::get('view.names'); - - if ( ! array_key_exists($view = substr($method, 3), $views)) - { - throw new \Exception("Named view [$view] is not defined."); - } - - return static::make($views[$view], (isset($parameters[0]) and is_array($parameters[0])) ? $parameters[0] : array()); + return static::of(substr($method, 3), Arr::get($parameters, 0, array())); } } diff --git a/unlicense.txt b/unlicense.txt new file mode 100644 index 00000000..00d2e135 --- /dev/null +++ b/unlicense.txt @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to \ No newline at end of file